add -ncwait for Unix based implememtations to make the backgrounder wait to make sure the process starts before detaching

This commit is contained in:
Anthony Minessale 2010-10-29 12:43:55 -05:00
parent 3c66b497d6
commit 23d5fc1900

View File

@ -50,7 +50,7 @@
/* pid filename: Stores the process id of the freeswitch process */ /* pid filename: Stores the process id of the freeswitch process */
#define PIDFILE "freeswitch.pid" #define PIDFILE "freeswitch.pid"
static char *pfile = PIDFILE; static char *pfile = PIDFILE;
static int system_ready = 0;
/* Picky compiler */ /* Picky compiler */
#ifdef __ICC #ifdef __ICC
@ -82,6 +82,31 @@ static void handle_SIGILL(int sig)
return; 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 */ /* kill a freeswitch process running in background mode */
static int freeswitch_kill_background() static int freeswitch_kill_background()
{ {
@ -209,27 +234,31 @@ void WINAPI service_main(DWORD numArgs, char **args)
#else #else
void daemonize(void) void daemonize(int do_wait)
{ {
int fd; int fd;
pid_t pid; pid_t pid;
switch (fork()) { if (!do_wait) {
case 0: switch (fork()) {
break; case 0:
case -1: break;
fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno)); case -1:
exit(0); fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
break; exit(0);
default: break;
exit(0); 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(); pid = fork();
switch (pid) { switch (pid) {
case 0: case 0:
break; break;
@ -238,10 +267,39 @@ void daemonize(void)
exit(0); exit(0);
break; break;
default: 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); exit(0);
} }
if (do_wait) {
setsid();
}
/* redirect std* to null */ /* redirect std* to null */
fd = open("/dev/null", O_RDONLY); fd = open("/dev/null", O_RDONLY);
if (fd != 0) { if (fd != 0) {
@ -286,9 +344,10 @@ int main(int argc, char *argv[])
int local_argc = argc; int local_argc = argc;
char *arg_argv[128] = { 0 }; char *arg_argv[128] = { 0 };
char *usageDesc; 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 known_opt;
int high_prio = 0; int high_prio = 0;
int do_wait = 0;
#ifdef __sun #ifdef __sun
switch_core_flag_t flags = SCF_USE_SQL; switch_core_flag_t flags = SCF_USE_SQL;
#else #else
@ -343,6 +402,9 @@ int main(int argc, char *argv[])
"\t-nort -- disable clock clock_realtime\n" "\t-nort -- disable clock clock_realtime\n"
"\t-stop -- stop freeswitch\n" "\t-stop -- stop freeswitch\n"
"\t-nc -- do not output to a console and background\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-c -- output to a console and stay in the foreground\n"
"\t-conf [confdir] -- specify an alternate config dir\n" "\t-conf [confdir] -- specify an alternate config dir\n"
"\t-log [logdir] -- specify an alternate log 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")) { if (local_argv[x] && !strcmp(local_argv[x], "-stop")) {
kill++; do_kill++;
known_opt++; known_opt++;
} }
@ -526,7 +588,13 @@ int main(int argc, char *argv[])
nc++; nc++;
known_opt++; 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")) { if (local_argv[x] && !strcmp(local_argv[x], "-c")) {
nc = 0; nc = 0;
known_opt++; known_opt++;
@ -664,7 +732,7 @@ int main(int argc, char *argv[])
strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir); strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir);
} }
if (kill) { if (do_kill) {
return freeswitch_kill_background(); return freeswitch_kill_background();
} }
@ -678,41 +746,33 @@ int main(int argc, char *argv[])
return 255; 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 defined(HAVE_SETRLIMIT) && !defined(__sun)
if (!waste && !(flags & SCF_VG)) { if (!waste && !(flags & SCF_VG)) {
int x;
memset(&rlp, 0, sizeof(rlp)); memset(&rlp, 0, sizeof(rlp));
getrlimit(RLIMIT_STACK, &rlp); x = getrlimit(RLIMIT_STACK, &rlp);
if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) { if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) {
char buf[1024] = ""; char buf[1024] = "";
int i = 0; 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", 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]); (int) (rlp.rlim_max / 1024), SWITCH_THREAD_STACKSIZE / 1024, local_argv[0]);
memset(&rlp, 0, sizeof(rlp)); memset(&rlp, 0, sizeof(rlp));
rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
rlp.rlim_max = SWITCH_THREAD_STACKSIZE; rlp.rlim_max = SWITCH_THREAD_STACKSIZE;
setrlimit(RLIMIT_STACK, &rlp); setrlimit(RLIMIT_STACK, &rlp);
apr_terminate(); apr_terminate();
ret = (int) execv(argv[0], argv); ret = (int) execv(argv[0], argv);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]); switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]);
} }
return system(buf); return system(buf);
} }
@ -720,6 +780,25 @@ int main(int argc, char *argv[])
#endif #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) { if (high_prio) {
@ -800,6 +879,12 @@ int main(int argc, char *argv[])
return 255; return 255;
} }
#ifndef WIN32
if (do_wait) {
kill(getppid(), SIGUSR2);
}
#endif
switch_core_runtime_loop(nc); switch_core_runtime_loop(nc);
destroy_status = switch_core_destroy(); destroy_status = switch_core_destroy();