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);
+ 

Reply via email to