rpms/kernel/F-11 linux-2.6-utrace-ftrace.patch, 1.3, 1.4 kernel.spec, 1.1699, 1.1700 linux-2.6-tracehook.patch, 1.10, 1.11 linux-2.6-utrace.patch, 1.112, 1.113
Kyle McMartin
kyle at fedoraproject.org
Mon Aug 10 20:49:42 UTC 2009
Author: kyle
Update of /cvs/pkgs/rpms/kernel/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv11473
Modified Files:
kernel.spec linux-2.6-tracehook.patch linux-2.6-utrace.patch
Added Files:
linux-2.6-utrace-ftrace.patch
Log Message:
utrace & tracehook rebase, utrace-ftrace build fixes
linux-2.6-utrace-ftrace.patch:
include/linux/processtrace.h | 41 ++
kernel/trace/Kconfig | 9
kernel/trace/Makefile | 1
kernel/trace/trace.h | 9
kernel/trace/trace_process.c | 599 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 658 insertions(+), 1 deletion(-)
Index: linux-2.6-utrace-ftrace.patch
===================================================================
RCS file: linux-2.6-utrace-ftrace.patch
diff -N linux-2.6-utrace-ftrace.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ftrace.patch 10 Aug 2009 20:49:41 -0000 1.4
@@ -0,0 +1,766 @@
+utrace-based ftrace "process" engine, v2
+
+This is v2 of the prototype utrace-ftrace interface. This code is
+based on Roland McGrath's utrace API, which provides programmatic
+hooks to the in-tree tracehook layer. This new patch interfaces many
+of those events to ftrace, as configured by a small number of debugfs
+controls. Here's the /debugfs/tracing/process_trace_README:
+
+process event tracer mini-HOWTO
+
+1. Select process hierarchy to monitor. Other processes will be
+completely unaffected. Leave at 0 for system-wide tracing.
+% echo NNN > process_follow_pid
+
+2. Determine which process event traces are potentially desired.
+syscall and signal tracing slow down monitored processes.
+% echo 0 > process_trace_{syscalls,signals,lifecycle}
+
+3. Add any final uid- or taskcomm-based filtering. Non-matching
+processes will skip trace messages, but will still be slowed.
+% echo NNN > process_trace_uid_filter # -1: unrestricted
+% echo ls > process_trace_taskcomm_filter # empty: unrestricted
+
+4. Start tracing.
+% echo process > current_tracer
+
+5. Examine trace.
+% cat trace
+
+6. Stop tracing.
+% echo nop > current_tracer
+
+Signed-off-by: Frank Ch. Eigler <fche at redhat.com>
+---
+diff --git a/include/linux/processtrace.h b/include/linux/processtrace.h
+new file mode 100644
+index 0000000..f2b7d94
+--- /dev/null
++++ b/include/linux/processtrace.h
+@@ -0,0 +1,41 @@
++#ifndef PROCESSTRACE_H
++#define PROCESSTRACE_H
++
++#include <linux/types.h>
++#include <linux/list.h>
++
++struct process_trace_entry {
++ unsigned char opcode; /* one of _UTRACE_EVENT_* */
++ char comm[TASK_COMM_LEN]; /* XXX: should be in/via trace_entry */
++ union {
++ struct {
++ pid_t child;
++ unsigned long flags;
++ } trace_clone;
++ struct {
++ long code;
++ } trace_exit;
++ struct {
++ } trace_exec;
++ struct {
++ int si_signo;
++ int si_errno;
++ int si_code;
++ } trace_signal;
++ struct {
++ long callno;
++ unsigned long args[6];
++ } trace_syscall_entry;
++ struct {
++ long rc;
++ long error;
++ } trace_syscall_exit;
++ };
++};
++
++/* in kernel/trace/trace_process.c */
++
++extern void enable_process_trace(void);
++extern void disable_process_trace(void);
++
++#endif /* PROCESSTRACE_H */
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 417d198..4b412e3 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -189,6 +189,15 @@ config FTRACE_SYSCALLS
+ help
+ Basic tracer to catch the syscall entry and exit events.
+
++config PROCESS_TRACER
++ bool "Trace process events via utrace"
++ depends on DEBUG_KERNEL
++ select TRACING
++ select UTRACE
++ help
++ This tracer provides trace records from process events
++ accessible to utrace: lifecycle, system calls, and signals.
++
+ config BOOT_TRACER
+ bool "Trace boot initcalls"
+ select TRACING
+diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
+index 2630f51..c043a50 100644
+--- a/kernel/trace/Makefile
++++ b/kernel/trace/Makefile
+@@ -46,5 +46,6 @@ obj-$(CONFIG_EVENT_TRACER) += trace_export.o
+ obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
+ obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
+ obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o
++obj-$(CONFIG_PROCESS_TRACER) += trace_process.o
+
+ libftrace-y := ftrace.o
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index e685ac2..323b174 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -7,6 +7,7 @@
+ #include <linux/clocksource.h>
+ #include <linux/ring_buffer.h>
+ #include <linux/mmiotrace.h>
++#include <linux/processtrace.h>
+ #include <linux/ftrace.h>
+ #include <trace/boot.h>
+ #include <trace/kmemtrace.h>
+@@ -37,6 +38,7 @@ enum trace_type {
+ TRACE_KMEM_FREE,
+ TRACE_POWER,
+ TRACE_BLK,
++ TRACE_PROCESS,
+
+ __TRACE_LAST_TYPE,
+ };
+@@ -218,6 +220,10 @@ struct syscall_trace_exit {
+ unsigned long ret;
+ };
+
++struct trace_process {
++ struct trace_entry ent;
++ struct process_trace_entry event;
++};
+
+ /*
+ * trace_flag_type is an enumeration that holds different
+@@ -327,15 +333,16 @@ extern void __ftrace_bad_type(void);
+ IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \
+ TRACE_GRAPH_RET); \
+ IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
+- IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+ IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry, \
+ TRACE_KMEM_ALLOC); \
+ IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \
+ TRACE_KMEM_FREE); \
++ IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+ IF_ASSIGN(var, ent, struct syscall_trace_enter, \
+ TRACE_SYSCALL_ENTER); \
+ IF_ASSIGN(var, ent, struct syscall_trace_exit, \
+ TRACE_SYSCALL_EXIT); \
++ IF_ASSIGN(var, ent, struct trace_process, TRACE_PROCESS); \
+ __ftrace_bad_type(); \
+ } while (0)
+
+diff --git a/kernel/trace/trace_process.c b/kernel/trace/trace_process.c
+new file mode 100644
+index 0000000..e877f95
+--- /dev/null
++++ b/kernel/trace/trace_process.c
+@@ -0,0 +1,599 @@
++/*
++ * utrace-based process event tracing
++ * Copyright (C) 2009 Red Hat Inc.
++ * By Frank Ch. Eigler <fche at redhat.com>
++ *
++ * Based on mmio ftrace engine by Pekka Paalanen
++ * and utrace-syscall-tracing prototype by Ananth Mavinakayanahalli
++ */
++
++/* #define DEBUG 1 */
++
++#include <linux/kernel.h>
++#include <linux/utrace.h>
++#include <linux/uaccess.h>
++#include <linux/debugfs.h>
++#include <asm/syscall.h>
++
++#include "trace.h"
++#include "trace_output.h"
++
++/* A process must match these filters in order to be traced. */
++static char trace_taskcomm_filter[TASK_COMM_LEN]; /* \0: unrestricted */
++static u32 trace_taskuid_filter = -1; /* -1: unrestricted */
++static u32 trace_lifecycle_p = 1;
++static u32 trace_syscalls_p = 1;
++static u32 trace_signals_p = 1;
++
++/* A process must be a direct child of given pid in order to be
++ followed. */
++static u32 process_follow_pid; /* 0: unrestricted/systemwide */
++
++/* XXX: lock the above? */
++
++
++/* trace data collection */
++
++static struct trace_array *process_trace_array;
++
++static void process_reset_data(struct trace_array *tr)
++{
++ pr_debug("in %s\n", __func__);
++ tracing_reset_online_cpus(tr);
++}
++
++static int process_trace_init(struct trace_array *tr)
++{
++ pr_debug("in %s\n", __func__);
++ process_trace_array = tr;
++ process_reset_data(tr);
++ enable_process_trace();
++ return 0;
++}
++
++static void process_trace_reset(struct trace_array *tr)
++{
++ pr_debug("in %s\n", __func__);
++ disable_process_trace();
++ process_reset_data(tr);
++ process_trace_array = NULL;
++}
++
++static void process_trace_start(struct trace_array *tr)
++{
++ pr_debug("in %s\n", __func__);
++ process_reset_data(tr);
++}
++
++static void __trace_processtrace(struct trace_array *tr,
++ struct trace_array_cpu *data,
++ struct process_trace_entry *ent)
++{
++ struct ring_buffer_event *event;
++ struct trace_process *entry;
++
++ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
++ if (!event)
++ return;
++ entry = ring_buffer_event_data(event);
++ tracing_generic_entry_update(&entry->ent, 0, preempt_count());
++ entry->ent.type = TRACE_PROCESS;
++ strlcpy(ent->comm, current->comm, TASK_COMM_LEN);
++ entry->event = *ent;
++ ring_buffer_unlock_commit(tr->buffer, event);
++
++ trace_wake_up();
++}
++
++void process_trace(struct process_trace_entry *ent)
++{
++ struct trace_array *tr = process_trace_array;
++ struct trace_array_cpu *data;
++
++ preempt_disable();
++ data = tr->data[smp_processor_id()];
++ __trace_processtrace(tr, data, ent);
++ preempt_enable();
++}
++
++
++/* trace data rendering */
++
++static void process_pipe_open(struct trace_iterator *iter)
++{
++ struct trace_seq *s = &iter->seq;
++ pr_debug("in %s\n", __func__);
++ trace_seq_printf(s, "VERSION 200901\n");
++}
++
++static void process_close(struct trace_iterator *iter)
++{
++ iter->private = NULL;
++}
++
++static ssize_t process_read(struct trace_iterator *iter, struct file *filp,
++ char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++ ssize_t ret;
++ struct trace_seq *s = &iter->seq;
++ ret = trace_seq_to_user(s, ubuf, cnt);
++ return (ret == -EBUSY) ? 0 : ret;
++}
++
++static enum print_line_t process_print(struct trace_iterator *iter)
++{
++ struct trace_entry *entry = iter->ent;
++ struct trace_process *field;
++ struct trace_seq *s = &iter->seq;
++ unsigned long long t = ns2usecs(iter->ts);
++ unsigned long usec_rem = do_div(t, 1000000ULL);
++ unsigned secs = (unsigned long)t;
++ int ret = 1;
++
++ trace_assign_type(field, entry);
++
++ /* XXX: If print_lat_fmt() were not static, we wouldn't have
++ to duplicate this. */
++ trace_seq_printf(s, "%16s %5d %9lu.%06ld ",
++ field->event.comm,
++ entry->pid,
++ secs,
++ usec_rem);
++
++ switch (field->event.opcode) {
++ case _UTRACE_EVENT_CLONE:
++ ret = trace_seq_printf(s, "fork %d flags 0x%lx\n",
++ field->event.trace_clone.child,
++ field->event.trace_clone.flags);
++ break;
++ case _UTRACE_EVENT_EXEC:
++ ret = trace_seq_printf(s, "exec\n");
++ break;
++ case _UTRACE_EVENT_EXIT:
++ ret = trace_seq_printf(s, "exit %ld\n",
++ field->event.trace_exit.code);
++ break;
++ case _UTRACE_EVENT_SIGNAL:
++ ret = trace_seq_printf(s, "signal %d errno %d code 0x%x\n",
++ field->event.trace_signal.si_signo,
++ field->event.trace_signal.si_errno,
++ field->event.trace_signal.si_code);
++ break;
++ case _UTRACE_EVENT_SYSCALL_ENTRY:
++ ret = trace_seq_printf(s, "syscall %ld [0x%lx 0x%lx 0x%lx"
++ " 0x%lx 0x%lx 0x%lx]\n",
++ field->event.trace_syscall_entry.callno,
++ field->event.trace_syscall_entry.args[0],
++ field->event.trace_syscall_entry.args[1],
++ field->event.trace_syscall_entry.args[2],
++ field->event.trace_syscall_entry.args[3],
++ field->event.trace_syscall_entry.args[4],
++ field->event.trace_syscall_entry.args[5]);
++ break;
++ case _UTRACE_EVENT_SYSCALL_EXIT:
++ ret = trace_seq_printf(s, "syscall rc %ld error %ld\n",
++ field->event.trace_syscall_exit.rc,
++ field->event.trace_syscall_exit.error);
++ break;
++ default:
++ ret = trace_seq_printf(s, "process code %d?\n",
++ field->event.opcode);
++ break;
++ }
++ if (ret)
++ return TRACE_TYPE_HANDLED;
++ return TRACE_TYPE_HANDLED;
++}
++
++
++static enum print_line_t process_print_line(struct trace_iterator *iter)
++{
++ switch (iter->ent->type) {
++ case TRACE_PROCESS:
++ return process_print(iter);
++ default:
++ return TRACE_TYPE_HANDLED; /* ignore unknown entries */
++ }
++}
++
++static struct tracer process_tracer = {
++ .name = "process",
++ .init = process_trace_init,
++ .reset = process_trace_reset,
++ .start = process_trace_start,
++ .pipe_open = process_pipe_open,
++ .close = process_close,
++ .read = process_read,
++ .print_line = process_print_line,
++};
++
++
++
++/* utrace backend */
++
++/* Should tracing apply to given task? Compare against filter
++ values. */
++static int trace_test(struct task_struct *tsk)
++{
++ if (trace_taskcomm_filter[0]
++ && strncmp(trace_taskcomm_filter, tsk->comm, TASK_COMM_LEN))
++ return 0;
++
++ if (trace_taskuid_filter != (u32)-1
++ && trace_taskuid_filter != task_uid(tsk))
++ return 0;
++
++ return 1;
++}
++
++
++static const struct utrace_engine_ops process_trace_ops;
++
++static void process_trace_tryattach(struct task_struct *tsk)
++{
++ struct utrace_engine *engine;
++
++ pr_debug("in %s\n", __func__);
++ engine = utrace_attach_task(tsk,
++ UTRACE_ATTACH_CREATE |
++ UTRACE_ATTACH_EXCLUSIVE,
++ &process_trace_ops, NULL);
++ if (IS_ERR(engine) || (engine == NULL)) {
++ pr_warning("utrace_attach_task %d (rc %p)\n",
++ tsk->pid, engine);
++ } else {
++ int rc;
++
++ /* We always hook cost-free events. */
++ unsigned long events =
++ UTRACE_EVENT(CLONE) |
++ UTRACE_EVENT(EXEC) |
++ UTRACE_EVENT(EXIT);
++
++ /* Penalizing events are individually controlled, so that
++ utrace doesn't even take the monitored threads off their
++ fast paths, nor bother call our callbacks. */
++ if (trace_syscalls_p)
++ events |= UTRACE_EVENT_SYSCALL;
++ if (trace_signals_p)
++ events |= UTRACE_EVENT_SIGNAL_ALL;
++
++ rc = utrace_set_events(tsk, engine, events);
++ if (rc == -EINPROGRESS)
++ rc = utrace_barrier(tsk, engine);
++ if (rc)
++ pr_warning("utrace_set_events/barrier rc %d\n", rc);
++
++ utrace_engine_put(engine);
++ pr_debug("attached in %s to %s(%d)\n", __func__,
++ tsk->comm, tsk->pid);
++ }
++}
++
++
++u32 process_trace_report_clone(enum utrace_resume_action action,
++ struct utrace_engine *engine,
++ struct task_struct *parent,
++ unsigned long clone_flags,
++ struct task_struct *child)
++{
++ if (trace_lifecycle_p && trace_test(parent)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_CLONE;
++ ent.trace_clone.child = child->pid;
++ ent.trace_clone.flags = clone_flags;
++ process_trace(&ent);
++ }
++
++ process_trace_tryattach(child);
++
++ return UTRACE_RESUME;
++}
++
++
++u32 process_trace_report_syscall_entry(u32 action,
++ struct utrace_engine *engine,
++ struct task_struct *task,
++ struct pt_regs *regs)
++{
++ if (trace_syscalls_p && trace_test(task)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_SYSCALL_ENTRY;
++ ent.trace_syscall_entry.callno = syscall_get_nr(task, regs);
++ syscall_get_arguments(task, regs, 0, 6,
++ ent.trace_syscall_entry.args);
++ process_trace(&ent);
++ }
++
++ return UTRACE_RESUME;
++}
++
++
++u32 process_trace_report_syscall_exit(enum utrace_resume_action action,
++ struct utrace_engine *engine,
++ struct task_struct *task,
++ struct pt_regs *regs)
++{
++ if (trace_syscalls_p && trace_test(task)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_SYSCALL_EXIT;
++ ent.trace_syscall_exit.rc =
++ syscall_get_return_value(task, regs);
++ ent.trace_syscall_exit.error = syscall_get_error(task, regs);
++ process_trace(&ent);
++ }
++
++ return UTRACE_RESUME;
++}
++
++
++u32 process_trace_report_exec(enum utrace_resume_action action,
++ struct utrace_engine *engine,
++ struct task_struct *task,
++ const struct linux_binfmt *fmt,
++ const struct linux_binprm *bprm,
++ struct pt_regs *regs)
++{
++ if (trace_lifecycle_p && trace_test(task)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_EXEC;
++ process_trace(&ent);
++ }
++
++ /* We're already attached; no need for a new tryattach. */
++
++ return UTRACE_RESUME;
++}
++
++
++u32 process_trace_report_signal(u32 action,
++ struct utrace_engine *engine,
++ struct task_struct *task,
++ struct pt_regs *regs,
++ siginfo_t *info,
++ const struct k_sigaction *orig_ka,
++ struct k_sigaction *return_ka)
++{
++ if (trace_signals_p && trace_test(task)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_SIGNAL;
++ ent.trace_signal.si_signo = info->si_signo;
++ ent.trace_signal.si_errno = info->si_errno;
++ ent.trace_signal.si_code = info->si_code;
++ process_trace(&ent);
++ }
++
++ /* We're already attached, so no need for a new tryattach. */
++
++ return UTRACE_RESUME | utrace_signal_action(action);
++}
++
++
++u32 process_trace_report_exit(enum utrace_resume_action action,
++ struct utrace_engine *engine,
++ struct task_struct *task,
++ long orig_code, long *code)
++{
++ if (trace_lifecycle_p && trace_test(task)) {
++ struct process_trace_entry ent;
++ ent.opcode = _UTRACE_EVENT_EXIT;
++ ent.trace_exit.code = orig_code;
++ process_trace(&ent);
++ }
++
++ /* There is no need to explicitly attach or detach here. */
++
++ return UTRACE_RESUME;
++}
++
++
++void enable_process_trace()
++{
++ struct task_struct *grp, *tsk;
++
++ pr_debug("in %s\n", __func__);
++ rcu_read_lock();
++ do_each_thread(grp, tsk) {
++ /* Skip over kernel threads. */
++ if (tsk->flags & PF_KTHREAD)
++ continue;
++
++ if (process_follow_pid) {
++ if (tsk->tgid == process_follow_pid ||
++ tsk->parent->tgid == process_follow_pid)
++ process_trace_tryattach(tsk);
++ } else {
++ process_trace_tryattach(tsk);
++ }
++ } while_each_thread(grp, tsk);
++ rcu_read_unlock();
++}
++
++void disable_process_trace()
++{
++ struct utrace_engine *engine;
++ struct task_struct *grp, *tsk;
++ int rc;
++
++ pr_debug("in %s\n", __func__);
++ rcu_read_lock();
++ do_each_thread(grp, tsk) {
++ /* Find matching engine, if any. Returns -ENOENT for
++ unattached threads. */
++ engine = utrace_attach_task(tsk, UTRACE_ATTACH_MATCH_OPS,
++ &process_trace_ops, 0);
++ if (IS_ERR(engine)) {
++ if (PTR_ERR(engine) != -ENOENT)
++ pr_warning("utrace_attach_task %d (rc %ld)\n",
++ tsk->pid, -PTR_ERR(engine));
++ } else if (engine == NULL) {
++ pr_warning("utrace_attach_task %d (null engine)\n",
++ tsk->pid);
++ } else {
++ /* Found one of our own engines. Detach. */
++ rc = utrace_control(tsk, engine, UTRACE_DETACH);
++ switch (rc) {
++ case 0: /* success */
++ break;
++ case -ESRCH: /* REAP callback already begun */
++ case -EALREADY: /* DEATH callback already begun */
++ break;
++ default:
++ rc = -rc;
++ pr_warning("utrace_detach %d (rc %d)\n",
++ tsk->pid, rc);
++ break;
++ }
++ utrace_engine_put(engine);
++ pr_debug("detached in %s from %s(%d)\n", __func__,
++ tsk->comm, tsk->pid);
++ }
++ } while_each_thread(grp, tsk);
++ rcu_read_unlock();
++}
++
++
++static const struct utrace_engine_ops process_trace_ops = {
++ .report_clone = process_trace_report_clone,
++ .report_exec = process_trace_report_exec,
++ .report_exit = process_trace_report_exit,
++ .report_signal = process_trace_report_signal,
++ .report_syscall_entry = process_trace_report_syscall_entry,
++ .report_syscall_exit = process_trace_report_syscall_exit,
++};
++
++
++
++/* control interfaces */
++
++
++static ssize_t
++trace_taskcomm_filter_read(struct file *filp, char __user *ubuf,
++ size_t cnt, loff_t *ppos)
++{
++ return simple_read_from_buffer(ubuf, cnt, ppos,
++ trace_taskcomm_filter, TASK_COMM_LEN);
++}
++
++
++static ssize_t
++trace_taskcomm_filter_write(struct file *filp, const char __user *ubuf,
++ size_t cnt, loff_t *fpos)
++{
++ char *end;
++
++ if (cnt > TASK_COMM_LEN)
++ cnt = TASK_COMM_LEN;
++
++ if (copy_from_user(trace_taskcomm_filter, ubuf, cnt))
++ return -EFAULT;
++
++ /* Cut from the first nil or newline. */
++ trace_taskcomm_filter[cnt] = '\0';
++ end = strchr(trace_taskcomm_filter, '\n');
++ if (end)
++ *end = '\0';
++
++ *fpos += cnt;
++ return cnt;
++}
++
++
++static const struct file_operations trace_taskcomm_filter_fops = {
++ .open = tracing_open_generic,
++ .read = trace_taskcomm_filter_read,
++ .write = trace_taskcomm_filter_write,
++};
++
++
++
++static char README_text[] =
++ "process event tracer mini-HOWTO\n"
++ "\n"
++ "1. Select process hierarchy to monitor. Other processes will be\n"
++ " completely unaffected. Leave at 0 for system-wide tracing.\n"
++ "# echo NNN > process_follow_pid\n"
++ "\n"
++ "2. Determine which process event traces are potentially desired.\n"
++ " syscall and signal tracing slow down monitored processes.\n"
++ "# echo 0 > process_trace_{syscalls,signals,lifecycle}\n"
++ "\n"
++ "3. Add any final uid- or taskcomm-based filtering. Non-matching\n"
++ " processes will skip trace messages, but will still be slowed.\n"
++ "# echo NNN > process_trace_uid_filter # -1: unrestricted \n"
++ "# echo ls > process_trace_taskcomm_filter # empty: unrestricted\n"
++ "\n"
++ "4. Start tracing.\n"
++ "# echo process > current_tracer\n"
++ "\n"
++ "5. Examine trace.\n"
++ "# cat trace\n"
++ "\n"
++ "6. Stop tracing.\n"
++ "# echo nop > current_tracer\n"
++ ;
++
++static struct debugfs_blob_wrapper README_blob = {
++ .data = README_text,
++ .size = sizeof(README_text),
++};
++
++
++static __init int init_process_trace(void)
++{
++ struct dentry *d_tracer;
++ struct dentry *entry;
++
++ d_tracer = tracing_init_dentry();
++
++ entry = debugfs_create_blob("process_trace_README", 0444, d_tracer,
++ &README_blob);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_README' entry\n");
++
++ /* Control for scoping process following. */
++ entry = debugfs_create_u32("process_follow_pid", 0644, d_tracer,
++ &process_follow_pid);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_follow_pid' entry\n");
++
++ /* Process-level filters */
++ entry = debugfs_create_file("process_trace_taskcomm_filter", 0644,
++ d_tracer, NULL,
++ &trace_taskcomm_filter_fops);
++ /* XXX: it'd be nice to have a read/write debugfs_create_blob. */
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_taskcomm_filter' entry\n");
++
++ entry = debugfs_create_u32("process_trace_uid_filter", 0644, d_tracer,
++ &trace_taskuid_filter);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_uid_filter' entry\n");
++
++ /* Event-level filters. */
++ entry = debugfs_create_u32("process_trace_lifecycle", 0644, d_tracer,
++ &trace_lifecycle_p);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_lifecycle' entry\n");
++
++ entry = debugfs_create_u32("process_trace_syscalls", 0644, d_tracer,
++ &trace_syscalls_p);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_syscalls' entry\n");
++
++ entry = debugfs_create_u32("process_trace_signals", 0644, d_tracer,
++ &trace_signals_p);
++ if (!entry)
++ pr_warning("Could not create debugfs "
++ "'process_trace_signals' entry\n");
++
++ return register_tracer(&process_tracer);
++}
++
++device_initcall(init_process_trace);
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1699
retrieving revision 1.1700
diff -u -p -r1.1699 -r1.1700
--- kernel.spec 10 Aug 2009 20:19:23 -0000 1.1699
+++ kernel.spec 10 Aug 2009 20:49:41 -0000 1.1700
@@ -592,6 +592,7 @@ Patch20: linux-2.6-hotfixes.patch
Patch21: linux-2.6-tracehook.patch
Patch22: linux-2.6-utrace.patch
+Patch23: linux-2.6-utrace-ftrace.patch
Patch41: linux-2.6-sysrq-c.patch
@@ -1104,6 +1105,7 @@ ApplyPatch linux-2.6-hotfixes.patch
# Roland's utrace ptrace replacement.
ApplyPatch linux-2.6-tracehook.patch
ApplyPatch linux-2.6-utrace.patch
+ApplyPatch linux-2.6-utrace-ftrace.patch
# mm patches
ApplyPatch linux-2.6-defaults-saner-vm-settings.patch
@@ -1873,12 +1875,6 @@ fi
# and build.
%changelog
-* Mon Aug 10 2009 Jarod Wilson <jarod at redhat.com>
-- Add tunable pad threshold support to lirc_imon
-- Blacklist all iMON devices in usbhid driver so lirc_imon can bind
-- Add new device ID to lirc_mceusb (#512483)
-- Enable IR transceiver on the HD PVR
-
* Mon Aug 10 2009 Kyle McMartin <kyle at redhat.com>
- Patch sync-up with F-11-2.6.29.y:
- linux-2.6-x86-delay-tsc-barrier.patch
@@ -1893,6 +1889,15 @@ fi
- linux-2.6-mm-lru-evict-streaming-io-pages-first.patch
- linux-2.6-mm-lru-report-vm-flags-in-page-referenced.patch
- linux-2.6-mm-lru-dont-evict-mapped-executable-pages.patch
+ - linux-2.6-utrace.patch
+ - linux-2.6-utrace-ftrace.patch
+ - linux-2.6-tracehook.patch
+
+* Mon Aug 10 2009 Jarod Wilson <jarod at redhat.com>
+- Add tunable pad threshold support to lirc_imon
+- Blacklist all iMON devices in usbhid driver so lirc_imon can bind
+- Add new device ID to lirc_mceusb (#512483)
+- Enable IR transceiver on the HD PVR
* Wed Aug 05 2009 Kyle McMartin <kyle at redhat.com>
- Update to released 2.6.30.4.
linux-2.6-tracehook.patch:
include/linux/tracehook.h | 25 ++++++++++------
kernel/signal.c | 69 +++++++++++++++++++++++-----------------------
2 files changed, 51 insertions(+), 43 deletions(-)
Index: linux-2.6-tracehook.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/linux-2.6-tracehook.patch,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 -r1.11
--- linux-2.6-tracehook.patch 25 Jul 2009 04:09:27 -0000 1.10
+++ linux-2.6-tracehook.patch 10 Aug 2009 20:49:41 -0000 1.11
@@ -14,12 +14,8 @@ readability to fold it in.
Signed-off-by: Roland McGrath <roland at redhat.com>
---
- include/linux/tracehook.h | 25 ++++++++++------
- kernel/signal.c | 69 +++++++++++++++++++++++----------------------
- 2 files changed, 51 insertions(+), 43 deletions(-)
-
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index c7aa154..4ec4821 100644
+index eb96603..6a168b9 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -1,7 +1,7 @@
@@ -31,7 +27,7 @@ index c7aa154..4ec4821 100644
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
-@@ -464,22 +464,29 @@ static inline int tracehook_get_signal(s
+@@ -463,22 +463,29 @@ static inline int tracehook_get_signal(struct task_struct *task,
/**
* tracehook_notify_jctl - report about job control stop/continue
@@ -70,10 +66,10 @@ index c7aa154..4ec4821 100644
#define DEATH_REAP -1
diff --git a/kernel/signal.c b/kernel/signal.c
-index d803473..424eff2 100644
+index d803473..424eff2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
-@@ -702,7 +702,7 @@ static int prepare_signal(int sig, struc
+@@ -702,7 +702,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
if (why) {
/*
@@ -174,7 +170,7 @@ index d803473..424eff2 100644
goto relock;
}
-@@ -1979,14 +1980,14 @@ void exit_signals(struct task_struct *ts
+@@ -1979,14 +1980,14 @@ void exit_signals(struct task_struct *tsk)
if (unlikely(tsk->signal->group_stop_count) &&
!--tsk->signal->group_stop_count) {
tsk->signal->flags = SIGNAL_STOP_STOPPED;
linux-2.6-utrace.patch:
Documentation/DocBook/Makefile | 2
Documentation/DocBook/utrace.tmpl | 590 +++++++++
fs/proc/array.c | 3
include/linux/init_task.h | 1
include/linux/sched.h | 6
include/linux/tracehook.h | 61
include/linux/utrace.h | 692 +++++++++++
include/linux/utrace_struct.h | 58
init/Kconfig | 9
kernel/Makefile | 1
kernel/ptrace.c | 18
kernel/utrace.c | 2357 ++++++++++++++++++++++++++++++++++++++
12 files changed, 3795 insertions(+), 3 deletions(-)
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/linux-2.6-utrace.patch,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -p -r1.112 -r1.113
--- linux-2.6-utrace.patch 25 Jul 2009 04:09:27 -0000 1.112
+++ linux-2.6-utrace.patch 10 Aug 2009 20:49:41 -0000 1.113
@@ -25,22 +25,8 @@ the utrace API.
Signed-off-by: Roland McGrath <roland at redhat.com>
---
- Documentation/DocBook/Makefile | 2 +-
- Documentation/DocBook/utrace.tmpl | 590 ++++++++++
- fs/proc/array.c | 3 +
- include/linux/init_task.h | 1 +
- include/linux/sched.h | 6 +
- include/linux/tracehook.h | 61 +-
- include/linux/utrace.h | 692 +++++++++++
- include/linux/utrace_struct.h | 58 +
- init/Kconfig | 9 +
- kernel/Makefile | 1 +
- kernel/ptrace.c | 18 +-
- kernel/utrace.c | 2357 +++++++++++++++++++++++++++++++++++++
- 12 files changed, 3795 insertions(+), 3 deletions(-)
-
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
-index b1eb661..02851f6 100644
+index b1eb661..02851f6 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -9,7 +9,7 @@
@@ -54,7 +40,7 @@ index b1eb661..02851f6 100644
mac80211.xml debugobjects.xml sh.xml regulator.xml \
diff --git a/Documentation/DocBook/utrace.tmpl b/Documentation/DocBook/utrace.tmpl
new file mode 100644
-index ...6cc58a1 100644
+index 0000000..6cc58a1
--- /dev/null
+++ b/Documentation/DocBook/utrace.tmpl
@@ -0,0 +1,590 @@
@@ -649,7 +635,7 @@ index ...6cc58a1 100644
+
+</book>
diff --git a/fs/proc/array.c b/fs/proc/array.c
-index 725a650..e299a63 100644
+index 725a650..e299a63 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -82,6 +82,7 @@
@@ -660,7 +646,7 @@ index 725a650..e299a63 100644
#include <asm/pgtable.h>
#include <asm/processor.h>
-@@ -188,6 +189,8 @@ static inline void task_state(struct seq
+@@ -188,6 +189,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
cred->uid, cred->euid, cred->suid, cred->fsuid,
cred->gid, cred->egid, cred->sgid, cred->fsgid);
@@ -670,7 +656,7 @@ index 725a650..e299a63 100644
if (p->files)
fdt = files_fdtable(p->files);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
-index d87247d..0d0b55d 100644
+index d87247d..0d0b55d 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -170,6 +170,7 @@ extern struct cred init_cred;
@@ -682,7 +668,7 @@ index d87247d..0d0b55d 100644
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index b4c38bc..30db106 100644
+index 03c6c36..fd11331 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -59,6 +59,7 @@ struct sched_param {
@@ -706,7 +692,7 @@ index b4c38bc..30db106 100644
u32 parent_exec_id;
u32 self_exec_id;
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index 4ec4821..a7de30f 100644
+index 6a168b9..d59e159 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -49,6 +49,7 @@
@@ -726,7 +712,7 @@ index 4ec4821..a7de30f 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -111,6 +114,9 @@ static inline void ptrace_report_syscall
+@@ -111,6 +114,9 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
static inline __must_check int tracehook_report_syscall_entry(
struct pt_regs *regs)
{
@@ -736,7 +722,7 @@ index 4ec4821..a7de30f 100644
ptrace_report_syscall(regs);
return 0;
}
-@@ -134,6 +140,8 @@ static inline __must_check int tracehook
+@@ -134,6 +140,8 @@ static inline __must_check int tracehook_report_syscall_entry(
*/
static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
{
@@ -745,7 +731,7 @@ index 4ec4821..a7de30f 100644
ptrace_report_syscall(regs);
}
-@@ -194,6 +202,8 @@ static inline void tracehook_report_exec
+@@ -194,6 +202,8 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
struct linux_binprm *bprm,
struct pt_regs *regs)
{
@@ -754,7 +740,7 @@ index 4ec4821..a7de30f 100644
if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
unlikely(task_ptrace(current) & PT_PTRACED))
send_sig(SIGTRAP, current, 0);
-@@ -211,6 +221,8 @@ static inline void tracehook_report_exec
+@@ -211,6 +221,8 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
*/
static inline void tracehook_report_exit(long *exit_code)
{
@@ -763,7 +749,7 @@ index 4ec4821..a7de30f 100644
ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
}
-@@ -254,6 +266,7 @@ static inline int tracehook_prepare_clon
+@@ -254,6 +266,7 @@ static inline int tracehook_prepare_clone(unsigned clone_flags)
static inline void tracehook_finish_clone(struct task_struct *child,
unsigned long clone_flags, int trace)
{
@@ -771,7 +757,7 @@ index 4ec4821..a7de30f 100644
ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace);
}
-@@ -280,6 +293,8 @@ static inline void tracehook_report_clon
+@@ -278,6 +291,8 @@ static inline void tracehook_report_clone(struct pt_regs *regs,
unsigned long clone_flags,
pid_t pid, struct task_struct *child)
{
@@ -780,7 +766,7 @@ index 4ec4821..a7de30f 100644
if (unlikely(task_ptrace(child))) {
/*
* It doesn't matter who attached/attaching to this
-@@ -311,6 +326,9 @@ static inline void tracehook_report_clon
+@@ -310,6 +325,9 @@ static inline void tracehook_report_clone_complete(int trace,
pid_t pid,
struct task_struct *child)
{
@@ -790,7 +776,7 @@ index 4ec4821..a7de30f 100644
if (unlikely(trace))
ptrace_event(0, trace, pid);
}
-@@ -345,6 +363,7 @@ static inline void tracehook_report_vfor
+@@ -344,6 +362,7 @@ static inline void tracehook_report_vfork_done(struct task_struct *child,
*/
static inline void tracehook_prepare_release_task(struct task_struct *task)
{
@@ -798,7 +784,7 @@ index 4ec4821..a7de30f 100644
}
/**
-@@ -359,6 +378,7 @@ static inline void tracehook_prepare_rel
+@@ -358,6 +377,7 @@ static inline void tracehook_prepare_release_task(struct task_struct *task)
static inline void tracehook_finish_release_task(struct task_struct *task)
{
ptrace_release_task(task);
@@ -806,7 +792,7 @@ index 4ec4821..a7de30f 100644
}
/**
-@@ -380,6 +400,8 @@ static inline void tracehook_signal_hand
+@@ -379,6 +399,8 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info,
const struct k_sigaction *ka,
struct pt_regs *regs, int stepping)
{
@@ -815,7 +801,7 @@ index 4ec4821..a7de30f 100644
if (stepping)
ptrace_notify(SIGTRAP);
}
-@@ -397,6 +419,8 @@ static inline void tracehook_signal_hand
+@@ -396,6 +418,8 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info,
static inline int tracehook_consider_ignored_signal(struct task_struct *task,
int sig)
{
@@ -824,7 +810,7 @@ index 4ec4821..a7de30f 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -416,6 +440,9 @@ static inline int tracehook_consider_ign
+@@ -415,6 +439,9 @@ static inline int tracehook_consider_ignored_signal(struct task_struct *task,
static inline int tracehook_consider_fatal_signal(struct task_struct *task,
int sig)
{
@@ -834,7 +820,7 @@ index 4ec4821..a7de30f 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -430,6 +457,8 @@ static inline int tracehook_consider_fat
+@@ -429,6 +456,8 @@ static inline int tracehook_consider_fatal_signal(struct task_struct *task,
*/
static inline int tracehook_force_sigpending(void)
{
@@ -843,7 +829,7 @@ index 4ec4821..a7de30f 100644
return 0;
}
-@@ -459,6 +488,8 @@ static inline int tracehook_get_signal(s
+@@ -458,6 +487,8 @@ static inline int tracehook_get_signal(struct task_struct *task,
siginfo_t *info,
struct k_sigaction *return_ka)
{
@@ -852,7 +838,7 @@ index 4ec4821..a7de30f 100644
return 0;
}
-@@ -486,6 +517,8 @@ static inline int tracehook_get_signal(s
+@@ -485,6 +516,8 @@ static inline int tracehook_get_signal(struct task_struct *task,
*/
static inline int tracehook_notify_jctl(int notify, int why)
{
@@ -861,7 +847,7 @@ index 4ec4821..a7de30f 100644
return notify ?: (current->ptrace & PT_PTRACED) ? why : 0;
}
-@@ -509,6 +542,8 @@ static inline int tracehook_notify_jctl(
+@@ -508,6 +541,8 @@ static inline int tracehook_notify_jctl(int notify, int why)
static inline int tracehook_notify_death(struct task_struct *task,
void **death_cookie, int group_dead)
{
@@ -870,7 +856,7 @@ index 4ec4821..a7de30f 100644
if (task_detached(task))
return task->ptrace ? SIGCHLD : DEATH_REAP;
-@@ -545,6 +580,20 @@ static inline void tracehook_report_deat
+@@ -544,6 +579,20 @@ static inline void tracehook_report_death(struct task_struct *task,
int signal, void *death_cookie,
int group_dead)
{
@@ -891,7 +877,7 @@ index 4ec4821..a7de30f 100644
}
#ifdef TIF_NOTIFY_RESUME
-@@ -574,10 +623,20 @@ static inline void set_notify_resume(str
+@@ -573,10 +622,20 @@ static inline void set_notify_resume(struct task_struct *task)
* asynchronously, this will be called again before we return to
* user mode.
*
@@ -915,7 +901,7 @@ index 4ec4821..a7de30f 100644
diff --git a/include/linux/utrace.h b/include/linux/utrace.h
new file mode 100644
-index ...f877ec6 100644
+index 0000000..f877ec6
--- /dev/null
+++ b/include/linux/utrace.h
@@ -0,0 +1,692 @@
@@ -1613,7 +1599,7 @@ index ...f877ec6 100644
+#endif /* linux/utrace.h */
diff --git a/include/linux/utrace_struct.h b/include/linux/utrace_struct.h
new file mode 100644
-index ...aba7e09 100644
+index 0000000..aba7e09
--- /dev/null
+++ b/include/linux/utrace_struct.h
@@ -0,0 +1,58 @@
@@ -1676,7 +1662,7 @@ index ...aba7e09 100644
+
+#endif /* linux/utrace_struct.h */
diff --git a/init/Kconfig b/init/Kconfig
-index 7be4d38..a6987df 100644
+index 7be4d38..a6987df 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1149,6 +1149,15 @@ config STOP_MACHINE
@@ -1696,7 +1682,7 @@ index 7be4d38..a6987df 100644
config PREEMPT_NOTIFIERS
diff --git a/kernel/Makefile b/kernel/Makefile
-index 4242366..a79634e 100644
+index 4242366..a79634e 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o
@@ -1708,7 +1694,7 @@ index 4242366..a79634e 100644
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index 0692ab5..1d33e9c 100644
+index 42c3178..3ac97b9 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -16,6 +16,7 @@
@@ -1719,7 +1705,7 @@ index 0692ab5..1d33e9c 100644
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/audit.h>
-@@ -174,6 +175,14 @@ bool ptrace_may_access(struct task_struc
+@@ -174,6 +175,14 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
return !err;
}
@@ -1746,7 +1732,7 @@ index 0692ab5..1d33e9c 100644
if (!task->mm)
goto bad;
/* the same process cannot be attached many times */
-@@ -588,7 +602,9 @@ int ptrace_traceme(void)
+@@ -590,7 +604,9 @@ int ptrace_traceme(void)
*/
repeat:
task_lock(current);
@@ -1759,7 +1745,7 @@ index 0692ab5..1d33e9c 100644
*/
diff --git a/kernel/utrace.c b/kernel/utrace.c
new file mode 100644
-index ...74b5fc5 100644
+index 0000000..74b5fc5
--- /dev/null
+++ b/kernel/utrace.c
@@ -0,0 +1,2357 @@
More information about the fedora-extras-commits
mailing list