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".
master
Harald Hoyer 2011-04-11 17:19:41 +02:00
parent 7eb40c488c
commit dbad9f4661
5 changed files with 120 additions and 48 deletions

48
dracut
View File

@ -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

View File

@ -234,6 +234,22 @@ include in the generic initramfs. This parameter can be specified multiple times
<para>do not strip binaries in the initramfs</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--prefix</option>
</term>
<listitem>
<para>prefix initramfs files with /run/initramfs/</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--noprefix</option>
</term>
<listitem>
<para>do not prefix initramfs files with /run/initramfs/ (default)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-h</option>

View File

@ -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

View File

@ -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

View File

@ -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
[ ! -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

mkdir -m 0755 /run/initramfs
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 </run/initramfs/loginit.pipe >/dev/console 2>&1 &
@ -374,31 +379,44 @@ else
esac
done
fi

info "Switching root"

wait_for_loginit

[ "$RD_DEBUG" = "yes" ] && set -x
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
NEWRUN="${NEWROOT}/run"
mount --bind /run "$NEWRUN"
NEWINITRAMFSROOT="$NEWRUN/initramfs"

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
umount -l /run
else
NEWRUN=/dev/.initramfs
mkdir -m 0755 "$NEWRUN"
mount --bind /run/initramfs "$NEWRUN"
fi

export PATH="$OLD_PATH"
wait_for_loginit
info "Switching root"
umount -l /run

unset PS4

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