Fix #261: support for overriding default runlevel from command line

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2022-05-08 09:57:18 +02:00
1 parent 3ca6256f87
commit 0cce69892a
5 files changed
+58 -7

No files matched your search

+1 -1
View File
@@ -130,7 +130,7 @@ AC_ARG_WITH(hostname,
[hostname=$withval], [hostname=yes]) [hostname=$withval], [hostname=yes])
AC_ARG_WITH(runlevel, AC_ARG_WITH(runlevel,
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap, default: 2]), AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap [1-9], default: 2]),
[runlevel=$withval], [runlevel=yes]) [runlevel=$withval], [runlevel=yes])
AC_ARG_WITH(random-seed, AC_ARG_WITH(random-seed,
+6
View File
@@ -73,6 +73,12 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
`[1]` will be started, so a `tty [1] @console nologin` configuration `[1]` will be started, so a `tty [1] @console nologin` configuration
presents you with a root console without login. presents you with a root console without login.
* `1-9`, except `6`: override the configured `runlevel`. Like the `S`
and `rescue`, giving a single number on the kernel command line tells
Finit to ignore any `runlevel` in `/etc/finit.conf` as well as the
configure fallback `--with-runlevel=N` setting. Remember, `6` is the
reboot runlevel and is not permitted. Any other values are ignored.
For more on kernel boot parameters, see the man page [bootparam(7)][]. For more on kernel boot parameters, see the man page [bootparam(7)][].
[config.md]: config.md#rescue-mode [config.md]: config.md#rescue-mode
+37 -2
View File
@@ -134,6 +134,33 @@ static void parse_finit_opts(char *opt)
} }
} }
/*
* When runlevel (single integer) is given on the command line,
* it overrides the runlevel in finit.conf and the built-in
* default (from configure). It do however have to pass the
* same sanity checks.
*/
static int parse_runlevel(char *arg)
{
const char *err = NULL;
char *ptr = arg;
long long num;
/* Sanity check the token is just digit(s) */
while (*ptr) {
if (!isdigit(*ptr++))
return 0;
}
num = strtonum(arg, 1, 9, &err);
if (err || num == 6) {
_d("Not a valid runlevel (%s), valid levels are [1-9], excluding 6, skipping.", arg);
return 0;
}
return (int)num;
}
static void parse_arg(char *arg) static void parse_arg(char *arg)
{ {
if (!strncmp(arg, "finit.", 6)) { if (!strncmp(arg, "finit.", 6)) {
@@ -141,11 +168,19 @@ static void parse_arg(char *arg)
return; return;
} }
if (string_compare(arg, "rescue") || string_compare(arg, "recover")) if (string_compare(arg, "rescue") || string_compare(arg, "recover")) {
rescue = 1; rescue = 1;
return;
}
if (string_compare(arg, "single") || string_compare(arg, "S")) if (string_compare(arg, "single") || string_compare(arg, "S")) {
single = 1; single = 1;
return;
}
/* Put any new command line options before this line. */
cmdlevel = parse_runlevel(arg);
} }
#ifdef KERNEL_CMDLINE #ifdef KERNEL_CMDLINE
+13 -4
View File
@@ -62,6 +62,7 @@
int runlevel = 0; /* Bootstrap 'S' */ int runlevel = 0; /* Bootstrap 'S' */
int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */ int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */
int cmdlevel = 0; /* runlevel override from cmdline */
int prevlevel = -1; int prevlevel = -1;
int debug = 0; /* debug mode from kernel cmdline */ int debug = 0; /* debug mode from kernel cmdline */
int rescue = 0; /* rescue mode from kernel cmdline */ int rescue = 0; /* rescue mode from kernel cmdline */
@@ -569,11 +570,12 @@ static void crank_worker(void *unused)
*/ */
static void bootstrap_worker(void *work) static void bootstrap_worker(void *work)
{ {
static int cnt = 120;
static struct wq final = { static struct wq final = {
.cb = finalize, .cb = finalize,
.delay = 10 .delay = 10
}; };
static int cnt = 120;
int level = cfglevel;
_d("Step all services ..."); _d("Step all services ...");
service_step_all(SVC_TYPE_ANY); service_step_all(SVC_TYPE_ANY);
@@ -598,11 +600,18 @@ static void bootstrap_worker(void *work)
if (runparts && fisdir(runparts) && !rescue) if (runparts && fisdir(runparts) && !rescue)
run_parts(runparts, NULL); run_parts(runparts, NULL);
/* /*
* Start all tasks/services in the configured runlevel * Start all tasks/services in the configured runlevel, or jump
* into the runlevel selected from the command line.
*/ */
_d("Change to default runlevel(%d), starting all services ...", cfglevel); if (cmdlevel) {
service_runlevel(cfglevel); _d("Runlevel %d requested from command line, starting all services ...", cmdlevel);
level = cmdlevel;
} else
_d("Change to default runlevel(%d), starting all services ...", cfglevel);
service_runlevel(level);
} }
static int version(int rc) static int version(int rc)
+1
View File
@@ -110,6 +110,7 @@ struct init_request {
extern int runlevel; extern int runlevel;
extern int cfglevel; extern int cfglevel;
extern int cmdlevel;
extern int prevlevel; extern int prevlevel;
extern int debug; extern int debug;
extern int rescue; extern int rescue;