aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2021-02-08 02:25:50 +0100
committerThomas Deutschmann <whissi@gentoo.org>2021-02-08 22:20:28 +0100
commitab6d73225f21be7d55649363ceb460d91270638d (patch)
tree9b653f50497464c7cafc04620f431e1c5bb66b43
parentlinuxrc: add kernel command-line argument to allow user to pass additional op... (diff)
downloadgenkernel-ab6d73225f21be7d55649363ceb460d91270638d.tar.gz
genkernel-ab6d73225f21be7d55649363ceb460d91270638d.tar.bz2
genkernel-ab6d73225f21be7d55649363ceb460d91270638d.zip
linuxrc: Add gk.preserverun.disabled
When this boolean option is set and enabled, genkernel initramfs will unmount /run before calling switch_root. This can help in SELinux context for example where labeling is required which is not supported by genkernel. Bug: https://bugs.gentoo.org/739424 Bug: https://bugs.gentoo.org/740576 Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
-rw-r--r--defaults/initrd.defaults1
-rw-r--r--defaults/linuxrc15
-rw-r--r--doc/genkernel.8.txt6
-rw-r--r--patches/util-linux/2.36.1/util-linux-2.36.1-switch_root-check-if-mountpoint-exists.patch31
4 files changed, 53 insertions, 0 deletions
diff --git a/defaults/initrd.defaults b/defaults/initrd.defaults
index ac3b072..7ee78e9 100644
--- a/defaults/initrd.defaults
+++ b/defaults/initrd.defaults
@@ -87,6 +87,7 @@ GK_NET_TIMEOUT_DAD=10
GK_NET_TIMEOUT_DECONFIGURATION=10
GK_NET_TIMEOUT_DHCP=10
GK_NET_TIMEOUT_INTERFACE=10
+GK_PRESERVE_RUN=1
GK_PROMPT_FILE='/tmp/current_prompt'
GK_PROMPT_TIMEOUT=0
GK_ROOTFS_DETECTED_STATEFILE="/tmp/rootfs.detected"
diff --git a/defaults/linuxrc b/defaults/linuxrc
index e33576d..d8fee73 100644
--- a/defaults/linuxrc
+++ b/defaults/linuxrc
@@ -372,6 +372,15 @@ do
fi
unset tmp_disabled
;;
+ gk.preserverun.disabled=*)
+ tmp_disabled=${x#*=}
+ if is_true "${tmp_disabled}"
+ then
+ warn_msg "gk.preserverun.disabled is set; /run will not be moved to newroot!"
+ GK_PRESERVE_RUN=0
+ fi
+ unset tmp_disabled
+ ;;
gk.prompt.timeout=*)
tmp_timeout=${x#*=}
if is_int "${tmp_timeout}"
@@ -1336,6 +1345,12 @@ fi
# Run debug shell if requested
rundebugshell "before entering switch_root"
+if [ "${GK_PRESERVE_RUN}" = '0' ]
+then
+ GK_INIT_LOG=
+ run umount /run
+fi
+
# init_opts is set in the environment by the kernel when it parses the command line
init=${REAL_INIT:-/sbin/init}
if ! mountpoint "${CHROOT}" 1>/dev/null 2>&1
diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt
index ddccd9f..74729be 100644
--- a/doc/genkernel.8.txt
+++ b/doc/genkernel.8.txt
@@ -745,6 +745,12 @@ recognized by the kernel itself.
By default we will wait up to 120 seconds (UDEV default) for
UDEV event queue to become empty.
+*gk.preserverun.disabled*=<...>::
+ By default, *switch_root* will preserve and move already mounted '/run'
+ to *newroot*. This boolean option allows you to disable preserving of
+ '/run', which is maybe required for SELinux due to missing labeling
+ support in genkernel.
+
*gk.prompt.timeout*=<...>::
By default a prompt within genkernel initramfs like shown when set
*root* could not be found will never timeout. Use this option to set
diff --git a/patches/util-linux/2.36.1/util-linux-2.36.1-switch_root-check-if-mountpoint-exists.patch b/patches/util-linux/2.36.1/util-linux-2.36.1-switch_root-check-if-mountpoint-exists.patch
new file mode 100644
index 0000000..17bcd91
--- /dev/null
+++ b/patches/util-linux/2.36.1/util-linux-2.36.1-switch_root-check-if-mountpoint-exists.patch
@@ -0,0 +1,31 @@
+switch_root: check if mount point to move even exists
+
+--- a/sys-utils/switch_root.c
++++ b/sys-utils/switch_root.c
+@@ -131,7 +131,12 @@ static int switchroot(const char *newroot)
+ int i;
+ int cfd;
+ pid_t pid;
+- struct stat newroot_stat, sb;
++ struct stat newroot_stat, oldroot_stat, sb;
++
++ if (stat("/", &oldroot_stat) != 0) {
++ warn(_("stat of %s failed"), "/");
++ return -1;
++ }
+
+ if (stat(newroot, &newroot_stat) != 0) {
+ warn(_("stat of %s failed"), newroot);
+@@ -143,6 +148,11 @@ static int switchroot(const char *newroot)
+
+ snprintf(newmount, sizeof(newmount), "%s%s", newroot, umounts[i]);
+
++ if ((stat(umounts[i], &sb) == 0) && sb.st_dev == oldroot_stat.st_dev) {
++ /* mount point to move seems to be a normal directory or stat failed */
++ continue;
++ }
++
+ if ((stat(newmount, &sb) != 0) || (sb.st_dev != newroot_stat.st_dev)) {
+ /* mount point seems to be mounted already or stat failed */
+ umount2(umounts[i], MNT_DETACH);
+