Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: e037af55da
Fetching contributors…

Cannot retrieve contributors at this time

286 lines (261 sloc) 8.221 kb
From michael.meeks@novell.com Fri Dec 4 09:44:01 2009
Subject: io tracing patch vs. 2.6.31 ...
From: Michael Meeks <michael.meeks@novell.com>
To: Greg Kroah-Hartman <GregKH@novell.com>
Date: Fri, 04 Dec 2009 17:47:04 +0000
Message-Id: <1259948824.6186.1668.camel@linux-h3ht.site>
This patch, inspired by Arjan, and Scott James Remnant's work adds
the ability to easily add trace points that refer to files, and
print full paths.
It also adds three of these trace points to open(), exec() and uselib()
Signed-off-by: Michael Meeks <michael.meeks@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/exec.c | 6 ++++++
fs/open.c | 4 ++++
include/linux/ftrace_event.h | 4 ++++
include/trace/ftrace.h | 28 ++++++++++++++++++++++++++++
kernel/trace/trace_events.c | 32 ++++++++++++++++++++++++++++++++
5 files changed, 74 insertions(+), 0 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index 077a075..757262a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -58,6 +58,8 @@
#include <linux/pipe_fs_i.h>
#include <trace/fs.h>
+#include <trace/events/fs-open.h>
+
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
@@ -138,6 +140,8 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
fsnotify_open(file->f_path.dentry);
+ trace_uselib(file);
+
error = -ENOEXEC;
if(file->f_op) {
struct linux_binfmt * fmt;
@@ -671,6 +675,8 @@ struct file *open_exec(const char *name)
fsnotify_open(file->f_path.dentry);
+ trace_open_exec(file);
+
if (file->f_op && file->f_op->open_exec) {
err = file->f_op->open_exec(file->f_path.dentry->d_inode);
if (err)
diff --git a/fs/open.c b/fs/open.c
index 2d5b513..d6065eb 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -35,6 +35,9 @@
DEFINE_TRACE(fs_open);
DEFINE_TRACE(fs_close);
+#define CREATE_TRACE_POINTS
+#include <trace/events/fs-open.h>
+
int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
int retval = -ENODEV;
@@ -1047,6 +1050,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
} else {
fsnotify_open(f->f_path.dentry);
fd_install(fd, f);
+ trace_do_sys_open(f, flags, mode);
}
trace_fs_open(fd, tmp);
}
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 4ec5e67..a620bb9 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -167,6 +167,10 @@ extern int trace_define_common_fields(struct ftrace_event_call *call);
int trace_set_clr_event(const char *system, const char *event, int set);
+/* file pointer helpers */
+extern int ftrace_file_name_len (const struct file *f);
+extern void ftrace_assign_file (char *dest, int dest_len, const struct file *f);
+
/*
* The double __builtin_constant_p is because gcc will give us an error
* if we try to allocate the static variable to fmt if it is not a
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index dacb8ef..914561e 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -33,6 +33,9 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef TP_STRUCT__entry
#define TP_STRUCT__entry(args...) args
@@ -89,6 +92,10 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) int item; \
+ int item##__size;
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
struct ftrace_data_offsets_##call { \
@@ -151,6 +158,9 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef __entry
#define __entry REC
@@ -315,6 +325,9 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
static int \
@@ -360,6 +373,14 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \
+#undef __file_p
+#define __file_p(item, src) \
+ __data_offsets->item = __data_size + \
+ offsetof(typeof(*entry), __data); \
+ __data_offsets->item##__size = ftrace_file_name_len(src); \
+ __data_size += __data_offsets->item##__size;
+
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
static inline int ftrace_get_offsets_##call( \
@@ -543,10 +564,17 @@ static void ftrace_profile_disable_##call(void) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1) \
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1) \
+
#undef __assign_str
#define __assign_str(dst, src) \
strcpy(__get_str(dst), src);
+#undef __assign_file_p
+#define __assign_file_p(dst, src) \
+ ftrace_assign_file(__get_str (dst), __data_offsets.dst##__size, src);
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
\
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d128f65..a733c58 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -93,6 +93,38 @@ int trace_define_common_fields(struct ftrace_event_call *call)
}
EXPORT_SYMBOL_GPL(trace_define_common_fields);
+/* file pointer helpers */
+int ftrace_file_name_len (const struct file *f)
+{
+ /* This performs pretty terribly - obviously */
+ int len = 1;
+ char *buf, *fname;
+
+ if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+ return len;
+ fname = d_path(&f->f_path, buf, PAGE_SIZE);
+ if (!IS_ERR (fname))
+ len += strlen (fname);
+ kfree(buf);
+ return len;
+}
+
+void ftrace_assign_file (char *dest, int dest_len, const struct file *f)
+{
+ char *buf, *fname;
+
+ dest[0] = '\0';
+ if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+ return;
+
+ /* it would be nicer to write this directly into the
+ * allocated buffer, but d_path doesn't like that */
+ fname = d_path(&f->f_path, buf, PAGE_SIZE);
+ if (!IS_ERR (fname))
+ strncpy (dest, fname, dest_len);
+ kfree(buf);
+}
+
#ifdef CONFIG_MODULES
static void trace_destroy_fields(struct ftrace_event_call *call)
diff --git a/dev/null b/include/trace/events/fs-open.h
new file mode 100644
index 0000000..b1aa653
--- /dev/null
+++ b/include/trace/events/fs-open.h
@@ -0,0 +1,66 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fs-open
+
+#if !defined(_TRACE_FS_OPEN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FS_OPEN_H
+
+#include <linux/fs.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Here we have a problem; the __string macro uses __dynamic_array,
+ * which requires the ability to know it's own length before we
+ * allocate the buffer - in the get_offsets_ call - which does not
+ * know the length of the resulting path we create in TP_fast_assign.
+ * So - give up and use a fixed length.
+ */
+TRACE_EVENT(do_sys_open,
+
+ TP_PROTO(struct file *filp, int flags, int mode),
+
+ TP_ARGS(filp, flags, mode),
+
+ TP_STRUCT__entry(
+ __file_p( filename, filp )
+ __field( int, flags )
+ __field( int, mode )
+ ),
+
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ __entry->flags = flags;
+ __entry->mode = mode;
+ ),
+
+ TP_printk("\"%s\" %x %o", __get_str(filename),
+ __entry->flags, __entry->mode)
+);
+
+TRACE_EVENT(uselib,
+ TP_PROTO(struct file *filp),
+ TP_ARGS(filp),
+ TP_STRUCT__entry(
+ __file_p(filename, filp)
+ ),
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ ),
+ TP_printk("\"%s\"", __get_str(filename))
+);
+
+TRACE_EVENT(open_exec,
+ TP_PROTO(struct file *filp),
+ TP_ARGS(filp),
+ TP_STRUCT__entry(
+ __file_p(filename, filp)
+ ),
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ ),
+ TP_printk("\"%s\"", __get_str(filename))
+);
+
+#endif /* _TRACE_FS_OPEN_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
Jump to Line
Something went wrong with that request. Please try again.