summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/transport/ChangeLog10
-rw-r--r--runtime/transport/control.c56
-rw-r--r--runtime/transport/control.h42
-rw-r--r--runtime/transport/debugfs.c45
-rw-r--r--runtime/transport/procfs.c243
-rw-r--r--runtime/transport/transport.c6
6 files changed, 132 insertions, 270 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index e70f2e7b..efaee102 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,13 @@
+2009-02-17 David Smith <dsmith@redhat.com>
+
+ * control.c: Contains generic control channel functions.
+ * procfs.c: Specific procfs control channel functions. All generic
+ control channel functions moved to control.c.
+ * debugfs.c: New file containing debugfs specific control channel
+ functions.
+ * control.h: New file.
+ * transport.c: Updated file inclusion.
+
2009-02-13 David Smith <dsmith@redhat.com>
* procfs.c: Added inclusion of ../procfs.c for
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index 93db97e1..da2a180c 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -1,7 +1,7 @@
/* -*- linux-c -*-
*
- * debugfs control channel
- * Copyright (C) 2007-2008 Red Hat Inc.
+ * control channel
+ * Copyright (C) 2007-2009 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -9,7 +9,6 @@
* later version.
*/
-#define STP_DEFAULT_BUFFERS 50
static int _stp_current_buffers = STP_DEFAULT_BUFFERS;
static _stp_mempool_t *_stp_pool_q;
@@ -72,13 +71,6 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz
return count; /* Pretend that we absorbed the entire message. */
}
-struct _stp_buffer {
- struct list_head list;
- int len;
- int type;
- char buf[STP_CTL_BUFFER_SIZE];
-};
-
static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq);
#ifdef DEBUG_TRANS
@@ -114,11 +106,16 @@ static int _stp_ctl_write(int type, void *data, unsigned len)
{
struct _stp_buffer *bptr;
unsigned long flags;
+ unsigned hlen;
#ifdef DEBUG_TRANS
_stp_ctl_write_dbug(type, data, len);
#endif
+ hlen = _stp_ctl_write_fs(type, data, len);
+ if (hlen > 0)
+ return hlen;
+
/* make sure we won't overflow the buffer */
if (unlikely(len > STP_CTL_BUFFER_SIZE))
return 0;
@@ -153,7 +150,8 @@ static int _stp_ctl_send(int type, void *data, int len)
return err;
}
-static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
struct _stp_buffer *bptr;
int len;
@@ -178,10 +176,12 @@ static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t cou
/* write it out */
len = bptr->len + 4;
if (len > count || copy_to_user(buf, &bptr->type, len)) {
- /* now what? We took it off the queue then failed to send it */
- /* we can't put it back on the queue because it will likely be out-of-order */
- /* fortunately this should never happen */
- /* FIXME need to mark this as a transport failure */
+ /* Now what? We took it off the queue then failed to
+ * send it. We can't put it back on the queue because
+ * it will likely be out-of-order. Fortunately, this
+ * should never happen.
+ *
+ * FIXME: need to mark this as a transport failure. */
errk("Supplied buffer too small. count:%d len:%d\n", (int)count, len);
return -EFAULT;
}
@@ -215,47 +215,33 @@ static struct file_operations _stp_ctl_fops_cmd = {
.release = _stp_ctl_close_cmd,
};
-static struct dentry *_stp_cmd_file = NULL;
-
static int _stp_register_ctl_channel(void)
{
- int i;
- struct list_head *p, *tmp;
- char buf[32];
-
- if (_stp_utt == NULL) {
- errk("_expected _stp_utt to be set.\n");
- return -1;
- }
-
INIT_LIST_HEAD(&_stp_ctl_ready_q);
/* allocate buffers */
- _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), STP_DEFAULT_BUFFERS);
+ _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer),
+ STP_DEFAULT_BUFFERS);
if (unlikely(_stp_pool_q == NULL))
goto err0;
_stp_allocated_net_memory += sizeof(struct _stp_buffer) * STP_DEFAULT_BUFFERS;
- /* create [debugfs]/systemtap/module_name/.cmd */
- _stp_cmd_file = debugfs_create_file(".cmd", 0600, _stp_utt->dir, NULL, &_stp_ctl_fops_cmd);
- if (_stp_cmd_file == NULL)
+ if (_stp_register_ctl_channel_fs() != 0)
goto err0;
- _stp_cmd_file->d_inode->i_uid = _stp_uid;
- _stp_cmd_file->d_inode->i_gid = _stp_gid;
return 0;
err0:
_stp_mempool_destroy(_stp_pool_q);
- errk("Error creating systemtap debugfs entries.\n");
+ errk("Error creating systemtap control channel.\n");
return -1;
}
static void _stp_unregister_ctl_channel(void)
{
struct list_head *p, *tmp;
- if (_stp_cmd_file)
- debugfs_remove(_stp_cmd_file);
+
+ _stp_unregister_ctl_channel_fs();
/* Return memory to pool and free it. */
list_for_each_safe(p, tmp, &_stp_ctl_ready_q) {
diff --git a/runtime/transport/control.h b/runtime/transport/control.h
new file mode 100644
index 00000000..5e7204ee
--- /dev/null
+++ b/runtime/transport/control.h
@@ -0,0 +1,42 @@
+/* -*- linux-c -*-
+ *
+ * control channel header
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _CONTROL_H_
+#define _CONTROL_H_
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+static _stp_mempool_t *_stp_pool_q;
+static struct list_head _stp_ctl_ready_q;
+static spinlock_t _stp_ctl_ready_lock;
+static wait_queue_head_t _stp_ctl_wq;
+
+struct _stp_buffer {
+ struct list_head list;
+ int len;
+ int type;
+ char buf[STP_CTL_BUFFER_SIZE];
+};
+
+static struct file_operations _stp_ctl_fops_cmd;
+
+static int _stp_ctl_send(int type, void *data, int len);
+
+static int _stp_ctl_write_fs(int type, void *data, unsigned len);
+
+static int _stp_register_ctl_channel(void);
+static void _stp_unregister_ctl_channel(void);
+
+static int _stp_register_ctl_channel_fs(void);
+static void _stp_unregister_ctl_channel_fs(void);
+
+#endif /* _CONTROL_H_ */
diff --git a/runtime/transport/debugfs.c b/runtime/transport/debugfs.c
new file mode 100644
index 00000000..dc651a56
--- /dev/null
+++ b/runtime/transport/debugfs.c
@@ -0,0 +1,45 @@
+/* -*- linux-c -*-
+ *
+ * debugfs functions
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#define STP_DEFAULT_BUFFERS 50
+
+inline static int _stp_ctl_write_fs(int type, void *data, unsigned len)
+{
+ return 0;
+}
+
+static struct dentry *_stp_cmd_file = NULL;
+
+static int _stp_register_ctl_channel_fs(void)
+{
+ if (_stp_utt == NULL) {
+ errk("_expected _stp_utt to be set.\n");
+ return -1;
+ }
+
+ /* create [debugfs]/systemtap/module_name/.cmd */
+ _stp_cmd_file = debugfs_create_file(".cmd", 0600, _stp_utt->dir,
+ NULL, &_stp_ctl_fops_cmd);
+ if (_stp_cmd_file == NULL) {
+ errk("Error creating systemtap debugfs entries.\n");
+ return -1;
+ }
+ _stp_cmd_file->d_inode->i_uid = _stp_uid;
+ _stp_cmd_file->d_inode->i_gid = _stp_gid;
+
+ return 0;
+}
+
+static void _stp_unregister_ctl_channel_fs(void)
+{
+ if (_stp_cmd_file)
+ debugfs_remove(_stp_cmd_file);
+}
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index 0c31ae3c..5a8e4238 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -1,7 +1,7 @@
/* -*- linux-c -*-
*
* /proc transport and control
- * Copyright (C) 2005-2008 Red Hat Inc.
+ * Copyright (C) 2005-2009 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -12,11 +12,6 @@
#include "../procfs.c" // for _stp_mkdir_proc_module()
#define STP_DEFAULT_BUFFERS 256
-static int _stp_current_buffers = STP_DEFAULT_BUFFERS;
-
-static _stp_mempool_t *_stp_pool_q;
-static struct list_head _stp_ctl_ready_q;
-DEFINE_SPINLOCK(_stp_ctl_ready_lock);
#ifdef STP_BULKMODE
extern int _stp_relay_flushing;
@@ -62,112 +57,19 @@ static struct file_operations _stp_proc_fops = {
};
#endif /* STP_BULKMODE */
-
-static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-{
- int type;
- static int started = 0;
-
- if (count < sizeof(int))
- return 0;
-
- if (get_user(type, (int __user *)buf))
- return -EFAULT;
-
-#if DEBUG_TRANS
- if (type < STP_MAX_CMD)
- _dbug("Got %s. len=%d\n", _stp_command_name[type], (int)count);
-#endif
-
- count -= sizeof(int);
- buf += sizeof(int);
-
- switch (type) {
- case STP_START:
- if (started == 0) {
- struct _stp_msg_start st;
- if (count < sizeof(st))
- return 0;
- if (copy_from_user(&st, buf, sizeof(st)))
- return -EFAULT;
- _stp_handle_start(&st);
- started = 1;
- }
- break;
-
- case STP_EXIT:
- _stp_exit_flag = 1;
- break;
-
- case STP_RELOCATION:
- _stp_do_relocation (buf, count);
- break;
-
- case STP_READY:
- break;
-
- default:
- errk("invalid command type %d\n", type);
- return -EINVAL;
- }
-
- return count;
-}
-
-struct _stp_buffer {
- struct list_head list;
- int len;
- int type;
- char buf[STP_CTL_BUFFER_SIZE];
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq);
-
-#if DEBUG_TRANS
-static void _stp_ctl_write_dbug(int type, void *data, int len)
-{
- char buf[64];
- switch (type) {
- case STP_START:
- _dbug("sending STP_START\n");
- break;
- case STP_EXIT:
- _dbug("sending STP_EXIT\n");
- break;
- case STP_OOB_DATA:
- snprintf(buf, sizeof(buf), "%s", (char *)data);
- _dbug("sending %d bytes of STP_OOB_DATA: %s\n", len, buf);
- break;
- case STP_SYSTEM:
- snprintf(buf, sizeof(buf), "%s", (char *)data);
- _dbug("sending STP_SYSTEM: %s\n", buf);
- break;
- case STP_TRANSPORT:
- _dbug("sending STP_TRANSPORT\n");
- break;
- default:
- _dbug("ERROR: unknown message type: %d\n", type);
- break;
- }
-}
-#endif
-
-static int _stp_ctl_write(int type, void *data, int len)
+inline static int _stp_ctl_write_fs(int type, void *data, unsigned len)
{
struct _stp_buffer *bptr;
unsigned long flags;
-#if DEBUG_TRANS
- _stp_ctl_write_dbug(type, data, len);
-#endif
-
#define WRITE_AGG
#ifdef WRITE_AGG
-
spin_lock_irqsave(&_stp_ctl_ready_lock, flags);
if (!list_empty(&_stp_ctl_ready_q)) {
bptr = (struct _stp_buffer *)_stp_ctl_ready_q.prev;
- if (bptr->len + len <= STP_BUFFER_SIZE && type == STP_REALTIME_DATA && bptr->type == STP_REALTIME_DATA) {
+ if ((bptr->len + len) <= STP_CTL_BUFFER_SIZE
+ && type == STP_REALTIME_DATA
+ && bptr->type == STP_REALTIME_DATA) {
memcpy(bptr->buf + bptr->len, data, len);
bptr->len += len;
spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags);
@@ -176,114 +78,9 @@ static int _stp_ctl_write(int type, void *data, int len)
}
spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags);
#endif
-
- /* make sure we won't overflow the buffer */
- if (unlikely(len > STP_BUFFER_SIZE))
- return 0;
-
- /* get a buffer from the free pool */
- bptr = _stp_mempool_alloc(_stp_pool_q);
- if (unlikely(bptr == NULL))
- return -1;
-
- bptr->type = type;
- memcpy(bptr->buf, data, len);
- bptr->len = len;
-
- /* put it on the pool of ready buffers */
- spin_lock_irqsave(&_stp_ctl_ready_lock, flags);
- list_add_tail(&bptr->list, &_stp_ctl_ready_q);
- spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags);
-
- return len;
-}
-
-
-/* send commands with timeout and retry */
-static int _stp_ctl_send(int type, void *data, int len)
-{
- int err, trylimit = 50;
- dbug_trans(1, "ctl_send: type=%d len=%d\n", type, len);
- while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
- msleep(5);
- if (err > 0)
- wake_up_interruptible(&_stp_ctl_wq);
- dbug_trans(1, "returning %d\n", err);
- return err;
-}
-
-
-static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
- struct _stp_buffer *bptr;
- int len;
- unsigned long flags;
-
- /* wait for nonempty ready queue */
- spin_lock_irqsave(&_stp_ctl_ready_lock, flags);
- while (list_empty(&_stp_ctl_ready_q)) {
- spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags);
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
- if (wait_event_interruptible(_stp_ctl_wq, !list_empty(&_stp_ctl_ready_q)))
- return -ERESTARTSYS;
- spin_lock_irqsave(&_stp_ctl_ready_lock, flags);
- }
-
- /* get the next buffer off the ready list */
- bptr = (struct _stp_buffer *)_stp_ctl_ready_q.next;
- list_del_init(&bptr->list);
- spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags);
-
- /* write it out */
- len = bptr->len + 4;
- if (len > count || copy_to_user(buf, &bptr->type, len)) {
- /* now what? We took it off the queue then failed to send it */
- /* we can't put it back on the queue because it will likely be out-of-order */
- /* fortunately this should never happen */
- /* FIXME need to mark this as a transport failure */
- errk("Supplied buffer too small. count:%d len:%d\n", (int)count, len);
- return -EFAULT;
- }
-
- /* put it on the pool of free buffers */
- _stp_mempool_free(bptr);
-
- return len;
-}
-
-static int _stp_ctl_open_cmd(struct inode *inode, struct file *file)
-{
- if (_stp_attached)
- return -1;
-
- _stp_attach();
- return 0;
-}
-
-static int _stp_ctl_close_cmd(struct inode *inode, struct file *file)
-{
- if (_stp_attached)
- _stp_detach();
return 0;
}
-static struct file_operations _stp_proc_fops_cmd = {
- .owner = THIS_MODULE,
- .read = _stp_ctl_read_cmd,
- .write = _stp_ctl_write_cmd,
- .open = _stp_ctl_open_cmd,
- .release = _stp_ctl_close_cmd,
-};
-
-/* copy since proc_match is not MODULE_EXPORT'd */
-static int my_proc_match(int len, const char *name, struct proc_dir_entry *de)
-{
- if (de->namelen != len)
- return 0;
- return !memcmp(name, de->name, len);
-}
-
/* set the number of buffers to use to 'num' */
static int _stp_set_buffers(int num)
{
@@ -305,7 +102,7 @@ static int _stp_ctl_read_bufsize(char *page, char **start, off_t off, int count,
return len;
}
-static int _stp_register_ctl_channel(void)
+static int _stp_register_ctl_channel_fs(void)
{
int i;
const char *dirname = "systemtap";
@@ -313,17 +110,7 @@ static int _stp_register_ctl_channel(void)
#ifdef STP_BULKMODE
int j;
#endif
-
struct proc_dir_entry *de, *bs = NULL;
- struct list_head *p, *tmp;
-
- INIT_LIST_HEAD(&_stp_ctl_ready_q);
-
- /* allocate buffers */
- _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), STP_DEFAULT_BUFFERS);
- if (unlikely(_stp_pool_q == NULL))
- goto err0;
- _stp_allocated_net_memory += sizeof(struct _stp_buffer) * STP_DEFAULT_BUFFERS;
if (!_stp_mkdir_proc_module())
goto err0;
@@ -354,7 +141,7 @@ static int _stp_register_ctl_channel(void)
goto err1;
de->uid = _stp_uid;
de->gid = _stp_gid;
- de->proc_fops = &_stp_proc_fops_cmd;
+ de->proc_fops = &_stp_ctl_fops_cmd;
return 0;
err2:
@@ -375,18 +162,16 @@ err1:
#endif /* STP_BULKMODE */
_stp_rmdir_proc_module();
err0:
- _stp_mempool_destroy(_stp_pool_q);
- errk("Error creating systemtap /proc entries.\n");
return -1;
}
-static void _stp_unregister_ctl_channel(void)
+static void _stp_unregister_ctl_channel_fs(void)
{
- struct list_head *p, *tmp;
- char buf[32];
#ifdef STP_BULKMODE
+ char buf[32];
int i;
struct proc_dir_entry *de;
+
dbug_trans(1, "unregistering procfs\n");
for (de = _stp_proc_root->subdir; de; de = de->next)
_stp_kfree(de->data);
@@ -398,14 +183,6 @@ static void _stp_unregister_ctl_channel(void)
remove_proc_entry("bufsize", _stp_proc_root);
#endif /* STP_BULKMODE */
- remove_proc_entry(".symbols", _stp_proc_root);
remove_proc_entry(".cmd", _stp_proc_root);
_stp_rmdir_proc_module();
-
- /* Return memory to pool and free it. */
- list_for_each_safe(p, tmp, &_stp_ctl_ready_q) {
- list_del(p);
- _stp_mempool_free(p);
- }
- _stp_mempool_destroy(_stp_pool_q);
}
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 23e4b855..81c5702c 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -27,13 +27,15 @@ static int _stp_probes_started = 0;
static pid_t _stp_target = 0;
static int _stp_exit_called = 0;
static int _stp_exit_flag = 0;
+#include "control.h"
#ifdef STP_OLD_TRANSPORT
#include "relayfs.c"
#include "procfs.c"
#else
#include "utt.c"
-#include "control.c"
+#include "debugfs.c"
#endif
+#include "control.c"
/* module parameters */
static int _stp_bufsize;
@@ -255,7 +257,7 @@ static int _stp_transport_init(void)
goto err0;
#endif
- /* create debugfs/procfs control channel */
+ /* create control channel */
if (_stp_register_ctl_channel() < 0)
goto err1;