From 23d5fc1900d06354b4ad9df21fdf02f256f40e13 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 29 Oct 2010 12:43:55 -0500 Subject: [PATCH] add -ncwait for Unix based implememtations to make the backgrounder wait to make sure the process starts before detaching --- src/switch.c | 157 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 36 deletions(-) diff --git a/src/switch.c b/src/switch.c index a28baba6f0..5c2cba3c63 100644 --- a/src/switch.c +++ b/src/switch.c @@ -50,7 +50,7 @@ /* pid filename: Stores the process id of the freeswitch process */ #define PIDFILE "freeswitch.pid" static char *pfile = PIDFILE; - +static int system_ready = 0; /* Picky compiler */ #ifdef __ICC @@ -82,6 +82,31 @@ static void handle_SIGILL(int sig) return; } +static void handle_SIGUSR2(int sig) +{ + if (sig); + + system_ready = 1; + + return; +} + +static void handle_SIGCHLD(int sig) +{ + int status = 0; + int pid = 0; + + if (sig); + + pid = wait(&status); + + if (pid > 0) { + system_ready = -1; + } + + return; +} + /* kill a freeswitch process running in background mode */ static int freeswitch_kill_background() { @@ -209,27 +234,31 @@ void WINAPI service_main(DWORD numArgs, char **args) #else -void daemonize(void) +void daemonize(int do_wait) { int fd; pid_t pid; - switch (fork()) { - case 0: - break; - case -1: - fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno)); - exit(0); - break; - default: - exit(0); + if (!do_wait) { + switch (fork()) { + case 0: + break; + case -1: + fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno)); + exit(0); + break; + default: + exit(0); + } + + if (setsid() < 0) { + fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno)); + exit(0); + } } - if (setsid() < 0) { - fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno)); - exit(0); - } pid = fork(); + switch (pid) { case 0: break; @@ -238,10 +267,39 @@ void daemonize(void) exit(0); break; default: - fprintf(stderr, "%d Backgrounding.\n", (int) pid); + { + fprintf(stderr, "%d Backgrounding.\n", (int) pid); + + + if (do_wait) { + unsigned int sanity = 20; + while(--sanity && !system_ready) { + + if (sanity % 2 == 0) { + printf("FreeSWITCH[%d] Waiting for background process pid:%d to be ready.....\n", getpid(), (int) pid); + } + sleep(1); + } + + if (system_ready == 1) { + printf("FreeSWITCH[%d] System Ready pid:%d\n", (int) getpid(), (int) pid); + } else { + printf("FreeSWITCH[%d] Error starting system! pid:%d\n", (int)getpid(), (int) pid); + kill(pid, 9); + exit(-1); + } + + } + + } + exit(0); } + if (do_wait) { + setsid(); + } + /* redirect std* to null */ fd = open("/dev/null", O_RDONLY); if (fd != 0) { @@ -286,9 +344,10 @@ int main(int argc, char *argv[]) int local_argc = argc; char *arg_argv[128] = { 0 }; char *usageDesc; - int alt_dirs = 0, log_set = 0, run_set = 0, kill = 0; + int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0; int known_opt; int high_prio = 0; + int do_wait = 0; #ifdef __sun switch_core_flag_t flags = SCF_USE_SQL; #else @@ -343,6 +402,9 @@ int main(int argc, char *argv[]) "\t-nort -- disable clock clock_realtime\n" "\t-stop -- stop freeswitch\n" "\t-nc -- do not output to a console and background\n" +#ifndef WIN32 + "\t-ncwait -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)\n" +#endif "\t-c -- output to a console and stay in the foreground\n" "\t-conf [confdir] -- specify an alternate config dir\n" "\t-log [logdir] -- specify an alternate log dir\n" @@ -518,7 +580,7 @@ int main(int argc, char *argv[]) } if (local_argv[x] && !strcmp(local_argv[x], "-stop")) { - kill++; + do_kill++; known_opt++; } @@ -526,7 +588,13 @@ int main(int argc, char *argv[]) nc++; known_opt++; } - +#ifndef WIN32 + if (local_argv[x] && !strcmp(local_argv[x], "-ncwait")) { + nc++; + do_wait++; + known_opt++; + } +#endif if (local_argv[x] && !strcmp(local_argv[x], "-c")) { nc = 0; known_opt++; @@ -664,7 +732,7 @@ int main(int argc, char *argv[]) strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir); } - if (kill) { + if (do_kill) { return freeswitch_kill_background(); } @@ -678,41 +746,33 @@ int main(int argc, char *argv[]) return 255; } - signal(SIGILL, handle_SIGILL); - signal(SIGTERM, handle_SIGILL); - if (nc) { -#ifdef WIN32 - FreeConsole(); -#else - if (!nf) { - daemonize(); - } -#endif - } #if defined(HAVE_SETRLIMIT) && !defined(__sun) if (!waste && !(flags & SCF_VG)) { + int x; + memset(&rlp, 0, sizeof(rlp)); - getrlimit(RLIMIT_STACK, &rlp); + x = getrlimit(RLIMIT_STACK, &rlp); + if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) { char buf[1024] = ""; int i = 0; fprintf(stderr, "Error: stacksize %d is too large: run ulimit -s %d or run %s -waste.\nauto-adjusting stack size for optimal performance...\n", (int) (rlp.rlim_max / 1024), SWITCH_THREAD_STACKSIZE / 1024, local_argv[0]); - + memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; rlp.rlim_max = SWITCH_THREAD_STACKSIZE; setrlimit(RLIMIT_STACK, &rlp); - + apr_terminate(); ret = (int) execv(argv[0], argv); - + for (i = 0; i < argc; i++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]); } - + return system(buf); } @@ -720,6 +780,25 @@ int main(int argc, char *argv[]) #endif + signal(SIGILL, handle_SIGILL); + signal(SIGTERM, handle_SIGILL); +#ifndef WIN32 + if (do_wait) { + signal(SIGUSR2, handle_SIGUSR2); + signal(SIGCHLD, handle_SIGCHLD); + } +#endif + + if (nc) { +#ifdef WIN32 + FreeConsole(); +#else + if (!nf) { + daemonize(do_wait); + } +#endif + } + if (high_prio) { @@ -800,6 +879,12 @@ int main(int argc, char *argv[]) return 255; } +#ifndef WIN32 + if (do_wait) { + kill(getppid(), SIGUSR2); + } +#endif + switch_core_runtime_loop(nc); destroy_status = switch_core_destroy();