141 lines
5.8 KiB
Diff
141 lines
5.8 KiB
Diff
From: Frederic Crozat <fcrozat@suse.com>
|
|
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(-)
|
|
|
|
diff --git a/src/core/service.c b/src/core/service.c
|
|
index a1b2d93..da22e55 100644
|
|
--- a/src/core/service.c
|
|
+++ b/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 TARGET_SUSE
|
|
+ /* 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] = {
|
|
@@ -332,6 +345,9 @@ static char *sysv_translate_name(const char *name) {
|
|
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");
|
|
@@ -934,6 +950,13 @@ static int service_load_sysv_path(Service *s, const char *path) {
|
|
|
|
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
|
|
@@ -1015,6 +1038,9 @@ static int service_load_sysv_name(Service *s, const char *name) {
|
|
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;
|
|
@@ -1035,6 +1061,18 @@ static int service_load_sysv_name(Service *s, const char *name) {
|
|
}
|
|
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;
|
|
|
|
@@ -3663,7 +3701,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);
|
|
|
|
@@ -3680,7 +3718,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);
|
|
@@ -3720,7 +3759,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);
|
|
|