summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Price <anprice@redhat.com>2014-04-26 15:31:19 +0100
committerChris Mason <clm@fb.com>2014-09-24 12:02:09 -0700
commit33e3face4ae0c7e0f67e3a92edc8d1e818ef6515 (patch)
tree1e29a8a22026a20bf055d2664ef4b91446266bc7
parent7f64c1928f85235e01e6f268fdc4cbfc921b5c42 (diff)
downloadblktrace-33e3face4ae0c7e0f67e3a92edc8d1e818ef6515.tar.gz
blktrace-33e3face4ae0c7e0f67e3a92edc8d1e818ef6515.tar.bz2
iowatcher: Separate program running from waiting
Until now run_program2() was a replacement for system() so it always waited for the process to end before returning. To make this function more useful move the waiting code into a separate function and add a mechanism to expect a specific exit code. Signed-off-by: Andrew Price <anprice@redhat.com>
-rw-r--r--iowatcher/blkparse.c2
-rw-r--r--iowatcher/tracers.c47
-rw-r--r--iowatcher/tracers.h3
3 files changed, 34 insertions, 18 deletions
diff --git a/iowatcher/blkparse.c b/iowatcher/blkparse.c
index 1555845..447d14c 100644
--- a/iowatcher/blkparse.c
+++ b/iowatcher/blkparse.c
@@ -801,7 +801,7 @@ static int dump_traces(struct tracelist *traces, int count, char *dumpfile)
argv[i++] = tl->name;
}
- err = run_program2(argc, argv);
+ err = run_program2(argc, argv, 0, NULL);
free(argv);
return err;
}
diff --git a/iowatcher/tracers.c b/iowatcher/tracers.c
index f42958b..12efb4e 100644
--- a/iowatcher/tracers.c
+++ b/iowatcher/tracers.c
@@ -36,6 +36,7 @@
#include "plot.h"
#include "blkparse.h"
#include "list.h"
+#include "tracers.h"
extern char **environ;
@@ -178,33 +179,47 @@ int run_program(char *str)
return 0;
}
-int run_program2(int argc, char **argv)
+int wait_program(pid_t pid, const char *pname, int expexit)
+{
+ int status;
+ int ret = 0;
+
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status)) {
+ ret = WEXITSTATUS(status);
+ if (ret == 127) /* spawnp failed after forking */
+ fprintf(stderr, "Failed to run '%s'\n", pname);
+ else if (ret != expexit)
+ fprintf(stderr, "'%s' exit status %d, expected %d\n",
+ pname, ret, expexit);
+ } else if (WIFSIGNALED(status)) {
+ fprintf(stderr, "'%s' killed by signal %d\n", pname, WTERMSIG(status));
+ ret = -1;
+ }
+ return ret;
+}
+
+int run_program2(int argc, char **argv, int expexit, pid_t *pid)
{
int i;
int err;
- int status;
- pid_t pid;
+ pid_t _pid;
fprintf(stderr, "running");
for (i = 0; i < argc; i++)
fprintf(stderr, " '%s'", argv[i]);
fprintf(stderr, "\n");
- err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ);
+ err = posix_spawnp(&_pid, argv[0], NULL, NULL, argv, environ);
if (err != 0) {
fprintf(stderr, "Could not run '%s': %s\n", argv[0], strerror(err));
- return -err;
- }
- waitpid(pid, &status, 0);
- if (WIFEXITED(status)) {
- err = WEXITSTATUS(status);
- if (err == 127) /* spawnp failed after forking */
- fprintf(stderr, "Failed to run '%s'\n", argv[0]);
- else if (err)
- fprintf(stderr, "'%s' failed with exit status %d\n", argv[0], err);
- } else if (WIFSIGNALED(status)) {
- fprintf(stderr, "'%s' killed by signal %d\n", argv[0], WTERMSIG(status));
- return 1;
+ } else if (expexit >= 0) {
+ err = wait_program(_pid, argv[0], expexit);
+ } else if (!pid) {
+ fprintf(stderr, "Warning: %s (%ld): Not saving pid and not waiting for it.\n",
+ argv[0], (long)_pid);
+ } else {
+ *pid = _pid;
}
return err;
}
diff --git a/iowatcher/tracers.h b/iowatcher/tracers.h
index 0db19b4..d0b8b6b 100644
--- a/iowatcher/tracers.h
+++ b/iowatcher/tracers.h
@@ -18,7 +18,8 @@
#ifndef __IOWATCH_TRACERS
#define __IOWATCH_TRACERS
int run_program(char *str);
-int run_program2(int argc, char **argv);
+int run_program2(int argc, char **argv, int expexit, pid_t *pid);
+int wait_program(pid_t pid, const char *pname, int expexit);
int stop_blktrace(void);
int start_blktrace(char **devices, int num_devices, char *trace_name, char *dest);
int start_mpstat(char *trace_name);