X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fservice.c;h=4ee7900e0833f408d49fa53436382b1e0c8efb12;hp=e7a5622f9c885df472715a889bac4b65a300aa84;hb=f401e48c2db22ff9d1a05885b5599bebf19c2707;hpb=6dfa54942c44201b78528d9812313fdb80641e1f diff --git a/src/service.c b/src/service.c index e7a5622f9..4ee7900e0 100644 --- a/src/service.c +++ b/src/service.c @@ -65,7 +65,7 @@ static const struct { { "boot.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, #endif -#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_FRUGALWARE) +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_FRUGALWARE) || defined(TARGET_ANGSTROM) /* Debian style rcS.d */ { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, #endif @@ -246,7 +246,7 @@ static char *sysv_translate_name(const char *name) { if (!(r = new(char, strlen(name) + sizeof(".service")))) return NULL; -#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) if (endswith(name, ".sh")) /* Drop Debian-style .sh suffix */ strcpy(stpcpy(r, name) - 3, ".service"); @@ -280,10 +280,10 @@ static int sysv_translate_facility(const char *name, const char *filename, char /* LSB defined facilities */ "local_fs", SPECIAL_LOCAL_FS_TARGET, #ifndef TARGET_MANDRIVA - /* Due to unfortunate name selection in Mandriva, - * $network is provided by network-up which is ordered - * after network which actually starts interfaces. - * To break the loop, just ignore it */ + /* Due to unfortunate name selection in Mandriva, + * $network is provided by network-up which is ordered + * after network which actually starts interfaces. + * To break the loop, just ignore it */ "network", SPECIAL_NETWORK_TARGET, #endif "named", SPECIAL_NSS_LOOKUP_TARGET, @@ -297,7 +297,7 @@ static int sysv_translate_facility(const char *name, const char *filename, char "x-display-manager", SPECIAL_DISPLAY_MANAGER_SERVICE, "null", NULL, -#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) "mail-transport-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, #endif @@ -372,7 +372,7 @@ static int sysv_fix_order(Service *s) { /* For each pair of services where at least one lacks a LSB * header, we use the start priority value to order things. */ - LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_SERVICE]) { + LIST_FOREACH(units_by_type, other, s->meta.manager->units_by_type[UNIT_SERVICE]) { Service *t; UnitDependency d; bool special_s, special_t; @@ -470,6 +470,7 @@ static int service_load_sysv_path(Service *s, const char *path) { LSB_DESCRIPTION } state = NORMAL; char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description; + struct stat st; assert(s); assert(path); @@ -481,12 +482,26 @@ static int service_load_sysv_path(Service *s, const char *path) { goto finish; } + zero(st); + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + free(s->sysv_path); if (!(s->sysv_path = strdup(path))) { r = -ENOMEM; goto finish; } + s->sysv_mtime = timespec_load(&st.st_mtim); + + if (null_or_empty(&st)) { + u->meta.load_state = UNIT_MASKED; + r = 0; + goto finish; + } + while (!feof(f)) { char l[LINE_MAX], *t; @@ -887,7 +902,7 @@ static int service_load_sysv_name(Service *s, const char *name) { /* For SysV services we strip the boot.*, rc.* and *.sh * prefixes/suffixes. */ -#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) if (endswith(name, ".sh.service")) return -ENOENT; #endif @@ -914,7 +929,7 @@ static int service_load_sysv_name(Service *s, const char *name) { r = service_load_sysv_path(s, path); -#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) if (r >= 0 && s->meta.load_state == UNIT_STUB) { /* Try Debian style *.sh source'able init scripts */ strcat(path, ".sh"); @@ -1006,7 +1021,7 @@ static int fsck_fix_order(Service *s) { /* For each pair of services where both have an fsck priority * we order things based on it. */ - LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_SERVICE]) { + LIST_FOREACH(units_by_type, other, s->meta.manager->units_by_type[UNIT_SERVICE]) { Service *t; UnitDependency d; @@ -2571,7 +2586,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { if (s->main_pid == pid) { s->main_pid = 0; - exec_status_exit(&s->main_exec_status, pid, code, status, s->exec_context.utmp_id); + exec_status_exit(&s->main_exec_status, &s->exec_context, pid, code, status); /* If this is not a forking service than the main * process got started and hence we copy the exit @@ -2650,7 +2665,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { s->control_pid = 0; if (s->control_command) { - exec_status_exit(&s->control_command->exec_status, pid, code, status, s->exec_context.utmp_id); + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); if (s->control_command->ignore) success = true; @@ -3212,6 +3227,29 @@ static void service_reset_failed(Unit *u) { s->failure = false; } +static bool service_need_daemon_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + +#ifdef HAVE_SYSV_COMPAT + if (s->sysv_path) { + struct stat st; + + zero(st); + if (stat(s->sysv_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; + + if (s->sysv_mtime > 0 && + timespec_load(&st.st_mtim) != s->sysv_mtime) + return true; + } +#endif + + return false; +} + static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { Service *s = SERVICE(u); int r = 0; @@ -3361,6 +3399,8 @@ const UnitVTable service_vtable = { .reset_failed = service_reset_failed, + .need_daemon_reload = service_need_daemon_reload, + .cgroup_notify_empty = service_cgroup_notify_event, .notify_message = service_notify_message,