mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
Fix #352: separate runlevel S from runlevel 0
Due to an old design decision runlevel S was encoded internally as '0', meaning it was the same as halt/poweroff. If you want to run scripts at system shutdown this was less then ideal since it meant your scripts also ran at bootstrap. This change is quite invasive. It introduces INIT_LEVEL (10) as the value for runlevel S, meaning all code that parses and/or evaluates anything for runlevel 0/S was affected and had to be reworked. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -244,7 +244,7 @@ networking here. The configured `runlevel NUM` from `/etc/finit.conf`
|
||||
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
|
||||
given on the kernel cmdline, in which case runlevel 1 is started.
|
||||
|
||||
All services in runlevel S(0) are started first, followed by the desired
|
||||
All services in runlevel S) are started first, followed by the desired
|
||||
run-time runlevel. Run tasks in runlevel S can be started in sequence
|
||||
by using `run [S] cmd`. Changing runlevels at runtime is done like any
|
||||
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
|
||||
@@ -585,24 +585,24 @@ scripting and documentation:
|
||||
|
||||
```
|
||||
alpine:~# initctl -p
|
||||
PID IDENT STATUS RUNLEVELS DESCRIPTION
|
||||
PID IDENT STATUS RUNLEVELS DESCRIPTION
|
||||
======================================================================
|
||||
1506 acpid running [--2345----] ACPI daemon
|
||||
1509 crond running [--2345----] Cron daemon
|
||||
1489 dropbear running [--2345----] Dropbear SSH daemon
|
||||
1511 klogd running [S12345----] Kernel log daemon
|
||||
1512 ntpd running [--2345----] NTP daemon
|
||||
1473 syslogd running [S12345----] Syslog daemon
|
||||
1506 acpid running [---2345----] ACPI daemon
|
||||
1509 crond running [---2345----] Cron daemon
|
||||
1489 dropbear running [---2345----] Dropbear SSH daemon
|
||||
1511 klogd running [S-12345----] Kernel log daemon
|
||||
1512 ntpd running [---2345----] NTP daemon
|
||||
1473 syslogd running [S-12345----] Syslog daemon
|
||||
|
||||
alpine:~# initctl -pv
|
||||
PID IDENT STATUS RUNLEVELS COMMAND
|
||||
PID IDENT STATUS RUNLEVELS COMMAND
|
||||
======================================================================
|
||||
1506 acpid running [--2345----] acpid -f
|
||||
1509 crond running [--2345----] crond -f -S $CRON_OPTS
|
||||
1489 dropbear running [--2345----] dropbear -R -F $DROPBEAR_OPTS
|
||||
1511 klogd running [S12345----] klogd -n $KLOGD_OPTS
|
||||
1512 ntpd running [--2345----] ntpd -n $NTPD_OPTS
|
||||
1473 syslogd running [S12345----] syslogd -n
|
||||
1506 acpid running [---2345----] acpid -f
|
||||
1509 crond running [---2345----] crond -f -S $CRON_OPTS
|
||||
1489 dropbear running [---2345----] dropbear -R -F $DROPBEAR_OPTS
|
||||
1511 klogd running [S-12345----] klogd -n $KLOGD_OPTS
|
||||
1512 ntpd running [---2345----] ntpd -n $NTPD_OPTS
|
||||
1473 syslogd running [S-12345----] syslogd -n
|
||||
```
|
||||
|
||||
The environment variables to each of the services above are read from,
|
||||
@@ -627,7 +627,7 @@ Condition(s):
|
||||
User : root
|
||||
Group : root
|
||||
Uptime : 2 hour 46 min 56 sec
|
||||
Runlevels : [--2345----]
|
||||
Runlevels : [---2345----]
|
||||
Memory : 1.2M
|
||||
CGroup : /system/dropbear cpu 0 [100, max] mem [--.--, max]
|
||||
|- 1485 dropbear -R -F
|
||||
|
||||
@@ -375,7 +375,7 @@ static void api_cb(uev_t *w, void *arg, int events)
|
||||
case INIT_CMD_HALT:
|
||||
case INIT_CMD_POWEROFF:
|
||||
case INIT_CMD_SUSPEND:
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
if (IS_RESERVED_RUNLEVEL(runlevel)) {
|
||||
warnx("Unsupported command in runlevel S and 6.");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
+7
-6
@@ -48,7 +48,7 @@
|
||||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
#define BOOTSTRAP (runlevel == 0)
|
||||
#define BOOTSTRAP (runlevel == INIT_LEVEL)
|
||||
|
||||
int logfile_size_max = 200000; /* 200 kB */
|
||||
int logfile_count_max = 5;
|
||||
@@ -475,7 +475,7 @@ static void kmod_load(char *mod)
|
||||
char module[64] = { 0 };
|
||||
char cmd[CMD_SIZE];
|
||||
|
||||
if (runlevel != 0)
|
||||
if (runlevel != INIT_LEVEL)
|
||||
return;
|
||||
|
||||
/* Strip args for progress below and kmod_exists() */
|
||||
@@ -508,15 +508,16 @@ int conf_parse_runlevels(char *runlevels)
|
||||
break;
|
||||
if ('!' == lvl) {
|
||||
not = 1;
|
||||
bitmask = 0x3FE;
|
||||
bitmask = 0x7FE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('s' == lvl || 'S' == lvl)
|
||||
lvl = '0';
|
||||
level = INIT_LEVEL;
|
||||
else
|
||||
level = lvl - '0';
|
||||
|
||||
level = lvl - '0';
|
||||
if (level > 9 || level < 0)
|
||||
if (level > INIT_LEVEL || level < 0)
|
||||
continue;
|
||||
|
||||
if (not)
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@
|
||||
#include "utmp-api.h"
|
||||
#include "schedule.h"
|
||||
|
||||
int runlevel = 0; /* Bootstrap 'S' */
|
||||
int runlevel = INIT_LEVEL; /* Bootstrap 'S' */
|
||||
int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */
|
||||
int cmdlevel = 0; /* runlevel override from cmdline */
|
||||
int prevlevel = -1;
|
||||
|
||||
+2
-1
@@ -63,10 +63,11 @@
|
||||
#define LINE_SIZE 1024
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
/* We extend the INIT_CMD_ range for the new initctl tool. */
|
||||
#define INIT_SOCKET _PATH_VARRUN "finit/socket"
|
||||
#define INIT_MAGIC 0x03091969
|
||||
#define INIT_LEVEL 10
|
||||
|
||||
/* We extend the INIT_CMD_ range for the new initctl tool. */
|
||||
#define INIT_CMD_START 0
|
||||
#define INIT_CMD_RUNLVL 1
|
||||
#define INIT_CMD_POWERFAIL 2
|
||||
|
||||
+24
-10
@@ -761,17 +761,18 @@ static int plugins_list(char *arg)
|
||||
char *runlevel_string(int currlevel, int levels)
|
||||
{
|
||||
static char lvl[21];
|
||||
int i, pos = 1;
|
||||
int i = INIT_LEVEL;
|
||||
int pos = 1;
|
||||
|
||||
memset(lvl, 0, sizeof(lvl));
|
||||
lvl[0] = '[';
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
do {
|
||||
if (ISSET(levels, i)) {
|
||||
if (!plain && currlevel == i)
|
||||
pos = strlcat(lvl, "\e[1m", sizeof(lvl));
|
||||
|
||||
if (i == 0)
|
||||
if (i == INIT_LEVEL)
|
||||
lvl[pos++] = 'S';
|
||||
else
|
||||
lvl[pos++] = '0' + i;
|
||||
@@ -781,7 +782,14 @@ char *runlevel_string(int currlevel, int levels)
|
||||
} else {
|
||||
lvl[pos++] = '-';
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: ugly hack to get order right: S0123456789 */
|
||||
if (i == INIT_LEVEL)
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
} while (i < INIT_LEVEL);
|
||||
|
||||
|
||||
lvl[pos++] = ']';
|
||||
lvl[pos] = 0;
|
||||
@@ -792,18 +800,24 @@ char *runlevel_string(int currlevel, int levels)
|
||||
char *runlevel_arr(int levels)
|
||||
{
|
||||
static char lvl[42];
|
||||
int i = INIT_LEVEL;
|
||||
int p = 2, s = 0;
|
||||
|
||||
strlcpy(lvl, "[ ", sizeof(lvl));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
do {
|
||||
if (ISSET(levels, i)) {
|
||||
if (i == 0)
|
||||
if (i == INIT_LEVEL)
|
||||
p += snprintf(&lvl[p], sizeof(lvl) - p, "\"S\"");
|
||||
else
|
||||
p += snprintf(&lvl[p], sizeof(lvl) - p, "%s%c", s ? ", " : "", '0' + i);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
/* XXX: ugly hack to get order right: S0123456789 */
|
||||
if (i == INIT_LEVEL)
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
} while (i < INIT_LEVEL);
|
||||
strlcat(lvl, " ]", sizeof(lvl));
|
||||
|
||||
return lvl;
|
||||
@@ -1162,7 +1176,7 @@ static int show_status(char *arg)
|
||||
if (heading) {
|
||||
char title[80];
|
||||
|
||||
snprintf(title, sizeof(title), "%-*s %-*s %-8s %-12s ",
|
||||
snprintf(title, sizeof(title), "%-*s %-*s %-8s %-13s ",
|
||||
pw, "PID", iw, "IDENT", "STATUS", "RUNLEVELS");
|
||||
if (!verbose)
|
||||
strlcat(title, "DESCRIPTION", sizeof(title));
|
||||
@@ -1184,9 +1198,9 @@ static int show_status(char *arg)
|
||||
|
||||
lvls = runlevel_string(runlevel, svc->runlevels);
|
||||
if (strchr(lvls, '\e'))
|
||||
printf("%-20.20s ", lvls);
|
||||
printf("%-21.21s ", lvls);
|
||||
else
|
||||
printf("%-12.12s ", lvls);
|
||||
printf("%-13.13s ", lvls);
|
||||
|
||||
if (!verbose)
|
||||
puts(svc->desc);
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#define MATCH_CMD(l, c, x) \
|
||||
(!strncasecmp(l, c, strlen(c)) && (x = (l) + strlen(c)))
|
||||
|
||||
#define IS_RESERVED_RUNLEVEL(l) (l == 0 || l == 6 || l == INIT_LEVEL)
|
||||
|
||||
extern char *finit_conf;
|
||||
extern char *finit_rcsd;
|
||||
extern svc_t *wdog;
|
||||
|
||||
+4
-4
@@ -1051,7 +1051,7 @@ static int service_restart(svc_t *svc)
|
||||
}
|
||||
|
||||
/* Skip progress if desc disabled or bootstrap task */
|
||||
if (!svc->desc[0] || svc_in_runlevel(svc, 0))
|
||||
if (!svc->desc[0] || svc_in_runlevel(svc, INIT_LEVEL))
|
||||
do_progress = 0;
|
||||
|
||||
if (do_progress)
|
||||
@@ -1106,13 +1106,13 @@ void service_reload_dynamic(void)
|
||||
*/
|
||||
void service_runlevel(int newlevel)
|
||||
{
|
||||
if (!rescue && runlevel <= 1 && newlevel > 1)
|
||||
if (!rescue && (runlevel == 1 || runlevel == INIT_LEVEL) && !IS_RESERVED_RUNLEVEL(newlevel))
|
||||
networking(1);
|
||||
|
||||
sm_set_runlevel(&sm, newlevel);
|
||||
sm_step(&sm);
|
||||
|
||||
if (!rescue && (runlevel <= 1 || runlevel == 6))
|
||||
if (!rescue && IS_RESERVED_RUNLEVEL(runlevel))
|
||||
networking(0);
|
||||
}
|
||||
|
||||
@@ -1538,7 +1538,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
id = "";
|
||||
|
||||
levels = conf_parse_runlevels(runlevels);
|
||||
if (runlevel > 0 && !ISOTHER(levels, 0)) {
|
||||
if (runlevel != INIT_LEVEL && !ISOTHER(levels, 0)) {
|
||||
dbg("Skipping %s%s%s, bootstrap is completed.",
|
||||
name, id[0] ? ":" : "", id[0] ? id : "");
|
||||
return 0;
|
||||
|
||||
@@ -429,7 +429,7 @@ static void sighup_cb(uev_t *w, void *arg, int events)
|
||||
return;
|
||||
}
|
||||
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
if (IS_RESERVED_RUNLEVEL(runlevel)) {
|
||||
warnx("SIGHUP ignored in runlevel S and 6.");
|
||||
return;
|
||||
}
|
||||
@@ -485,7 +485,7 @@ static void sigusr1_cb(uev_t *w, void *arg, int events)
|
||||
return;
|
||||
}
|
||||
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
if (IS_RESERVED_RUNLEVEL(runlevel)) {
|
||||
warnx("SIGUSR1 ignored in runlevel S and 6.");
|
||||
return;
|
||||
}
|
||||
@@ -506,7 +506,7 @@ static void sigusr2_cb(uev_t *w, void *arg, int events)
|
||||
return;
|
||||
}
|
||||
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
if (IS_RESERVED_RUNLEVEL(runlevel)) {
|
||||
warnx("SIGUSR2 ignored in runlevel S and 6.");
|
||||
return;
|
||||
}
|
||||
@@ -526,7 +526,7 @@ static void sigterm_cb(uev_t *w, void *arg, int events)
|
||||
return;
|
||||
}
|
||||
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
if (IS_RESERVED_RUNLEVEL(runlevel)) {
|
||||
warnx("SIGTERM ignored in runlevel S and 6.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,10 +86,10 @@ static char *sm_status(sm_state_t state)
|
||||
*/
|
||||
static void nologin(void)
|
||||
{
|
||||
if (runlevel == 1 || runlevel == 0 || runlevel == 6)
|
||||
if (runlevel == 1 || IS_RESERVED_RUNLEVEL(runlevel))
|
||||
touch(FINIT_NOLOGIN_PATH);
|
||||
|
||||
if (prevlevel == 1 || prevlevel == 0 || prevlevel == 6)
|
||||
if (prevlevel == 1 || IS_RESERVED_RUNLEVEL(prevlevel))
|
||||
erase(FINIT_NOLOGIN_PATH);
|
||||
}
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ void svc_clean_dynamic(void (*cb)(svc_t *))
|
||||
*/
|
||||
int svc_clean_bootstrap(svc_t *svc)
|
||||
{
|
||||
if (!ISOTHER(svc->runlevels, 0)) {
|
||||
if (!ISOTHER(svc->runlevels, INIT_LEVEL)) {
|
||||
svc->pid = 0;
|
||||
svc_del(svc);
|
||||
return 1;
|
||||
|
||||
+3
-1
@@ -32,6 +32,7 @@
|
||||
# include <lite/lite.h>
|
||||
#endif
|
||||
|
||||
#include "finit.h"
|
||||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
#include "utmp-api.h"
|
||||
@@ -174,7 +175,8 @@ int utmp_set_dead(int pid)
|
||||
|
||||
static int encode(int lvl)
|
||||
{
|
||||
if (!lvl) return 0;
|
||||
if (lvl == INIT_LEVEL)
|
||||
return 0;
|
||||
return lvl + '0';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user