void MGT_Run(void) { struct sigaction sac; struct vev *e; int i; mgt_uptime_t0 = VTIM_real(); e = vev_new(); XXXAN(e); e->callback = mgt_uptime; e->timeout = 1.0; e->name = "mgt_uptime"; AZ(vev_add(mgt_evb, e)); e = vev_new(); XXXAN(e); e->sig = SIGTERM; e->callback = mgt_sigint; e->name = "mgt_sigterm"; AZ(vev_add(mgt_evb, e)); e = vev_new(); XXXAN(e); e->sig = SIGINT; e->callback = mgt_sigint; e->name = "mgt_sigint"; AZ(vev_add(mgt_evb, e)); #ifdef HAVE_SETPROCTITLE setproctitle("Varnish-Mgr %s", heritage.name); #endif memset(&sac, 0, sizeof sac); sac.sa_handler = SIG_IGN; sac.sa_flags = SA_RESTART; AZ(sigaction(SIGPIPE, &sac, NULL)); AZ(sigaction(SIGHUP, &sac, NULL)); if (!d_flag && !mgt_has_vcl()) MGT_complain(C_ERR, "No VCL loaded yet"); else if (!d_flag) { mgt_launch_child(NULL); if (child_state != CH_RUNNING) { // XXX correct? or 0? exit_status = 2; return; } } mgt_SHM_Commit(); i = vev_schedule(mgt_evb); if (i != 0) MGT_complain(C_ERR, "vev_schedule() = %d", i); MGT_complain(C_INFO, "manager dies"); }
mcf_server_start(struct cli *cli, const char * const *av, void *priv) { (void)av; (void)priv; if (child_state == CH_STOPPED) { if (mgt_has_vcl()) { mgt_launch_child(cli); } else { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "No VCL available"); } } else { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "Child in state %s", ch_state[child_state]); } }
mcf_server_startstop(struct cli *cli, const char * const *av, void *priv) { (void)av; if (priv != NULL && child_state == CH_RUNNING) mgt_stop_child(); else if (priv == NULL && child_state == CH_STOPPED) { if (mgt_has_vcl()) { mgt_launch_child(cli); } else { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "No VCL available"); } } else { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "Child in state %s", ch_state[child_state]); } }
static void mgt_reap_child(void) { int i; int status = 0xffff; struct vsb *vsb; pid_t r = 0; assert(child_pid != -1); /* * Close the CLI connections * This signals orderly shut down to child */ mgt_cli_stop_child(); if (child_cli_out >= 0) closex(&child_cli_out); if (child_cli_in >= 0) closex(&child_cli_in); /* Stop the poker */ if (ev_poker != NULL) { vev_del(mgt_evb, ev_poker); free(ev_poker); } ev_poker = NULL; /* Stop the listener */ if (ev_listen != NULL) { vev_del(mgt_evb, ev_listen); free(ev_listen); ev_listen = NULL; } /* Compose obituary */ vsb = VSB_new_auto(); XXXAN(vsb); /* Wait for child to die */ for (i = 0; i < mgt_param.cli_timeout; i++) { r = waitpid(child_pid, &status, WNOHANG); if (r == child_pid) break; (void)sleep(1); } if (r == 0) { VSB_printf(vsb, "Child (%jd) not dying, killing", (intmax_t)r); /* Kick it Jim... */ if (MGT_FEATURE(FEATURE_NO_COREDUMP)) (void)kill(child_pid, SIGKILL); else (void)kill(child_pid, SIGQUIT); r = waitpid(child_pid, &status, 0); } if (r != child_pid) fprintf(stderr, "WAIT 0x%jx\n", (uintmax_t)r); assert(r == child_pid); MAC_reopen_sockets(NULL); VSB_printf(vsb, "Child (%jd) %s", (intmax_t)r, status ? "died" : "ended"); if (WIFEXITED(status) && WEXITSTATUS(status)) { VSB_printf(vsb, " status=%d", WEXITSTATUS(status)); exit_status |= 0x20; if (WEXITSTATUS(status) == 1) VSC_C_mgt->child_exit = ++static_VSC_C_mgt.child_exit; else VSC_C_mgt->child_stop = ++static_VSC_C_mgt.child_stop; } if (WIFSIGNALED(status)) { VSB_printf(vsb, " signal=%d", WTERMSIG(status)); exit_status |= 0x40; VSC_C_mgt->child_died = ++static_VSC_C_mgt.child_died; } #ifdef WCOREDUMP if (WCOREDUMP(status)) { VSB_printf(vsb, " (core dumped)"); exit_status |= 0x80; VSC_C_mgt->child_dump = ++static_VSC_C_mgt.child_dump; } #endif AZ(VSB_finish(vsb)); MGT_complain(status ? C_ERR : C_INFO, "%s", VSB_data(vsb)); VSB_delete(vsb); /* Dispose of shared memory but evacuate panic messages first */ if (heritage.panic_str[0] != '\0') { mgt_panic_record(r); mgt_SHM_Destroy(1); VSC_C_mgt->child_panic = ++static_VSC_C_mgt.child_panic; } else { mgt_SHM_Destroy(MGT_DO_DEBUG(DBG_VSM_KEEP)); } mgt_SHM_Create(); mgt_SHM_Commit(); if (child_state == CH_RUNNING) child_state = CH_DIED; /* Pick up any stuff lingering on stdout/stderr */ (void)child_listener(NULL, EV_RD); closex(&child_output); VLU_Destroy(child_std_vlu); child_pid = -1; MGT_complain(C_DEBUG, "Child cleanup complete"); if (child_state == CH_DIED && mgt_param.auto_restart) mgt_launch_child(NULL); else if (child_state == CH_DIED) child_state = CH_STOPPED; else if (child_state == CH_STOPPING) child_state = CH_STOPPED; }