From 0e22e86348bb356e69ed28a58e959b7fab7c43cc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 16 Oct 2011 14:26:40 -0400 Subject: [PATCH] Add support for subroot= option Passing this option causes the initrd to chroot() into a subdirectory of /. This is useful for parallel installing multiple systems in one filesystem. This relies on a patched switch_root from util-linux. --- init | 32 +++++++++++++++++++++----------- scripts/init-bottom/udev | 5 ++--- scripts/local | 6 ++++-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/init b/init index 445c354..3ff2750 100755 --- a/init +++ b/init @@ -49,6 +49,8 @@ export init=/sbin/init export quiet=n export readonly=y export rootmnt=/root +export subroot= +export rootsubmnt= export debug= export panic= export blacklist= @@ -68,6 +70,10 @@ for x in $(cat /proc/cmdline); do init=*) init=${x#init=} ;; + subroot=*) + subroot=${x#subroot=} + rootsubmnt=${x#subroot=} + ;; root=*) ROOT=${x#root=} case $ROOT in @@ -218,14 +224,18 @@ maybe_break mountroot mountroot log_end_msg +if test -n "${rootsubmnt}"; then + rootsubmnt=${rootmnt}/${rootsubmnt} +fi + maybe_break bottom [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom" run_scripts /scripts/init-bottom [ "$quiet" != "y" ] && log_end_msg # Preserve information on old systems without /run on the rootfs -if [ -d ${rootmnt}/run ]; then - mount -n -o move /run ${rootmnt}/run +if [ -d ${rootsubmnt}/run ]; then + mount -n -o move /run ${rootsubmnt}/run else # The initramfs udev database must be migrated: if [ -d /run/udev ] && [ ! -d /dev/.udev ]; then @@ -239,27 +249,27 @@ else fi # Move virtual filesystems over to the real filesystem -mount -n -o move /sys ${rootmnt}/sys -mount -n -o move /proc ${rootmnt}/proc +mount -n -o move /sys ${rootsubmnt}/sys +mount -n -o move /proc ${rootsubmnt}/proc validate_init() { checktarget="${1}" # Work around absolute symlinks - if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${checktarget}" ]; then - case $(readlink "${rootmnt}${checktarget}") in /*) - checktarget="$(chroot ${rootmnt} readlink ${checktarget})" + if [ -d "${rootsubmnt}" ] && [ -h "${rootsubmnt}${checktarget}" ]; then + case $(readlink "${rootsubmnt}${checktarget}") in /*) + checktarget="$(chroot ${rootsubmnt} readlink ${checktarget})" ;; esac fi # Make sure the specified init can be executed - if [ ! -x "${rootmnt}${checktarget}" ]; then + if [ ! -x "${rootsubmnt}${checktarget}" ]; then return 1 fi # Upstart uses /etc/init as configuration directory :-/ - if [ -d "${rootmnt}${checktarget}" ]; then + if [ -d "${rootsubmnt}${checktarget}" ]; then return 1 fi } @@ -273,7 +283,7 @@ if [ -n "${init}" ]; then fi # Common case: /sbin/init is present -if [ ! -x "${rootmnt}/sbin/init" ]; then +if [ ! -x "${rootsubmnt}/sbin/init" ]; then # ... if it's not available search for valid init if [ -z "${init}" ] ; then for inittest in /sbin/init /etc/init /bin/init /bin/sh; do @@ -315,5 +325,5 @@ unset resume unset resume_offset # Chain to real filesystem -exec run-init ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console +exec switch_root --subroot ${subroot} ${rootmnt} ${init} "$@" <${rootsubmnt}/dev/console >${rootsubmnt}/dev/console panic "Could not execute run-init." diff --git a/scripts/init-bottom/udev b/scripts/init-bottom/udev index 375dfab..7922d0f 100755 --- a/scripts/init-bottom/udev +++ b/scripts/init-bottom/udev @@ -20,9 +20,8 @@ if [ -e /etc/udev/udev.conf ]; then fi # move the /dev tmpfs to the rootfs -mount -n -o move /dev ${rootmnt}${udev_root} +mount -n -o move /dev ${rootsubmnt}${udev_root} # create a temporary symlink to the final /dev for other initramfs scripts nuke /dev -ln -s ${rootmnt}${udev_root} /dev - +ln -s ${rootsubmnt}${udev_root} /dev diff --git a/scripts/local b/scripts/local index 521e69a..25b518f 100644 --- a/scripts/local +++ b/scripts/local @@ -101,9 +101,11 @@ mountroot() # FIXME This has no error checking # Mount root if [ "${FSTYPE}" != "unknown" ]; then - mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} + echo mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} + mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} || echo "FAILED TO MOUNT ROOT" else - mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} + echo mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} + mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} || echo "FAILED TO MOUNT ROOT" fi [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom" -- 1.7.6.4