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