summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/transport/ChangeLog8
-rw-r--r--runtime/transport/control.c6
-rw-r--r--runtime/transport/procfs.c59
-rw-r--r--runtime/transport/relayfs.c50
-rw-r--r--runtime/transport/symbols.c2
-rw-r--r--runtime/transport/transport.c108
-rw-r--r--runtime/transport/transport.h3
-rw-r--r--runtime/transport/utt.c40
-rw-r--r--runtime/transport/utt.h7
9 files changed, 220 insertions, 63 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index f752ccd4..e588e546 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,11 @@
+2007-03-26 Martin Hunt <hunt@redhat.com>
+
+ * symbols.c (_stp_do_module): If a module has no symbols, just
+ return NULL instead of an errorcode.
+
+ * control.c, procfs.c, relayfs.c, transport.c, utt.c, utt.h:
+ Revert back to using systemtap/modulename instead of systemtap_pid.
+
2007-03-21 Martin Hunt <hunt@redhat.com>
* symbols.c (_stp_del_module): Add a call to _stp_module_relocate
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index 3ad3e309..2924edab 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -206,7 +206,6 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
return len;
}
-
static struct file_operations _stp_ctl_fops_cmd = {
.owner = THIS_MODULE,
.read = _stp_ctl_read_cmd,
@@ -240,11 +239,10 @@ static int _stp_register_ctl_channel (void)
}
- /* create [debugfs]/systemtap_[pid]/cmd */
- _stp_cmd_file = debugfs_create_file("cmd", 0444, _stp_utt->utt_tree_root, NULL, &_stp_ctl_fops_cmd);
+ /* create [debugfs]/systemtap/module_name/cmd */
+ _stp_cmd_file = debugfs_create_file("cmd", 0444, _stp_utt->dir, NULL, &_stp_ctl_fops_cmd);
if (_stp_cmd_file == NULL)
goto err0;
-
return 0;
err0:
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index bb97c411..92724f9f 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -244,7 +244,7 @@ static struct file_operations _stp_proc_fops_cmd = {
.write = _stp_ctl_write_cmd,
};
-static struct proc_dir_entry *_stp_proc_root, *_stp_proc_pid;
+static struct proc_dir_entry *_stp_proc_root, *_stp_proc_mod;
/* copy since proc_match is not MODULE_EXPORT'd */
static int my_proc_match(int len, const char *name, struct proc_dir_entry *de)
@@ -295,6 +295,7 @@ err:
static int _stp_register_ctl_channel (void)
{
int i;
+ const char *dirname = "systemtap";
char buf[32];
#ifdef STP_BULKMODE
int j;
@@ -316,30 +317,53 @@ static int _stp_register_ctl_channel (void)
list_add (p, &_stp_pool_q);
}
- /* now create /proc/systemtap_[pid] */
- sprintf(buf, "systemtap_%d", _stp_pid);
- _stp_proc_pid = proc_mkdir (buf, NULL);
- if (!_stp_proc_pid)
+ if (!_stp_lock_debugfs()) {
+ errk("Unable to lock transport directory.\n");
goto err0;
+ }
+
+ /* look for existing /proc/systemtap */
+ for (de = proc_root.subdir; de; de = de->next) {
+ if (my_proc_match (strlen (dirname), dirname, de)) {
+ _stp_proc_root = de;
+ break;
+ }
+ }
+
+ /* create /proc/systemtap if it doesn't exist */
+ if (_stp_proc_root == NULL) {
+ _stp_proc_root = proc_mkdir (dirname, NULL);
+ if (_stp_proc_root == NULL) {
+ _stp_unlock_debugfs();
+ goto err0;
+ }
+ }
+ _stp_unlock_debugfs();
+
+ /* now create /proc/systemtap/module_name */
+ _stp_proc_mod = proc_mkdir (THIS_MODULE->name, _stp_proc_root);
+ if (_stp_proc_mod == NULL)
+ goto err0;
+
#ifdef STP_BULKMODE
- /* now for each cpu "n", create /proc/systemtap_[pid]/n */
+ /* now for each cpu "n", create /proc/systemtap/module_name/n */
for_each_cpu(i) {
sprintf(buf, "%d", i);
- de = create_proc_entry (buf, S_IFREG|S_IRUSR, _stp_proc_pid);
+ de = create_proc_entry (buf, S_IFREG|S_IRUSR, _stp_proc_mod);
if (de == NULL)
goto err1;
de->proc_fops = &_stp_proc_fops;
de->data = _stp_kmalloc(sizeof(int));
if (de->data == NULL) {
- remove_proc_entry (buf, _stp_proc_pid);
+ remove_proc_entry (buf, _stp_proc_mod);
goto err1;
}
*(int *)de->data = i;
}
#endif /* STP_BULKMODE */
- /* finally create /proc/systemtap_[pid]/cmd */
- de = create_proc_entry ("cmd", S_IFREG|S_IRUSR, _stp_proc_pid);
+ /* finally create /proc/systemtap/module_name/cmd */
+ de = create_proc_entry ("cmd", S_IFREG|S_IRUSR, _stp_proc_mod);
if (de == NULL)
goto err1;
de->proc_fops = &_stp_proc_fops_cmd;
@@ -347,18 +371,16 @@ static int _stp_register_ctl_channel (void)
err1:
#ifdef STP_BULKMODE
- for (de = _stp_proc_pid->subdir; de; de = de->next)
+ for (de = _stp_proc_mod->subdir; de; de = de->next)
kfree (de->data);
for_each_cpu(j) {
if (j == i)
break;
sprintf(buf, "%d", i);
- remove_proc_entry (buf, _stp_proc_pid);
+ remove_proc_entry (buf, _stp_proc_mod);
}
#endif /* STP_BULKMODE */
- sprintf(buf, "systemtap_%d", _stp_pid);
- remove_proc_entry (buf, NULL);
err0:
list_for_each_safe(p, tmp, &_stp_pool_q) {
list_del(p);
@@ -378,18 +400,17 @@ static void _stp_unregister_ctl_channel (void)
int i;
struct proc_dir_entry *de;
kbug("unregistering procfs\n");
- for (de = _stp_proc_pid->subdir; de; de = de->next)
+ for (de = _stp_proc_mod->subdir; de; de = de->next)
kfree (de->data);
for_each_cpu(i) {
sprintf(buf, "%d", i);
- remove_proc_entry (buf, _stp_proc_pid);
+ remove_proc_entry (buf, _stp_proc_mod);
}
#endif /* STP_BULKMODE */
- remove_proc_entry ("cmd", _stp_proc_pid);
- sprintf(buf, "systemtap_%d", _stp_pid);
- remove_proc_entry (buf, NULL);
+ remove_proc_entry ("cmd", _stp_proc_mod);
+ remove_proc_entry (THIS_MODULE->name, _stp_proc_root);
/* free memory pools */
list_for_each_safe(p, tmp, &_stp_pool_q) {
diff --git a/runtime/transport/relayfs.c b/runtime/transport/relayfs.c
index ccbdc63e..2615145c 100644
--- a/runtime/transport/relayfs.c
+++ b/runtime/transport/relayfs.c
@@ -26,13 +26,6 @@
static int _stp_relay_flushing = 0;
-static void _stp_remove_relay_dir(struct dentry *dir)
-{
- if (dir)
- relayfs_remove_dir(dir);
-}
-
-
/**
* _stp_subbuf_start - subbuf_start() relayfs callback implementation
*/
@@ -66,10 +59,22 @@ static struct rchan_callbacks stp_rchan_callbacks =
};
+static void _stp_remove_relay_dir(struct dentry *dir)
+{
+ if (dir)
+ relayfs_remove_dir(dir);
+}
+
static void _stp_remove_relay_root(struct dentry *root)
{
- if (root)
+ if (root) {
+ if (!_stp_lock_debugfs()) {
+ errk("Unable to lock transport directory.\n");
+ return;
+ }
_stp_remove_relay_dir(root);
+ _stp_unlock_debugfs();
+ }
}
struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts)
@@ -80,25 +85,31 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts)
if (!utt)
return NULL;
- utt->utt_tree_root = relayfs_create_dir(utts->root, NULL);
- if (!utt->utt_tree_root) {
- errk("couldn't get relay root dir.\n");
+ utt->utt_tree_root = _stp_get_root_dir(utts->root);
+ if (!utt->utt_tree_root)
return NULL;
- }
-
+ utt->dir = relayfs_create_dir(utts->name, utt->utt_tree_root);
+ if (!utt->dir)
+ goto err;
+
kbug("relay_open %d %d\n", utts->buf_size, utts->buf_nr);
- utt->rchan = relay_open("trace", utt->utt_tree_root, utts->buf_size, utts->buf_nr, 0, &stp_rchan_callbacks);
- if (!utt->rchan) {
- errk("couldn't create relay channel.\n");
- _stp_remove_relay_root(utt->utt_tree_root);
- return NULL;
- }
+
+ utt->rchan = relay_open("trace", utt->dir, utts->buf_size, utts->buf_nr, 0, &stp_rchan_callbacks);
+ if (!utt->rchan)
+ goto err1;
utt->rchan->private_data = utt;
utt->trace_state = Utt_trace_setup;
utts->err = 0;
return utt;
+
+err1:
+ errk("couldn't create relay channel.\n");
+ _stp_remove_relay_dir(utt->dir);
+err:
+ _stp_remove_relay_root(utt->utt_tree_root);
+ return NULL;
}
int utt_trace_startstop(struct utt_trace *utt, int start,
@@ -141,6 +152,7 @@ int utt_trace_remove(struct utt_trace *utt)
kbug("removing relayfs files. %d\n", utt->trace_state);
if (utt && (utt->trace_state == Utt_trace_setup || utt->trace_state == Utt_trace_stopped)) {
relay_close(utt->rchan);
+ _stp_remove_relay_dir(utt->dir);
_stp_remove_relay_root(utt->utt_tree_root);
kfree(utt);
}
diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index 9780b0b1..a91a8b70 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -387,7 +387,7 @@ static int _stp_do_module(const char __user *buf, int count)
mod = _stp_load_module_symbols(&tmpmod);
if (mod == NULL) {
kfree(tmpmod.sections);
- return -EFAULT;
+ return 0;
}
_stp_ins_module(mod);
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 59402f6f..51586dbd 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -32,9 +32,7 @@ static int _stp_start_finished = 0;
static int _stp_probes_started = 0;
/* module parameters */
-static int _stp_pid, _stp_bufsize;
-module_param(_stp_pid, int, 0);
-MODULE_PARM_DESC(_stp_pid, "pid");
+static int _stp_bufsize;
module_param(_stp_bufsize, int, 0);
MODULE_PARM_DESC(_stp_bufsize, "buffer size");
@@ -208,8 +206,9 @@ void _stp_transport_close()
static struct utt_trace *_stp_utt_open(void)
{
- struct utt_trace_setup utts;
- sprintf(utts.root, "systemtap_%d", _stp_pid);
+ struct utt_trace_setup utts;
+ strlcpy(utts.root, "systemtap", sizeof(utts.root));
+ strlcpy(utts.name, THIS_MODULE->name, sizeof(utts.name));
utts.buf_size = _stp_subbuf_size;
utts.buf_nr = _stp_nsubbufs;
@@ -230,7 +229,7 @@ int _stp_transport_init(void)
{
int ret;
- kbug("transport_init from %ld %ld\n", (long)_stp_pid, (long)current->pid);
+ kbug("transport_init\n");
if (_stp_bufsize) {
unsigned size = _stp_bufsize * 1024 * 1024;
@@ -249,6 +248,7 @@ int _stp_transport_init(void)
if (!_stp_utt)
goto err0;
#endif
+
/* create debugfs/procfs control channel */
if (_stp_register_ctl_channel() < 0)
goto err1;
@@ -281,4 +281,100 @@ err0:
return -1;
}
+
+static inline void _stp_lock_inode(struct inode *inode)
+{
+#ifdef DEFINE_MUTEX
+ mutex_lock(&inode->i_mutex);
+#else
+ down(&inode->i_sem);
+#endif
+}
+
+static inline void _stp_unlock_inode(struct inode *inode)
+{
+#ifdef DEFINE_MUTEX
+ mutex_unlock(&inode->i_mutex);
+#else
+ up(&inode->i_sem);
+#endif
+}
+
+static struct dentry *_stp_lockfile = NULL;
+
+static int _stp_lock_debugfs(void)
+{
+ int numtries = 0;
+#ifdef STP_OLD_TRANSPORT
+ while ((_stp_lockfile = relayfs_create_dir("systemtap_lock", NULL)) == NULL) {
+#else
+ while ((_stp_lockfile = debugfs_create_dir("systemtap_lock", NULL)) == NULL) {
+#endif
+ if (numtries++ >= 50)
+ return 0;
+ msleep(50);
+ }
+ return 1;
+}
+
+static void _stp_unlock_debugfs(void)
+{
+ if (_stp_lockfile) {
+#ifdef STP_OLD_TRANSPORT
+ relayfs_remove_dir(_stp_lockfile);
+#else
+ debugfs_remove(_stp_lockfile);
+#endif
+ _stp_lockfile = NULL;
+ }
+}
+
+/* _stp_get_root_dir(name) - creates root directory 'name' or */
+/* returns a pointer to it if it already exists. Used in */
+/* utt.c and relayfs.c. Will not be necessary if utt is included */
+/* in the kernel. */
+
+static struct dentry *_stp_get_root_dir(const char *name) {
+ struct file_system_type *fs;
+ struct dentry *root;
+ struct super_block *sb;
+
+#ifdef STP_OLD_TRANSPORT
+ fs = get_fs_type("relayfs");
+#else
+ fs = get_fs_type("debugfs");
+#endif
+ if (!fs) {
+ errk("Couldn't find debugfs or relayfs filesystem.\n");
+ return NULL;
+ }
+
+ if (!_stp_lock_debugfs()) {
+ errk("Couldn't lock transport directory.\n");
+ return NULL;
+ }
+
+#ifdef STP_OLD_TRANSPORT
+ root = relayfs_create_dir(name, NULL);
+#else
+ root = debugfs_create_dir(name, NULL);
+#endif
+ if (!root) {
+ /* couldn't create it because it is already there, so find it. */
+ sb = list_entry(fs->fs_supers.next, struct super_block, s_instances);
+ _stp_lock_inode(sb->s_root->d_inode);
+ root = lookup_one_len(name, sb->s_root, strlen(name));
+ _stp_unlock_inode(sb->s_root->d_inode);
+ kbug("root=%p\n", root);
+ if (!IS_ERR(root))
+ dput(root);
+ else {
+ root = NULL;
+ kbug("Could not create or find transport directory.\n");
+ }
+ }
+ _stp_unlock_debugfs();
+ return root;
+}
+
#endif /* _TRANSPORT_C_ */
diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h
index 2d77414c..09a0615e 100644
--- a/runtime/transport/transport.h
+++ b/runtime/transport/transport.h
@@ -19,4 +19,7 @@ static unsigned _stp_subbuf_size = 65536*2;
extern void _stp_transport_close(void);
extern int _stp_print_init(void);
extern void _stp_print_cleanup(void);
+static struct dentry *_stp_get_root_dir(const char *name);
+static int _stp_lock_debugfs(void);
+static void _stp_unlock_debugfs(void);
#endif /* _TRANSPORT_TRANSPORT_H_ */
diff --git a/runtime/transport/utt.c b/runtime/transport/utt.c
index b23260d7..0c0dd02c 100644
--- a/runtime/transport/utt.c
+++ b/runtime/transport/utt.c
@@ -31,25 +31,43 @@
static void utt_remove_root(struct utt_trace *utt)
{
- if (utt->utt_tree_root && simple_empty(utt->utt_tree_root)) {
- debugfs_remove(utt->utt_tree_root);
+ if (utt->utt_tree_root) {
+ if (!_stp_lock_debugfs()) {
+ errk("Unable to lock transport directory.\n");
+ return;
+ }
+ if (simple_empty(utt->utt_tree_root))
+ debugfs_remove(utt->utt_tree_root);
+ _stp_unlock_debugfs();
utt->utt_tree_root = NULL;
}
}
static void utt_remove_tree(struct utt_trace *utt)
{
+ debugfs_remove(utt->dir);
utt_remove_root(utt);
}
-static struct dentry *utt_create_tree(struct utt_trace *utt, const char *root)
+static struct dentry *utt_create_tree(struct utt_trace *utt, const char *root, const char *name)
{
- if (root == NULL)
- return NULL;
-
- if (!utt->utt_tree_root)
- utt->utt_tree_root = debugfs_create_dir(root, NULL);
- return utt->utt_tree_root;
+ struct dentry *dir = NULL;
+
+ if (root == NULL || name == NULL)
+ return NULL;
+
+ if (!utt->utt_tree_root) {
+ utt->utt_tree_root = _stp_get_root_dir(root);
+ if (!utt->utt_tree_root)
+ goto err;
+ }
+
+ dir = debugfs_create_dir(name, utt->utt_tree_root);
+ if (!dir)
+ utt_remove_root(utt);
+
+err:
+ return dir;
}
@@ -173,10 +191,10 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts)
goto err;
ret = -ENOENT;
- dir = utt_create_tree(utt, utts->root);
+ dir = utt_create_tree(utt, utts->root, utts->name);
if (!dir)
goto err;
-
+ utt->dir = dir;
atomic_set(&utt->dropped, 0);
ret = -EIO;
diff --git a/runtime/transport/utt.h b/runtime/transport/utt.h
index f6eba64b..a89b31f0 100644
--- a/runtime/transport/utt.h
+++ b/runtime/transport/utt.h
@@ -11,14 +11,15 @@ struct utt_trace {
int trace_state;
struct rchan *rchan;
unsigned long *sequence;
+ struct dentry *dir; /* systemtap/module_name */
struct dentry *dropped_file;
atomic_t dropped;
- struct dentry *utt_tree_root;
+ struct dentry *utt_tree_root; /* systemtap */
void *private_data;
};
-#define UTT_TRACE_ROOT_NAME_SIZE 32 /* Largest string for a root dir identifier */
-#define UTT_TRACE_NAME_SIZE 32 /* Largest string for a trace identifier */
+#define UTT_TRACE_ROOT_NAME_SIZE 64 /* Largest string for a root dir identifier */
+#define UTT_TRACE_NAME_SIZE 64 /* Largest string for a trace identifier */
/*
* User setup structure