diff options
author | trz <trz> | 2006-03-15 16:14:09 +0000 |
---|---|---|
committer | trz <trz> | 2006-03-15 16:14:09 +0000 |
commit | 5b1cd012831a6b729422e34cf0ed616600613771 (patch) | |
tree | 069912a0908ebcc8f3e7f80fa5f18bb5c510a34b /runtime/transport/procfs.c | |
parent | 9e0abebdf8aca24910b68ed35107926aab91443b (diff) | |
download | systemtap-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.c | 52 |
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) { |