diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-07-28 19:12:58 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-07-28 19:12:58 +0200 |
commit | 8cb45947aad7ed308d7eb7098b79fd1be865d966 (patch) | |
tree | a70e5ff3140eb276696d4b4fa68257480476d9ab /src/mds-respawn.c | |
parent | doc (diff) | |
download | mds-8cb45947aad7ed308d7eb7098b79fd1be865d966.tar.gz mds-8cb45947aad7ed308d7eb7098b79fd1be865d966.tar.bz2 mds-8cb45947aad7ed308d7eb7098b79fd1be865d966.tar.xz |
doc
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/mds-respawn.c')
-rw-r--r-- | src/mds-respawn.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/mds-respawn.c b/src/mds-respawn.c index 23c07e6..6da3500 100644 --- a/src/mds-respawn.c +++ b/src/mds-respawn.c @@ -96,6 +96,8 @@ static size_t live_count = 0; */ int parse_cmdline(void) { + /* Parse command line arguments. */ + int i; size_t j, args = 0, stack = 0; for (i = 1; i < argc; i++) @@ -126,13 +128,22 @@ int parse_cmdline(void) eprint("re-exec performed."); } + + /* Validate command line arguments. */ + exit_if (stack > 0, eprint("Non-terminated command specified, aborting.");); exit_if (servers == 0, eprint("No programs to spawn, aborting.");); + + /* Allocate arrays. */ + fail_if (xmalloc(commands_args, args + servers, char*)); fail_if (xmalloc(commands, servers, char**)); fail_if (xmalloc(states, servers, server_state_t)); + + /* Fill command arrays. */ + for (i = 1, args = j = 0; i < argc; i++) { char* arg = argv[i]; @@ -160,6 +171,8 @@ static void spawn_server(size_t index) struct timespec started; pid_t pid; + /* When did the spawned server start? */ + if (monotone(&started) < 0) { perror(*argv); @@ -169,6 +182,9 @@ static void spawn_server(size_t index) } states[index].started = started; + + /* Fork process to spawn the server. */ + pid = fork(); if (pid == (pid_t)-1) { @@ -178,6 +194,9 @@ static void spawn_server(size_t index) return; } + + /* In the parent process (respawner): store spawned server information. */ + if (pid) { states[index].pid = pid; @@ -186,6 +205,8 @@ static void spawn_server(size_t index) return; } + /* In the child process (server): change execution image to the server.. */ + execvp(commands[index][0], commands[index]); perror(commands[index][0]); _exit(1); @@ -255,10 +276,15 @@ int postinitialise_server(void) { size_t i, j; + /* Spawn servers that has not been spawned yet. */ + for (i = 0; i < servers; i++) if (states[i].state == UNBORN) spawn_server(i); + /* Forever mark newly spawned services (after this point in time) + as respawned. */ + for (i = j = 0; j < servers; i++) if (commands_args[i] == NULL) j++; @@ -266,6 +292,8 @@ int postinitialise_server(void) if ((commands_args[i] = strdup("--respawn")) == NULL) goto pfail; + /* Respawn dead and dead and buried servers.*/ + for (i = 0; i < servers; i++) if ((states[i].state == DEAD) || (states[i].state == DEAD_AND_BURIED)) @@ -408,6 +436,7 @@ static void joined_with_server(pid_t pid, int status) struct timespec ended; size_t i; + /* Find index of reaped server. */ for (i = 0; i < servers; i++) if (states[i].pid == pid) break; @@ -417,16 +446,19 @@ static void joined_with_server(pid_t pid, int status) return; } + /* Do nothing if the server is cremated. */ if (states[i].state == CREMATED) { eprintf("cremated child process `%s' exited, ignoring.", commands[i][0]); return; } + /* Mark server as dead if it was alive. */ if (states[i].state == ALIVE) live_count--; states[i].state = DEAD; + /* Cremate server if it exited normally or was killed nicely. */ if (WIFEXITED(status) ? (WEXITSTATUS(status) == 0) : ((WTERMSIG(status) == SIGTERM) || (WTERMSIG(status) == SIGINT))) { @@ -435,11 +467,13 @@ static void joined_with_server(pid_t pid, int status) return; } + /* Print exit status of the reaped server. */ if (WIFEXITED(status)) eprintf("`%s' exited with code %i.", commands[i][0], WEXITSTATUS(status)); else eprintf("`%s' died by signal %i.", commands[i][0], WTERMSIG(status)); + /* When did the server exit. */ if (monotone(&ended) < 0) { perror(*argv); @@ -448,6 +482,7 @@ static void joined_with_server(pid_t pid, int status) return; } + /* Bury the server if it died abnormally too fast. */ if (ended.tv_sec - states[i].started.tv_sec < interval) { eprintf("`%s' died abnormally, burying because it died too fast.", commands[i][0]); @@ -455,6 +490,7 @@ static void joined_with_server(pid_t pid, int status) return; } + /* Respawn server if it died abnormally in a responable time. */ eprintf("`%s' died abnormally, respawning.", commands[i][0]); spawn_server(i); } |