From dbad9f466157b66762931e0803960140e9e47c3d Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 11 Apr 2011 17:19:41 +0200 Subject: [PATCH] Move all files to /run/initramfs Given that we boot into a modern Linux distribution with the "/run" toplevel directory, we can easily mount move the whole /run directory to the real root in the end and have the complete initramfs later on in /run/initramfs. All log files and /run states are still accessible and to save space /run/initramfs can be removed later on. Because the kernel does not mount a tmpfs on /run prior to unpacking the initramfs cpio image, we have to copy ourselves very early to a tmpfs and mount it on /run. Due to lazy umount the old initramfs binaries should be removed in the end by switch_root. This feature can be turned on with "--prefix". --- dracut | 48 +++++++++++++++--- dracut.8.xml | 16 ++++++ modules.d/45ifcfg/write-ifcfg.sh | 8 +-- modules.d/90mdraid/mdmon-pre-udev.sh | 2 +- modules.d/99base/init | 94 +++++++++++++++++++++--------------- 5 files changed, 120 insertions(+), 48 deletions(-) diff --git a/dracut b/dracut index 92fb40a..544f4b5 100755 --- a/dracut +++ b/dracut @@ -53,6 +53,9 @@ Creates initial ramdisk images for preloading modules --no-kernel Do not install kernel drivers and firmware files --strip Strip binaries in the initramfs --nostrip Do not strip binaries in the initramfs (default) + --prefix Prefix initramfs files with /run/initramfs/ + --noprefix Do not prefix initramfs files with /run/initramfs/ + (default) --mdadmconf Include local /etc/mdadm.conf --nomdadmconf Do not include local /etc/mdadm.conf --lvmconf Include local /etc/lvm/lvm.conf @@ -211,6 +214,8 @@ while (($# > 0)); do --no-kernel) kernel_only="no"; no_kernel="yes";; --strip) do_strip_l="yes";; --nostrip) do_strip_l="no";; + --prefix) do_prefix_l="yes";; + --noprefix) do_prefix_l="no";; --mdadmconf) mdadmconf_l="yes";; --nomdadmconf) mdadmconf_l="no";; --lvmconf) lvmconf_l="yes";; @@ -345,6 +350,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l)) [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l [[ $do_strip_l ]] && do_strip=$do_strip_l +[[ $do_prefix_l ]] && do_prefix=$do_prefix_l [[ $hostonly_l ]] && hostonly=$hostonly_l [[ $use_fstab_l ]] && use_fstab=$use_fstab_l [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l @@ -352,6 +358,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l)) [[ $dracutbasedir ]] || dracutbasedir=/usr/share/dracut [[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware" [[ $do_strip ]] || do_strip=no +[[ $do_prefix ]] || do_prefix=no [[ $compress_l ]] && compress=$compress_l [[ $show_modules_l ]] && show_modules=$show_modules_l # eliminate IFS hackery when messing with fw_dir @@ -463,12 +470,27 @@ export initdir dracutbasedir dracutmodules drivers \ stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \ debug +[[ $do_prefix = yes ]] && PREFIX=/run/initramfs + +# Create some directory structure first +[[ $PREFIX ]] && mkdir -m 0755 -p "${initdir}${PREFIX}" + +mkdir -m 0755 -p "${initdir}${PREFIX}/lib" +[[ $PREFIX ]] && ln -sfn "${PREFIX#/}/lib" "$initdir/lib" + if [[ $kernel_only != yes ]]; then - # Create some directory structure first - for d in bin sbin usr/bin usr/sbin usr/lib etc \ - proc sys sysroot tmp dev/pts var/run; do - inst_dir "/$d"; + for d in bin etc lib "$libdir" sbin tmp usr var; do + [[ -e "${initdir}${PREFIX}/$d" ]] && continue + mkdir -m 0755 -p "${initdir}${PREFIX}/$d" + [[ $PREFIX ]] && ln -sfn "${PREFIX#/}/${d#/}" "$initdir/$d" + done + + for d in proc sys sysroot root run run/lock run/initramfs; do + mkdir -m 0755 -p "$initdir/$d"; done + + ln -sfn /run "$initdir/var/run" + ln -sfn /run/lock "$initdir/var/lock" fi # check all our modules to see if they should be sourced. @@ -509,9 +531,23 @@ while pop include_src src && pop include_target tgt; do if [[ -f $src ]]; then inst $src $tgt else - ddebug "Including directory: $src" + ddebug "Including directory: $src" mkdir -p "${initdir}/${tgt}" - cp -a -t "${initdir}/${tgt}" "$src"/* + # check for preexisting symlinks, so we can cope with the + # symlinks to $PREFIX + for i in "$src"/*; do + [[ -e "$i" || -h "$i" ]] || continue + s=${initdir}/${tgt}/${i#$src/} + if [[ -d "$i" ]]; then + if ! [[ -e "$s" ]]; then + mkdir -m 0755 -p "$s" + chmod --reference="$i" "$s" + fi + cp -a -t "$s" "$i"/* + else + cp -a -t "$s" "$i" + fi + done fi fi done diff --git a/dracut.8.xml b/dracut.8.xml index f915b7d..4663d70 100644 --- a/dracut.8.xml +++ b/dracut.8.xml @@ -236,6 +236,22 @@ include in the generic initramfs. This parameter can be specified multiple times + + + + prefix initramfs files with /run/initramfs/ + + + + + + + + do not prefix initramfs files with /run/initramfs/ (default) + + + + diff --git a/modules.d/45ifcfg/write-ifcfg.sh b/modules.d/45ifcfg/write-ifcfg.sh index fb88318..f495e24 100755 --- a/modules.d/45ifcfg/write-ifcfg.sh +++ b/modules.d/45ifcfg/write-ifcfg.sh @@ -134,9 +134,11 @@ for netif in $IFACES ; do done # Pass network opts -mkdir -m 0755 -p /run/initramfs +[ -d /run/initramfs ] || mkdir -m 0755 -p /run/initramfs cp /tmp/net.* /run/initramfs/ >/dev/null 2>&1 -mkdir -m 0755 -p /run/initramfs/state/etc/sysconfig/network-scripts/ +for i in /run/initramfs/state /run/initramfs/state/etc/ /run/initramfs/state/etc/sysconfig /run/initramfs/state/etc/sysconfig/network-scripts; do + [ -d $i ] || mkdir -m 0755 -p $i +done cp /tmp/net.$netif.resolv.conf /run/initramfs/state/etc/ >/dev/null 2>&1 echo "files /etc/sysconfig/network-scripts" > /run/initramfs/rwtab -cp -a /tmp/ifcfg/* /run/initramfs/state/etc/sysconfig/network-scripts/ >/dev/null 2>&1 +cp -a -t /run/initramfs/state/etc/sysconfig/network-scripts/ /tmp/ifcfg/* >/dev/null 2>&1 diff --git a/modules.d/90mdraid/mdmon-pre-udev.sh b/modules.d/90mdraid/mdmon-pre-udev.sh index e38163b..676e69b 100755 --- a/modules.d/90mdraid/mdmon-pre-udev.sh +++ b/modules.d/90mdraid/mdmon-pre-udev.sh @@ -2,5 +2,5 @@ # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # ex: ts=8 sw=4 sts=4 et filetype=sh # save state dir for mdmon/mdadm for the real root -mkdir -m 0755 /run/mdadm +[ -d /run/mdadm ] || mkdir -m 0755 /run/mdadm # backward compat link diff --git a/modules.d/99base/init b/modules.d/99base/init index f0445e7..3569f0b 100755 --- a/modules.d/99base/init +++ b/modules.d/99base/init @@ -98,9 +98,12 @@ else unset _tmp fi -if [ ! -c /dev/ptmx ]; then +ismounted sys || \ + mount -t sysfs -o nosuid,noexec,nodev /sys /sys >/dev/null 2>&1 + +if ! ismounted /dev; then # try to mount devtmpfs - if ! mount -t devtmpfs -o mode=0755,nosuid udev /dev >/dev/null 2>&1; then + if ! mount -t devtmpfs -o mode=0755,nosuid,noexec,nosuid udev /dev >/dev/null 2>&1; then # if it failed fall back to normal tmpfs mount -t tmpfs -o mode=0755,nosuid udev /dev >/dev/null 2>&1 # Make some basic devices first, let udev handle the rest @@ -112,17 +115,28 @@ if [ ! -c /dev/ptmx ]; then fi # prepare the /dev directory -ln -s /proc/self/fd /dev/fd >/dev/null 2>&1 -ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1 -ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1 -ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1 -mkdir -m 0755 /dev/shm /dev/pts /run -mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null 2>&1 -mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm >/dev/null 2>&1 -# create /run which will obsolete /var/run -mount -t tmpfs -o mode=0755,nodev,noexec,nosuid tmpfs /run >/dev/null 2>&1 - -mkdir -m 0755 /run/initramfs +[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd >/dev/null 2>&1 +[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1 +[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1 +[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1 + +if ! ismounted /dev/pts; then + mkdir -m 0755 /dev/pts + mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null 2>&1 +fi + +if ! ismounted /dev/shm; then + mkdir -m 0755 /dev/shm + mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm >/dev/null 2>&1 +fi + +if ! ismounted /run; then + mkdir -m 0755 /newrun + mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs /newrun >/dev/null 2>&1 + cp -a -t /newrun /run/* + mount --move /newrun /run + rm -fr /newrun +fi UDEVVERSION=$(udevadm --version) if [ $UDEVVERSION -gt 166 ]; then @@ -133,15 +147,6 @@ else export UDEVRULESD=/dev/.udev/rules.d fi -[ -e /var/run ] && mv /var/run /var/run.bak -[ -e /var/lock ] && mv /var/lock /var/lock.bak -ln -fs /run /var/run -mkdir -m 0755 /run/lock -ln -fs /run/lock /var/lock -# copy over any possible directory structure -cp -ar /var/run.bak/* /run/ 2>/dev/null -cp -ar /var/lock.bak/* /run/lock/ 2>/dev/null - if [ "$RD_DEBUG" = "yes" ]; then mkfifo /run/initramfs/loginit.pipe loginit $DRACUT_QUIET /dev/console 2>&1 & @@ -374,31 +379,44 @@ else esac done fi +[ "$RD_DEBUG" = "yes" ] && set -x + +if [ -d "$NEWROOT"/run ]; then + NEWRUN="${NEWROOT}/run" + mount --bind /run "$NEWRUN" + NEWINITRAMFSROOT="$NEWRUN/initramfs" -info "Switching root" + if [ "$NEWINITRAMFSROOT/lib" -ef "/lib" ]; then + for d in bin etc lib lib64 sbin tmp usr var; do + [ -h /$d ] && ln -fsn $NEWINITRAMFSROOT/$d /$d + done + fi +else + NEWRUN=/dev/.initramfs + mkdir -m 0755 "$NEWRUN" + mount --bind /run/initramfs "$NEWRUN" +fi wait_for_loginit + +info "Switching root" + +umount -l /run -if [ -d "$NEWROOT"/run ]; then - mount --move /run "$NEWROOT"/run -else - if [ -e /run/initramfs ]; then - cp -axr /run/initramfs /dev/.initramfs >/dev/null 2>&1 - if [ -e /run/initramfs/live ]; then - mkdir -m 0755 /dev/.initramfs/live - mount --move /run/initramfs/live /dev/.initramfs/live - fi - fi - umount -l /run -fi +unset PS4 -export PATH="$OLD_PATH" +CAPSH=$(command -v capsh) +SWITCH_ROOT=$(command -v switch_root) +PATH=$OLDPATH +export PATH if [ -f /etc/capsdrop ]; then . /etc/capsdrop info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped." unset RD_DEBUG - exec /usr/sbin/capsh --drop="$CAPS_INIT_DROP" -- -c "exec /sbin/switch_root \"$NEWROOT\" \"$INIT\" $initargs" || { + exec $CAPSH --drop="$CAPS_INIT_DROP" -- \ + -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \ + { warn "Command:" warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs warn "failed." @@ -406,7 +424,7 @@ if [ -f /etc/capsdrop ]; then } else unset RD_DEBUG - exec /sbin/switch_root "$NEWROOT" "$INIT" $initargs || { + exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || { warn "Something went very badly wrong in the initramfs. Please " warn "file a bug against dracut." emergency_shell -- 2.7.4