Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | From 8791b5b3934c55694872b6915a67340683ead91b Mon Sep 17 00:00:00 2001 |
| 2 | From: Khem Raj <raj.khem@gmail.com> |
| 3 | Date: Fri, 20 Feb 2015 05:22:52 +0000 |
| 4 | Subject: [PATCH 09/11] sysv-generator: add support for executing scripts under |
| 5 | /etc/rcS.d/ |
| 6 | |
| 7 | To be compatible, all services translated from scripts under /etc/rcS.d would |
| 8 | run before services translated from scripts under /etc/rcN.d. |
| 9 | |
| 10 | Upstream-Status: Inappropriate [OE specific] |
| 11 | |
| 12 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> |
| 13 | Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| 14 | --- |
| 15 | src/sysv-generator/sysv-generator.c | 50 ++++++++++++++++++++++++++++--------- |
| 16 | 1 file changed, 38 insertions(+), 12 deletions(-) |
| 17 | |
| 18 | diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c |
| 19 | index bd67f32..6756cc6 100644 |
| 20 | --- a/src/sysv-generator/sysv-generator.c |
| 21 | +++ b/src/sysv-generator/sysv-generator.c |
| 22 | @@ -42,7 +42,8 @@ |
| 23 | |
| 24 | typedef enum RunlevelType { |
| 25 | RUNLEVEL_UP, |
| 26 | - RUNLEVEL_DOWN |
| 27 | + RUNLEVEL_DOWN, |
| 28 | + RUNLEVEL_SYSINIT |
| 29 | } RunlevelType; |
| 30 | |
| 31 | static const struct { |
| 32 | @@ -57,6 +58,9 @@ static const struct { |
| 33 | { "rc4.d", SPECIAL_MULTI_USER_TARGET, RUNLEVEL_UP }, |
| 34 | { "rc5.d", SPECIAL_GRAPHICAL_TARGET, RUNLEVEL_UP }, |
| 35 | |
| 36 | + /* Debian style rcS.d, also adopted by OE */ |
| 37 | + { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT}, |
| 38 | + |
| 39 | /* Standard SysV runlevels for shutdown */ |
| 40 | { "rc0.d", SPECIAL_POWEROFF_TARGET, RUNLEVEL_DOWN }, |
| 41 | { "rc6.d", SPECIAL_REBOOT_TARGET, RUNLEVEL_DOWN } |
| 42 | @@ -65,7 +69,7 @@ static const struct { |
| 43 | directories in this order, and we want to make sure that |
| 44 | sysv_start_priority is known when we first load the |
| 45 | unit. And that value we only know from S links. Hence |
| 46 | - UP must be read before DOWN */ |
| 47 | + UP/SYSINIT must be read before DOWN */ |
| 48 | }; |
| 49 | |
| 50 | typedef struct SysvStub { |
| 51 | @@ -81,6 +85,8 @@ typedef struct SysvStub { |
| 52 | char **conflicts; |
| 53 | bool has_lsb; |
| 54 | bool reload; |
| 55 | + bool default_dependencies; |
| 56 | + bool from_rcsd; |
| 57 | } SysvStub; |
| 58 | |
| 59 | const char *arg_dest = "/tmp"; |
| 60 | @@ -183,6 +189,9 @@ static int generate_unit_file(SysvStub *s) { |
| 61 | "Description=%s\n", |
| 62 | s->path, s->description); |
| 63 | |
| 64 | + if (!s->default_dependencies) |
| 65 | + fprintf(f, "DefaultDependencies=no\n"); |
| 66 | + |
| 67 | if (!isempty(before)) |
| 68 | fprintf(f, "Before=%s\n", before); |
| 69 | if (!isempty(after)) |
| 70 | @@ -704,18 +713,30 @@ static int fix_order(SysvStub *s, Hashmap *all_services) { |
| 71 | if (s->has_lsb && other->has_lsb) |
| 72 | continue; |
| 73 | |
| 74 | - if (other->sysv_start_priority < s->sysv_start_priority) { |
| 75 | - r = strv_extend(&s->after, other->name); |
| 76 | + /* All scripts under /etc/rcS.d should execute before scripts under |
| 77 | + * /etc/rcN.d */ |
| 78 | + if (!other->from_rcsd && s->from_rcsd) { |
| 79 | + r = strv_extend(&s->before, other->name); |
| 80 | if (r < 0) |
| 81 | return log_oom(); |
| 82 | - } |
| 83 | - else if (other->sysv_start_priority > s->sysv_start_priority) { |
| 84 | - r = strv_extend(&s->before, other->name); |
| 85 | + } else if (other->from_rcsd && !s->from_rcsd) { |
| 86 | + r = strv_extend(&s->after, other->name); |
| 87 | if (r < 0) |
| 88 | return log_oom(); |
| 89 | - } |
| 90 | - else |
| 91 | - continue; |
| 92 | + } else { |
| 93 | + if (other->sysv_start_priority < s->sysv_start_priority) { |
| 94 | + r = strv_extend(&s->after, other->name); |
| 95 | + if (r < 0) |
| 96 | + return log_oom(); |
| 97 | + } |
| 98 | + else if (other->sysv_start_priority > s->sysv_start_priority) { |
| 99 | + r = strv_extend(&s->before, other->name); |
| 100 | + if (r < 0) |
| 101 | + return log_oom(); |
| 102 | + } |
| 103 | + else |
| 104 | + continue; |
| 105 | + } |
| 106 | |
| 107 | /* FIXME: Maybe we should compare the name here lexicographically? */ |
| 108 | } |
| 109 | @@ -778,6 +799,8 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) { |
| 110 | return log_oom(); |
| 111 | |
| 112 | service->sysv_start_priority = -1; |
| 113 | + service->default_dependencies = true; |
| 114 | + service->from_rcsd = false; |
| 115 | service->name = name; |
| 116 | service->path = fpath; |
| 117 | |
| 118 | @@ -864,9 +887,11 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) { |
| 119 | |
| 120 | if (de->d_name[0] == 'S') { |
| 121 | |
| 122 | - if (rcnd_table[i].type == RUNLEVEL_UP) { |
| 123 | + if (rcnd_table[i].type == RUNLEVEL_UP || rcnd_table[i].type == RUNLEVEL_SYSINIT) { |
| 124 | service->sysv_start_priority = |
| 125 | MAX(a*10 + b, service->sysv_start_priority); |
| 126 | + service->default_dependencies = (rcnd_table[i].type == RUNLEVEL_SYSINIT)?false:true; |
| 127 | + service->from_rcsd = (rcnd_table[i].type == RUNLEVEL_SYSINIT)?true:false; |
| 128 | } |
| 129 | |
| 130 | r = set_ensure_allocated(&runlevel_services[i], NULL); |
| 131 | @@ -878,7 +903,8 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) { |
| 132 | goto finish; |
| 133 | |
| 134 | } else if (de->d_name[0] == 'K' && |
| 135 | - (rcnd_table[i].type == RUNLEVEL_DOWN)) { |
| 136 | + (rcnd_table[i].type == RUNLEVEL_DOWN || |
| 137 | + rcnd_table[i].type == RUNLEVEL_SYSINIT)) { |
| 138 | |
| 139 | r = set_ensure_allocated(&shutdown_services, NULL); |
| 140 | if (r < 0) |
| 141 | -- |
| 142 | 2.1.4 |
| 143 | |