diff options
Diffstat (limited to 'runtime/stpd')
-rw-r--r-- | runtime/stpd/ChangeLog | 401 | ||||
-rw-r--r-- | runtime/stpd/Makefile | 18 | ||||
-rw-r--r-- | runtime/stpd/librelay.c | 861 | ||||
-rw-r--r-- | runtime/stpd/librelay.h | 33 | ||||
-rw-r--r-- | runtime/stpd/stp_dump.c | 82 | ||||
-rw-r--r-- | runtime/stpd/stp_merge.c | 121 | ||||
-rw-r--r-- | runtime/stpd/stpd.c | 179 | ||||
-rw-r--r-- | runtime/stpd/symbols.c | 233 |
8 files changed, 0 insertions, 1928 deletions
diff --git a/runtime/stpd/ChangeLog b/runtime/stpd/ChangeLog deleted file mode 100644 index 7b60957e..00000000 --- a/runtime/stpd/ChangeLog +++ /dev/null @@ -1,401 +0,0 @@ -2007-03-12 Frank Ch. Eigler <fche@elastic.org> - - * librelay.c (init_stp): Use /proc/MODULE rather than - /proc/systemtap/MODULE. - -2006-12-11 Martin Hunt <hunt@redhat.com> - - * symbols.c (get_sections): Set buffer sizes to large enough - sizes to hold all possible values, but also include checks in case - we are wrong. - -2006-11-15 Martin Hunt <hunt@redhat.com> - - * symbols.c (do_kernel_symbols): Add sizeof(long) to sym_base - to preserve 64-bit alignment. - -2006-11-09 Martin Hunt <hunt@redhat.com> - - * librelay.c: Change all references to transport messages - to use the new names with "_stp" prefix. - (stp_main_loop): For STP_SYMBOLS, check pointer size and - endianess to confirm staprun is compatible with the kernel. - - * librelay.h: Move a bunch of common includes here. - * stpd.c: Cleanup includes. - * symbols.c: Ditto. - -2006-11-02 Martin Hunt <hunt@redhat.com> - - * symbols.c: New file. Sends symbol and module information to - the systemtap module. - - * librelay.c (stp_main_loop): Add STP_MODULE and STP_SYMBOLS - message handling. - - * librelay.h: Add some new function prototypes. - - * Makefile (CFLAGS): Set to be the same as for building modules. - Added symbols.c to sources. - -2006-10-10 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (merge_output): Add check for min when writing - output, otherwise last write happens twice. - -2006-09-26 David Smith <dsmith@redhat.com> - - * Makefile: Changed 'stpd' references to 'staprun'. - * librelay.c: Ditto. - * stpd.c: Ditto. - -2006-09-25 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (kill_percpu_threads): Remove printf. - (wait_for_percpu_threads): New. - (process_subbufs): Remove processing, processing_mutex, exit - thread if exiting flag set. - (read_last_buffers): Removed. - (cleanup_and_exit): Remove call to read_last_buffers, wait for - threads to read flushed buffers instead. - (stp_main_loop): Remove mutex init. - -2006-09-22 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (init_relayfs): Cleanup if stp_check fails. - -2006-09-19 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (init_relayfs): Add debugfs path to relay files and - add new systemtap directory to path. - (init_stp): rmmod module on failure. - (merge_output): Remove debugging printfs left in code. - (close_relay_files): Clear relay_file descriptor after close. - (cleanup_and_exit): Allow cleanup and exit even if there was an - error opening relay files. - (stp_main_loop): Call cleanup_and_exit() if init_relayfs() fails. - -2006-09-18 Martin Hunt <hunt@redhat.com> - - * stpd.c (usage): Remove "-m" option. - (main): Print warning if "-m" is used. - * librelay.c (merge_output): Rewrite to handle - new format that support binary. - (stp_main_loop): Read merge option from the - transport info message. - -2006-09-13 Martin Hunt <hunt@redhat.com> - - * librelay.c (init_relayfs): Exec stp_check and find - relay_filebase. - - * librelay.h (stp_main_loop): Fix declaration of init_stp(). - - * stpd.c (usage): Remove "-r" option. - (main): Don't find stpd_filebase and don't send it to init_stp(). - - -2006-08-02 Tom Zanussi <zanussi@us.ibm.com> - - * stpd.c (main): Use modname rather than driver_pid in - stpd_filebase. - -2006-07-20 Martin Hunt <hunt@redhat.com> - - * librelay.c (stp_main_loop): If module doesn't start, kill any - target command. - -2006-06-23 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (cleanup_and_exit): Close relay files even if - not merging. - -2006-06-13 Martin Hunt <hunt@redhat.com> - - * librelay.c (start_cmd): Rewrite using sigwait() to eliminate - a race. - -2006-05-18 Martin Hunt <hunt@redhat.com> - - * librelay.c (stp_main_loop): Set output to always be line - buffered. - -2006-04-08 Martin Hunt <hunt@redhat.com> - - * librelay.c (stp_main_loop): Write with fwrite() instead - of fputs() so we can write binary data. - -2006-04-05 Martin Hunt <hunt@redhat.com> - * librelay.c (merge_output): Remove ANSI codes and write - warning to stderr. - -2006-04-05 Martin Hunt <hunt@redhat.com> - * librelay.c (merge_output): Set the output filename if necessary. - (merge_output): - - * stpd.c (main): Don't reset output_filename just because - relayfs is possible. Move that code to librelay.c. - -2006-04-04 Roland McGrath <roland@redhat.com> - - * stpd.c (main): Cast f_type when comparing; type differs by machine. - -2006-04-04 Tom Zanussi <zanussi@us.ibm.com> - - * stpd.c (main): Check that /mnt/relay is actually relayfs. - -2006-03-15 Tom Zanussi <zanussi@us.ibm.com> - - * stpd.c (main): Add runtime check for relayfs vs relay-on-proc. - -2006-03-06 Martin Hunt <hunt@redhat.com> - - * librelay.c (start_cmd): Set proper uid/gid before execing - command. - (system_cmd): New function. - (cleanup_and_exit): Wait for any child processes to complete. - (stp_main_loop): Recognize STP_SYSTEM message. - - * stpd.c (main): Add support for "-u username". - -2006-02-25 Martin Hunt <hunt@redhat.com> - - * librelay.c (init_stp): Better error handling and cleanup. - -2006-02-23 Frank Ch. Eigler <fche@elastic.org> - - PR 1304 - * stpd.c (mdooptions): New array. - (main): Populate it with leftover arguments. - * librelay.c (init_stp): Pass it to execve(). - -2005-12-08 Frank Ch. Eigler <fche@elastic.org> - - PR 1937 - * stpd.c (main): Support new "-d" option. - (usage): Document it. - * librelay.c (driver_poll): New function to react to death of - driver process. - (stp_main_loop): Call it if "-d PID" given. Treat SIGHUP like others. - -2005-10-19 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c: Move output_file var to stpd.c. - (stp_main_loop): If the output_file option was specified, - and streaming mode is being used, send output to the file - instead of stdout. If !streaming, send output to the file - instead of probe.out. - * stpd.c (usage): Add comment for -o option. - (main): Add -o option. - -2005-10-19 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (merge_output): Switch to binary TIMESTAMP. - * stp_dump.c (main): Switch to binary TIMESTAMP. - * stp_merge.c (main): Switch to binary TIMESTAMP. - -2005-10-14 Tom Zanussi <zanussi@us.ibm.com> - - PR 1476 - * librelay.c: Add flag for buffer processing. - (reader_thread): Disable/enable cancel state around buffer - processing, and update flag to show we're busy processing. - (cleanup_and_exit): Wait for any threads busy processing. - (stp_main_loop): Initialize processing mutex. - -2005-09-06 Martin Hunt <hunt@redhat.com> - - * librelay.c: Remove all USE_PROCFS ifdefs. - (sig_usr): Signal handler for SIGUSR1. - (start_cmd): New function to handle "-c" option, forks() - off a new process then waits for SIGUSR1 to exec it. - (init_stp): Call start_cmd(). - (stp_main_loop): Set a signal handler for SIGCHLD. - - * stpd.c (main): Add "-t" and "-c" options. - (usage): Update with new options. - -2005-08-29 Martin Hunt <hunt@redhat.com> - - * stpd.c main): Add enable_relayfs flag. - Turn it off with "-r". - -2005-08-24 Martin Hunt <hunt@redhat.com> - - * librelay.c (sigproc): Removed the "Exiting..." - message for now. - -2005-08-24 Martin Hunt <hunt@redhat.com> - - * librelay.c (sigproc): Reestablish signal handler so - impatient people don't hit ^C twice and terminate the - program before it saves the data and removes the module. - Also print a message to stderr that it is exiting. - (stp_main_loop): Write OOB data (warnings, errors, etc) - to stderr instead of stdout. - * librelay.h: Write debug info to stderr. - * Makefile: add librelay.h to dependencies. - -2005-08-23 Martin Hunt <hunt@redhat.com> - - * librelay.c (merge_output): Don't add an extra \n. - -2005-08-23 Martin Hunt <hunt@redhat.com> - - * librelay.c (read_last_buffers): New function. Directly grab the - last buffers. - (info_pending): Deleted. - (request_last_buffers): Deleted. - -2005-08-22 Martin Hunt <hunt@redhat.com> - - * Makefile (debug): Add debug target. - * librelay.h (dbug): Define. - * librelay.c: Enable some dbug lines. - -2005-08-19 Martin Hunt <hunt@redhat.com> - - * librelay.c (reader_thread): Check the return value for write(). - -2005-08-19 Frank Ch. Eigler <fche@elastic.org> - - * librelay.c (modpath): New global. Use it for insmod only. - * stpd.c (main): Set both modpath and modname, to support - modules specified by full path name. - -2005-08-19 Martin Hunt <hunt@redhat.com> - - * stpd.c (main): Simplify buffer size code. - * librelay.c: Major changes to support procfs instead of netlink. - -2005-08-03 Tom Zanussi <trz@us.ibm.com> - - * librelay.c: Track subbuf info requests/replies - so we know unequivocally when it's ok to do final - processing. - (reader_thread): Remove buffer-full warning. - -2005-08-03 Martin Hunt <hunt@redhat.com> - * librelay.c (init_stp): Change variable name to eliminate shadow warning. - -2005-08-03 Martin Hunt <hunt@redhat.com> - * librelay.c (open_control_channel): Set the receive buffer - to 512K, or the max allowed. - - * stpd.c: Remove "-n" subbug option and change "-b" option - so you can specify buffering in different ways. Add a verbose option. - Exec the "stp_check" script. - -2005-08-01 Frank Ch. Eigler <fche@redhat.com> - - * librelay.c: Correct fwrite api usage. - * all: Correct copyright holder name. - -2005-08-01 Martin Hunt <hunt@redhat.com> - - * librelay.h: Get structs and enums from - ../transport/transport_msgs.h to eliminate duplication. - - * librelay.c (send_request): Retry if send fails. - (open_relayfs_files): Use fopen() instead of open() for the - percpu tmpfiles. - (request_last_buffers): Just send cpu number for STP_BUF_INFO request. - (reader_thread): Ditto. - (process_subbufs): Use fwrite_unlocked() instead of write(). - (sigchld): Removed. - (init_stp): Go back to using system() instead of fork and exec - to load module. When done, send a TRANSPORT_INFO request. - (cleanup_and_exit): Change parameter to simple flag to - indicate if the module needs removing. - (sigproc): Remove complicated logic and just send STP_EXIT. - (stp_main_loop): When receiving STP_TRANSPORT_INFO, set - the local params and reply with a STP_START. When - receiving STP_START, there was an error, so cleanup and exit. - - * stpd.c (main): Added new options to set number of - buffers and their size. - -2005-07-29 Roland McGrath <roland@redhat.com> - - * librelay.c (process_subbufs): Use unsigned for I. - (sigproc): Add __attribute__((unused)) on parameter. - (sigchld): Likewise. Avoid shadowing global variable name. - (stp_main_loop): Add a cast. - -2005-07-18 Martin Hunt <hunt@redhat.com> - - * stp_merge.c (main): Fix dropped count calculation. - -2005-07-14 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c (reader_thread): Add missing pthread_mutex_lock - -2005-07-14 Frank Ch. Eigler <fche@redhat.com> - - * stpd.c (main): Pass !quiet mode to init_stp(). - * librelay.c (init_relayfs): Be quiet if !print_totals. - -2005-07-13 Martin Hunt <hunt@redhat.com> - - * stpd.c (usage): Fix usage string. - - * librelay.c (init_stp): Change last arg to NULL, not 0. - -2005-07-08 Martin Hunt <hunt@redhat.com> - - * librelay.c (sigchld): Signal handler to detect - completion of module loading. - (init_stp): Use fork/exec instead of system() so - we can get async signal of module load success/failure. - (cleanup_and_exit): New function. - (sigproc): If module is not loaded, don't send message to it. - (stp_main_loop): Call cleanup_and_exit() when STP_EXIT - is received. Don't send a request for the transport - mode. The module will send notification to the daemon - when it is ready. - - * stpd.c (main): Don't print message until module - is loaded. - -2005-07-01 Martin Hunt <hunt@redhat.com> - - * librelay.c: Removed the color coding of cpu output. - -2005-06-28 Martin Hunt <hunt@redhat.com> - - * librelay.c (merge_output): Use unlocked stdio - to improve speed. - - * stp_merge.c: New file. - - * Makefile: Add stp_merge. - -2005-06-27 Martin Hunt <hunt@redhat.com> - - * stpd.c (main): Add new command line arg, "-m" - to disable the per-cpu merging. - - * librelay.c (merge_output): Replacement for sort_output(). - Efficiently merges per-cpu streams. - - -2005-06-20 Tom Zanussi <zanussi@us.ibm.com> - - * librelay.c: Large refactoring, important changes are - added transport_mode command, for relayfs transport - display results only when probe completes and/or write - output file, merge, sort and delete the per-cpu files - in postprocessing, refactor so that relayfs files aren't - created until transport command received, removed sigalrm, - read the final subbuffers on exit - - * stpd.c: Remove all command-line args except for -p - and -q as well as all code related to buffer sizes. - - * librelay.h: Add transport mode command and struct. - -2005-05-16 Martin Hunt <hunt@redhat.com> - - * librelay.c (sigproc): If STP_EXIT send fails, keep retrying - every 10ms. - (init_stp): Don't set n_subbufs and subbuf_size params. diff --git a/runtime/stpd/Makefile b/runtime/stpd/Makefile deleted file mode 100644 index 48613a0a..00000000 --- a/runtime/stpd/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CFLAGS = -Wall -std=gnu99 -D_GNU_SOURCE -fexceptions -Wall -Werror -Wshadow -Wunused - -all: staprun stp_merge stp_dump - -staprun: stpd.c librelay.c symbols.c ../transport/transport_msgs.h librelay.h - gcc -O3 $(CFLAGS) -o staprun stpd.c librelay.c symbols.c -lpthread - -stp_merge: stp_merge.c - gcc -O3 $(CFLAGS) -o stp_merge stp_merge.c - -stp_dump: stp_dump.c - gcc -O3 $(CFLAGS) -o stp_dump stp_dump.c - -debug: stpd.c librelay.c symbols.c ../transport/transport_msgs.h librelay.h - gcc -g -D DEBUG $(CFLAGS) -o staprun stpd.c librelay.c symbols.c -lpthread - -clean: - /bin/rm -f staprun stp_merge *.o *~ diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c deleted file mode 100644 index 6acbe7f8..00000000 --- a/runtime/stpd/librelay.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * libstp - staprun '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 - * 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) Red Hat Inc, 2005, 2006 - * - */ -#include "librelay.h" -#include <signal.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <linux/fd.h> -#include <sys/mman.h> -#include <sys/poll.h> -#include <pthread.h> -#include <sys/socket.h> -#include <linux/types.h> -#include <linux/limits.h> -#include <sys/wait.h> -#include <sys/statfs.h> - - -/* stp_check script */ -#ifdef PKGLIBDIR -char *stp_check=PKGLIBDIR "/stp_check"; -#else -char *stp_check="stp_check"; -#endif - -/* maximum number of CPUs we can handle - change if more */ -#define NR_CPUS 256 - -/* relayfs parameters */ -static struct params -{ - unsigned subbuf_size; - unsigned n_subbufs; - int merge; - char relay_filebase[256]; -} params; - -/* temporary per-cpu output written here for relayfs, filebase0...N */ -static char *percpu_tmpfilebase = "stpd_cpu"; - -/* procfs files */ -static char proc_filebase[128]; -static int proc_file[NR_CPUS]; - -/* probe output written here, if non-NULL */ -/* if no output file name is specified, use this */ -#define DEFAULT_RELAYFS_OUTFILE_NAME "probe.out" -extern char *outfile_name; - -/* internal variables */ -static int transport_mode; -static int ncpus; -static int print_totals; -static int exiting; - -/* per-cpu data */ -static int relay_file[NR_CPUS]; -static FILE *percpu_tmpfile[NR_CPUS]; -static char *relay_buffer[NR_CPUS]; -static pthread_t reader[NR_CPUS]; - -/* control channel */ -int control_channel; - -/* flags */ -extern int print_only, quiet, verbose; -extern unsigned int buffer_size; -extern char *modname; -extern char *modpath; -extern char *modoptions[]; -extern int target_pid; -extern int driver_pid; -extern char *target_cmd; - -/* uid/gid to use when execing external programs */ -extern uid_t cmd_uid; -extern gid_t cmd_gid; - -/* per-cpu buffer info */ -static struct buf_status -{ - struct _stp_buf_info info; - unsigned max_backlog; /* max # sub-buffers ready at one time */ -} status[NR_CPUS]; - - - -/** - * streaming - is the current transport mode streaming or not? - * - * Returns 1 if in streaming mode, 0 otherwise. - */ -static int streaming(void) -{ - if (transport_mode == STP_TRANSPORT_PROC) - return 1; - - return 0; -} - -/** - * send_request - send request to kernel over control channel - * @type: the relay-app command id - * @data: pointer to the data to be sent - * @len: length of the data to be sent - * - * Returns 0 on success, negative otherwise. - */ -int send_request(int type, void *data, int len) -{ - char buf[1024]; - memcpy(buf, &type, 4); - memcpy(&buf[4],data,len); - return write(control_channel, buf, len+4); -} - - -/** - * summarize - print a summary if applicable - */ -static void summarize(void) -{ - int i; - - if (transport_mode != STP_TRANSPORT_RELAYFS) - return; - - printf("summary:\n"); - for (i = 0; i < ncpus; i++) { - printf("cpu %u:\n", i); - printf(" %u sub-buffers processed\n", - status[i].info.consumed); - printf(" %u max backlog\n", status[i].max_backlog); - } -} - -static void close_proc_files() -{ - int i; - for (i = 0; i < ncpus; i++) - close(proc_file[i]); -} - -/** - * close_relayfs_files - close and munmap buffer and open output file - */ -static void close_relayfs_files(int cpu) -{ - size_t total_bufsize = params.subbuf_size * params.n_subbufs; - - munmap(relay_buffer[cpu], total_bufsize); - close(relay_file[cpu]); - relay_file[cpu] = 0; - fclose(percpu_tmpfile[cpu]); -} - -/** - * close_all_relayfs_files - close and munmap buffers and output files - */ -static void close_all_relayfs_files(void) -{ - int i; - - if (!streaming()) { - for (i = 0; i < ncpus; i++) - close_relayfs_files(i); - } -} - -/** - * open_relayfs_files - open and mmap buffer and open output file - */ -static int open_relayfs_files(int cpu, const char *relay_filebase) -{ - size_t total_bufsize; - char tmp[PATH_MAX]; - - memset(&status[cpu], 0, sizeof(struct buf_status)); - status[cpu].info.cpu = cpu; - - sprintf(tmp, "%s%d", relay_filebase, cpu); - relay_file[cpu] = open(tmp, O_RDONLY | O_NONBLOCK); - if (relay_file[cpu] < 0) { - fprintf(stderr, "ERROR: couldn't open relayfs file %s: errcode = %s\n", tmp, strerror(errno)); - return -1; - } - - sprintf(tmp, "%s/%d", proc_filebase, cpu); - dbug("Opening %s.\n", tmp); - proc_file[cpu] = open(tmp, O_RDWR | O_NONBLOCK); - if (proc_file[cpu] < 0) { - fprintf(stderr, "ERROR: couldn't open proc file %s: errcode = %s\n", tmp, strerror(errno)); - return -1; - } - - sprintf(tmp, "%s%d", percpu_tmpfilebase, cpu); - if((percpu_tmpfile[cpu] = fopen(tmp, "w+")) == NULL) { - fprintf(stderr, "ERROR: Couldn't open output file %s: errcode = %s\n", tmp, strerror(errno)); - close(relay_file[cpu]); - return -1; - } - - total_bufsize = params.subbuf_size * params.n_subbufs; - relay_buffer[cpu] = mmap(NULL, total_bufsize, PROT_READ, - MAP_PRIVATE | MAP_POPULATE, relay_file[cpu], - 0); - if(relay_buffer[cpu] == MAP_FAILED) - { - fprintf(stderr, "ERROR: couldn't mmap relay file, total_bufsize (%d) = subbuf_size (%d) * n_subbufs(%d), error = %s \n", (int)total_bufsize, (int)params.subbuf_size, (int)params.n_subbufs, strerror(errno)); - close(relay_file[cpu]); - fclose(percpu_tmpfile[cpu]); - return -1; - } - - return 0; -} - -/** - * delete_percpu_files - delete temporary per-cpu output files - * - * Returns 0 if successful, -1 otherwise. - */ -static int delete_percpu_files(void) -{ - int i; - char tmp[PATH_MAX]; - - for (i = 0; i < ncpus; i++) { - sprintf(tmp, "%s%d", percpu_tmpfilebase, i); - if (unlink(tmp) < 0) { - fprintf(stderr, "ERROR: couldn't unlink percpu file %s: errcode = %s\n", tmp, strerror(errno)); - return -1; - } - } - return 0; -} - -/** - * kill_percpu_threads - kill per-cpu threads 0->n-1 - * @n: number of threads to kill - * - * Returns number of threads killed. - */ -static int kill_percpu_threads(int n) -{ - int i, killed = 0; - - for (i = 0; i < n; i++) { - if (pthread_cancel(reader[i]) == 0) - killed++; - } - - return killed; -} - -/** - * wait_for_percpu_threads - wait for all threads to exit - * @n: number of threads to wait for - */ -static void wait_for_percpu_threads(int n) -{ - int i; - - for (i = 0; i < n; i++) - pthread_join(reader[i], NULL); -} - -/** - * process_subbufs - write ready subbufs to disk - */ -static int process_subbufs(struct _stp_buf_info *info) -{ - unsigned subbufs_ready, start_subbuf, end_subbuf, subbuf_idx, i; - int len, cpu = info->cpu; - char *subbuf_ptr; - int subbufs_consumed = 0; - unsigned padding; - - subbufs_ready = info->produced - info->consumed; - start_subbuf = info->consumed % params.n_subbufs; - end_subbuf = start_subbuf + subbufs_ready; - - for (i = start_subbuf; i < end_subbuf; i++) { - subbuf_idx = i % params.n_subbufs; - subbuf_ptr = relay_buffer[cpu] + subbuf_idx * params.subbuf_size; - padding = *((unsigned *)subbuf_ptr); - subbuf_ptr += sizeof(padding); - len = (params.subbuf_size - sizeof(padding)) - padding; - if (len) { - if (fwrite_unlocked (subbuf_ptr, len, 1, percpu_tmpfile[cpu]) != 1) { - fprintf(stderr, "ERROR: couldn't write to output file for cpu %d, exiting: errcode = %d: %s\n", cpu, errno, strerror(errno)); - exit(1); - } - } - subbufs_consumed++; - } - - return subbufs_consumed; -} - -/** - * reader_thread - per-cpu channel buffer reader - */ -static void *reader_thread(void *data) -{ - int rc; - int cpu = (long)data; - struct pollfd pollfd; - struct _stp_consumed_info consumed_info; - unsigned subbufs_consumed; - - pollfd.fd = relay_file[cpu]; - pollfd.events = POLLIN; - - do { - rc = poll(&pollfd, 1, -1); - if (rc < 0) { - if (errno != EINTR) { - fprintf(stderr, "ERROR: poll error: %s\n", - strerror(errno)); - exit(1); - } - fprintf(stderr, "WARNING: poll warning: %s\n", - strerror(errno)); - rc = 0; - } - - rc = read(proc_file[cpu], &status[cpu].info, - sizeof(struct _stp_buf_info)); - subbufs_consumed = process_subbufs(&status[cpu].info); - if (subbufs_consumed) { - if (subbufs_consumed > status[cpu].max_backlog) - status[cpu].max_backlog = subbufs_consumed; - status[cpu].info.consumed += subbufs_consumed; - consumed_info.cpu = cpu; - consumed_info.consumed = subbufs_consumed; - if (write (proc_file[cpu], &consumed_info, sizeof(struct _stp_consumed_info)) < 0) - fprintf(stderr,"WARNING: writing consumed info failed.\n"); - } - if (status[cpu].info.flushing) - pthread_exit(NULL); - } while (1); -} - -#define RELAYFS_MAGIC 0xF0B4A981 -#define DEBUGFS_MAGIC 0x64626720 -/** - * init_relayfs - create files and threads for relayfs processing - * - * Returns 0 if successful, negative otherwise - */ -int init_relayfs(void) -{ - int i, j, wstat; - pid_t pid; - struct statfs st; - - dbug("initializing relayfs\n"); - - /* first run the _stp_check script */ - if ((pid = fork()) < 0) { - perror ("fork of stp_check failed."); - exit(-1); - } else if (pid == 0) { - if (execlp(stp_check, stp_check, NULL) < 0) - _exit (-1); - } - if (waitpid(pid, &wstat, 0) < 0) { - perror("waitpid"); - exit(-1); - } - if (WIFEXITED(wstat) && WEXITSTATUS(wstat)) { - perror (stp_check); - fprintf(stderr, "Could not execute %s\n", stp_check); - return -1; - } - - if (statfs("/mnt/relay", &st) == 0 && (int) st.f_type == (int) RELAYFS_MAGIC) - sprintf(params.relay_filebase, "/mnt/relay/systemtap/%d/cpu", getpid()); - else if (statfs("/sys/kernel/debug", &st) == 0 && (int) st.f_type == (int) DEBUGFS_MAGIC) - sprintf(params.relay_filebase, "/sys/kernel/debug/systemtap/%d/cpu", getpid()); - else - sprintf(params.relay_filebase, "/debug/systemtap/%d/cpu", getpid()); - - for (i = 0; i < ncpus; i++) { - if (open_relayfs_files(i, params.relay_filebase) < 0) { - fprintf(stderr, "ERROR: couldn't open relayfs files, cpu = %d\n", i); - goto err; - } - /* create a thread for each per-cpu buffer */ - if (pthread_create(&reader[i], NULL, reader_thread, (void *)(long)i) < 0) { - close_relayfs_files(i); - fprintf(stderr, "ERROR: Couldn't create reader thread, cpu = %d\n", i); - goto err; - } - } - - if (print_totals && verbose) - printf("Using channel with %u sub-buffers of size %u.\n", - params.n_subbufs, params.subbuf_size); - - return 0; -err: - for (j = 0; j < i; j++) - close_relayfs_files(j); - kill_percpu_threads(i); - - return -1; -} - -void start_cmd(void) -{ - pid_t pid; - sigset_t usrset; - - sigemptyset(&usrset); - sigaddset(&usrset, SIGUSR1); - sigprocmask(SIG_BLOCK, &usrset, NULL); - - dbug ("execing target_cmd %s\n", target_cmd); - if ((pid = fork()) < 0) { - perror ("fork"); - exit(-1); - } else if (pid == 0) { - int signum; - - if (setregid(cmd_gid, cmd_gid) < 0) { - perror("setregid"); - } - if (setreuid(cmd_uid, cmd_uid) < 0) { - perror("setreuid"); - } - /* wait here until signaled */ - sigwait(&usrset, &signum); - - if (execl("/bin/sh", "sh", "-c", target_cmd, NULL) < 0) - perror(target_cmd); - _exit(-1); - } - target_pid = pid; -} - -void system_cmd(char *cmd) -{ - pid_t pid; - - dbug ("system %s\n", cmd); - if ((pid = fork()) < 0) { - perror ("fork"); - } else if (pid == 0) { - if (setregid(cmd_gid, cmd_gid) < 0) { - perror("setregid"); - } - if (setreuid(cmd_uid, cmd_uid) < 0) { - perror("setreuid"); - } - if (execl("/bin/sh", "sh", "-c", cmd, NULL) < 0) - perror(cmd); - _exit(-1); - } -} - -/** - * init_stp - initialize the app - * @print_summary: boolean, print summary or not at end of run - * - * Returns 0 on success, negative otherwise. - */ -int init_stp(int print_summary) -{ - char buf[1024]; - struct _stp_transport_info ti; - pid_t pid; - int rstatus; - - ncpus = sysconf(_SC_NPROCESSORS_ONLN); - print_totals = print_summary; - - /* insert module */ - sprintf(buf, "_stp_pid=%d", (int)getpid()); - modoptions[0] = "insmod"; - modoptions[1] = modpath; - modoptions[2] = buf; - /* modoptions[3...N] set by command line parser. */ - - if ((pid = fork()) < 0) { - perror ("fork"); - exit(-1); - } else if (pid == 0) { - if (execvp("/sbin/insmod", modoptions) < 0) - _exit(-1); - } - if (waitpid(pid, &rstatus, 0) < 0) { - perror("waitpid"); - exit(-1); - } - if (WIFEXITED(rstatus) && WEXITSTATUS(rstatus)) { - fprintf(stderr, "ERROR, couldn't insmod probe module %s\n", modpath); - return -1; - } - - /* We no longer use /proc/systemtap/, just /proc. */ - sprintf (proc_filebase, "/proc/%s", modname); - char *ptr = index(proc_filebase,'.'); - if (ptr) - *ptr = 0; - - sprintf(buf, "%s/cmd", proc_filebase); - dbug("Opening %s\n", buf); - control_channel = open(buf, O_RDWR); - if (control_channel < 0) { - fprintf(stderr, "ERROR: couldn't open control channel %s: errcode = %s\n", buf, strerror(errno)); - goto do_rmmod; - } - - /* start target_cmd if necessary */ - if (target_cmd) - start_cmd(); - - /* now send TRANSPORT_INFO */ - ti.buf_size = buffer_size; - ti.subbuf_size = 0; - ti.n_subbufs = 0; - ti.target = target_pid; - if (send_request(STP_TRANSPORT_INFO, &ti, sizeof(ti)) < 0) { - fprintf(stderr, "staprun failed because TRANSPORT_INFO returned an error.\n"); - if (target_cmd) - kill (target_pid, SIGKILL); - close(control_channel); - goto do_rmmod; - } - return 0; - - do_rmmod: - snprintf(buf, sizeof(buf), "/sbin/rmmod -w %s", modname); - if (system(buf)) - fprintf(stderr, "ERROR: couldn't rmmod probe module %s.\n", modname); - return -1; -} - - -/* length of timestamp in output field 0 */ -#define TIMESTAMP_SIZE (sizeof(uint32_t)) - -/** - * merge_output - merge per-cpu output - * - */ -#define MERGE_BUF_SIZE 16*1024 -static int merge_output(void) -{ - char *buf[ncpus], tmp[PATH_MAX]; - int i, j, dropped=0; - uint32_t count=0, min, num[ncpus]; - FILE *ofp, *fp[ncpus]; - uint32_t length[ncpus]; - - for (i = 0; i < ncpus; i++) { - sprintf (tmp, "%s%d", percpu_tmpfilebase, i); - fp[i] = fopen (tmp, "r"); - if (!fp[i]) { - fprintf (stderr, "error opening file %s.\n", tmp); - return -1; - } - num[i] = 0; - buf[i] = malloc(MERGE_BUF_SIZE); - if (!buf[i]) { - fprintf(stderr,"Out of memory in merge_output(). Aborting merge.\n"); - printf("Out of memory in merge_output(). Aborting merge.\n"); - return -1; - } - - if (fread_unlocked (&length[i], sizeof(uint32_t), 1, fp[i])) { - if (fread_unlocked (buf[i], length[i]+TIMESTAMP_SIZE, 1, fp[i])) - num[i] = *((uint32_t *)buf[i]); - } - } - - if (!outfile_name) - outfile_name = DEFAULT_RELAYFS_OUTFILE_NAME; - - ofp = fopen (outfile_name, "w"); - if (!ofp) { - fprintf (stderr, "ERROR: couldn't open output file %s: errcode = %s\n", - outfile_name, strerror(errno)); - return -1; - } - - do { - min = num[0]; - j = 0; - for (i = 1; i < ncpus; i++) { - if (min == 0 || (num[i] && num[i] < min)) { - min = num[i]; - j = i; - } - } - - if (min && !quiet) - fwrite_unlocked (buf[j]+TIMESTAMP_SIZE, length[j], 1, stdout); - if (min && !print_only) - fwrite_unlocked (buf[j]+TIMESTAMP_SIZE, length[j], 1, ofp); - - if (min && ++count != min) { - count = min; - dropped++ ; - } - - num[j] = 0; - if (fread_unlocked (&length[j], sizeof(uint32_t), 1, fp[j])) { - if (fread_unlocked (buf[j], length[j]+TIMESTAMP_SIZE, 1, fp[j])) - num[j] = *((uint32_t *)buf[j]); - } - } while (min); - - if (!print_only) - fwrite_unlocked ("\n", 1, 1, ofp); - - for (i = 0; i < ncpus; i++) - fclose (fp[i]); - fclose (ofp); - - if (dropped) - fprintf (stderr, "Sequence had %d drops.\n", dropped); - - return 0; -} - -void cleanup_and_exit (int closed) -{ - char tmpbuf[128]; - pid_t err; - - if (exiting) - return; - exiting = 1; - - dbug("CLEANUP AND EXIT closed=%d mode=%d\n", closed, transport_mode); - - /* what about child processes? we will wait for them here. */ - err = waitpid(-1, NULL, WNOHANG); - if (err >= 0) - fprintf(stderr,"\nWaititing for processes to exit\n"); - while(wait(NULL) > 0); - - if (transport_mode == STP_TRANSPORT_RELAYFS && relay_file[0] > 0) - wait_for_percpu_threads(ncpus); - - close_proc_files(); - - if (print_totals && verbose) - summarize(); - - if (transport_mode == STP_TRANSPORT_RELAYFS && relay_file[0] > 0) { - close_all_relayfs_files(); - if (params.merge) { - merge_output(); - delete_percpu_files(); - } - } - - dbug("closing control channel\n"); - close(control_channel); - - if (!closed) { - snprintf(tmpbuf, sizeof(tmpbuf), "/sbin/rmmod -w %s", modname); - if (system(tmpbuf)) { - fprintf(stderr, "ERROR: couldn't rmmod probe module %s. No output will be written.\n", - modname); - exit(1); - } - } - exit(0); -} - -static void sigproc(int signum) -{ - if (signum == SIGCHLD) { - pid_t pid = waitpid(-1, NULL, WNOHANG); - if (pid != target_pid) - return; - } - send_request(STP_EXIT, NULL, 0); -} - -static void driver_poll (int signum __attribute__((unused))) -{ - /* See if the driver process is still alive. If not, time to exit. */ - if (kill (driver_pid, 0) < 0) { - send_request(STP_EXIT, NULL, 0); - return; - } else { - /* Check again later. Use any reasonable poll interval */ - signal (SIGALRM, driver_poll); - alarm (10); - } -} - - -/** - * stp_main_loop - loop forever reading data - */ -static char recvbuf[8192]; - -int stp_main_loop(void) -{ - int nb, rc; - void *data; - int type; - FILE *ofp = stdout; - - setvbuf(ofp, (char *)NULL, _IOLBF, 0); - - signal(SIGINT, sigproc); - signal(SIGTERM, sigproc); - signal(SIGCHLD, sigproc); - signal(SIGHUP, sigproc); - - if (driver_pid) - driver_poll(0); // And by the way, I'm also the signal handler. - - dbug("in main loop\n"); - - while (1) { /* handle messages from control channel */ - nb = read(control_channel, recvbuf, sizeof(recvbuf)); - if (nb <= 0) { - perror("recv"); - fprintf(stderr, "WARNING: unexpected EOF. nb=%d\n", nb); - continue; - } - - type = *(int *)recvbuf; - data = (void *)(recvbuf + sizeof(int)); - - if (!transport_mode && type != STP_TRANSPORT_INFO && type != STP_EXIT) { - fprintf(stderr, "WARNING: invalid stp command: no transport\n"); - continue; - } - - switch (type) { - case STP_REALTIME_DATA: - fwrite_unlocked(data, nb - sizeof(int), 1, ofp); - break; - case STP_OOB_DATA: - fputs ((char *)data, stderr); - break; - case STP_EXIT: - { - /* module asks us to unload it and exit */ - int *closed = (int *)data; - cleanup_and_exit(*closed); - break; - } - case STP_START: - { - struct _stp_transport_start *t = (struct _stp_transport_start *)data; - dbug("probe_start() returned %d\n", t->pid); - if (t->pid < 0) { - if (target_cmd) - kill (target_pid, SIGKILL); - cleanup_and_exit(0); - } else if (target_cmd) - kill (target_pid, SIGUSR1); - break; - } - case STP_SYSTEM: - { - struct _stp_cmd_info *c = (struct _stp_cmd_info *)data; - system_cmd(c->cmd); - break; - } - case STP_TRANSPORT_INFO: - { - struct _stp_transport_info *info = (struct _stp_transport_info *)data; - struct _stp_transport_start ts; - transport_mode = info->transport_mode; - params.subbuf_size = info->subbuf_size; - params.n_subbufs = info->n_subbufs; - params.merge = info->merge; -#ifdef DEBUG - if (transport_mode == STP_TRANSPORT_RELAYFS) { - fprintf(stderr,"TRANSPORT_INFO recvd: RELAYFS %d bufs of %d bytes.\n", - params.n_subbufs, - params.subbuf_size); - if (params.merge) - fprintf(stderr,"Merge output\n"); - } else - fprintf(stderr,"TRANSPORT_INFO recvd: PROC with %d Mbyte buffers.\n", - info->buf_size); -#endif - if (!streaming()) { - rc = init_relayfs(); - if (rc < 0) { - fprintf(stderr, "ERROR: couldn't init relayfs, exiting\n"); - cleanup_and_exit(0); - } - } else if (outfile_name) { - ofp = fopen (outfile_name, "w"); - if (!ofp) { - fprintf (stderr, "ERROR: couldn't open output file %s: errcode = %s\n", - outfile_name, strerror(errno)); - cleanup_and_exit(0); - } - } - ts.pid = getpid(); - send_request(STP_START, &ts, sizeof(ts)); - break; - } - case STP_MODULE: - { - struct _stp_transport_start ts; - if (do_module(data)) { - ts.pid = getpid(); - send_request(STP_START, &ts, sizeof(ts)); - } - break; - } - case STP_SYMBOLS: - { - struct _stp_symbol_req *req = (struct _stp_symbol_req *)data; - struct _stp_transport_start ts; - dbug("STP_SYMBOLS request received\n"); - if (req->endian != 0x1234) { - fprintf(stderr,"ERROR: staprun is compiled with different endianess than the kernel!\n"); - cleanup_and_exit(0); - } - if (req->ptr_size != sizeof(char *)) { - fprintf(stderr,"ERROR: staprun is compiled with %d-bit pointers and the kernel uses %d-bit.\n", - 8*sizeof(char *), 8*req->ptr_size); - cleanup_and_exit(0); - } - do_kernel_symbols(); - ts.pid = getpid(); - send_request(STP_START, &ts, sizeof(ts)); - break; - } - default: - fprintf(stderr, "WARNING: ignored message of type %d\n", (type)); - } - } - fclose(ofp); - return 0; -} diff --git a/runtime/stpd/librelay.h b/runtime/stpd/librelay.h deleted file mode 100644 index 15ef6c40..00000000 --- a/runtime/stpd/librelay.h +++ /dev/null @@ -1,33 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <unistd.h> -#include <dirent.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <stdint.h> - -#include "../transport/transport_msgs.h" - -#ifdef DEBUG -#define dbug(args...) {fprintf(stderr,"%s:%d ",__FUNCTION__, __LINE__); fprintf(stderr,args); } -#else -#define dbug(args...) ; -#endif /* DEBUG */ - -/* - * functions - */ -int init_stp(int print_summary); -int stp_main_loop(void); -int send_request(int type, void *data, int len); -void cleanup_and_exit (int); -int do_module(void *); -void do_kernel_symbols(void); - -/* - * variables - */ -extern int control_channel; diff --git a/runtime/stpd/stp_dump.c b/runtime/stpd/stp_dump.c deleted file mode 100644 index 5923a2e1..00000000 --- a/runtime/stpd/stp_dump.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * stp_dump.c - stp data dump program - * - * 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) Red Hat Inc, 2005 - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -static void usage (char *prog) -{ - fprintf(stderr, "%s input_file \n", prog); - exit(1); -} - -#define TIMESTAMP_SIZE (sizeof(int)) - -int main (int argc, char *argv[]) -{ - char buf[32]; - int c, seq, lastseq = 0; - FILE *fp; - - if (argc != 2) - usage(argv[0]); - - fp = fopen(argv[1], "r"); - if (!fp) { - fprintf(stderr, "ERROR: couldn't open input file %s: errcode = %s\n", - argv[1], strerror(errno)); - return -1; - } - - while (1) { - int numbytes = 0; - - if (fread (buf, TIMESTAMP_SIZE, 1, fp)) - seq = *((int *)buf); - else - break; - - if (seq < lastseq) - fprintf(stderr, "WARNING: seq %d followed by %d\n", lastseq, seq); - lastseq = seq; - - while (1) { - c = fgetc_unlocked(fp); - if (c == 0 || c == EOF) - break; - numbytes++; - } - printf ("<%d><%d BYTES>", seq, numbytes); - if (c == 0) - printf ("<0>\n"); - else { - printf ("<EOF>\n"); - break; - } - } - - printf ("DONE\n"); - fclose (fp); - return 0; -} diff --git a/runtime/stpd/stp_merge.c b/runtime/stpd/stp_merge.c deleted file mode 100644 index 14cb785b..00000000 --- a/runtime/stpd/stp_merge.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * stp_merge.c - stp merge program - * - * 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) Red Hat Inc, 2005 - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -static void usage (char *prog) -{ - fprintf(stderr, "%s [-o output_filename] input_files ...\n", prog); - exit(1); -} - -#define TIMESTAMP_SIZE (sizeof(int)) -#define NR_CPUS 256 - -int main (int argc, char *argv[]) -{ - char *outfile_name = NULL; - char buf[32]; - int c, i, j, dropped=0; - long count=0, min, num[NR_CPUS]; - FILE *ofp, *fp[NR_CPUS]; - int ncpus; - - while ((c = getopt (argc, argv, "o:")) != EOF) { - switch (c) { - case 'o': - outfile_name = optarg; - break; - default: - usage(argv[0]); - } - } - - if (optind == argc) - usage (argv[0]); - - i = 0; - while (optind < argc) { - fp[i] = fopen(argv[optind++], "r"); - if (!fp[i]) { - fprintf(stderr, "error opening file %s.\n", argv[optind - 1]); - return -1; - } - if (fread (buf, TIMESTAMP_SIZE, 1, fp[i])) - num[i] = *((int *)buf); - else - num[i] = 0; - i++; - } - ncpus = i; - - if (!outfile_name) - ofp = stdout; - else { - ofp = fopen(outfile_name, "w"); - if (!ofp) { - fprintf(stderr, "ERROR: couldn't open output file %s: errcode = %s\n", - outfile_name, strerror(errno)); - return -1; - } - } - - do { - min = num[0]; - j = 0; - for (i = 1; i < ncpus; i++) { - if (min == 0 || (num[i] && num[i] < min)) { - min = num[i]; - j = i; - } - } - - while (1) { - c = fgetc_unlocked(fp[j]); - if (c == 0 || c == EOF) - break; - fputc_unlocked (c, ofp); - } - - if (min && ++count != min) { - fprintf(stderr, "got %ld. expected %ld\n", min, count); - dropped += min - count ; - count = min; - } - - if (fread (buf, TIMESTAMP_SIZE, 1, fp[j])) - num[j] = *((int *)buf); - else - num[j] = 0; - } while (min); - - fputs ("\n", ofp); - - for (i = 0; i < ncpus; i++) - fclose (fp[i]); - fclose (ofp); - printf ("sequence had %d drops\n", dropped); - return 0; -} diff --git a/runtime/stpd/stpd.c b/runtime/stpd/stpd.c deleted file mode 100644 index f5c2ea13..00000000 --- a/runtime/stpd/stpd.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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) 2005 IBM Corporation - * Copyright (C) 2005-2006 Red Hat, Inc. - * - */ - -#include "librelay.h" -#include <pwd.h> - -extern char *optarg; -extern int optopt; -extern int optind; - -int print_only = 0; -int quiet = 0; -int verbose = 0; -int target_pid = 0; -int driver_pid = 0; -unsigned int buffer_size = 0; -char *modname = NULL; -char *modpath = NULL; -#define MAXMODOPTIONS 64 -char *modoptions[MAXMODOPTIONS]; -char *target_cmd = NULL; -char *outfile_name = NULL; -char *username = NULL; -uid_t cmd_uid; -gid_t cmd_gid; - -static void usage(char *prog) -{ - fprintf(stderr, "\n%s [-m] [-p] [-q] [-r] [-c cmd ] [-t pid]\n" - "\t[-b bufsize] [-o FILE] kmod-name [kmod-options]\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, "-c cmd. Command \'cmd\' will be run and staprun will exit when it does.\n"); - fprintf(stderr, " _stp_target will contain the pid for the command.\n"); - fprintf(stderr, "-t pid. Sets _stp_target to pid.\n"); - fprintf(stderr, "-d pid. Pass the systemtap driver's pid.\n"); - fprintf(stderr, "-o FILE. Send output to FILE.\n"); - fprintf(stderr, "-u username. Run commands as username.\n"); - fprintf(stderr, "-b buffer size. The systemtap module will specify a buffer size.\n"); - fprintf(stderr, " Setting one here will override that value. The value should be\n"); - fprintf(stderr, " an integer between 1 and 64 which be assumed to be the\n"); - fprintf(stderr, " buffer size in MB. That value will be per-cpu if relayfs is used.\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "mpqrb:n:t:d:c:vo:u:")) != EOF) - { - switch (c) { - case 'm': - fprintf(stderr, "Warning: -m option deprecated. Ignoring...\n"); - break; - case 'p': - print_only = 1; - break; - case 'q': - quiet = 1; - break; - case 'v': - verbose = 1; - break; - case 'r': - fprintf(stderr, "Warning: -r option deprecated. Ignoring...\n"); - break; - case 'b': - { - int size = (unsigned)atoi(optarg); - if (!size) - usage(argv[0]); - if (size > 64) { - fprintf(stderr, "Maximum buffer size is 64 (MB)\n"); - exit(1); - } - buffer_size = size; - break; - } - case 't': - target_pid = atoi(optarg); - break; - case 'd': - driver_pid = atoi(optarg); - break; - case 'c': - target_cmd = optarg; - break; - case 'o': - outfile_name = optarg; - break; - case 'u': - username = optarg; - break; - default: - usage(argv[0]); - } - } - - if (verbose) { - if (buffer_size) - printf ("Using a buffer of %u bytes.\n", buffer_size); - } - - if (optind < argc) - { - /* Collect both full path and just the trailing module name. */ - modpath = argv[optind++]; - modname = rindex (modpath, '/'); - if (modname == NULL) - modname = modpath; - else - modname++; /* skip over / */ - } - - if (optind < argc) - { - unsigned start_idx = 3; /* reserve three slots in modoptions[] */ - while (optind < argc && start_idx+1 < MAXMODOPTIONS) - modoptions[start_idx++] = argv[optind++]; - /* Redundantly ensure that there is a NULL pointer at the end - of modoptions[]. */ - modoptions[start_idx] = NULL; - } - - 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 (username) { - struct passwd *pw = getpwnam(username); - if (!pw) { - fprintf(stderr, "Cannot find user \"%s\".\n", username); - exit(1); - } - cmd_uid = pw->pw_uid; - cmd_gid = pw->pw_gid; - } else { - cmd_uid = getuid(); - cmd_gid = getgid(); - } - - if (init_stp(!quiet)) { - //fprintf(stderr, "Couldn't initialize staprun. Exiting.\n"); - exit(1); - } - - if (stp_main_loop()) { - fprintf(stderr,"Couldn't enter main loop. Exiting.\n"); - exit(1); - } - - return 0; -} diff --git a/runtime/stpd/symbols.c b/runtime/stpd/symbols.c deleted file mode 100644 index 26c9bb1d..00000000 --- a/runtime/stpd/symbols.c +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- linux-c -*- - * Symbols and modules functions for staprun. - * - * Copyright (C) 2006 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. - */ - -#include "librelay.h" -#include "../sym.h" - -static int send_data(void *data, int len) -{ - return write(control_channel, data, len); -} - -/* Get the sections for a module. Put them in the supplied buffer */ -/* in the following order: */ -/* [struct _stp_module][struct _stp_symbol sections ...][string data] */ -/* Return the total length of all the data. */ - -#define SECDIR "/sys/module/%s/sections" -static int get_sections(char *name, char *data_start, int datalen) -{ - char dir[STP_MODULE_NAME_LEN + sizeof(SECDIR)]; - char filename[STP_MODULE_NAME_LEN + 256]; - char buf[32], strdata_start[4096]; - char *strdata=strdata_start, *data=data_start; - int fd, len, res; - struct _stp_module *mod = (struct _stp_module *)data_start; - struct dirent *d; - DIR *secdir; - struct _stp_symbol *sec; - - /* start of data is a struct _stp_module */ - data += sizeof(struct _stp_module); - - res = snprintf(dir, sizeof(dir), SECDIR, name); - if (res >= sizeof(dir)) { - fprintf(stderr, "ERROR: couldn't fit module \"%s\" into dir buffer.\n", name); - fprintf(stderr, "This should never happen. Please file a bug report.\n"); - cleanup_and_exit(0); - } - - if ((secdir = opendir(dir)) == NULL) - return 0; - - memset(mod, 0, sizeof(struct _stp_module)); - strncpy(mod->name, name, STP_MODULE_NAME_LEN); - - while ((d = readdir(secdir))) { - char *secname = d->d_name; - res = snprintf(filename, sizeof(filename), "/sys/module/%s/sections/%s", name, secname); - if (res >= sizeof(filename)) { - fprintf(stderr, "ERROR: couldn't fit secname \"%s\" into filename buffer.\n", secname); - fprintf(stderr, "This should never happen. Please file a bug report.\n"); - closedir(secdir); - cleanup_and_exit(0); - } - if ((fd = open(filename,O_RDONLY)) >= 0) { - if (read(fd, buf, 32) > 0) { - /* filter out some non-useful stuff */ - if (!strncmp(secname,"__",2) - || !strcmp(secname,".module_sig") - || !strcmp(secname,".modinfo") - || !strcmp(secname,".strtab") - || !strcmp(secname,".symtab") ) { - close(fd); - continue; - } - /* create next section */ - sec = (struct _stp_symbol *)data; - data += sizeof(struct _stp_symbol); - sec->addr = strtoul(buf,NULL,16); - sec->symbol = (char *)(strdata - strdata_start); - mod->num_sections++; - - /* now create string data for the section */ - strcpy(strdata, secname); - strdata += strlen(secname) + 1; - - /* These sections are used a lot so keep the values handy */ - if (!strcmp(secname, ".data")) - mod->data = sec->addr; - if (!strcmp(secname, ".text")) - mod->text = sec->addr; - if (!strcmp(secname, ".gnu.linkonce.this_module")) - mod->module = sec->addr; - } - close(fd); - } - } - closedir(secdir); - - /* consolidate buffers */ - len = strdata - strdata_start; - if ((len + data - data_start) > datalen) { - fprintf(stderr, "ERROR: overflowed buffers in get_sections. Size needed = %d\n", - (int)(len + data - data_start)); - cleanup_and_exit(0); - } - strdata = strdata_start; - while (len--) - *data++ = *strdata++; - - return data - data_start; -} -#undef SECDIR - -void send_module (char *modname) -{ - char data[8192]; - int len = get_sections(modname, data, sizeof(data)); - if (len) - send_request(STP_MODULE, data, len); -} - -int do_module (void *data) -{ - struct _stp_module *mod = (struct _stp_module *)data; - - if (mod->name[0] == 0) { - struct dirent *d; - DIR *moddir = opendir("/sys/module"); - if (moddir) { - while ((d = readdir(moddir))) - send_module(d->d_name); - closedir(moddir); - } - return 1; - } - - send_module(mod->name); - return 0; -} - -static int compar(const void *p1, const void *p2) -{ - struct _stp_symbol *s1 = (struct _stp_symbol *)p1; - struct _stp_symbol *s2 = (struct _stp_symbol *)p2; - if (s1->addr == s2->addr) return 0; - if (s1->addr < s2->addr) return -1; - return 1; -} - -#define MAX_SYMBOLS 32768 - -void do_kernel_symbols(void) -{ - FILE *kallsyms; - char *sym_base, *data_base; - char buf[128], *ptr, *name, *data, *dataptr, *datamax, type; - unsigned long addr; - struct _stp_symbol *syms; - int num_syms, i = 0; - - sym_base = malloc(MAX_SYMBOLS*sizeof(struct _stp_symbol)+sizeof(long)); - data_base = malloc(MAX_SYMBOLS*32); - if (data_base == NULL || sym_base == NULL) { - fprintf(stderr,"Failed to allocate memory for symbols\n"); - cleanup_and_exit(0); - } - *(int *)data_base = STP_SYMBOLS; - dataptr = data = data_base + sizeof(long); - datamax = dataptr + MAX_SYMBOLS*32 - sizeof(long); - - *(int *)sym_base = STP_SYMBOLS; - syms = (struct _stp_symbol *)(sym_base + sizeof(long)); - - kallsyms = fopen ("/proc/kallsyms", "r"); - if (!kallsyms) { - perror("Fatal error: Unable to open /proc/kallsyms:"); - cleanup_and_exit(0); - } - - /* put empty string in data */ - *dataptr++ = 0; - - while (fgets_unlocked(buf, 128, kallsyms) && dataptr < datamax) { - addr = strtoul(buf, &ptr, 16); - while (isspace(*ptr)) ptr++; - type = *ptr++; - if (type == 't' || type == 'T' || type == 'A') { - while (isspace(*ptr)) ptr++; - name = ptr++; - while (!isspace(*ptr)) ptr++; - *ptr++ = 0; - while (*ptr && *ptr != '[') ptr++; - if (*ptr) - continue; /* it was a module */ - syms[i].addr = addr; - syms[i].symbol = (char *)(dataptr - data); - while (*name) *dataptr++ = *name++; - *dataptr++ = 0; - i++; - if (dataptr > datamax - 1000) - break; - } - } - num_syms = i; - qsort(syms, num_syms, sizeof(struct _stp_symbol), compar); - -#if 0 - for (i=0;i<num_syms;i++) { - fprintf(stderr,"%p , \"%s\"\n", (char *)(syms[i].addr), - (char *)((long)(syms[i].symbol) + data)); - } -#endif - - /* send header */ - *(int *)buf = STP_SYMBOLS; - *(int *)(buf+sizeof(long)) = num_syms; - *(int *)(buf+sizeof(long)+sizeof(int)) = (unsigned)(dataptr - data); - send_data(buf, 2*sizeof(int)+sizeof(long)); - - /* send syms */ - send_data(sym_base, num_syms*sizeof(struct _stp_symbol)+sizeof(long)); - - /* send data */ - send_data(data_base, dataptr-data+sizeof(long)); - - free(data_base); - free(sym_base); - fclose(kallsyms); - - if (dataptr >= datamax) { - fprintf(stderr,"Error: overflowed symbol data area.\n"); - cleanup_and_exit(0); - } -} |