commit: ab6d73225f21be7d55649363ceb460d91270638d Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> AuthorDate: Mon Feb 8 01:25:50 2021 +0000 Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> CommitDate: Mon Feb 8 21:20:28 2021 +0000 URL: https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=ab6d7322
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 <AT> gentoo.org> defaults/initrd.defaults | 1 + defaults/linuxrc | 15 +++++++++++ doc/genkernel.8.txt | 6 +++++ ....1-switch_root-check-if-mountpoint-exists.patch | 31 ++++++++++++++++++++++ 4 files changed, 53 insertions(+) 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); +