mirror of
https://github.com/troglobit/finit.git
synced 2026-11-06 15:51:03 +00:00
Add support for a rescue (recovery) mode from kernel cmdline
This patch adds a rescue (revovery) mode to Finit. Simply add `rescue` to the kernel cmdline at boot and the following steps at bootstrap will be skipped: - Load of services/run/task/etc in /etc/finit.conf + /etc/finit.d/*.conf - fsck of filesystems in /etc/fstab - Remount of / to read-write - Mount of all filesystems in /etc/fstab - swapon - A few plugin hooks: - HOOK_ROOTFS_UP - HOOK_MOUNT_ERROR - HOOK_BASEFS_UP - `runparts DIR` - /etc/rc.local Instead of loading /etc/finit.conf and /etc/finit.d/*.conf Finit loads the file /lib/finit/rescue.conf, which can be overridden by the operator if needed. If this file is removed (or lost), Finit falls back to start a simple root shell, without any login. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
bc149d95fc
commit
ab723d2f31
7 files changed
+58
-23
No files matched your search
@@ -217,6 +217,9 @@ AC_EXPAND_DIR(plugin_path, "$libdir/finit/plugins")
|
|||||||
AC_SUBST(plugin_path)
|
AC_SUBST(plugin_path)
|
||||||
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
|
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
|
||||||
|
|
||||||
|
AC_EXPAND_DIR(rescue_conf, "$libdir/finit/rescue.conf")
|
||||||
|
AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
|
||||||
|
|
||||||
# Generate all files
|
# Generate all files
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ can also be used.
|
|||||||
General
|
General
|
||||||
-------
|
-------
|
||||||
|
|
||||||
* Add support for `rescue` on the kernel command line, start rescue mode
|
|
||||||
if enabled with `configure` script. Could mean skip `/etc/finit.conf`
|
|
||||||
et al and jump straight to a single getty login on console.
|
|
||||||
* Add support for timed shutdown in Finit, including cancelled shutdown.
|
* Add support for timed shutdown in Finit, including cancelled shutdown.
|
||||||
* SysV init and systemd use SIGUSR1 to restart their FIFO/D-Bus. Add
|
* SysV init and systemd use SIGUSR1 to restart their FIFO/D-Bus. Add
|
||||||
API restart to SIGHUP callback for the same functionality in Finit.
|
API restart to SIGHUP callback for the same functionality in Finit.
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ REBOOT_LNKS = shutdown halt poweroff suspend
|
|||||||
|
|
||||||
# Hook in install to add finit and reboot symlink(s)
|
# Hook in install to add finit and reboot symlink(s)
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
|
@$(INSTALL_DATA) $(srcdir)/rescue.conf $(DESTDIR)$(pkglibdir)
|
||||||
@for file in $(INIT_LNKS); do \
|
@for file in $(INIT_LNKS); do \
|
||||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||||
if [ -e $$lnk ]; then \
|
if [ -e $$lnk ]; then \
|
||||||
@@ -80,6 +81,7 @@ install-exec-hook:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
uninstall-hook:
|
uninstall-hook:
|
||||||
|
@$(RM) $(DESTDIR)$(pkglibdir)/rescue.conf
|
||||||
@for file in $(INIT_LNKS); do \
|
@for file in $(INIT_LNKS); do \
|
||||||
lnk=`readlink $(DESTDIR)$(sbindir)/$$file`; \
|
lnk=`readlink $(DESTDIR)$(sbindir)/$$file`; \
|
||||||
if [ "$$lnk" != "finit" ]; then \
|
if [ "$$lnk" != "finit" ]; then \
|
||||||
|
|||||||
+20
@@ -78,6 +78,9 @@ void conf_parse_cmdline(void)
|
|||||||
/* Catches finit_debug (deprecated), --debug, and debug */
|
/* Catches finit_debug (deprecated), --debug, and debug */
|
||||||
if (strstr(tok, "debug"))
|
if (strstr(tok, "debug"))
|
||||||
dbg = 1;
|
dbg = 1;
|
||||||
|
|
||||||
|
if (strstr(tok, "rescue") || strstr(tok, "recover"))
|
||||||
|
rescue = 1;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
@@ -551,6 +554,19 @@ int conf_reload(void)
|
|||||||
svc_mark_dynamic();
|
svc_mark_dynamic();
|
||||||
tty_mark();
|
tty_mark();
|
||||||
|
|
||||||
|
if (rescue) {
|
||||||
|
int rc;
|
||||||
|
char line[80] = "tty [12345] @console noclear nologin";
|
||||||
|
|
||||||
|
/* If rescue.conf is missing, fall back to a root shell */
|
||||||
|
rc = parse_conf(RESCUE_CONF);
|
||||||
|
if (rc)
|
||||||
|
tty_register(line, global_rlimit, NULL);
|
||||||
|
|
||||||
|
print(rc, "Entering rescue mode");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* First, read /etc/finit.conf */
|
/* First, read /etc/finit.conf */
|
||||||
parse_conf(FINIT_CONF);
|
parse_conf(FINIT_CONF);
|
||||||
|
|
||||||
@@ -795,6 +811,10 @@ int conf_monitor(uev_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
/* Skip second run, when called from finit.c in rescue mode */
|
||||||
|
if (ctx && rescue)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If only one watcher fails, that's OK. A user may have only
|
* If only one watcher fails, that's OK. A user may have only
|
||||||
* one of /etc/finit.conf or /etc/finit.d in use, and may also
|
* one of /etc/finit.conf or /etc/finit.d in use, and may also
|
||||||
|
|||||||
+29
-20
@@ -53,6 +53,7 @@ int wdogpid = 0; /* No watchdog by default */
|
|||||||
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 prevlevel = -1;
|
int prevlevel = -1;
|
||||||
|
int rescue = 0; /* rescue mode from kernel cmdline */
|
||||||
char *sdown = NULL;
|
char *sdown = NULL;
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
@@ -262,18 +263,20 @@ static void finalize(void)
|
|||||||
/*
|
/*
|
||||||
* Network stuff
|
* Network stuff
|
||||||
*/
|
*/
|
||||||
_d("Setting up networking ...");
|
if (!rescue) {
|
||||||
networking();
|
_d("Setting up networking ...");
|
||||||
umask(022);
|
networking();
|
||||||
|
|
||||||
/* Hooks that rely on loopback, or basic networking being up. */
|
/* Hooks that rely on loopback, or basic networking being up. */
|
||||||
_d("Calling all network up hooks ...");
|
_d("Calling all network up hooks ...");
|
||||||
plugin_run_hooks(HOOK_NETWORK_UP);
|
plugin_run_hooks(HOOK_NETWORK_UP);
|
||||||
|
}
|
||||||
|
umask(022);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run startup scripts in the runparts directory, if any.
|
* Run startup scripts in the runparts directory, if any.
|
||||||
*/
|
*/
|
||||||
if (runparts && fisdir(runparts)) {
|
if (runparts && fisdir(runparts) && !rescue) {
|
||||||
_d("Running startup scripts in %s ...", runparts);
|
_d("Running startup scripts in %s ...", runparts);
|
||||||
run_parts(runparts, NULL);
|
run_parts(runparts, NULL);
|
||||||
if (conf_any_change())
|
if (conf_any_change())
|
||||||
@@ -296,7 +299,7 @@ static void finalize(void)
|
|||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
/* Convenient SysV compat for when you just don't care ... */
|
/* Convenient SysV compat for when you just don't care ... */
|
||||||
if (!access(FINIT_RC_LOCAL, X_OK)) {
|
if (!access(FINIT_RC_LOCAL, X_OK) && !rescue) {
|
||||||
run_interactive(FINIT_RC_LOCAL, "Calling %s", FINIT_RC_LOCAL);
|
run_interactive(FINIT_RC_LOCAL, "Calling %s", FINIT_RC_LOCAL);
|
||||||
if (conf_any_change())
|
if (conf_any_change())
|
||||||
service_reload_dynamic();
|
service_reload_dynamic();
|
||||||
@@ -385,7 +388,7 @@ int main(int argc, char* argv[])
|
|||||||
/*
|
/*
|
||||||
* Check file filesystems in /etc/fstab
|
* Check file filesystems in /etc/fstab
|
||||||
*/
|
*/
|
||||||
for (int pass = 1; pass < 10; pass++) {
|
for (int pass = 1; pass < 10 && !rescue; pass++) {
|
||||||
if (fsck(pass))
|
if (fsck(pass))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -479,12 +482,14 @@ int main(int argc, char* argv[])
|
|||||||
/*
|
/*
|
||||||
* Mount filesystems
|
* Mount filesystems
|
||||||
*/
|
*/
|
||||||
|
if (!rescue) {
|
||||||
#ifdef REMOUNT_ROOTFS
|
#ifdef REMOUNT_ROOTFS
|
||||||
run("mount -n -o remount,rw /");
|
run("mount -n -o remount,rw /");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SYSROOT
|
#ifdef SYSROOT
|
||||||
mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Debian has this little script to copy generated rules while the system was read-only */
|
/* Debian has this little script to copy generated rules while the system was read-only */
|
||||||
if (fexist("/lib/udev/udev-finish"))
|
if (fexist("/lib/udev/udev-finish"))
|
||||||
@@ -493,15 +498,17 @@ int main(int argc, char* argv[])
|
|||||||
/* Bootstrap conditions, needed for hooks */
|
/* Bootstrap conditions, needed for hooks */
|
||||||
cond_init();
|
cond_init();
|
||||||
|
|
||||||
_d("Root FS up, calling hooks ...");
|
if (!rescue) {
|
||||||
plugin_run_hooks(HOOK_ROOTFS_UP);
|
_d("Root FS up, calling hooks ...");
|
||||||
|
plugin_run_hooks(HOOK_ROOTFS_UP);
|
||||||
|
|
||||||
umask(0);
|
umask(0);
|
||||||
if (run_interactive("mount -na", "Mounting filesystems"))
|
if (run_interactive("mount -na", "Mounting filesystems"))
|
||||||
plugin_run_hooks(HOOK_MOUNT_ERROR);
|
plugin_run_hooks(HOOK_MOUNT_ERROR);
|
||||||
|
|
||||||
run("swapon -ea");
|
run("swapon -ea");
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
}
|
||||||
|
|
||||||
/* Base FS up, enable standard SysV init signals */
|
/* Base FS up, enable standard SysV init signals */
|
||||||
sig_setup(&loop);
|
sig_setup(&loop);
|
||||||
@@ -512,8 +519,10 @@ int main(int argc, char* argv[])
|
|||||||
*/
|
*/
|
||||||
conf_monitor(&loop);
|
conf_monitor(&loop);
|
||||||
|
|
||||||
_d("Base FS up, calling hooks ...");
|
if (!rescue) {
|
||||||
plugin_run_hooks(HOOK_BASEFS_UP);
|
_d("Base FS up, calling hooks ...");
|
||||||
|
plugin_run_hooks(HOOK_BASEFS_UP);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initalize state machine and start all bootstrap tasks
|
* Initalize state machine and start all bootstrap tasks
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ extern int wdogpid;
|
|||||||
extern int runlevel;
|
extern int runlevel;
|
||||||
extern int cfglevel;
|
extern int cfglevel;
|
||||||
extern int prevlevel;
|
extern int prevlevel;
|
||||||
|
extern int rescue;
|
||||||
extern char *rcsd;
|
extern char *rcsd;
|
||||||
extern char *sdown;
|
extern char *sdown;
|
||||||
extern char *network;
|
extern char *network;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
runlevel 1
|
||||||
|
hostname rescue
|
||||||
|
tty [12345] @console noclear nologin
|
||||||
Reference in new issue
Block a user