commit:     848f9d5eb48f6fe7cf1d11a2ccb2df9198f474f1
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 19 21:29:34 2020 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Aug 19 21:29:34 2020 +0000
URL:        https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=848f9d5e

defaults/linuxrc: Process /etc/initramfs.mounts multiple times

We need to mount mountpoints listed in /etc/initramfs.mounts
before validating REAL_INIT in case init is located on seperate
mount.

In addition the code was moved to a dedicated function named
process_initramfs_mounts() to allow to run it multiple times
which is needed if REAL_INIT wasn't verified (in case system
was booted from livecd).

Link: https://forums.gentoo.org/viewtopic-t-1117762.html
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 defaults/initrd.scripts | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 defaults/linuxrc        | 41 +++++++----------------------------------
 2 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
index 14f3c4e..f34e5a3 100644
--- a/defaults/initrd.scripts
+++ b/defaults/initrd.scripts
@@ -1249,6 +1249,55 @@ preserve_log() {
        fi
 }
 
+process_initramfs_mounts() {
+       local fslist=
+
+       if [ -f "${NEW_ROOT}/etc/initramfs.mounts" ]
+       then
+               fslist="$(get_mounts_list)"
+       else
+               fslist="/usr"
+       fi
+
+       local dev= fs= fstype= opts= mnt= cmd=
+       for fs in ${fslist}
+       do
+               mnt="${NEW_ROOT}${fs}"
+               if run mountpoint -q "${mnt}"
+               then
+                       good_msg "${fs} already mounted, skipping..."
+                       continue
+               fi
+
+               dev=$(get_mount_device "${fs}")
+               [ -z "${dev}" ] && continue
+               # Resolve it like util-linux mount does
+               [ -L "${dev}" ] && dev=$(realpath "${dev}")
+               # In this case, it's probably part of the filesystem
+               # and not a mountpoint
+               [ -z "${dev}" ] && continue
+
+               fstype=$(get_mount_fstype "${fs}")
+               if get_mount_options "${fs}" | grep -Fq bind
+               then
+                       opts="bind"
+                       dev="${NEW_ROOT}${dev}"
+               else
+                       # ro must be trailing, and the options will always
+                       # contain at least 'defaults'
+                       opts="$(get_mount_options ${fs} | strip_mount_options)"
+                       opts="${opts},ro"
+               fi
+
+               cmd="mount -t ${fstype} -o ${opts} ${dev} ${mnt}"
+               good_msg "Mounting ${dev} as ${fs}: ${cmd}"
+               if ! run ${cmd}
+               then
+                       bad_msg "Unable to mount ${dev} for ${fs}"
+               fi
+       done
+}
+
 prompt_user() {
        # $1 = variable whose value is the path (examples: "REAL_ROOT",
        #      "LUKS_KEYDEV")

diff --git a/defaults/linuxrc b/defaults/linuxrc
index 3ca7e86..e0704f7 100644
--- a/defaults/linuxrc
+++ b/defaults/linuxrc
@@ -930,6 +930,11 @@ do
                # else not a good root and start over.
                if [ "${mountret}" = '0' ]
                then
+                       # Make sure that entries from 
$NEWROOT/etc/initramfs.mounts
+                       # are mounted before validating $REAL_INIT in case init 
isn't
+                       # located on $REAL_ROOT.
+                       process_initramfs_mounts
+
                        init_binary_file="${NEW_ROOT}${REAL_INIT:-/sbin/init}"
                        init_binary_fallback_file="${NEW_ROOT}/bin/sh"
 
@@ -1261,40 +1266,8 @@ else
        fi
 fi # if [ "${CDROOT}" = '1' ]
 
-# Mount the additional things as required by udev & systemd
-if [ -f ${NEW_ROOT}/etc/initramfs.mounts ]
-then
-       fslist=$(get_mounts_list)
-else
-       fslist="/usr"
-fi
-
-for fs in ${fslist}
-do
-       dev=$(get_mount_device ${fs})
-       [ -z "${dev}" ] && continue
-       # Resolve it like util-linux mount does
-       [ -L ${dev} ] && dev=$(readlink ${dev})
-       # In this case, it's probably part of the filesystem
-       # and not a mountpoint
-       [ -z "${dev}" ] && continue
-       fstype=$(get_mount_fstype ${fs})
-       if get_mount_options ${fs} | grep -Fq bind
-       then
-               opts='bind'
-               dev=${NEW_ROOT}${dev}
-       else
-               # ro must be trailing, and the options will always contain at 
least 'defaults'
-               opts="$(get_mount_options ${fs} | strip_mount_options),ro"
-       fi
-       mnt=${NEW_ROOT}${fs}
-       cmd="mount -t ${fstype} -o ${opts} ${dev} ${mnt}"
-       good_msg "Mounting ${dev} as ${fs}: ${cmd}"
-       if ! ${cmd}
-       then
-               bad_msg "Unable to mount ${dev} for ${fs}"
-       fi
-done # for fs in $fslist; do
+# Re-run to ensure $NEWROOT/etc/initramfs.mounts was processed at least once
+process_initramfs_mounts
 
 # Execute script on the cdrom just before boot to update things if necessary
 cdupdate

Reply via email to