summaryrefslogtreecommitdiffstats
path: root/tapset
diff options
context:
space:
mode:
authorJeff Moyer <jmoyer@redhat.com>2009-07-17 15:19:26 -0400
committerFrank Ch. Eigler <fche@elastic.org>2009-07-17 15:19:26 -0400
commit003ea323310bd597c7263344cefd232377d8d89e (patch)
tree660a586d7a20863ecedb885f1200c4865b81876d /tapset
parentea14cf671a7ad543ad4752b301883789ab86f70f (diff)
downloadsystemtap-steved-003ea323310bd597c7263344cefd232377d8d89e.tar.gz
systemtap-steved-003ea323310bd597c7263344cefd232377d8d89e.tar.xz
systemtap-steved-003ea323310bd597c7263344cefd232377d8d89e.zip
PR10410: dentry tapset, autofs4 sample
* tapset/dentry.stp: New d_path, d_name, reverse_path_walk. * .../examples/.../autofs4.*: New autofs demo. Signed-off-by: Frank Ch. Eigler <fche@elastic.org>
Diffstat (limited to 'tapset')
-rw-r--r--tapset/dentry.stp117
1 files changed, 117 insertions, 0 deletions
diff --git a/tapset/dentry.stp b/tapset/dentry.stp
new file mode 100644
index 00000000..af8a866f
--- /dev/null
+++ b/tapset/dentry.stp
@@ -0,0 +1,117 @@
+// dentry tapset
+// Copyright (c) 2009 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+
+function __dentry_IS_ROOT:long(dentry:long)
+{
+ return (@cast(dentry, "dentry")->d_parent == dentry)
+}
+
+
+function __dentry_prepend:string(dentry:long,name:string)
+{
+ dname = d_name(dentry)
+
+ /*
+ * In case we are following down a mount point trigger, we can get
+ * multiple instances of a root mount.
+ */
+ c = substr(name, strlen(name)-1, strlen(name)-1)
+ if (dname == "/" && c == "/")
+ return name;
+
+ return sprintf("%s/%s", dname, name);
+}
+
+
+
+%{
+#include <linux/sched.h>
+#include <linux/fs_struct.h>
+%}
+
+
+function __dentry_get_current_root:long()
+%{
+ THIS->__retvalue = (long)&current->fs->root;
+%}
+
+
+
+
+/**
+ * sfunction d_name - get the dirent name
+ *
+ * Returns the dirent name (path basename).
+ * @dentry: Pointer to dentry.
+ */
+function d_name:string(dentry:long)
+{
+ len = @cast(dentry, "dentry")->d_name->len;
+ return kernel_string_n(@cast(dentry, "dentry")->d_name->name, len);
+}
+
+
+
+/**
+ * sfunction reverse_path_walk - get the full dirent path
+ *
+ * Returns the path name (partial path to mount point).
+ * @dentry: Pointer to dentry.
+ */
+function reverse_path_walk:string(dentry:long)
+{
+ while(1) {
+ name = __dentry_prepend(dentry, name);
+ dentry = @cast(dentry, "dentry")->d_parent;
+ if (__dentry_IS_ROOT(dentry))
+ return name;
+ }
+}
+
+
+
+/**
+ * sfunction d_path - get the full nameidata path
+ *
+ * Returns the full dirent name (full path to the root), like
+ * the kernel d_path function.
+ * @nd: Pointer to nameidata.
+ */
+function d_path:string(nd:long)
+{
+ root = __dentry_get_current_root()
+ dentry = %( kernel_vr < "2.6.25"
+ %? @cast(nd,"nameidata")->dentry
+ %: @cast(nd,"nameidata")->path->dentry
+ %)
+ vfsmnt = %( kernel_vr < "2.6.25"
+ %? @cast(nd,"nameidata")->mnt
+ %: @cast(nd,"nameidata")->path->mnt
+ %)
+ while (1) {
+ if (dentry == @cast(root, "path")->dentry &&
+ vfsmnt == @cast(root, "path")->mnt)
+ break;
+
+ if (dentry == @cast(vfsmnt, "vfsmount")->mnt_root ||
+ __dentry_IS_ROOT(dentry)) {
+ /* Global root? */
+ if (@cast(vfsmnt, "vfsmount")->mnt_parent == vfsmnt)
+ return sprintf("/%s", name);
+
+ dentry = @cast(vfsmnt, "vfsmount")->mnt_mountpoint;
+ vfsmnt = @cast(vfsmnt, "vfsmount")->mnt_parent;
+ continue;
+ }
+ name = __dentry_prepend(dentry, name);
+ dentry = @cast(dentry, "dentry")->d_parent;
+ }
+
+ return sprintf("/%s", name);
+}