summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrz <trz>2006-09-19 19:16:55 +0000
committertrz <trz>2006-09-19 19:16:55 +0000
commit18c785eef991aae229e7416d1b5edfc9306fa3a7 (patch)
treeeef461a67160f247cf4f6bef96a0204f082c517a
parentb96baad9f8f5bf04c3d136ed16fe59270ae947e9 (diff)
downloadsystemtap-steved-18c785eef991aae229e7416d1b5edfc9306fa3a7.tar.gz
systemtap-steved-18c785eef991aae229e7416d1b5edfc9306fa3a7.tar.xz
systemtap-steved-18c785eef991aae229e7416d1b5edfc9306fa3a7.zip
Conversion from relay-on-procfs to relay-on-debugfs
-rw-r--r--ChangeLog4
-rw-r--r--README3
-rw-r--r--runtime/stpd/ChangeLog11
-rw-r--r--runtime/stpd/librelay.c39
-rw-r--r--runtime/transport/ChangeLog21
-rw-r--r--runtime/transport/procfs.c48
-rw-r--r--runtime/transport/relayfs.c162
-rw-r--r--runtime/transport/relayfs.h12
-rw-r--r--runtime/transport/transport.c13
9 files changed, 148 insertions, 165 deletions
diff --git a/ChangeLog b/ChangeLog
index fc0fa772..f624d905 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-09-19 Tom Zanussi <zanussi@us.ibm.com>
+
+ * README: Add CONFIG_DEBUG_FS to config options.
+
2006-09-18 Josh Stone <joshua.i.stone@intel.com>
PR 3219
diff --git a/README b/README
index 2c47ee7a..6832b987 100644
--- a/README
+++ b/README
@@ -53,7 +53,8 @@ Tips:
Building a kernel.org kernel:
- Build the kernel using your normal procedures. Enable
- CONFIG_DEBUG_INFO, CONFIG_KPROBES, and optionally CONFIG_RELAY.
+ CONFIG_DEBUG_INFO, CONFIG_KPROBES, and optionally CONFIG_RELAY and
+ CONFIG_DEBUG_FS.
- Boot into the kernel.
- Make sure the large unstripped kernel image 'vmlinux' from your
build can be found by systemtap (see above) You can just symlink
diff --git a/runtime/stpd/ChangeLog b/runtime/stpd/ChangeLog
index dfc22682..d804d285 100644
--- a/runtime/stpd/ChangeLog
+++ b/runtime/stpd/ChangeLog
@@ -1,3 +1,14 @@
+2006-09-19 Tom Zanussi <zanussi@us.ibm.com>
+
+ * librelay.c (init_relayfs): Add debugfs path to relay files and
+ add new systemtap directory to path.
+ (init_stp): rmmod module on failure.
+ (merge_output): Remove debugging printfs left in code.
+ (close_relay_files): Clear relay_file descriptor after close.
+ (cleanup_and_exit): Allow cleanup and exit even if there was an
+ error opening relay files.
+ (stp_main_loop): Call cleanup_and_exit() if init_relayfs() fails.
+
2006-09-18 Martin Hunt <hunt@redhat.com>
* stpd.c (usage): Remove "-m" option.
diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c
index 13b00ebf..fb600280 100644
--- a/runtime/stpd/librelay.c
+++ b/runtime/stpd/librelay.c
@@ -178,6 +178,7 @@ static void close_relayfs_files(int cpu)
munmap(relay_buffer[cpu], total_bufsize);
close(relay_file[cpu]);
+ relay_file[cpu] = 0;
fclose(percpu_tmpfile[cpu]);
}
@@ -387,6 +388,7 @@ static void read_last_buffers(void)
}
#define RELAYFS_MAGIC 0xF0B4A981
+#define DEBUGFS_MAGIC 0x64626720
/**
* init_relayfs - create files and threads for relayfs processing
*
@@ -417,17 +419,13 @@ int init_relayfs(void)
fprintf(stderr, "Could not execute %s\n", stp_check);
exit(1);
}
-
+
if (statfs("/mnt/relay", &st) == 0 && (int) st.f_type == (int) RELAYFS_MAGIC)
- sprintf(params.relay_filebase, "/mnt/relay/%d/cpu", getpid());
- else {
- char *ptr;
- sprintf(params.relay_filebase, "/proc/systemtap/%s", modname);
- ptr = index(params.relay_filebase,'.');
- if (ptr)
- *ptr = 0;
- strcat(params.relay_filebase, "/cpu");
- }
+ sprintf(params.relay_filebase, "/mnt/relay/systemtap/%d/cpu", getpid());
+ else if (statfs("/sys/kernel/debug", &st) == 0 && (int) st.f_type == (int) DEBUGFS_MAGIC)
+ sprintf(params.relay_filebase, "/sys/kernel/debug/systemtap/%d/cpu", getpid());
+ else
+ sprintf(params.relay_filebase, "/debug/systemtap/%d/cpu", getpid());
for (i = 0; i < ncpus; i++) {
if (open_relayfs_files(i, params.relay_filebase) < 0) {
@@ -559,7 +557,7 @@ int init_stp(int print_summary)
control_channel = open(buf, O_RDWR);
if (control_channel < 0) {
fprintf(stderr, "ERROR: couldn't open control channel %s: errcode = %s\n", buf, strerror(errno));
- return -1;
+ goto do_rmmod;
}
/* start target_cmd if necessary */
@@ -576,9 +574,15 @@ int init_stp(int print_summary)
if (target_cmd)
kill (target_pid, SIGKILL);
close(control_channel);
- return -1;
+ goto do_rmmod;
}
return 0;
+
+do_rmmod:
+ snprintf(buf, sizeof(buf), "/sbin/rmmod -w %s", modname);
+ if (system(buf))
+ fprintf(stderr, "ERROR: couldn't rmmod probe module %s.\n", modname);
+ return -1;
}
@@ -607,7 +611,6 @@ static int merge_output(void)
}
num[i] = 0;
buf[i] = malloc(MERGE_BUF_SIZE);
- printf("buf[%d] = %p\n", i, buf[i]);
if (!buf[i]) {
fprintf(stderr,"Out of memory in merge_output(). Aborting merge.\n");
printf("Out of memory in merge_output(). Aborting merge.\n");
@@ -652,8 +655,6 @@ static int merge_output(void)
num[j] = 0;
if (fread_unlocked (&length[j], sizeof(uint32_t), 1, fp[j])) {
- printf("length[%d] = %d\n", j, length[j]);
- printf("buf[%d] = %p\n", j, buf[j]);
if (fread_unlocked (buf[j], length[j]+TIMESTAMP_SIZE, 1, fp[j]))
num[j] = *((uint32_t *)buf[j]);
}
@@ -689,7 +690,7 @@ static void cleanup_and_exit (int closed)
fprintf(stderr,"\nWaititing for processes to exit\n");
while(wait(NULL) > 0);
- if (transport_mode == STP_TRANSPORT_RELAYFS) {
+ if (transport_mode == STP_TRANSPORT_RELAYFS && relay_file[0] > 0) {
kill_percpu_threads(ncpus);
while(1) {
pthread_mutex_lock(&processing_mutex);
@@ -707,7 +708,7 @@ static void cleanup_and_exit (int closed)
if (print_totals && verbose)
summarize();
- if (transport_mode == STP_TRANSPORT_RELAYFS) {
+ if (transport_mode == STP_TRANSPORT_RELAYFS && relay_file[0] > 0) {
close_all_relayfs_files();
if (params.merge) {
merge_output();
@@ -817,10 +818,8 @@ int stp_main_loop(void)
if (!streaming()) {
rc = init_relayfs();
if (rc < 0) {
- close(control_channel);
fprintf(stderr, "ERROR: couldn't init relayfs, exiting\n");
- /* FIXME. Need to cleanup properly */
- exit(1);
+ cleanup_and_exit(0);
}
} else if (outfile_name) {
ofp = fopen (outfile_name, "w");
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 81618d7b..969f6fb0 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,24 @@
+2006-09-19 Tom Zanussi <zanussi@us.ibm.com>
+
+ * procfs.c (_stp_get_proc_root): Removed.
+ (_stp_force_dir_creation): Removed.
+ (_stp_register_procfs): Remove unneeded procfs dentry code. *
+ relayfs.c (_stp_create_buf_file): Remove code to create relay
+ files in procfs, add code to create in debugfs.
+ (_stp_remove_buf_file): Remove code to delete relay files in
+ procfs, add code to delete from debugfs.
+ (_stp_create_relay_dir): New.
+ (_stp_remove_relay_dir): New.
+ (_stp_get_relay_root): New.
+ (_stp_relayfs_close): Use new functions.
+ (_stp_relayfs_open): Consolidate alternative versions and remove
+ extraneous version. * relayfs.h: Remove extraneous
+ _stp_relayfs_open prototype.
+ * transport.c (_stp_transport_open): Remove extraneous call to
+ _stp_relayfs_open() and remove call to _stp_unregister_procfs() on
+ failure - since it's called from cmd write, cmd can't be removed;
+ it's removed in normal shutdown anyway.
+
2006-09-18 Martin Hunt <hunt@redhat.com>
* transport_msgs.h (struct transport_info): Add merge field.
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index d61beba2..857a36c7 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -267,38 +267,6 @@ 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;
@@ -307,10 +275,6 @@ 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;
@@ -342,23 +306,11 @@ 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) {
diff --git a/runtime/transport/relayfs.c b/runtime/transport/relayfs.c
index 3672c453..defe0087 100644
--- a/runtime/transport/relayfs.c
+++ b/runtime/transport/relayfs.c
@@ -78,35 +78,15 @@ static struct dentry *_stp_create_buf_file(const char *filename,
struct rchan_buf *buf,
int *is_global)
{
- struct proc_dir_entry *pde;
- struct dentry *dentry;
- struct proc_dir_entry *parent_pde = NULL;
-
- if (parent)
- parent_pde = PDE(parent->d_inode);
- pde = create_proc_entry(filename, S_IFREG|S_IRUSR, parent_pde);
- if (unlikely(!pde))
- return NULL;
- pde->proc_fops = &relay_file_operations;
-
- mutex_lock(&parent->d_inode->i_mutex);
- dentry = lookup_one_len(filename, parent, strlen(filename));
- mutex_unlock(&parent->d_inode->i_mutex);
- if (IS_ERR(dentry))
- remove_proc_entry(filename, parent_pde);
-
- dentry->d_inode->u.generic_ip = buf;
-
- return dentry;
+ return debugfs_create_file(filename, mode, parent, buf,
+ &relay_file_operations);
}
static int _stp_remove_buf_file(struct dentry *dentry)
{
- struct proc_dir_entry *pde = PDE(dentry->d_inode);
-
- remove_proc_entry(pde->name, pde->parent);
+ debugfs_remove(dentry);
- return 0;
+ return 0;
}
#endif /* CONFIG_RELAY */
@@ -128,34 +108,85 @@ static struct rchan_callbacks stp_rchan_callbacks =
};
#endif /* CONFIG_RELAY */
-/**
- * _stp_relayfs_close - destroys relayfs channel
- * @chan: the relayfs channel
- * @dir: the directory containing the relayfs files
- */
+static struct dentry *_stp_create_relay_dir(const char *dirname, struct dentry *parent)
+{
+ struct dentry *dir;
+
#if defined (CONFIG_RELAY)
-void _stp_relayfs_close(struct rchan *chan, struct dentry *dir)
+ dir = debugfs_create_dir(dirname, parent);
+ if (IS_ERR(dir)) {
+ printk("STP: Couldn't create directory %s - debugfs not configured in.\n", dirname);
+ dir = NULL;
+ }
+#else
+ dir = relayfs_create_dir(dirname, parent);
+#endif
+
+ return dir;
+}
+
+static void _stp_remove_relay_dir(struct dentry *dir)
{
- if (!chan)
+ if (dir == NULL)
return;
-
- relay_close(chan);
- if (dir) {
- struct proc_dir_entry *pde = PDE(dir->d_inode);
- remove_proc_entry(pde->name, pde->parent);
- }
+
+#if defined (CONFIG_RELAY)
+ debugfs_remove(dir);
+#else
+ relayfs_remove_dir(dir);
+#endif
}
+
+static struct dentry *_stp_get_relay_root(void)
+{
+ struct file_system_type *fs;
+ struct super_block *sb;
+ struct dentry *root;
+ char *dirname = "systemtap";
+
+ root = _stp_create_relay_dir(dirname, NULL);
+ if (root)
+ return root;
+
+#if defined (CONFIG_RELAY)
+ fs = get_fs_type("debugfs");
#else
+ fs = get_fs_type("relayfs");
+#endif
+ if (!fs)
+ return NULL;
+
+ sb = list_entry(fs->fs_supers.next, struct super_block, s_instances);
+ mutex_lock(&sb->s_root->d_inode->i_mutex);
+ root = lookup_one_len(dirname, sb->s_root, strlen(dirname));
+ mutex_unlock(&sb->s_root->d_inode->i_mutex);
+ if (!IS_ERR(root))
+ dput(root);
+
+ return root;
+}
+
+static void _stp_put_relay_root(struct dentry *root)
+{
+ if (root)
+ _stp_remove_relay_dir(root);
+}
+
+static struct dentry *_relay_root;
+
+/**
+ * _stp_relayfs_close - destroys relayfs channel
+ * @chan: the relayfs channel
+ * @dir: the directory containing the relayfs files
+ */
void _stp_relayfs_close(struct rchan *chan, struct dentry *dir)
{
if (!chan)
return;
-
relay_close(chan);
- if (dir)
- relayfs_remove_dir(dir);
+ _stp_remove_relay_dir(dir);
+ _stp_put_relay_root(_relay_root);
}
-#endif /* CONFIG_RELAY */
/**
* _stp_relayfs_open - create relayfs channel
@@ -163,56 +194,35 @@ void _stp_relayfs_close(struct rchan *chan, struct dentry *dir)
* @subbuf_size: size of relayfs sub-buffers
* @pid: daemon pid
* @outdir: receives directory dentry
- * @parentdir: parent directory dentry
*
* Returns relay channel, NULL on failure
*
* Creates relayfs files as /systemtap/pid/cpuX in relayfs root
*/
-#if defined (CONFIG_RELAY)
-extern struct dentry *module_dentry;
struct rchan *_stp_relayfs_open(unsigned n_subbufs,
unsigned subbuf_size,
int pid,
- struct dentry **outdir,
- struct dentry *parent_dir)
+ struct dentry **outdir)
{
char dirname[16];
struct rchan *chan;
- struct dentry* dir = NULL;
+ struct dentry* root, *dir;
sprintf(dirname, "%d", pid);
- /* TODO: need to create systemtap dir */
- chan = relay_open("cpu", parent_dir, subbuf_size,
- n_subbufs, &stp_rchan_callbacks);
- if (!chan) {
- printk("STP: couldn't create relayfs channel.\n");
- if (dir)
- remove_proc_entry(dirname, NULL);
+ root = _stp_get_relay_root();
+ if (!root) {
+ printk("STP: couldn't get relay root dir.\n");
+ return NULL;
}
- *outdir = dir;
- return chan;
-}
-#else
-struct rchan *_stp_relayfs_open(unsigned n_subbufs,
- unsigned subbuf_size,
- int pid,
- struct dentry **outdir)
-{
- char dirname[16];
- struct rchan *chan;
- struct dentry* dir = NULL;
- sprintf(dirname, "%d", pid);
-
- /* TODO: need to create systemtap dir */
- dir = relayfs_create_dir(dirname, NULL);
+ dir = _stp_create_relay_dir(dirname, root);
if (!dir) {
- printk("STP: couldn't create relayfs dir %s.\n", dirname);
+ printk("STP: couldn't create relay dir %s.\n", dirname);
+ _stp_put_relay_root(root);
return NULL;
}
-
+
#if (RELAYFS_CHANNEL_VERSION >= 4)
chan = relay_open("cpu", dir, subbuf_size,
n_subbufs, &stp_rchan_callbacks);
@@ -222,15 +232,15 @@ struct rchan *_stp_relayfs_open(unsigned n_subbufs,
#endif /* RELAYFS_CHANNEL_VERSION >= 4 */
if (!chan) {
- printk("STP: couldn't create relayfs channel.\n");
- if (dir)
- relayfs_remove_dir(dir);
+ printk("STP: couldn't create relay channel.\n");
+ _stp_remove_relay_dir(dir);
+ _stp_put_relay_root(root);
}
+ _relay_root = root;
*outdir = dir;
return chan;
}
-#endif /* CONFIG_RELAY */
#endif /* _TRANSPORT_RELAYFS_C_ */
diff --git a/runtime/transport/relayfs.h b/runtime/transport/relayfs.h
index c871db31..c47f4b98 100644
--- a/runtime/transport/relayfs.h
+++ b/runtime/transport/relayfs.h
@@ -9,23 +9,17 @@
# include <linux/relayfs_fs.h>
#elif defined (CONFIG_RELAY)
# include <linux/relay.h>
-# include <linux/namei.h>
+# include <linux/debugfs.h>
#else
# undef STP_RELAYFS
#endif
-#if defined (CONFIG_RELAY)
-struct rchan *_stp_relayfs_open(unsigned n_subbufs,
- unsigned subbuf_size,
- int pid,
- struct dentry **outdir,
- struct dentry *parent_dir);
-#else
+# include <linux/namei.h>
+
struct rchan *_stp_relayfs_open(unsigned n_subbufs,
unsigned subbuf_size,
int pid,
struct dentry **outdir);
-#endif
void _stp_relayfs_close(struct rchan *chan, struct dentry *dir);
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index c9be3311..8cc624a9 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -204,10 +204,6 @@ void _stp_transport_close()
kbug("---- CLOSED ----\n");
}
-#if defined (STP_RELAYFS) && defined (CONFIG_RELAY)
-extern struct dentry *module_dir_dentry;
-#endif /* STP_RELAYFS && CONFIG_RELAY */
-
/**
* _stp_transport_open - open proc and relayfs channels
* with proper parameters
@@ -247,15 +243,10 @@ int _stp_transport_open(struct transport_info *info)
info->merge = 1;
#endif
-#if defined (CONFIG_RELAY)
- _stp_chan = _stp_relayfs_open(n_subbufs, subbuf_size, _stp_pid, &_stp_dir, module_dir_dentry);
-#else
_stp_chan = _stp_relayfs_open(n_subbufs, subbuf_size, _stp_pid, &_stp_dir);
-#endif /* CONFIG_RELAY */
- if (!_stp_chan) {
- _stp_unregister_procfs();
+
+ if (!_stp_chan)
return -ENOMEM;
- }
kbug ("stp_transport_open: %u Mb buffers, subbuf_size=%u, n_subbufs=%u\n",
info->buf_size, subbuf_size, n_subbufs);
} else