From: Frederic Crozat Date: Fri, 12 Apr 2013 16:56:26 +0200 Subject: Revert "service: drop support for SysV scripts for the early boot" This reverts commit 3cdebc217c42c8529086f2965319b6a48eaaeabe. Conflicts: src/core/service.c --- src/core/service.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) Index: systemd-205/src/core/service.c =================================================================== --- systemd-205.orig/src/core/service.c +++ systemd-205/src/core/service.c @@ -51,7 +51,8 @@ typedef enum RunlevelType { RUNLEVEL_UP, - RUNLEVEL_DOWN + RUNLEVEL_DOWN, + RUNLEVEL_SYSINIT } RunlevelType; static const struct { @@ -66,6 +67,16 @@ static const struct { { "rc4.d", SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP }, { "rc5.d", SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP }, +#ifdef HAVE_SYSV_COMPAT + /* SUSE style boot.d */ + { "boot.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, +#endif + +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + /* Debian style rcS.d */ + { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, +#endif + /* Standard SysV runlevels for shutdown */ { "rc0.d", SPECIAL_POWEROFF_TARGET, RUNLEVEL_DOWN }, { "rc6.d", SPECIAL_REBOOT_TARGET, RUNLEVEL_DOWN } @@ -74,10 +85,12 @@ static const struct { directories in this order, and we want to make sure that sysv_start_priority is known when we first load the unit. And that value we only know from S links. Hence - UP must be read before DOWN */ + UP/SYSINIT must be read before DOWN */ }; #define RUNLEVELS_UP "12345" +/* #define RUNLEVELS_DOWN "06" */ +#define RUNLEVELS_BOOT "bBsS" #endif static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { @@ -334,6 +347,9 @@ static char *sysv_translate_name(const c if (endswith(name, ".sh")) /* Drop .sh suffix */ strcpy(stpcpy(r, name) - 3, ".service"); + if (startswith(name, "boot.")) + /* Drop SuSE-style boot. prefix */ + strcpy(stpcpy(r, name + 5), ".service"); else /* Normal init script name */ strcpy(stpcpy(r, name), ".service"); @@ -936,6 +952,13 @@ static int service_load_sysv_path(Servic if ((r = sysv_exec_commands(s, supports_reload)) < 0) goto finish; + if (s->sysv_runlevels && + chars_intersect(RUNLEVELS_BOOT, s->sysv_runlevels) && + chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { + /* Service has both boot and "up" runlevels + configured. Kill the "up" ones. */ + delete_chars(s->sysv_runlevels, RUNLEVELS_UP); + } if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { /* If there a runlevels configured for this service @@ -1017,6 +1040,9 @@ static int service_load_sysv_name(Servic if (endswith(name, ".sh.service")) return -ENOENT; + if (startswith(name, "boot.")) + return -ENOENT; + STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) { char *path; int r; @@ -1037,6 +1063,18 @@ static int service_load_sysv_name(Servic } free(path); + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try SUSE style boot.* init scripts */ + + path = strjoin(*p, "/boot.", name, NULL); + if (!path) + return -ENOMEM; + + /* Drop .service suffix */ + path[strlen(path)-8] = 0; + r = service_load_sysv_path(s, path); + free(path); + } if (r < 0) return r; @@ -3587,7 +3625,7 @@ static int service_enumerate(Manager *m) if (de->d_name[0] == 'S') { - if (rcnd_table[i].type == RUNLEVEL_UP) { + if (rcnd_table[i].type == RUNLEVEL_UP || rcnd_table[i].type == RUNLEVEL_SYSINIT) { SERVICE(service)->sysv_start_priority_from_rcnd = MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd); @@ -3604,7 +3642,8 @@ static int service_enumerate(Manager *m) goto finish; } else if (de->d_name[0] == 'K' && - (rcnd_table[i].type == RUNLEVEL_DOWN)) { + (rcnd_table[i].type == RUNLEVEL_DOWN || + rcnd_table[i].type == RUNLEVEL_SYSINIT)) { r = set_ensure_allocated(&shutdown_services, trivial_hash_func, trivial_compare_func); @@ -3644,7 +3683,9 @@ static int service_enumerate(Manager *m) * runlevels we assume the stop jobs will be implicitly added * by the core logic. Also, we don't really distinguish here * between the runlevels 0 and 6 and just add them to the - * special shutdown target. */ + * special shutdown target. On SUSE the boot.d/ runlevel is + * also used for shutdown, so we add links for that too to the + * shutdown target.*/ SET_FOREACH(service, shutdown_services, j) { service = unit_follow_merge(service);