diff options
-rw-r--r-- | cmogstored.h | 10 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | iostat_process.c | 6 | ||||
-rw-r--r-- | upgrade.c | 8 |
4 files changed, 19 insertions, 6 deletions
diff --git a/cmogstored.h b/cmogstored.h index 5aa7c01..4bb0716 100644 --- a/cmogstored.h +++ b/cmogstored.h @@ -360,6 +360,16 @@ void mog_oom_if_null(const void *); #define warn(...) error(0, 0, __VA_ARGS__) +/* + * vfork is poorly-specified, but at least on Linux it improves + * performance when used for spawning iostat processes + */ +#if defined(HAVE_VFORK) && defined(__linux__) +# define mog_fork_for_exec() vfork() +#else +# define mog_fork_for_exec() fork() +#endif + /* maxconns.c */ void mog_set_maxconns(unsigned long); diff --git a/configure.ac b/configure.ac index 8bd98e2..0d551c3 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ AC_CHECK_FUNCS([ioctl]) AC_CHECK_FUNCS([sendfile]) AC_CHECK_FUNCS([open_memstream]) AC_CHECK_FUNCS([posix_fadvise]) +AC_CHECK_FUNCS([vfork]) dnl need LIBS=-lfreebsd-glue (but not CFLAGS=-I/usr/include/freebsd) AC_CHECK_FUNCS([bsd_sendfile]) diff --git a/iostat_process.c b/iostat_process.c index 90a291f..4d7dfbf 100644 --- a/iostat_process.c +++ b/iostat_process.c @@ -65,7 +65,7 @@ static void dup2_or_die(int oldfd, int newfd, const char *errdesc) if (rc < 0) { syslog(LOG_CRIT, "dup2(%s) failed: %m", errdesc); - abort(); + _exit(1); } } @@ -96,7 +96,7 @@ static pid_t iostat_fork_exec(int out_fd) cmd = exec_cmd(cmd); - iostat_pid = fork(); + iostat_pid = mog_fork_for_exec(); if (iostat_pid < 0) { syslog(LOG_ERR, "fork() for iostat failed: %m"); } else if (iostat_pid > 0) { @@ -111,7 +111,7 @@ static pid_t iostat_fork_exec(int out_fd) mog_intr_enable(); execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); syslog(LOG_CRIT, "execl(%s) failed: %m", cmd); - abort(); + _exit(1); } mog_free(cmd); return iostat_pid; @@ -125,13 +125,14 @@ pid_t mog_upgrade_spawn(void) assert(dst[bytes - 1] == ',' && "not comma-terminated no listeners?"); dst[bytes - 1] = '\0'; /* kill the last comma */ + start.envp[0] = dst; - pid = fork(); + pid = mog_fork_for_exec(); if (pid == 0) { - start.envp[0] = dst; mog_svc_upgrade_prepare(); execve(execfile, start.argv, start.envp); - die_errno("execve %s", execfile); + syslog(LOG_ERR, "execve %s failed for upgrade: %m", execfile); + _exit(2); } else if (pid > 0) { mog_process_register(pid, MOG_PROC_UPGRADE); syslog(LOG_INFO, "upgrade spawned PID:%d", pid); @@ -143,6 +144,7 @@ out: /* find_in_path does not malloc if output == input */ if (execfile != start.argv[0]) mog_free(execfile); + start.envp[0] = 0; free(dst); return pid; |