diff options
author | hunt <hunt> | 2005-09-06 17:13:56 +0000 |
---|---|---|
committer | hunt <hunt> | 2005-09-06 17:13:56 +0000 |
commit | c0b3ea3235ced04f5f372c98c5ea321e2da22c59 (patch) | |
tree | b071fe11b66d3fcae27a6ba112ea02e6222931e0 /runtime/stpd/librelay.c | |
parent | a899efa27ced5705b76155eee371bc16cdb2742e (diff) | |
download | systemtap-steved-c0b3ea3235ced04f5f372c98c5ea321e2da22c59.tar.gz systemtap-steved-c0b3ea3235ced04f5f372c98c5ea321e2da22c59.tar.xz systemtap-steved-c0b3ea3235ced04f5f372c98c5ea321e2da22c59.zip |
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.
Diffstat (limited to 'runtime/stpd/librelay.c')
-rw-r--r-- | runtime/stpd/librelay.c | 72 |
1 files changed, 53 insertions, 19 deletions
diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c index 1bdc4814..bd550be3 100644 --- a/runtime/stpd/librelay.c +++ b/runtime/stpd/librelay.c @@ -20,8 +20,6 @@ * */ -#define USE_PROCFS 1 - #include <ctype.h> #include <stdio.h> #include <stdlib.h> @@ -53,13 +51,12 @@ static struct params char relay_filebase[256]; } params; -/* temporary per-cpu output written here, filebase0...N */ +/* temporary per-cpu output written here for relayfs, filebase0...N */ static char *percpu_tmpfilebase = "stpd_cpu"; -#ifdef USE_PROCFS +/* procfs files */ static char proc_filebase[128]; static int proc_file[NR_CPUS]; -#endif /* probe output written here */ static char *outfile_name = "probe.out"; @@ -84,6 +81,8 @@ extern int print_only, quiet, merge, verbose; extern unsigned int buffer_size; extern char *modname; extern char *modpath; +extern int target_pid; +extern char *target_cmd; /* per-cpu buffer info */ static struct buf_status @@ -144,16 +143,12 @@ static void summarize(void) } } -#ifdef USE_PROCFS static void close_proc_files() { int i; for (i = 0; i < ncpus; i++) close(proc_file[i]); } -#else -static void close_proc_files() {} -#endif /** * close_relayfs_files - close and munmap buffer and open output file @@ -200,7 +195,6 @@ static int open_relayfs_files(int cpu, const char *relay_filebase) return -1; } -#ifdef USE_PROCFS sprintf(tmp, "%s/%d", proc_filebase, cpu); dbug("Opening %s.\n", tmp); proc_file[cpu] = open(tmp, O_RDWR | O_NONBLOCK); @@ -208,7 +202,6 @@ static int open_relayfs_files(int cpu, const char *relay_filebase) fprintf(stderr, "ERROR: couldn't open proc file %s: errcode = %s\n", tmp, strerror(errno)); return -1; } -#endif sprintf(tmp, "%s%d", percpu_tmpfilebase, cpu); if((percpu_tmpfile[cpu] = fopen(tmp, "w+")) == NULL) { @@ -401,6 +394,40 @@ err: return -1; } +static volatile sig_atomic_t got_signal; +static sigset_t usrmask, nullmask, oldmask; + +static void sig_usr(int sig __attribute__((unused))) +{ + got_signal = 1; +} + +void start_cmd(void) +{ + pid_t pid; + + dbug ("execing target_cmd %s\n", target_cmd); + if ((pid = fork()) < 0) { + perror ("fork"); + exit(-1); + } else if (pid == 0) { + /* wait here until signaled */ + signal(SIGUSR1, sig_usr); + sigemptyset(&nullmask); + sigemptyset(&usrmask); + sigaddset(&usrmask, SIGUSR1); + sigprocmask(SIG_BLOCK, &usrmask, &oldmask); + while (!got_signal) + sigsuspend(&nullmask); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + if (execl("/bin/sh", "sh", "-c", target_cmd, NULL) < 0) + perror(target_cmd); + exit(-1); + } + + target_pid = pid; +} + #include <sys/wait.h> static void cleanup_and_exit (int); @@ -421,6 +448,7 @@ int init_stp(const char *relay_filebase, int print_summary) ncpus = sysconf(_SC_NPROCESSORS_ONLN); print_totals = print_summary; + /* insert module */ sprintf(buf, "_stp_pid=%d", (int)getpid()); if ((pid = vfork()) < 0) { perror ("vfork"); @@ -441,7 +469,6 @@ int init_stp(const char *relay_filebase, int print_summary) if (relay_filebase) strcpy(params.relay_filebase, relay_filebase); -#ifdef USE_PROCFS sprintf (proc_filebase, "/proc/systemtap/%s", modname); char *ptr = index(proc_filebase,'.'); if (ptr) @@ -454,22 +481,25 @@ int init_stp(const char *relay_filebase, int print_summary) fprintf(stderr, "ERROR: couldn't open control channel %s: errcode = %s\n", buf, strerror(errno)); return -1; } -#endif + + /* 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 = 0; // FIXME. not implemented yet + ti.target = target_pid; send_request(STP_TRANSPORT_INFO, &ti, sizeof(ti)); return 0; } + /* length of timestamp in output field 0 - TODO: make binary, variable */ #define TIMESTAMP_SIZE 11 - /** * merge_output - merge per-cpu output * @@ -610,7 +640,9 @@ int stp_main_loop(void) signal(SIGINT, sigproc); signal(SIGTERM, sigproc); - + signal(SIGCHLD, sigproc); + dbug("in main loop\n"); + while (1) { /* handle messages from control channel */ nb = read(control_channel, recvbuf, sizeof(recvbuf)); if (nb <= 0) { @@ -671,10 +703,12 @@ int stp_main_loop(void) } case STP_START: { - /* we only get this if probe_start() errors */ struct transport_start *t = (struct transport_start *)data; - fprintf(stderr, "probe_start() returned %d\nExiting...\n", t->pid); - cleanup_and_exit(0); + dbug("probe_start() returned %d\n", t->pid); + if (t->pid < 0) + cleanup_and_exit(0); + else if (target_cmd) + kill (target_pid, SIGUSR1); break; } default: |