Add -reincarnate flag to FS

When FS is given the -reincarnate flag, FS will be automatically
restarted after any uncontrolled exit.
This commit is contained in:
Travis Cross 2013-07-03 06:31:59 +00:00
parent bc851de200
commit 9fc3990e04

View File

@ -357,6 +357,32 @@ static void daemonize(int *fds)
return; return;
} }
static void reincarnate_protect(char **argv) {
int i;
refork:
if ((i=fork())) { /* parent */
int s; pid_t r;
rewait:
r = waitpid(i, &s, 0);
if (r == (pid_t)-1) {
if (errno == EINTR) goto rewait;
exit(EXIT_FAILURE);
}
if (r != i) goto rewait;
if (WIFEXITED(s)
&& (WEXITSTATUS(s) == EXIT_SUCCESS
|| WEXITSTATUS(s) == EXIT_FAILURE)) {
exit(WEXITSTATUS(s));
}
if (WIFEXITED(s) || WIFSIGNALED(s)) {
if (argv) {
execv(argv[0], argv); return;
} else goto refork;
}
goto rewait;
}
}
#endif #endif
static const char usage[] = static const char usage[] =
@ -369,6 +395,8 @@ static const char usage[] =
"\t-monotonic-clock -- use monotonic clock as timer source\n" "\t-monotonic-clock -- use monotonic clock as timer source\n"
#else #else
"\t-nf -- no forking\n" "\t-nf -- no forking\n"
"\t-reincarnate -- restart the switch on an uncontrolled exit\n"
"\t-reincarnate-reexec -- run execv on a restart (helpful for upgrades)\n"
"\t-u [user] -- specify user to switch to\n" "\t-u [user] -- specify user to switch to\n"
"\t-g [group] -- specify group to switch to\n" "\t-g [group] -- specify group to switch to\n"
#endif #endif
@ -437,6 +465,7 @@ int main(int argc, char *argv[])
switch_bool_t do_wait = SWITCH_FALSE; switch_bool_t do_wait = SWITCH_FALSE;
char *runas_user = NULL; char *runas_user = NULL;
char *runas_group = NULL; char *runas_group = NULL;
switch_bool_t reincarnate = SWITCH_FALSE, reincarnate_reexec = SWITCH_FALSE;
int fds[2] = { 0, 0 }; int fds[2] = { 0, 0 };
#else #else
switch_bool_t win32_service = SWITCH_FALSE; switch_bool_t win32_service = SWITCH_FALSE;
@ -612,6 +641,14 @@ int main(int argc, char *argv[])
nf = SWITCH_TRUE; nf = SWITCH_TRUE;
} }
else if (!strcmp(local_argv[x], "-reincarnate")) {
reincarnate = SWITCH_TRUE;
}
else if (!strcmp(local_argv[x], "-reincarnate-reexec")) {
reincarnate = SWITCH_TRUE;
reincarnate_reexec = SWITCH_TRUE;
}
else if (!strcmp(local_argv[x], "-version")) { else if (!strcmp(local_argv[x], "-version")) {
fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -994,6 +1031,10 @@ int main(int argc, char *argv[])
} }
#endif #endif
} }
#ifndef WIN32
if (reincarnate)
reincarnate_protect(reincarnate_reexec ? argv : NULL);
#endif
switch (priority) { switch (priority) {
case 2: case 2: