From 7f2d56c366c79e11eb20f5fb9a226769ea1e8740 Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 18 Aug 2011 13:34:01 -0500 Subject: [PATCH] Fixed PR13055 by getting procfs probes working on 3.1 kernels. * runtime/procfs.c (_stp_rmdir_proc_module): Fix problem where '/proc/systemtap' wasn't getting removed correctly. (_stp_mkdir_proc_module): Add support for kernels where neither path_lookup() or kern_path_parent() are exported (such as the 3.1 kernels). * buildrun.cxx (compile_pass): Convert compile test for kern_path_parent() to an export test. Add exports tests for path_lookup() and vfs_path_lookup(). * runtime/autoconf-kern-path-parent.c: Removed. --- buildrun.cxx | 5 +-- runtime/autoconf-kern-path-parent.c | 7 ---- runtime/procfs.c | 52 +++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 12 deletions(-) delete mode 100644 runtime/autoconf-kern-path-parent.c diff --git a/buildrun.cxx b/buildrun.cxx index 60c774129..b0dc07021 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -249,8 +249,9 @@ compile_pass (systemtap_session& s) "STAPCONF_PERF_COUNTER_CONTEXT", NULL); output_autoconf(s, o, "perf_probe_handler_nmi.c", "STAPCONF_PERF_HANDLER_NMI", NULL); - output_autoconf(s, o, "autoconf-kern-path-parent.c", - "STAPCONF_KERN_PATH_PARENT", NULL); + output_exportconf(s, o, "path_lookup", "STAPCONF_PATH_LOOKUP"); + output_exportconf(s, o, "kern_path_parent", "STAPCONF_KERN_PATH_PARENT"); + output_exportconf(s, o, "vfs_path_lookup", "STAPCONF_VFS_PATH_LOOKUP"); // used by tapset/timestamp_monotonic.stp output_exportconf(s, o, "cpu_clock", "STAPCONF_CPU_CLOCK"); diff --git a/runtime/autoconf-kern-path-parent.c b/runtime/autoconf-kern-path-parent.c deleted file mode 100644 index fad64d6f5..000000000 --- a/runtime/autoconf-kern-path-parent.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -/* kernel commit c9c6cac0c2bdbda */ -int ____autoconf_func(const char *name) -{ - return kern_path_parent(name, NULL); -} diff --git a/runtime/procfs.c b/runtime/procfs.c index 3587f62d0..13712c467 100644 --- a/runtime/procfs.c +++ b/runtime/procfs.c @@ -12,6 +12,15 @@ #ifndef _STP_PROCFS_C_ #define _STP_PROCFS_C_ +#if (!defined(STAPCONF_PATH_LOOKUP) && !defined(STAPCONF_KERN_PATH_PARENT) \ + && !defined(STAPCONF_VFS_PATH_LOOKUP)) +#error "Either path_lookup(), kern_path_parent(), or vfs_path_lookup() must be exported by the kernel." +#endif + +#ifdef STAPCONF_VFS_PATH_LOOKUP +#include +#endif + /* The maximum number of files AND directories that can be opened. * It would be great if the translator would emit this based on the actual * number of needed files. @@ -20,7 +29,7 @@ #define STP_MAX_PROCFS_FILES 16 #endif -#ifndef STAPCONF_KERN_PATH_PARENT +#if defined(STAPCONF_PATH_LOOKUP) && !defined(STAPCONF_KERN_PATH_PARENT) #define kern_path_parent(name, nameidata) \ path_lookup(name, LOOKUP_PARENT, nameidata) #endif @@ -67,7 +76,7 @@ static void _stp_rmdir_proc_module(void) * though it will not show up in directory * listings. */ - if (atomic_read(&_stp_proc_stap->count) == 0) { + if (atomic_read(&_stp_proc_stap->count) == LAST_ENTRY_COUNT) { remove_proc_entry("systemtap", NULL); _stp_proc_stap = NULL; } @@ -83,6 +92,7 @@ static void _stp_rmdir_proc_module(void) static int _stp_mkdir_proc_module(void) { if (_stp_proc_root == NULL) { +#if defined(STAPCONF_PATH_LOOKUP) || defined(STAPCONF_KERN_PATH_PARENT) struct nameidata nd; if (!_stp_lock_transport_dir()) { @@ -119,7 +129,43 @@ static int _stp_mkdir_proc_module(void) path_release (&nd); #endif } - +#else /* STAPCONF_VFS_PATH_LOOKUP */ + struct path path; + struct vfsmount *mnt; + int rc; + + if (!_stp_lock_transport_dir()) { + errk("Unable to lock transport directory.\n"); + goto done; + } + + /* See if '/proc/systemtap' exists. */ + if (! init_pid_ns.proc_mnt) { + _stp_unlock_transport_dir(); + goto done; + } + mnt = init_pid_ns.proc_mnt; + rc = vfs_path_lookup(mnt->mnt_root, mnt, "systemtap", 0, + &path); + + /* If '/proc/systemtap' exists, update + * _stp_proc_stap. Otherwise create the directory. */ + if (rc == 0) { + _stp_proc_stap = PDE(path.dentry->d_inode); + path_put (&path); + } + else if (rc == -ENOENT) { + _stp_proc_stap = proc_mkdir ("systemtap", NULL); + if (_stp_proc_stap == NULL) { + _stp_unlock_transport_dir(); + goto done; + } + } +#endif /* STAPCONF_VFS_PATH_LOOKUP */ + + /* Now that we've found '/proc/systemtap', create the + * module specific directory + * '/proc/systemtap/MODULE_NAME'. */ _stp_proc_root = proc_mkdir(THIS_MODULE->name, _stp_proc_stap); #ifdef STAPCONF_PROCFS_OWNER if (_stp_proc_root != NULL) -- 2.43.5