X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fservice.c;h=2febdb69d148ffd68e4d412717b56bbcd6dbd2d2;hb=19e65613563dd9c14cf1ce58aa6e151de8fb90c2;hp=69c71508f8145285ca120e3054495557af7c34f8;hpb=2abba39d759bacebd7461f7370bb108f48dcce92;p=elogind.git diff --git a/src/core/service.c b/src/core/service.c index 69c71508f..2febdb69d 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -526,7 +526,7 @@ static ExecCommand *exec_command_new(const char *path, const char *arg1) { return c; } -static int sysv_exec_commands(Service *s) { +static int sysv_exec_commands(Service *s, const bool supports_reload) { ExecCommand *c; assert(s); @@ -543,14 +543,25 @@ static int sysv_exec_commands(Service *s) { return -ENOMEM; exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c); - c = exec_command_new(UNIT(s)->source_path, "reload"); - if (!c) - return -ENOMEM; - exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c); + if (supports_reload) { + c = exec_command_new(UNIT(s)->source_path, "reload"); + if (!c) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c); + } return 0; } +static bool usage_contains_reload(const char *line) { + return (strcasestr(line, "{reload|") || + strcasestr(line, "{reload}") || + strcasestr(line, "{reload\"") || + strcasestr(line, "|reload|") || + strcasestr(line, "|reload}") || + strcasestr(line, "|reload\"")); +} + static int service_load_sysv_path(Service *s, const char *path) { FILE *f; Unit *u; @@ -560,10 +571,12 @@ static int service_load_sysv_path(Service *s, const char *path) { NORMAL, DESCRIPTION, LSB, - LSB_DESCRIPTION + LSB_DESCRIPTION, + USAGE_CONTINUATION } state = NORMAL; char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description; struct stat st; + bool supports_reload = false; assert(s); assert(path); @@ -612,8 +625,23 @@ static int service_load_sysv_path(Service *s, const char *path) { line++; t = strstrip(l); - if (*t != '#') + if (*t != '#') { + /* Try to figure out whether this init script supports + * the reload operation. This heuristic looks for + * "Usage" lines which include the reload option. */ + if ( state == USAGE_CONTINUATION || + (state == NORMAL && strcasestr(t, "usage"))) { + if (usage_contains_reload(t)) { + supports_reload = true; + state = NORMAL; + } else if (t[strlen(t)-1] == '\\') + state = USAGE_CONTINUATION; + else + state = NORMAL; + } + continue; + } if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) { state = LSB; @@ -906,7 +934,7 @@ static int service_load_sysv_path(Service *s, const char *path) { } } - if ((r = sysv_exec_commands(s)) < 0) + if ((r = sysv_exec_commands(s, supports_reload)) < 0) goto finish; if (s->sysv_runlevels && chars_intersect(RUNLEVELS_BOOT, s->sysv_runlevels) && @@ -1586,7 +1614,12 @@ static void service_set_state(Service *s, ServiceState state) { cgroup_bonding_trim_list(UNIT(s)->cgroup_bondings, true); if (old_state != state) - log_debug("%s changed %s -> %s", UNIT(s)->id, service_state_to_string(old_state), service_state_to_string(state)); + log_struct(LOG_DEBUG, + "UNIT=%s", UNIT(s)->id, + "MESSAGE=%s changed %s -> %s", UNIT(s)->id, + service_state_to_string(old_state), + service_state_to_string(state), + NULL); unit_notify(UNIT(s), table[old_state], table[state], s->reload_result == SERVICE_SUCCESS); s->reload_result = SERVICE_SUCCESS; @@ -1773,7 +1806,8 @@ static int service_spawn( goto fail; } - if (!(our_env = new0(char*, 4))) { + our_env = new0(char*, 5); + if (!our_env) { r = -ENOMEM; goto fail; } @@ -1796,10 +1830,14 @@ static int service_spawn( goto fail; } - if (!(final_env = strv_env_merge(2, - UNIT(s)->manager->environment, - our_env, - NULL))) { + if (s->meta.manager->running_as != SYSTEMD_SYSTEM) + if (asprintf(our_env + n_env++, "MANAGERPID=%lu", (unsigned long) getpid()) < 0) { + r = -ENOMEM; + goto fail; + } + + final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL); + if (!final_env) { r = -ENOMEM; goto fail; } @@ -2915,8 +2953,16 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { f = SERVICE_SUCCESS; } - log_full(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, - "%s: main process exited, code=%s, status=%i", u->id, sigchld_code_to_string(code), status); + log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "MESSAGE=%s: main process exited, code=%s, status=%i/%s", + u->id, sigchld_code_to_string(code), status, + strna(code == CLD_EXITED + ? exit_status_to_string(status, EXIT_STATUS_FULL) + : signal_to_string(status)), + "UNIT=%s", u->id, + "EXIT_CODE=%s", sigchld_code_to_string(code), + "EXIT_STATUS=%i", status, + NULL); if (f != SERVICE_SUCCESS) s->result = f;