You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
4.0 KiB
100 lines
4.0 KiB
2 years ago
|
From 99ca5b681fceedd010b2616b1248a483f4bfbd97 Mon Sep 17 00:00:00 2001
|
||
|
From: Kairui Song <kasong@redhat.com>
|
||
|
Date: Wed, 13 Jan 2021 00:04:53 +0800
|
||
|
Subject: [PATCH] initrd: extend SYSTEMD_IN_INITRD to accept non-ramfs rootfs
|
||
|
|
||
|
Sometimes, non-ramfs initrd root are useful. Eg, for kdump, because
|
||
|
initramfs is memory consuming, so mount a compressed image in earlier
|
||
|
initrd, chroot into it then let systemd do the rest of job is a good
|
||
|
solution.
|
||
|
|
||
|
But systemd doesn't recognize the initrd environment if rootfs is not a
|
||
|
temporary fs. This is a reasonable check, because switch-root in initrd
|
||
|
will wipe the whole rootfs, will be a disaster if there are any
|
||
|
misdetect.
|
||
|
|
||
|
So extend SYSTEMD_IN_INITRD environment variable, now it accepts boolean
|
||
|
value and two extra keyword, "auto" and "lenient". "auto" is same as
|
||
|
before, and it's the default value. "lenient" will let systemd bypass
|
||
|
the rootfs check.
|
||
|
|
||
|
(cherry picked from commit db4c45cf4f10ca094b9e9570b758abd445d65381)
|
||
|
|
||
|
Related: #1959339
|
||
|
---
|
||
|
doc/ENVIRONMENT.md | 8 ++++++++
|
||
|
src/basic/util.c | 28 +++++++++++++++++++++++++---
|
||
|
2 files changed, 33 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md
|
||
|
index 36b649afe1..8d7ce6ae2c 100644
|
||
|
--- a/doc/ENVIRONMENT.md
|
||
|
+++ b/doc/ENVIRONMENT.md
|
||
|
@@ -37,6 +37,14 @@ All tools:
|
||
|
useful for debugging, in order to test generators and other code against
|
||
|
specific kernel command lines.
|
||
|
|
||
|
+* `$SYSTEMD_IN_INITRD=[auto|lenient|0|1]` — if set, specifies initrd detection
|
||
|
+ method. Defaults to `auto`. Behavior is defined as follows:
|
||
|
+ `auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted
|
||
|
+ on `/`. If both conditions meet, then it's in initrd.
|
||
|
+ `lenient`: Similiar to `auto`, but the rootfs check is skipped.
|
||
|
+ `0|1`: Simply overrides initrd detection. This is useful for debugging and
|
||
|
+ testing initrd-only programs in the main system.
|
||
|
+
|
||
|
* `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will
|
||
|
not output graphical smiley emojis, but ASCII alternatives instead. Note that
|
||
|
this only controls use of Unicode emoji glyphs, and has no effect on other
|
||
|
diff --git a/src/basic/util.c b/src/basic/util.c
|
||
|
index b443e639f3..59bcf7b00c 100644
|
||
|
--- a/src/basic/util.c
|
||
|
+++ b/src/basic/util.c
|
||
|
@@ -130,11 +130,14 @@ int prot_from_flags(int flags) {
|
||
|
}
|
||
|
|
||
|
bool in_initrd(void) {
|
||
|
+ int r;
|
||
|
+ const char *e;
|
||
|
+ bool lenient = false;
|
||
|
|
||
|
if (saved_in_initrd >= 0)
|
||
|
return saved_in_initrd;
|
||
|
|
||
|
- /* We make two checks here:
|
||
|
+ /* We have two checks here:
|
||
|
*
|
||
|
* 1. the flag file /etc/initrd-release must exist
|
||
|
* 2. the root file system must be a memory file system
|
||
|
@@ -142,10 +145,29 @@ bool in_initrd(void) {
|
||
|
* The second check is extra paranoia, since misdetecting an
|
||
|
* initrd can have bad consequences due the initrd
|
||
|
* emptying when transititioning to the main systemd.
|
||
|
+ *
|
||
|
+ * If env var $SYSTEMD_IN_INITRD is not set or set to "auto",
|
||
|
+ * both checks are used. If it's set to "lenient", only check
|
||
|
+ * 1 is used. If set to a booleen value, then the boolean
|
||
|
+ * value is returned.
|
||
|
*/
|
||
|
|
||
|
- saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 &&
|
||
|
- path_is_temporary_fs("/") > 0;
|
||
|
+ e = secure_getenv("SYSTEMD_IN_INITRD");
|
||
|
+ if (e) {
|
||
|
+ if (streq(e, "lenient"))
|
||
|
+ lenient = true;
|
||
|
+ else if (!streq(e, "auto")) {
|
||
|
+ r = parse_boolean(e);
|
||
|
+ if (r >= 0) {
|
||
|
+ saved_in_initrd = r > 0;
|
||
|
+ return saved_in_initrd;
|
||
|
+ }
|
||
|
+ log_debug_errno(r, "Failed to parse $SYSTEMD_IN_INITRD, ignoring: %m");
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ saved_in_initrd = (lenient || path_is_temporary_fs("/") > 0) &&
|
||
|
+ access("/etc/initrd-release", F_OK) >= 0;
|
||
|
|
||
|
return saved_in_initrd;
|
||
|
}
|