Hi, Ian, I got a fairly simply request from a customer. They wanted to use systemtap to track automounter mount and unmount activity. Unfortunately, the compiler inlined the expire functions I wanted to instrument, so I needed to add a tracepoint to get at useful information.
This patch, then, adds a few trace points so that we don't have to worry about compiler inlining. I have an example script using these trace points that I'll be sending along to the systemtap mailing list shortly. Let me know what you think. If you're interested in trying it out, I've made my systemtap patch available at: http://people.redhat.com/jmoyer/systemtap You can try running testsuite/systemtap.examples/general/autofs.stp. It should run with or without the below patch applied, though the results are not as accurate (can't get full paths for unmounts) without the tracepoint in autofs4_do_expire_multi. Cheers, Jeff Signed-off-by: Jeff Moyer <[email protected]> diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index aa39ae8..6c86df9 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -13,6 +13,7 @@ * ------------------------------------------------------------------------- */ #include "autofs_i.h" +#include <trace/events/autofs4.h> static unsigned long now; @@ -496,6 +497,7 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, /* This is synchronous because it makes the daemon a little easier */ ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); + trace_autofs4_do_expire_multi(mnt, dentry, ret); spin_lock(&sbi->fs_lock); if (ino->flags & AUTOFS_INF_MOUNTPOINT) { diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index b96a3c5..cbb17b7 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -19,6 +19,9 @@ #include <linux/time.h> #include "autofs_i.h" +#define CREATE_TRACE_POINTS +#include <trace/events/autofs4.h> + static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); static int autofs4_dir_unlink(struct inode *,struct dentry *); static int autofs4_dir_rmdir(struct inode *,struct dentry *); @@ -216,6 +219,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) (!d_mountpoint(dentry) && __simple_empty(dentry))) { spin_unlock(&dcache_lock); + trace_autofs4_follow_link(nd, dentry); status = try_to_fill_dentry(dentry, 0); if (status) goto out_error; @@ -540,6 +544,8 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s dput(expiring); } + trace_autofs4_lookup(nd, dentry); + spin_lock(&dentry->d_lock); dentry->d_flags |= DCACHE_AUTOFS_PENDING; spin_unlock(&dentry->d_lock); diff --git a/include/trace/events/autofs4.h b/include/trace/events/autofs4.h new file mode 100644 index 0000000..dae6873 --- /dev/null +++ b/include/trace/events/autofs4.h @@ -0,0 +1,75 @@ +#if !defined(_TRACE_AUTOFS4_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_AUTOFS4_H + +#include <linux/dcache.h> +#include <linux/mount.h> +#include <linux/limits.h> +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM autofs4 + +TRACE_EVENT(autofs4_do_expire_multi, + TP_PROTO(struct vfsmount *mnt, struct dentry *dentry, int status), + TP_ARGS(mnt, dentry, status), + TP_STRUCT__entry( + __array(char, comm, TASK_COMM_LEN) + __field(pid_t, pid) + __array(char, path, MAX_FILTER_STR_VAL) + __field(int, status) + ), + TP_fast_assign( + __entry->pid = current->pid; + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + snprintf(__entry->path, + dentry->d_name.len < MAX_FILTER_STR_VAL ? + dentry->d_name.len : MAX_FILTER_STR_VAL, + "%s", dentry->d_name.name); + __entry->status = status; + ), + TP_printk("%s[%d]: expiry of %s %s", + __entry->comm, __entry->pid, __entry->path, + __entry->status == 0 ? "succeeded" : "failed") +); + +TRACE_EVENT(autofs4_lookup, + TP_PROTO(struct nameidata *nd, struct dentry *dentry), + TP_ARGS(nd, dentry), + TP_STRUCT__entry( + __array(char, comm, TASK_COMM_LEN) + __array(char, path, MAX_FILTER_STR_VAL) + __field(char *, pathptr) + __field(pid_t, pid) + ), + TP_fast_assign( + __entry->pid = current->pid; + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + __entry->pathptr = d_path(&nd->path, + __entry->path, MAX_FILTER_STR_VAL); + ), + TP_printk("%s[%d]: looking up %s", + __entry->comm, __entry->pid, __entry->pathptr) +); + +TRACE_EVENT(autofs4_follow_link, + TP_PROTO(struct nameidata *nd, struct dentry *dentry), + TP_ARGS(nd, dentry), + TP_STRUCT__entry( + __array(char, comm, TASK_COMM_LEN) + __array(char, path, MAX_FILTER_STR_VAL) + __field(char *, pathptr) + __field(pid_t, pid) + ), + TP_fast_assign( + __entry->pid = current->pid; + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + __entry->pathptr = d_path(&nd->path, + __entry->path, MAX_FILTER_STR_VAL); + ), + TP_printk("%s[%d]: looking up trigger %s", + __entry->comm, __entry->pid, __entry->pathptr) +); +#endif /* _TRACE_AUTOFS4_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> _______________________________________________ autofs mailing list [email protected] http://linux.kernel.org/mailman/listinfo/autofs
