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