summaryrefslogtreecommitdiffstats
path: root/runtime/staprun
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/staprun')
-rw-r--r--runtime/staprun/ChangeLog25
-rw-r--r--runtime/staprun/common.c6
-rw-r--r--runtime/staprun/mainloop.c122
-rw-r--r--runtime/staprun/stapio.c2
-rw-r--r--runtime/staprun/staprun.c2
5 files changed, 107 insertions, 50 deletions
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 9e0ccb73..969c299d 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,28 @@
+2008-05-05 Martin Hunt <hunt@redhat.com>
+
+ * mainloop.c (child_proc): Handle sig_chld
+ in the proper thread.
+ (signal_thread): Don't call send_request()
+ because it isn't thread-safe.
+
+2008-05-05 Martin Hunt <hunt@redhat.com>
+
+ * mainloop.c (signal_thread): New thread to handle signals
+ better.
+ (setup_main_signals): Create signal thread.
+
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR 6008
+ * common.c (parse_args): Increase the limitation of the buffer size
+ to 4095MB.
+ * common.c (usage): Ditto.
+
+2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
+
+ * stapio.c (main): Fix a typo in a debug message.
+ * staprun.c (main): Ditto.
+
2008-04-24 Frank Ch. Eigler <fche@elastic.org>
PR 6451.
diff --git a/runtime/staprun/common.c b/runtime/staprun/common.c
index b716d27f..93da51d8 100644
--- a/runtime/staprun/common.c
+++ b/runtime/staprun/common.c
@@ -58,8 +58,8 @@ void parse_args(int argc, char **argv)
break;
case 'b':
buffer_size = (unsigned)atoi(optarg);
- if (buffer_size < 1 || buffer_size > 64) {
- err("Invalid buffer size '%d' (should be 1-64).\n", buffer_size);
+ if (buffer_size < 1 || buffer_size > 4095) {
+ err("Invalid buffer size '%d' (should be 1-4095).\n", buffer_size);
usage(argv[0]);
}
break;
@@ -130,7 +130,7 @@ void usage(char *prog)
err("-o FILE Send output to FILE.\n");
err("-b buffer size The systemtap module specifies a buffer size.\n");
err(" Setting one here will override that value. The\n");
- err(" value should be an integer between 1 and 64\n");
+ err(" value should be an integer between 1 and 4095 \n");
err(" which be assumed to be the buffer size in MB.\n");
err(" That value will be per-cpu in bulk mode.\n");
err("-L Load module and start probes, then detach.\n");
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c
index 37a4f58a..61963743 100644
--- a/runtime/staprun/mainloop.c
+++ b/runtime/staprun/mainloop.c
@@ -16,8 +16,8 @@
/* globals */
int ncpus;
static int use_old_transport = 0;
-enum _stp_sig_type { sig_none, sig_done, sig_detach };
-static enum _stp_sig_type got_signal = sig_none;
+//enum _stp_sig_type { sig_none, sig_done, sig_detach };
+//static enum _stp_sig_type got_signal = sig_none;
/**
* send_request - send request to kernel over control channel
@@ -29,48 +29,83 @@ static enum _stp_sig_type got_signal = sig_none;
*/
int send_request(int type, void *data, int len)
{
- char buf[1024];
-
- /* Before doing memcpy, make sure 'buf' is big enough. */
- if ((len + 4) > (int)sizeof(buf)) {
- _err("exceeded maximum send_request size.\n");
- return -1;
- }
- memcpy(buf, &type, 4);
- memcpy(&buf[4], data, len);
- return write(control_channel, buf, len+4);
+ char buf[1024];
+
+ /* Before doing memcpy, make sure 'buf' is big enough. */
+ if ((len + 4) > (int)sizeof(buf)) {
+ _err("exceeded maximum send_request size.\n");
+ return -1;
+ }
+ memcpy(buf, &type, 4);
+ memcpy(&buf[4], data, len);
+ return write(control_channel, buf, len + 4);
}
+static void *signal_thread(void *arg)
+{
+ sigset_t *s = (sigset_t *) arg;
+ int signum, rc, btype = STP_EXIT;
+
+ while (1) {
+ if (sigwait(s, &signum) < 0) {
+ _perr("sigwait");
+ continue;
+ }
+ dbug(2, "sigproc %d (%s)\n", signum, strsignal(signum));
+ if (signum == SIGQUIT)
+ cleanup_and_exit(1);
+ else if (signum == SIGINT || signum == SIGHUP || signum == SIGTERM) {
+ // send STP_EXIT
+ rc = write(control_channel, &btype, sizeof(btype));
+ break;
+ }
+ }
+ return NULL;
+}
-static void sigproc(int signum)
+static void chld_proc(int signum)
{
- dbug(2, "sigproc %d (%s)\n", signum, strsignal(signum));
-
- if (signum == SIGCHLD) {
- pid_t pid = waitpid(-1, NULL, WNOHANG);
- if (pid != target_pid)
- return;
- send_request(STP_EXIT, NULL, 0);
- } else if (signum == SIGQUIT)
- got_signal = sig_detach;
- else if (signum == SIGINT || signum == SIGHUP || signum == SIGTERM)
- got_signal = sig_done;
+ int32_t rc, btype = STP_EXIT;
+ dbug(2, "chld_proc %d (%s)\n", signum, strsignal(signum));
+ pid_t pid = waitpid(-1, NULL, WNOHANG);
+ if (pid != target_pid)
+ return;
+ // send STP_EXIT
+ rc = write(control_channel, &btype, sizeof(btype));
}
-static void setup_main_signals(int cleanup)
+static void setup_main_signals(void)
{
- struct sigaction a;
- memset(&a, 0, sizeof(a));
- sigfillset(&a.sa_mask);
- if (cleanup == 0) {
- a.sa_handler = sigproc;
- sigaction(SIGCHLD, &a, NULL);
- } else
- a.sa_handler = SIG_IGN;
- sigaction(SIGINT, &a, NULL);
- sigaction(SIGTERM, &a, NULL);
- sigaction(SIGHUP, &a, NULL);
- sigaction(SIGQUIT, &a, NULL);
+ pthread_t tid;
+ struct sigaction sa;
+ sigset_t *s = malloc(sizeof(*s));
+ if (!s) {
+ _perr("malloc failed");
+ exit(1);
+ }
+ sigfillset(s);
+ pthread_sigmask(SIG_SETMASK, s, NULL);
+ memset(&sa, 0, sizeof(sa));
+ sigfillset(&sa.sa_mask);
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+
+ sa.sa_handler = chld_proc;
+ sigaction(SIGCHLD, &sa, NULL);
+
+ sigemptyset(s);
+ sigaddset(s, SIGINT);
+ sigaddset(s, SIGTERM);
+ sigaddset(s, SIGHUP);
+ sigaddset(s, SIGQUIT);
+ pthread_sigmask(SIG_SETMASK, s, NULL);
+ if (pthread_create(&tid, NULL, signal_thread, s) < 0) {
+ _perr("failed to create thread");
+ exit(1);
+ }
}
/*
@@ -229,7 +264,7 @@ void cleanup_and_exit(int detach)
return;
exiting = 1;
- setup_main_signals(1);
+ setup_main_signals();
dbug(1, "detach=%d\n", detach);
@@ -272,20 +307,17 @@ int stp_main_loop(void)
char recvbuf[8196];
setvbuf(ofp, (char *)NULL, _IOLBF, 0);
- setup_main_signals(0);
+ setup_main_signals();
dbug(2, "in main loop\n");
send_request(STP_READY, NULL, 0);
- while (1) { /* handle messages from control channel */
+ /* handle messages from control channel */
+ while (1) {
nb = read(control_channel, recvbuf, sizeof(recvbuf));
dbug(2, "nb=%d\n", (int)nb);
if (nb <= 0) {
- if (got_signal == sig_done)
- send_request(STP_EXIT, NULL, 0);
- else if (got_signal == sig_detach)
- cleanup_and_exit(1);
- else if (errno != EINTR)
+ if (errno != EINTR)
_perr("Unexpected EOF in read (nb=%ld)", (long)nb);
continue;
}
diff --git a/runtime/staprun/stapio.c b/runtime/staprun/stapio.c
index b591244f..3c8c4f7f 100644
--- a/runtime/staprun/stapio.c
+++ b/runtime/staprun/stapio.c
@@ -30,7 +30,7 @@ int main(int argc, char **argv)
parse_args(argc, argv);
if (buffer_size)
- dbug(1, "Using a buffer of %u bytes.\n", buffer_size);
+ dbug(1, "Using a buffer of %u MB.\n", buffer_size);
if (optind < argc) {
parse_modpath(argv[optind++]);
diff --git a/runtime/staprun/staprun.c b/runtime/staprun/staprun.c
index ee9bdc7b..0291d01f 100644
--- a/runtime/staprun/staprun.c
+++ b/runtime/staprun/staprun.c
@@ -230,7 +230,7 @@ int main(int argc, char **argv)
parse_args(argc, argv);
if (buffer_size)
- dbug(2, "Using a buffer of %u bytes.\n", buffer_size);
+ dbug(2, "Using a buffer of %u MB.\n", buffer_size);
if (optind < argc) {
parse_modpath(argv[optind++]);