X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fservice.c;h=431bccc4e1ad5bcb0ec7bd99310f70df2ad22f6b;hb=e2f3b44cfc8864bfea7c77ff4c383ce9b535f27e;hp=9f2ee4192fff506d099539a8b450ca4e1fa9351d;hpb=5b8191986c5e00323315e61a53efadbf64de8161;p=elogind.git diff --git a/src/service.c b/src/service.c index 9f2ee4192..431bccc4e 100644 --- a/src/service.c +++ b/src/service.c @@ -247,11 +247,6 @@ static char *sysv_translate_name(const char *name) { /* Drop SuSE-style boot. prefix */ strcpy(stpcpy(r, name + 5), ".service"); #endif -#ifdef TARGET_ARCH - if (startswith(name, "@")) - /* Drop Arch-style background prefix */ - strcpy(stpcpy(r, name + 1), ".service"); -#endif #ifdef TARGET_FRUGALWARE if (startswith(name, "rc.")) /* Drop Frugalware-style rc. prefix */ @@ -328,10 +323,13 @@ static int sysv_translate_facility(const char *name, const char *filename, char /* If we don't know this name, fallback heuristics to figure * out whether something is a target or a service alias. */ - if (*name == '$') + if (*name == '$') { + if (!unit_prefix_is_valid(n)) + return -EINVAL; + /* Facilities starting with $ are most likely targets */ r = unit_name_build(n, NULL, ".target"); - else if (filename && streq(name, filename)) + } else if (filename && streq(name, filename)) /* Names equalling the file name of the services are redundant */ return 0; else @@ -684,10 +682,14 @@ static int service_load_sysv_path(Service *s, const char *path) { } r = sysv_translate_facility(n, file_name_from_path(path), &m); - free(n); - if (r < 0) - goto finish; + if (r < 0) { + log_error("[%s:%u] Failed to translate LSB dependency %s, ignoring: %s", path, line, n, strerror(-r)); + free(n); + continue; + } + + free(n); if (r == 0) continue; @@ -1444,7 +1446,8 @@ static void service_set_state(Service *s, ServiceState state) { if (old_state != state) log_debug("%s changed %s -> %s", s->meta.id, service_state_to_string(old_state), service_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], !s->reload_failure); + s->reload_failure = false; } static int service_coldplug(Unit *u) { @@ -2118,7 +2121,8 @@ static void service_enter_reload(Service *s) { fail: log_warning("%s failed to run 'reload' task: %s", s->meta.id, strerror(-r)); - service_enter_stop(s, false); + s->reload_failure = true; + service_enter_running(s, true); } static void service_run_next_control(Service *s, bool success) { @@ -2159,7 +2163,10 @@ fail: service_enter_signal(s, SERVICE_STOP_SIGTERM, false); else if (s->state == SERVICE_STOP_POST) service_enter_dead(s, false, true); - else + else if (s->state == SERVICE_RELOAD) { + s->reload_failure = true; + service_enter_running(s, true); + } else service_enter_stop(s, false); } @@ -2645,11 +2652,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { /* Fall through */ case SERVICE_RELOAD: - if (success) - service_enter_running(s, true); - else - service_enter_stop(s, false); - + s->reload_failure = !success; + service_enter_running(s, true); break; case SERVICE_STOP: @@ -2699,19 +2703,30 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { break; case SERVICE_START_POST: - case SERVICE_RELOAD: log_warning("%s operation timed out. Stopping.", u->meta.id); service_enter_stop(s, false); break; + case SERVICE_RELOAD: + log_warning("%s operation timed out. Stopping.", u->meta.id); + s->reload_failure = true; + service_enter_running(s, true); + break; + case SERVICE_STOP: log_warning("%s stopping timed out. Terminating.", u->meta.id); service_enter_signal(s, SERVICE_STOP_SIGTERM, false); break; case SERVICE_STOP_SIGTERM: - log_warning("%s stopping timed out. Killing.", u->meta.id); - service_enter_signal(s, SERVICE_STOP_SIGKILL, false); + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out. Killing.", u->meta.id); + service_enter_signal(s, SERVICE_STOP_SIGKILL, false); + } else { + log_warning("%s stopping timed out. Skipping SIGKILL.", u->meta.id); + service_enter_stop_post(s, false); + } + break; case SERVICE_STOP_SIGKILL: @@ -2729,8 +2744,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { break; case SERVICE_FINAL_SIGTERM: - log_warning("%s stopping timed out (2). Killing.", u->meta.id); - service_enter_signal(s, SERVICE_FINAL_SIGKILL, false); + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out (2). Killing.", u->meta.id); + service_enter_signal(s, SERVICE_FINAL_SIGKILL, false); + } else { + log_warning("%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.", u->meta.id); + service_enter_dead(s, false, true); + } + break; case SERVICE_FINAL_SIGKILL: @@ -2865,67 +2886,9 @@ static int service_enumerate(Manager *m) { Unit *service; Iterator j; int r; -#ifdef TARGET_ARCH - Unit *previous = NULL; - char *arch_daemons = NULL; - char *arch_daemons_stripped = NULL; - char **arch_daemons_split = NULL; -#endif assert(m); -#ifdef TARGET_ARCH - if ((r = parse_env_file("/etc/rc.conf", NEWLINE, - "DAEMONS", &arch_daemons, - NULL)) < 0) { - - if (r != -ENOENT) - log_warning("Failed to read /etc/rc.conf: %s", strerror(-r)); - - } else if (arch_daemons) { - if (!(arch_daemons_stripped = strchr(arch_daemons, '('))) - arch_daemons_stripped = arch_daemons; - else - arch_daemons_stripped++; /* strip start paren */ - - arch_daemons_stripped[strcspn(arch_daemons_stripped, ")")] = 0; /* strip end paren */ - - if (!(arch_daemons_split = strv_split_quoted(arch_daemons_stripped))) { - r = -ENOMEM; - goto finish; - } - - STRV_FOREACH(p, arch_daemons_split) { - - free(name); - name = NULL; - - if (**p == '!') /* daemons prefixed with ! are disabled, so ignore them */ - continue; - - if (!(name = sysv_translate_name(*p))) { - r = -ENOMEM; - goto finish; - } - - if ((r = manager_load_unit_prepare(m, name, NULL, NULL, &service)) < 0) { - log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); - continue; - } - - if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, "multi-user.target", NULL, true)) < 0) - goto finish; - - if (previous) - if ((r = unit_add_dependency(service, UNIT_AFTER, previous, true)) < 0) - goto finish; - - if (**p != '@') /* daemons prefixed with @ can be started in the background */ - previous = service; - } - } -#endif - zero(runlevel_services); STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path) @@ -3063,10 +3026,6 @@ finish: free(path); free(fpath); free(name); -#ifdef TARGET_ARCH - free(arch_daemons); - free(arch_daemons_split); -#endif for (i = 0; i < ELEMENTSOF(rcnd_table); i++) set_free(runlevel_services[i]);