diff options
Diffstat (limited to 'runtime/stpd')
-rw-r--r-- | runtime/stpd/librelay.c | 224 | ||||
-rw-r--r-- | runtime/stpd/librelay.h | 56 | ||||
-rw-r--r-- | runtime/stpd/stpd.c | 168 |
3 files changed, 206 insertions, 242 deletions
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; } |