summaryrefslogtreecommitdiffstats
path: root/runtime/transport/procfs.c
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2009-02-17 08:32:43 -0600
committerDavid Smith <dsmith@redhat.com>2009-02-17 08:32:43 -0600
commita79ec729450bc24d0943c2c1ee67efa8acb58273 (patch)
treedeae00cc69b4bf5da3a440bb47004c371cefc75f /runtime/transport/procfs.c
parentea1248d39b26b7f4288751cdf9eb019266bfd91b (diff)
downloadsystemtap-steved-a79ec729450bc24d0943c2c1ee67efa8acb58273.tar.gz
systemtap-steved-a79ec729450bc24d0943c2c1ee67efa8acb58273.tar.xz
systemtap-steved-a79ec729450bc24d0943c2c1ee67efa8acb58273.zip
Reduced control channel code duplication.
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.
Diffstat (limited to 'runtime/transport/procfs.c')
-rw-r--r--runtime/transport/procfs.c243
1 files changed, 10 insertions, 233 deletions
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);
}