about summary refs log tree commit homepage
path: root/iostat_process.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2012-04-24 16:01:06 -0700
committerEric Wong <normalperson@yhbt.net>2012-04-24 16:11:48 -0700
commit7db031ed20cee6ca49628e9b5f10d0811bff0647 (patch)
tree973edde85e2331512519c10d09a48f3d36ff64a0 /iostat_process.c
parent13027727d2ddce6ed9e630e34671fc0866a1ddd0 (diff)
downloadcmogstored-7db031ed20cee6ca49628e9b5f10d0811bff0647.tar.gz
Since xvasprintf() allocates heap memory, malloc()
implementations may not release/reinitialize locks in child
processes properly.  This shouldn't be a problem on glibc, but
other systems may encounter deadlocks or SEGV as a result.

Eventually we'll replace fork()+exec with posix_spawn()
(patches accepted).
Diffstat (limited to 'iostat_process.c')
-rw-r--r--iostat_process.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/iostat_process.c b/iostat_process.c
index 935736a..d806366 100644
--- a/iostat_process.c
+++ b/iostat_process.c
@@ -107,26 +107,30 @@ static void preexec_redirect(int out_fd)
 
 static pid_t iostat_fork_exec(int out_fd)
 {
+        /* rely on /bin/sh to parse iostat command-line args */
+        const char *cmd = getenv("MOG_IOSTAT_CMD");
+        if (!cmd)
+                cmd = "iostat -dx 1 30";
+
+        cmd = exec_cmd(cmd);
+
         iostat_pid = fork();
         if (iostat_pid < 0) {
                 syslog(LOG_ERR, "fork() for iostat failed: %m");
         } else if (iostat_pid > 0) {
                 mog_close(out_fd);
         } else {
-                /* rely on /bin/sh to parse iostat command-line args */
-                const char *cmd = getenv("MOG_IOSTAT_CMD");
-                if (!cmd) cmd = "iostat -dx 1 30";
-
+                /* child */
                 preexec_redirect(out_fd);
                 if (! mog_cloexec_atomic)
                         mog_cloexec_from(STDERR_FILENO + 1);
 
-                cmd = exec_cmd(cmd);
                 mog_intr_enable();
                 execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
                 syslog(LOG_CRIT, "execl(%s) failed: %m", cmd);
                 abort();
         }
+        free(cmd);
         return iostat_pid;
 }