summaryrefslogtreecommitdiffstats
path: root/runtime/transport/procfs.c
diff options
context:
space:
mode:
authortrz <trz>2006-03-15 16:14:09 +0000
committertrz <trz>2006-03-15 16:14:09 +0000
commit5b1cd012831a6b729422e34cf0ed616600613771 (patch)
tree069912a0908ebcc8f3e7f80fa5f18bb5c510a34b /runtime/transport/procfs.c
parent9e0abebdf8aca24910b68ed35107926aab91443b (diff)
downloadsystemtap-steved-5b1cd012831a6b729422e34cf0ed616600613771.tar.gz
systemtap-steved-5b1cd012831a6b729422e34cf0ed616600613771.tar.xz
systemtap-steved-5b1cd012831a6b729422e34cf0ed616600613771.zip
Fix for bug #2406 (autodetect supported relayfs versions)
Diffstat (limited to 'runtime/transport/procfs.c')
-rw-r--r--runtime/transport/procfs.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index 96337466..22b14046 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -31,13 +31,13 @@ _stp_proc_read (struct file *file, char __user *buf, size_t count, loff_t *ppos)
return -EINVAL;
out.cpu = cpu;
-#ifdef RELAYFS_VERSION_GE_4
+#if RELAYFS_VERSION_GE_4 || defined (CONFIG_RELAY)
out.produced = _stp_chan->buf[cpu]->subbufs_produced;
out.consumed = _stp_chan->buf[cpu]->subbufs_consumed;
#else
out.produced = atomic_read(&_stp_chan->buf[cpu]->subbufs_produced);
out.consumed = atomic_read(&_stp_chan->buf[cpu]->subbufs_consumed);
-#endif /* RELAYFS_VERSION_GE_4 */
+#endif /* RELAYFS_VERSION_GE_4 || CONFIG_RELAY */
num = sizeof(out);
if (copy_to_user(buf, &out, num))
@@ -262,6 +262,38 @@ err:
return _stp_current_buffers;
}
+#if defined (STP_RELAYFS) && defined(CONFIG_RELAY)
+struct dentry *module_dir_dentry;
+
+static inline struct dentry *_stp_get_proc_root(void)
+{
+ struct file_system_type *procfs_type;
+ struct super_block *procfs_sb;
+
+ procfs_type = get_fs_type("proc");
+ if (!procfs_type || list_empty(&procfs_type->fs_supers))
+ return NULL;
+ procfs_sb = list_entry(procfs_type->fs_supers.next,
+ struct super_block, s_instances);
+ return procfs_sb->s_root;
+}
+
+static inline struct dentry *_stp_force_dir_creation(const char *dirname, struct dentry *parent)
+{
+ struct dentry *dir_dentry;
+
+ mutex_lock(&parent->d_inode->i_mutex);
+ dir_dentry = lookup_one_len(dirname, parent, strlen(dirname));
+ mutex_unlock(&parent->d_inode->i_mutex);
+ if (IS_ERR(dir_dentry)) {
+ dir_dentry = NULL;
+ remove_proc_entry(dirname, NULL);
+ }
+
+ return dir_dentry;
+}
+#endif /* STP_RELAYFS && CONFIG_RELAY */
+
static int _stp_register_procfs (void)
{
int i;
@@ -270,6 +302,10 @@ static int _stp_register_procfs (void)
int j;
char buf[8];
#endif
+#if defined (CONFIG_RELAY)
+ struct dentry *proc_root_dentry;
+ struct dentry *systemtap_dir_dentry;
+#endif /* CONFIG_RELAY */
struct proc_dir_entry *de;
struct list_head *p, *tmp;
@@ -301,11 +337,23 @@ static int _stp_register_procfs (void)
goto err0;
}
+#if defined (STP_RELAYFS) && defined (CONFIG_RELAY)
+ proc_root_dentry = _stp_get_proc_root();
+ systemtap_dir_dentry = _stp_force_dir_creation(dirname, proc_root_dentry);
+ if (!systemtap_dir_dentry)
+ goto err0;
+#endif /* STP_RELAYFS && CONFIG_RELAY */
/* now create /proc/systemtap/module_name */
_stp_proc_mod = proc_mkdir (THIS_MODULE->name, _stp_proc_root);
if (_stp_proc_mod == NULL)
goto err0;
+#if defined (STP_RELAYFS) && defined (CONFIG_RELAY)
+ module_dir_dentry = _stp_force_dir_creation(THIS_MODULE->name, systemtap_dir_dentry);
+ if (!module_dir_dentry)
+ goto err0;
+#endif /* STP_RELAYFS && CONFIG_RELAY */
+
#ifdef STP_RELAYFS
/* now for each cpu "n", create /proc/systemtap/module_name/n */
for_each_cpu(i) {