diff options
-rw-r--r-- | runtime/io.c | 74 | ||||
-rw-r--r-- | runtime/print.c | 33 | ||||
-rw-r--r-- | runtime/probes/shellsnoop/dtr.c | 56 | ||||
-rwxr-xr-x | runtime/probes/shellsnoop/stp | 16 | ||||
-rwxr-xr-x | runtime/probes/tasklet/stp | 10 | ||||
-rw-r--r-- | runtime/probes/tasklet/stp_tasklet.c | 45 | ||||
-rw-r--r-- | runtime/probes/test4/dtr.c | 33 | ||||
-rwxr-xr-x | runtime/probes/test4/stp | 10 | ||||
-rw-r--r-- | runtime/probes/where_func/kprobe_where_funct.c | 33 | ||||
-rwxr-xr-x | runtime/probes/where_func/stp | 13 | ||||
-rw-r--r-- | runtime/stpd/librelay.c | 224 | ||||
-rw-r--r-- | runtime/stpd/librelay.h | 56 | ||||
-rw-r--r-- | runtime/stpd/stpd.c | 168 |
13 files changed, 388 insertions, 383 deletions
diff --git a/runtime/io.c b/runtime/io.c index 0b409ead..effa750c 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -1,7 +1,7 @@ #ifndef _IO_C_ /* -*- linux-c -*- */ #define _IO_C_ -#include "relay-app.h" +#include "transport/transport.c" #include "print.c" /** @file io.c @@ -17,8 +17,7 @@ static char _stp_lbuf[NR_CPUS][STP_LOG_BUF_LEN + 1]; /** Logs Data. - * This function prints to the system log if stpd has not connected - * yet. Otherwise it sends the message immediately to stpd. + * This function sends the message immediately to stpd. * @param fmt A variable number of args. * @note Lines are limited in length by printk buffer. If there is * no newline in the format string, then other syslog output could @@ -36,74 +35,7 @@ void _stp_log (const char *fmt, ...) va_end(args); buf[num] = '\0'; - if (app.logging) - send_reply (STP_REALTIME_DATA, buf, num + 1, stpd_pid); - else - printk("STP: %s", buf); -} - -static void stpd_app_started(void) -{ - printk ("stpd has started.\n"); -} - -static void stpd_app_stopped(void) -{ - printk ("stpd has stopped.\n"); -} - -static void probe_exit(void); - -#include <linux/delay.h> -static int stpd_command (int type, void *data) -{ - if (type == STP_EXIT) { - printk ("STP_EXIT received\n"); - probe_exit(); -#ifndef STP_NETLINK_ONLY - relay_flush(app.chan); - ssleep(2); /* FIXME: time for data to be flushed */ -#endif - send_reply (STP_EXIT, __this_module.name, strlen(__this_module.name) + 1, stpd_pid); - return 1; - } - return 0; -} - -/* - * relay-app callbacks - */ -static struct relay_app_callbacks stp_callbacks = -{ - .app_started = stpd_app_started, - .app_stopped = stpd_app_stopped, - .user_command = stpd_command -}; - -/** Opens netlink and relayfs connections to stpd. - * This must be called before any I/O is done, probably - * at the start of module initialization. - */ -int _stp_netlink_open(void) -{ - if (init_relay_app("stpd", "cpu", &stp_callbacks)) { - printk ("STP: couldn't init relay app\n"); - return -1; - } - return 0; -} - -/** Closes netlink and relayfs connections to stpd. - * This must be called after all I/O is done, probably - * at the end of module cleanup. - * @returns 0 on success. -1 if there is a problem establishing - * a connection. - */ - -void _stp_netlink_close (void) -{ - send_reply (STP_DONE, NULL, 0, stpd_pid); - close_relay_app(); + _stp_ctrl_send(STP_REALTIME_DATA, buf, num + 1, t->pid); } /** @} */ diff --git a/runtime/print.c b/runtime/print.c index bb738d14..b6fd4323 100644 --- a/runtime/print.c +++ b/runtime/print.c @@ -23,35 +23,6 @@ static int _stp_pbuf_len[NR_CPUS]; -#ifdef STP_NETLINK_ONLY -#define STP_PRINT_BUF_START 0 -static char _stp_pbuf[NR_CPUS][STP_PRINT_BUF_LEN + 1]; - -void _stp_print_flush (void) -{ - int cpu = smp_processor_id(); - char *buf = &_stp_pbuf[cpu][0]; - int len = _stp_pbuf_len[cpu]; - - if (len == 0) - return; - - if ( app.logging == 0) { - _stp_pbuf_len[cpu] = 0; - return; - } - - /* enforce newline at end */ - if (buf[len - 1] != '\n') { - buf[len++] = '\n'; - buf[len] = '\0'; - } - - send_reply (STP_REALTIME_DATA, buf, len + 1, stpd_pid); - _stp_pbuf_len[cpu] = 0; -} - -#else /* ! STP_NETLINK_ONLY */ /* size of timestamp, in bytes, including space */ #define TIMESTAMP_SIZE 19 #define STP_PRINT_BUF_START (TIMESTAMP_SIZE + 1) @@ -61,7 +32,6 @@ static char _stp_pbuf[NR_CPUS][STP_PRINT_BUF_LEN + STP_PRINT_BUF_START + 1]; * Output accumulates in the print buffer until this is called. * Size is limited by length of print buffer, #STP_PRINT_BUF_LEN. */ - void _stp_print_flush (void) { int cpu = smp_processor_id(); @@ -81,10 +51,9 @@ void _stp_print_flush (void) do_gettimeofday(&tv); scnprintf (buf, TIMESTAMP_SIZE+1, "[%li.%06li] ", tv.tv_sec, tv.tv_usec); buf[TIMESTAMP_SIZE] = ' '; - relayapp_write(buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 2); + _stp_transport_write(t, buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 2); _stp_pbuf_len[cpu] = 0; } -#endif /* STP_NETLINK_ONLY */ /** Print into the print buffer. * Like printf, except output goes to the print buffer. diff --git a/runtime/probes/shellsnoop/dtr.c b/runtime/probes/shellsnoop/dtr.c index e529b054..b857a618 100644 --- a/runtime/probes/shellsnoop/dtr.c +++ b/runtime/probes/shellsnoop/dtr.c @@ -100,36 +100,62 @@ static struct jprobe dtr_probes[] = { #define MAX_DTR_ROUTINE (sizeof(dtr_probes)/sizeof(struct jprobe)) +static unsigned n_subbufs = 4; +module_param(n_subbufs, uint, 0); +MODULE_PARM_DESC(n_subbufs, "number of sub-buffers per per-cpu buffer"); + +static unsigned subbuf_size = 65536; +module_param(subbuf_size, uint, 0); +MODULE_PARM_DESC(subbuf_size, "size of each per-cpu sub-buffers"); + +static int pid; +module_param(pid, int, 0); +MODULE_PARM_DESC(pid, "daemon pid"); + static int init_dtr(void) { - int ret; + int ret; - if (_stp_netlink_open() < 0) - return -1; + if (!pid) { + printk("init_dtr: Can't start without daemon pid\n"); + return -1; + } - pids = _stp_map_new (10000, INT64); - arglist = _stp_list_new (10, STRING); + if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) { + printk("init_dtr: Couldn't open transport\n"); + return -1; + } - ret = _stp_register_jprobes (dtr_probes, MAX_DTR_ROUTINE); + pids = _stp_map_new (10000, INT64); + arglist = _stp_list_new (10, STRING); - _stp_log("instrumentation is enabled... %s\n", __this_module.name); - return ret; + ret = _stp_register_jprobes (dtr_probes, MAX_DTR_ROUTINE); + + printk("instrumentation is enabled... %s\n", __this_module.name); + + return ret; } +static int exited; /* FIXME: this is a stopgap - if we don't do this + * and are manually removed, bad things happen */ + static void probe_exit (void) { - _stp_unregister_jprobes (dtr_probes, MAX_DTR_ROUTINE); + exited = 1; - _stp_print ("In probe_exit now."); - _stp_map_del (pids); - _stp_print_flush(); -} + _stp_unregister_jprobes (dtr_probes, MAX_DTR_ROUTINE); + _stp_print ("In probe_exit now."); + _stp_map_del (pids); + _stp_print_flush(); +} static void cleanup_dtr(void) { - _stp_netlink_close(); - + if (!exited) + probe_exit(); + + _stp_transport_close(); } module_init(init_dtr); diff --git a/runtime/probes/shellsnoop/stp b/runtime/probes/shellsnoop/stp index d10fcaab..14e8f47a 100755 --- a/runtime/probes/shellsnoop/stp +++ b/runtime/probes/shellsnoop/stp @@ -24,13 +24,25 @@ then mount -t relayfs relayfs /mnt/relay fi -/sbin/insmod $modulename +STP_CONTROL=`lsmod | grep stp_control |awk '{print $1}'` +if [ "$STP_CONTROL" != "stp_control" ] +then + /sbin/insmod ../../transport/stp-control.ko +fi + +#/sbin/insmod $modulename # print to screen only, 4 8K buffers #../../stpd/stpd -p -b 8192 -n 4 +# print to screen +../../stpd/stpd -b 8192 -n 4 $modulename + +# log to files (relayfs), 4 8K buffers +#../../stpd/stpd -r -b 8192 -n 4 $modulename + # print to screen and log to files, 4 8K buffers -../../stpd/stpd -b 8192 -n 4 +#../../stpd/stpd -b 8192 -n 4 # no screen or log #../../stpd/stpd -q -b 8192 -n 4 diff --git a/runtime/probes/tasklet/stp b/runtime/probes/tasklet/stp index d10fcaab..185a5905 100755 --- a/runtime/probes/tasklet/stp +++ b/runtime/probes/tasklet/stp @@ -24,13 +24,19 @@ then mount -t relayfs relayfs /mnt/relay fi -/sbin/insmod $modulename +STP_CONTROL=`lsmod | grep stp_control |awk '{print $1}'` +if [ "$STP_CONTROL" != "stp_control" ] +then + /sbin/insmod ../../transport/stp-control.ko +fi + +#/sbin/insmod $modulename # print to screen only, 4 8K buffers #../../stpd/stpd -p -b 8192 -n 4 # print to screen and log to files, 4 8K buffers -../../stpd/stpd -b 8192 -n 4 +../../stpd/stpd -b 8192 -n 4 $modulename # no screen or log #../../stpd/stpd -q -b 8192 -n 4 diff --git a/runtime/probes/tasklet/stp_tasklet.c b/runtime/probes/tasklet/stp_tasklet.c index f9274281..c3581eb2 100644 --- a/runtime/probes/tasklet/stp_tasklet.c +++ b/runtime/probes/tasklet/stp_tasklet.c @@ -30,27 +30,54 @@ static struct jprobe stp_probes[] = { }; #define MAX_STP_PROBES (sizeof(stp_probes)/sizeof(struct jprobe)) +static unsigned n_subbufs = 4; +module_param(n_subbufs, uint, 0); +MODULE_PARM_DESC(n_subbufs, "number of sub-buffers per per-cpu buffer"); + +static unsigned subbuf_size = 65536; +module_param(subbuf_size, uint, 0); +MODULE_PARM_DESC(subbuf_size, "size of each per-cpu sub-buffers"); + +static int pid; +module_param(pid, int, 0); +MODULE_PARM_DESC(pid, "daemon pid"); static int init_stp(void) { - int ret; + int ret; + + if (!pid) { + printk("init_dtr: Can't start without daemon pid\n"); + return -1; + } - if (_stp_netlink_open() < 0) - return -1; - ret = _stp_register_jprobes (stp_probes, MAX_STP_PROBES); - _stp_log ("instrumentation is enabled...\n"); - return ret; + if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) { + printk("init_dtr: Couldn't open transport\n"); + return -1; + } + + ret = _stp_register_jprobes (stp_probes, MAX_STP_PROBES); + printk("instrumentation is enabled...\n"); + return ret; } +static int exited; /* FIXME: this is a stopgap - if we don't do this + * and are manually removed, bad things happen */ + static void probe_exit (void) { - _stp_unregister_jprobes (stp_probes, MAX_STP_PROBES); - _stp_log ("EXIT\n"); + exited = 1; + + _stp_unregister_jprobes (stp_probes, MAX_STP_PROBES); + _stp_log ("EXIT\n"); } static void cleanup_stp(void) { - _stp_netlink_close(); + if (!exited) + probe_exit(); + + _stp_transport_close(); } module_init(init_stp); diff --git a/runtime/probes/test4/dtr.c b/runtime/probes/test4/dtr.c index 814bb61d..09b0f52d 100644 --- a/runtime/probes/test4/dtr.c +++ b/runtime/probes/test4/dtr.c @@ -78,12 +78,31 @@ static struct jprobe dtr_probes[] = { #define MAX_DTR_ROUTINE (sizeof(dtr_probes)/sizeof(struct jprobe)) +static unsigned n_subbufs = 4; +module_param(n_subbufs, uint, 0); +MODULE_PARM_DESC(n_subbufs, "number of sub-buffers per per-cpu buffer"); + +static unsigned subbuf_size = 65536; +module_param(subbuf_size, uint, 0); +MODULE_PARM_DESC(subbuf_size, "size of each per-cpu sub-buffers"); + +static int pid; +module_param(pid, int, 0); +MODULE_PARM_DESC(pid, "daemon pid"); + static int init_dtr(void) { int ret; - if (_stp_netlink_open() < 0) - return -1; + if (!pid) { + printk("init_dtr: Can't start without daemon pid\n"); + return -1; + } + + if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) { + printk("init_dtr: Couldn't open transport\n"); + return -1; + } opens = _stp_map_new (1000, INT64); reads = _stp_map_new (1000, STAT); @@ -96,12 +115,17 @@ static int init_dtr(void) return ret; } +static int exited; /* FIXME: this is a stopgap - if we don't do this + * and are manually removed, bad things happen */ + static void probe_exit (void) { struct map_node_stat *st; struct map_node_int64 *ptr; struct map_node_str *sptr; + exited = 1; + _stp_unregister_jprobes (dtr_probes, MAX_DTR_ROUTINE); foreach (traces, sptr) { @@ -133,7 +157,10 @@ static void probe_exit (void) static void cleanup_dtr(void) { - _stp_netlink_close(); + if (!exited) + probe_exit(); + + _stp_transport_close(); } module_init(init_dtr); diff --git a/runtime/probes/test4/stp b/runtime/probes/test4/stp index d10fcaab..185a5905 100755 --- a/runtime/probes/test4/stp +++ b/runtime/probes/test4/stp @@ -24,13 +24,19 @@ then mount -t relayfs relayfs /mnt/relay fi -/sbin/insmod $modulename +STP_CONTROL=`lsmod | grep stp_control |awk '{print $1}'` +if [ "$STP_CONTROL" != "stp_control" ] +then + /sbin/insmod ../../transport/stp-control.ko +fi + +#/sbin/insmod $modulename # print to screen only, 4 8K buffers #../../stpd/stpd -p -b 8192 -n 4 # print to screen and log to files, 4 8K buffers -../../stpd/stpd -b 8192 -n 4 +../../stpd/stpd -b 8192 -n 4 $modulename # no screen or log #../../stpd/stpd -q -b 8192 -n 4 diff --git a/runtime/probes/where_func/kprobe_where_funct.c b/runtime/probes/where_func/kprobe_where_funct.c index 027a40de..960f2290 100644 --- a/runtime/probes/where_func/kprobe_where_funct.c +++ b/runtime/probes/where_func/kprobe_where_funct.c @@ -45,12 +45,31 @@ static struct kprobe kp[] = { }; #define MAX_KPROBES (sizeof(kp)/sizeof(struct kprobe)) +static unsigned n_subbufs = 4; +module_param(n_subbufs, uint, 0); +MODULE_PARM_DESC(n_subbufs, "number of sub-buffers per per-cpu buffer"); + +static unsigned subbuf_size = 65536; +module_param(subbuf_size, uint, 0); +MODULE_PARM_DESC(subbuf_size, "size of each per-cpu sub-buffers"); + +static int pid; +module_param(pid, int, 0); +MODULE_PARM_DESC(pid, "daemon pid"); + int init_module(void) { int ret; - - if (_stp_netlink_open() < 0) + + if (!pid) { + printk("init_dtr: Can't start without daemon pid\n"); return -1; + } + + if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) { + printk("init_dtr: Couldn't open transport\n"); + return -1; + } funct_locations = _stp_map_new(1000, INT64); @@ -62,10 +81,15 @@ int init_module(void) return ret; } +static int exited; /* FIXME: this is a stopgap - if we don't do this + * and are manually removed, bad things happen */ + static void probe_exit (void) { struct map_node_int64 *ptr; + exited = 1; + _stp_unregister_kprobes (kp, MAX_KPROBES); _stp_printf("%s() called %d times.\n", funct_name, count_funct); @@ -83,7 +107,10 @@ static void probe_exit (void) void cleanup_module(void) { - _stp_netlink_close(); + if (!exited) + probe_exit(); + + _stp_transport_close(); } MODULE_LICENSE("GPL"); diff --git a/runtime/probes/where_func/stp b/runtime/probes/where_func/stp index d10fcaab..ca0cb63c 100755 --- a/runtime/probes/where_func/stp +++ b/runtime/probes/where_func/stp @@ -24,13 +24,22 @@ then mount -t relayfs relayfs /mnt/relay fi -/sbin/insmod $modulename +STP_CONTROL=`lsmod | grep stp_control |awk '{print $1}'` +if [ "$STP_CONTROL" != "stp_control" ] +then + /sbin/insmod ../../transport/stp-control.ko +fi + +#/sbin/insmod $modulename # print to screen only, 4 8K buffers #../../stpd/stpd -p -b 8192 -n 4 # print to screen and log to files, 4 8K buffers -../../stpd/stpd -b 8192 -n 4 +../../stpd/stpd -b 8192 -n 4 $modulename + +# print to screen and log to files, 4 8K buffers +#../../stpd/stpd -b 8192 -n 4 # no screen or log #../../stpd/stpd -q -b 8192 -n 4 diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c index 04d1ba6b..a0421749 100644 --- a/runtime/stpd/librelay.c +++ b/runtime/stpd/librelay.c @@ -1,5 +1,5 @@ /* - * librelay - relay-app user space 'library' + * libstp - stpd 'library' * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Copyright (C) 2005 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) IBM Corporation, 2005 + * Copyright (C) Redhat Inc, 2005 * */ #include <ctype.h> @@ -54,11 +55,11 @@ static char *relay_buffer[NR_CPUS]; /* netlink control channel */ static int control_channel; -static int nl_unit; /* flags */ extern int print_only; extern int quiet; +extern int streaming; /* used to communicate with kernel over control channel */ @@ -75,12 +76,6 @@ struct consumed_info unsigned consumed; }; -struct channel_create_info -{ - unsigned subbuf_size; - unsigned n_subbufs; -}; - struct app_msg { struct nlmsghdr nlh; @@ -108,15 +103,6 @@ static char *color[] = { "\033[36m", /* cyan */ }; - -enum -{ - STP_REALTIME_DATA = RELAY_APP_USERCMD_START, - STP_EXIT, - STP_DONE -}; - - /** * send_request - send request to kernel over control channel * @type: the relay-app command id @@ -154,7 +140,7 @@ static int open_control_channel() struct sockaddr_nl snl; int channel; - channel = socket(AF_NETLINK, SOCK_RAW, nl_unit); + channel = socket(AF_NETLINK, SOCK_RAW, NETLINK_USERSOCK); if (channel < 0) { printf("socket() failed\n"); return channel; @@ -174,49 +160,46 @@ static int open_control_channel() /** * process_subbufs - write ready subbufs to disk and/or screen */ - -static int process_subbufs (struct buf_info *info) +static int process_subbufs(struct buf_info *info) { - unsigned subbufs_ready, start_subbuf, end_subbuf, subbuf_idx; - int i, len, cpu = info->cpu; - char *subbuf_ptr; - int subbufs_consumed = 0; - unsigned padding; - - subbufs_ready = info->produced - info->consumed; - start_subbuf = info->consumed % n_subbufs; - end_subbuf = start_subbuf + subbufs_ready; - - if (!quiet) - fputs ( color[cpu % 4], stdout); - - for (i = start_subbuf; i < end_subbuf; i++) { - subbuf_idx = i % n_subbufs; - subbuf_ptr = relay_buffer[cpu] + subbuf_idx * subbuf_size; - padding = *((unsigned *)subbuf_ptr); - subbuf_ptr += sizeof(padding); - len = (subbuf_size - sizeof(padding)) - padding; - - if (!print_only) - { - if (write(out_file[cpu], subbuf_ptr, len) < 0) - { - printf("Couldn't write to output file for cpu %d, exiting: errcode = %d: %s\n", cpu, errno, strerror(errno)); - exit(1); - } - } - - if (!quiet) - fwrite (subbuf_ptr, len, 1, stdout); - - subbufs_consumed++; - } + unsigned subbufs_ready, start_subbuf, end_subbuf, subbuf_idx; + int i, len, cpu = info->cpu; + char *subbuf_ptr; + int subbufs_consumed = 0; + unsigned padding; - return subbufs_consumed; + subbufs_ready = info->produced - info->consumed; + start_subbuf = info->consumed % n_subbufs; + end_subbuf = start_subbuf + subbufs_ready; + + if (!quiet) + fputs ( color[cpu % 4], stdout); + + for (i = start_subbuf; i < end_subbuf; i++) { + subbuf_idx = i % n_subbufs; + subbuf_ptr = relay_buffer[cpu] + subbuf_idx * subbuf_size; + padding = *((unsigned *)subbuf_ptr); + subbuf_ptr += sizeof(padding); + len = (subbuf_size - sizeof(padding)) - padding; + + if (!print_only) + { + if (write(out_file[cpu], subbuf_ptr, len) < 0) + { + printf("Couldn't write to output file for cpu %d, exiting: errcode = %d: %s\n", cpu, errno, strerror(errno)); + exit(1); + } + } + + if (!quiet) + fwrite (subbuf_ptr, len, 1, stdout); + + subbufs_consumed++; + } + + return subbufs_consumed; } - - /** * reader_thread - per-cpu channel buffer reader */ @@ -241,7 +224,7 @@ static void *reader_thread(void *data) rc = 0; } - send_request(RELAY_APP_BUF_INFO, &status[cpu].info, + send_request(STP_BUF_INFO, &status[cpu].info, sizeof(struct buf_info)); if (status[cpu].info.produced == status[cpu].info.consumed) pthread_cond_wait(&status[cpu].ready_cond, @@ -257,7 +240,7 @@ static void *reader_thread(void *data) status[cpu].info.consumed += subbufs_consumed; consumed_info.cpu = cpu; consumed_info.consumed = subbufs_consumed; - send_request(RELAY_APP_SUBBUFS_CONSUMED, + send_request(STP_SUBBUFS_CONSUMED, &consumed_info, sizeof(struct consumed_info)); } @@ -268,9 +251,12 @@ static void summarize(void) { int i; + if (streaming) + return; + printf("summary:\n"); for (i = 0; i < ncpus; i++) { - printf("%s cpu %u:\n", color[i % 4], i); + printf("%s cpu %u:\n", color[i % 4], i); printf(" %u sub-buffers processed\n", status[i].info.consumed); printf(" %u max backlog\n", status[i].max_backlog); @@ -302,7 +288,6 @@ static void sigalarm(int signum) if (print_totals) summarize(); close_all_files(); - send_request(RELAY_APP_CHAN_DESTROY, NULL, 0); exit(0); } @@ -334,14 +319,14 @@ static int open_files(int cpu, const char *relay_filebase, } if (!print_only) { - sprintf(tmp, "%s%d", out_filebase, cpu); - if((out_file[cpu] = open(tmp, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | - S_IWUSR | S_IRGRP | S_IROTH)) < 0) { - printf("Couldn't open output file %s: errcode = %s\n", - tmp, strerror(errno)); - close(relay_file[cpu]); - return -1; - } + sprintf(tmp, "%s%d", out_filebase, cpu); + if((out_file[cpu] = open(tmp, O_CREAT | O_RDWR | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + printf("Couldn't open output file %s: errcode = %s\n", + tmp, strerror(errno)); + close(relay_file[cpu]); + return -1; + } } total_bufsize = subbuf_size * n_subbufs; @@ -360,50 +345,49 @@ static int open_files(int cpu, const char *relay_filebase, } /** - * _init_relay_app - initialize the relay-app with specific netlink unit + * init_stp - initialize the app * @relay_filebase: full path of base name of the per-cpu relayfs files * @out_filebase: base name of the per-cpu files data will be written to * @sub_buf_size: relayfs sub-buffer size of channel to be created * @n_sub_bufs: relayfs number of sub-buffers of channel to be created * @print_summary: boolean, print summary or not at end of run - * @netlink_unit: netlink unit, see netlink.h * * Returns 0 on success, negative otherwise. - * - * NOTE: use init_relay_app() instead if you don't need to specify a - * non-default netlink unit */ -int _init_relay_app(const char *relay_filebase, - const char *out_filebase, - unsigned sub_buf_size, - unsigned n_sub_bufs, - int print_summary, - int netlink_unit) +int init_stp(const char *modname, + const char *relay_filebase, + const char *out_filebase, + unsigned sub_buf_size, + unsigned n_sub_bufs, + int print_summary) { int i; - struct channel_create_info create_info; - + int daemon_pid; + char buf[1024]; + ncpus = sysconf(_SC_NPROCESSORS_ONLN); subbuf_size = sub_buf_size; n_subbufs = n_sub_bufs; print_totals = print_summary; - nl_unit = netlink_unit; + + daemon_pid = getpid(); + sprintf(buf, "insmod %s n_subbufs=%u subbuf_size=%u pid=%d", + modname, n_subbufs, subbuf_size, daemon_pid); + if (system(buf)) { + printf("Couldn't insmod probe module %s\n", modname); + return -1; + } control_channel = open_control_channel(); if (control_channel < 0) return -1; - create_info.subbuf_size = subbuf_size; - create_info.n_subbufs = n_subbufs; + if (streaming) + return 0; - send_request(RELAY_APP_STOP, NULL, 0); /* in case we exited badly before */ - send_request(RELAY_APP_CHAN_CREATE, &create_info, sizeof(create_info)); - for (i = 0; i < ncpus; i++) { if (open_files(i, relay_filebase, out_filebase) < 0) { printf("Couldn't open files\n"); - send_request(RELAY_APP_STOP, NULL, 0); - send_request(RELAY_APP_CHAN_DESTROY, NULL, 0); return -1; } } @@ -412,35 +396,9 @@ int _init_relay_app(const char *relay_filebase, } /** - * init_relay_app - initialize the relay-app application - * @relay_filebase: full path of base name of the per-cpu relayfs files - * @out_filebase: base name of the per-cpu files data will be written to - * @sub_buf_size: relayfs sub-buffer size of channel to be created - * @n_sub_bufs: relayfs number of sub-buffers of channel to be created - * @print_summary: boolean, print summary or not at end of run - * - * Returns 0 on success, negative otherwise. - * - * The relayfs channel is created as a result of this function. - */ -int init_relay_app(const char *relay_filebase, - const char *out_filebase, - unsigned sub_buf_size, - unsigned n_sub_bufs, - int print_summary) -{ - return _init_relay_app(relay_filebase, - out_filebase, - sub_buf_size, - n_sub_bufs, - print_summary, - NETLINK_USERSOCK); -} - -/** - * relay_app_main_loop - loop forever reading data + * stp_main_loop - loop forever reading data */ -int relay_app_main_loop(void) +int stp_main_loop(void) { pthread_t thread; int cpu, nb; @@ -453,15 +411,13 @@ int relay_app_main_loop(void) signal(SIGTERM, sigproc); signal(SIGALRM, sigalarm); - send_request(RELAY_APP_START, NULL, 0); - - for (i = 0; i < ncpus; i++) { - /* create a thread for each per-cpu buffer */ - if (pthread_create(&thread, NULL, reader_thread, (void *)i) < 0) { - printf("Couldn't create thread\n"); - send_request(RELAY_APP_STOP, NULL, 0); - send_request(RELAY_APP_CHAN_DESTROY, NULL, 0); - return -1; + if (!streaming) { + for (i = 0; i < ncpus; i++) { + /* create a thread for each per-cpu buffer */ + if (pthread_create(&thread, NULL, reader_thread, (void *)i) < 0) { + printf("Couldn't create thread\n"); + return -1; + } } } @@ -482,8 +438,7 @@ int relay_app_main_loop(void) continue; } switch (nlh->nlmsg_type) { - case RELAY_APP_BUF_INFO: - case RELAY_APP_SUBBUFS_CONSUMED: + case STP_BUF_INFO: msg = (struct app_msg *)nlh; cpu = msg->info.cpu; memcpy(&status[cpu].info, &msg->info, sizeof (struct buf_info)); @@ -503,13 +458,14 @@ int relay_app_main_loop(void) /* FIXME. overflow check */ strcpy (tmpbuf, "/sbin/rmmod "); strcpy (tmpbuf + strlen(tmpbuf), (char *)ptr); +#if 0 printf ("Executing \"system %s\"\n", tmpbuf); +#endif system (tmpbuf); - break; - case STP_DONE: if (print_totals) - summarize(); - close_all_files(); + summarize(); + if (!streaming) + close_all_files(); exit(0); break; default: diff --git a/runtime/stpd/librelay.h b/runtime/stpd/librelay.h index 78acac47..033976d9 100644 --- a/runtime/stpd/librelay.h +++ b/runtime/stpd/librelay.h @@ -1,51 +1,21 @@ -/* - * librelay.h - relay-app user space 'library' header - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2005 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp - * - */ - -/* relay-app control channel command values */ +/* SystemTap control channel command values */ enum { - RELAY_APP_BUF_INFO = 1, - RELAY_APP_SUBBUFS_CONSUMED, - RELAY_APP_START, - RELAY_APP_STOP, - RELAY_APP_CHAN_CREATE, - RELAY_APP_CHAN_DESTROY, - RELAY_APP_USERCMD_START = 32 + STP_BUF_INFO = 1, + STP_SUBBUFS_CONSUMED, + STP_REALTIME_DATA, + STP_EXIT, }; /* - * relay-app external API functions + * stp external API functions */ -extern int init_relay_app(const char *relay_filebase, - const char *out_filebase, - unsigned sub_buf_size, - unsigned n_sub_bufs, - int print_summary); - -extern int _init_relay_app(const char *relay_filebase, - const char *out_filebase, - unsigned sub_buf_size, - unsigned n_sub_bufs, - int print_summary, - int netlink_unit); +extern int init_stp(const char *modname, + const char *relay_filebase, + const char *out_filebase, + unsigned sub_buf_size, + unsigned n_sub_bufs, + int print_summary); -extern int relay_app_main_loop(void); +extern int stp_main_loop(void); extern int send_request(int type, void *data, int len); diff --git a/runtime/stpd/stpd.c b/runtime/stpd/stpd.c index 264cb36d..881556cc 100644 --- a/runtime/stpd/stpd.c +++ b/runtime/stpd/stpd.c @@ -1,11 +1,30 @@ +/* + * stp.c - stp 'daemon' + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2005 + * Copyright (C) Redhat Inc, 2005 + * + */ + #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "librelay.h" - /* relayfs base file name */ -static char *stpd_filebase = "/mnt/relay/stpd/cpu"; - /* packet logging output written here, filebase0...N */ static char *stpd_outfilebase = "stpd_cpu"; @@ -16,83 +35,102 @@ static unsigned n_subbufs = DEFAULT_N_SUBBUFS; extern char *optarg; extern int optopt; +extern int optind; + int print_only = 0; int quiet = 0; +int streaming = 1; + + /* relayfs base file name */ +static char stpd_filebase[1024]; static void usage(char *prog) { - fprintf(stderr, "%s [-p] [-q] [-b subbuf_size -n n_subbufs]\n", prog); - fprintf(stderr, "-p Print only. Don't log to files.\n"); - fprintf(stderr, "-q Quiet. Don't display trace to stdout.\n"); - fprintf(stderr, "-b subbuf_size (default is %d)\n", DEFAULT_SUBBUF_SIZE); - fprintf(stderr, "-b subbufs (default is %d)\n", DEFAULT_N_SUBBUFS); - exit(1); + fprintf(stderr, "%s [-p] [-q] [-b subbuf_size -n n_subbufs] kmod-name\n", prog); + fprintf(stderr, "-p Print only. Don't log to files.\n"); + fprintf(stderr, "-q Quiet. Don't display trace to stdout.\n"); + fprintf(stderr, "-r Use relayfs for buffering i.e. non-streaming mode.\n"); + fprintf(stderr, "-b subbuf_size (default is %d)\n", DEFAULT_SUBBUF_SIZE); + fprintf(stderr, "-n subbufs (default is %d)\n", DEFAULT_N_SUBBUFS); + exit(1); } int main(int argc, char **argv) { - int c; - unsigned opt_subbuf_size = 0; - unsigned opt_n_subbufs = 0; + int c; + unsigned opt_subbuf_size = 0; + unsigned opt_n_subbufs = 0; + char *modname = NULL; - while ((c = getopt(argc, argv, "b:n:pq")) != EOF) - { - switch (c) { - case 'b': - opt_subbuf_size = (unsigned)atoi(optarg); - if (!opt_subbuf_size) - usage(argv[0]); - break; - case 'n': - opt_n_subbufs = (unsigned)atoi(optarg); - if (!opt_n_subbufs) - usage(argv[0]); - break; - case 'p': - print_only = 1; - break; - case 'q': - quiet = 1; - break; - default: - usage(argv[0]); - } - } + while ((c = getopt(argc, argv, "b:n:pqr")) != EOF) + { + switch (c) { + case 'b': + opt_subbuf_size = (unsigned)atoi(optarg); + if (!opt_subbuf_size) + usage(argv[0]); + break; + case 'n': + opt_n_subbufs = (unsigned)atoi(optarg); + if (!opt_n_subbufs) + usage(argv[0]); + break; + case 'p': + print_only = 1; + break; + case 'q': + quiet = 1; + break; + case 'r': + streaming = 0; + break; + default: + usage(argv[0]); + } + } - if ( print_only && quiet) - { - fprintf (stderr, "Cannot do \"-p\" and \"-q\" both.\n"); - usage(argv[0]); - } - - if ((opt_n_subbufs && !opt_subbuf_size) || - (!opt_n_subbufs && opt_subbuf_size)) - usage(argv[0]); + if (optind < argc) + modname = argv[optind++]; - if (opt_n_subbufs && opt_n_subbufs) { - subbuf_size = opt_subbuf_size; - n_subbufs = opt_n_subbufs; - } + if (!modname) { + fprintf (stderr, "Cannot invoke daemon without probe module\n"); + usage(argv[0]); + } + + if (print_only && quiet) { + fprintf (stderr, "Cannot do \"-p\" and \"-q\" both.\n"); + usage(argv[0]); + } - if (init_relay_app(stpd_filebase, stpd_outfilebase, - subbuf_size, n_subbufs, 1)) - { - fprintf(stderr, "Couldn't initialize relay app. Exiting.\n"); - exit(1); - } + if ((opt_n_subbufs && !opt_subbuf_size) || + (!opt_n_subbufs && opt_subbuf_size)) + usage(argv[0]); - printf("Creating channel with %u sub-buffers of size %u.\n", - n_subbufs, subbuf_size); + if (opt_n_subbufs && opt_n_subbufs) { + subbuf_size = opt_subbuf_size; + n_subbufs = opt_n_subbufs; + } + + sprintf(stpd_filebase, "/mnt/relay/%d/cpu", getpid()); + if (init_stp(modname, stpd_filebase, stpd_outfilebase, + subbuf_size, n_subbufs, 1)) { + fprintf(stderr, "Couldn't initialize stpd. Exiting.\n"); + exit(1); + } + + if (!streaming) + printf("Creating channel with %u sub-buffers of size %u.\n", + n_subbufs, subbuf_size); - if (quiet) - printf("Logging... Press Control-C to stop.\n"); - else - printf("Press Control-C to stop.\n"); + if (quiet) + printf("Logging... Press Control-C to stop.\n"); + else + printf("Press Control-C to stop.\n"); - if (relay_app_main_loop()) { - printf("Couldn't enter main loop. Exiting.\n"); - exit(1); - } + if (stp_main_loop()) { + printf("Couldn't enter main loop. Exiting.\n"); + exit(1); + } - return 0; + return 0; } |