diff options
author | David Smith <dsmith@redhat.com> | 2009-02-17 08:32:43 -0600 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2009-02-17 08:32:43 -0600 |
commit | a79ec729450bc24d0943c2c1ee67efa8acb58273 (patch) | |
tree | deae00cc69b4bf5da3a440bb47004c371cefc75f /runtime/transport/procfs.c | |
parent | ea1248d39b26b7f4288751cdf9eb019266bfd91b (diff) | |
download | systemtap-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.c | 243 |
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); } |