mirror of
https://salsa.debian.org/kernel-team/initramfs-tools.git
synced 2026-01-28 02:14:49 +00:00
When mounting kernel filesystems and tmpfs filesystems, "none" is unsuitable as the filesystem name. This is because it causes breakage when /etc/mtab is a symlink to /proc/mounts. This is needed so that we can switch /etc/mtab to be a symlink when util-linux is updated to use libmount (#620710). When /etc/mtab is a file updated by mount, the initscripts mountkernfs.sh, mountdevsubfs.sh and mtab.sh initialise the mtab at boot using values other than "none". For example, /proc uses "proc", /dev/pts uses "devpts" and /sys uses "sysfs". The mtab entries are created from defaults, plus any user customisations added to /etc/fstab. When /etc/mtab is a symlink to /proc/mounts, the values set when the filesystems were mounted by init in the initramfs are now visible, and these differ from values in /etc/fstab. The initscripts are now no longer able to update the mtab file, and this causes problems mounting local filesystems. The most visible issue is /proc. The default fstab entry is: proc /proc proc defaults 0 0 while init is using mount -t proc -o nodev,noexec,nosuid none /proc rather than mount -t proc -o nodev,noexec,nosuid proc /proc which results in "mount -a" failing with an exit code of 32 (mount failure). While altering "proc" to "none" in the fstab file corrects this boot failure, this is present by default in the fstab file of every installed system, and so is not easy to update. Additionally, the /dev/pts and /sys mounts may also have been added using the "devpts" and "sysfs" names, and so these should ideally also be corrected to use these names in the initramfs. This behaviour may be easily verified by changing the fsname for /proc in /etc/fstab and checking the exit status of "mount -a". I also fixed an inconsistency in the udev /dev fsname. It might use "none" or "udev"; it now always uses "udev". Closes: #603858 Reported-by: Goswin von Brederlow <goswin-v-b@web.de> Signed-off-by: Roger Leigh <rleigh@debian.org> [ fixes bug in old initscripts barking on 'none' fsname. -maks ] Signed-off-by: maximilian attems <max@stro.at> Reviewed-by: Christian Hofstaedtler <ch@grml.org> Reviewed-by: Michael Prokop <mika@debian.org>
320 lines
6.3 KiB
Bash
Executable File
320 lines
6.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
echo "Loading, please wait..."
|
|
|
|
[ -d /dev ] || mkdir -m 0755 /dev
|
|
[ -d /root ] || mkdir -m 0700 /root
|
|
[ -d /sys ] || mkdir /sys
|
|
[ -d /proc ] || mkdir /proc
|
|
[ -d /tmp ] || mkdir /tmp
|
|
mkdir -p /var/lock
|
|
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
|
|
mount -t proc -o nodev,noexec,nosuid proc /proc
|
|
|
|
# Note that this only becomes /dev on the real filesystem if udev's scripts
|
|
# are used; which they will be, but it's worth pointing out
|
|
tmpfs_size="10M"
|
|
if [ -e /etc/udev/udev.conf ]; then
|
|
. /etc/udev/udev.conf
|
|
fi
|
|
if ! mount -t devtmpfs -o mode=0755 udev /dev; then
|
|
echo "W: devtmpfs not available, falling back to tmpfs for /dev"
|
|
mount -t tmpfs -o size=$tmpfs_size,mode=0755 udev /dev
|
|
[ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
|
|
[ -e /dev/null ] || mknod /dev/null c 1 3
|
|
fi
|
|
mkdir /dev/pts
|
|
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
|
|
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
|
|
mkdir /run/initramfs
|
|
|
|
# Export the dpkg architecture
|
|
export DPKG_ARCH=
|
|
. /conf/arch.conf
|
|
|
|
# Set modprobe env
|
|
export MODPROBE_OPTIONS="-qb"
|
|
|
|
# Export relevant variables
|
|
export ROOT=
|
|
export ROOTDELAY=
|
|
export ROOTFLAGS=
|
|
export ROOTFSTYPE=
|
|
export IP=
|
|
export BOOT=
|
|
export BOOTIF=
|
|
export UBIMTD=
|
|
export break=
|
|
export init=/sbin/init
|
|
export quiet=n
|
|
export readonly=y
|
|
export rootmnt=/root
|
|
export debug=
|
|
export panic=
|
|
export blacklist=
|
|
export resume=
|
|
export resume_offset=
|
|
|
|
# Bring in the main config
|
|
. /conf/initramfs.conf
|
|
for conf in conf/conf.d/*; do
|
|
[ -f ${conf} ] && . ${conf}
|
|
done
|
|
. /scripts/functions
|
|
|
|
# Parse command line options
|
|
for x in $(cat /proc/cmdline); do
|
|
case $x in
|
|
init=*)
|
|
init=${x#init=}
|
|
;;
|
|
root=*)
|
|
ROOT=${x#root=}
|
|
case $ROOT in
|
|
LABEL=*)
|
|
ROOT="${ROOT#LABEL=}"
|
|
|
|
# support any / in LABEL= path (escape to \x2f)
|
|
case "${ROOT}" in
|
|
*/*)
|
|
if command -v sed >/dev/null 2>&1; then
|
|
ROOT="$(echo ${ROOT} | sed 's,/,\\x2f,g')"
|
|
else
|
|
if [ "${ROOT}" != "${ROOT#/}" ]; then
|
|
ROOT="\x2f${ROOT#/}"
|
|
fi
|
|
if [ "${ROOT}" != "${ROOT%/}" ]; then
|
|
ROOT="${ROOT%/}\x2f"
|
|
fi
|
|
IFS='/'
|
|
newroot=
|
|
for s in $ROOT; do
|
|
newroot="${newroot:+${newroot}\\x2f}${s}"
|
|
done
|
|
unset IFS
|
|
ROOT="${newroot}"
|
|
fi
|
|
esac
|
|
ROOT="/dev/disk/by-label/${ROOT}"
|
|
;;
|
|
UUID=*)
|
|
ROOT="/dev/disk/by-uuid/${ROOT#UUID=}"
|
|
;;
|
|
/dev/nfs)
|
|
[ -z "${BOOT}" ] && BOOT=nfs
|
|
;;
|
|
esac
|
|
;;
|
|
rootflags=*)
|
|
ROOTFLAGS="-o ${x#rootflags=}"
|
|
;;
|
|
rootfstype=*)
|
|
ROOTFSTYPE="${x#rootfstype=}"
|
|
;;
|
|
rootdelay=*)
|
|
ROOTDELAY="${x#rootdelay=}"
|
|
case ${ROOTDELAY} in
|
|
*[![:digit:].]*)
|
|
ROOTDELAY=
|
|
;;
|
|
esac
|
|
;;
|
|
nfsroot=*)
|
|
NFSROOT="${x#nfsroot=}"
|
|
;;
|
|
ip=*)
|
|
IP="${x#ip=}"
|
|
;;
|
|
boot=*)
|
|
BOOT=${x#boot=}
|
|
;;
|
|
ubi.mtd=*)
|
|
UBIMTD=${x#ubi.mtd=}
|
|
;;
|
|
resume=*)
|
|
RESUME="${x#resume=}"
|
|
;;
|
|
resume_offset=*)
|
|
resume_offset="${x#resume_offset=}"
|
|
;;
|
|
noresume)
|
|
noresume=y
|
|
;;
|
|
panic=*)
|
|
panic="${x#panic=}"
|
|
case ${panic} in
|
|
*[![:digit:].]*)
|
|
panic=
|
|
;;
|
|
esac
|
|
;;
|
|
quiet)
|
|
quiet=y
|
|
;;
|
|
ro)
|
|
readonly=y
|
|
;;
|
|
rw)
|
|
readonly=n
|
|
;;
|
|
debug)
|
|
debug=y
|
|
quiet=n
|
|
exec >/run/initramfs/initramfs.debug 2>&1
|
|
set -x
|
|
;;
|
|
debug=*)
|
|
debug=y
|
|
quiet=n
|
|
set -x
|
|
;;
|
|
break=*)
|
|
break=${x#break=}
|
|
;;
|
|
break)
|
|
break=premount
|
|
;;
|
|
blacklist=*)
|
|
blacklist=${x#blacklist=}
|
|
;;
|
|
netconsole=*)
|
|
netconsole=${x#netconsole=}
|
|
;;
|
|
BOOTIF=*)
|
|
BOOTIF=${x#BOOTIF=}
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -n "${noresume}" ]; then
|
|
export noresume
|
|
unset resume
|
|
else
|
|
resume=${RESUME:-}
|
|
fi
|
|
|
|
maybe_break top
|
|
|
|
# Don't do log messages here to avoid confusing graphical boots
|
|
run_scripts /scripts/init-top
|
|
|
|
maybe_break modules
|
|
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
|
|
load_modules
|
|
[ "$quiet" != "y" ] && log_end_msg
|
|
|
|
[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}"
|
|
|
|
maybe_break premount
|
|
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount"
|
|
run_scripts /scripts/init-premount
|
|
[ "$quiet" != "y" ] && log_end_msg
|
|
|
|
maybe_break mount
|
|
log_begin_msg "Mounting root file system"
|
|
. /scripts/${BOOT}
|
|
parse_numeric ${ROOT}
|
|
maybe_break mountroot
|
|
mountroot
|
|
log_end_msg
|
|
|
|
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
|
|
else
|
|
# The initramfs udev database must be migrated:
|
|
if [ -d /run/udev ] && [ ! -d /dev/.udev ]; then
|
|
mv /run/udev /dev/.udev
|
|
fi
|
|
# The initramfs debug info must be migrated:
|
|
if [ -d /run/initramfs ] && [ ! -d /dev/.initramfs ]; then
|
|
mv /run/initramfs /dev/.initramfs
|
|
fi
|
|
umount /run
|
|
fi
|
|
|
|
# Move virtual filesystems over to the real filesystem
|
|
mount -n -o move /sys ${rootmnt}/sys
|
|
mount -n -o move /proc ${rootmnt}/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})"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# Make sure the specified init can be executed
|
|
if [ ! -x "${rootmnt}${checktarget}" ]; then
|
|
return 1
|
|
fi
|
|
|
|
# Upstart uses /etc/init as configuration directory :-/
|
|
if [ -d "${rootmnt}${checktarget}" ]; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Check init bootarg
|
|
if [ -n "${init}" ]; then
|
|
if ! validate_init "$init"; then
|
|
echo "Target filesystem doesn't have requested ${init}."
|
|
init=
|
|
fi
|
|
fi
|
|
|
|
# Common case: /sbin/init is present
|
|
if [ ! -x "${rootmnt}/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
|
|
if validate_init "${inittest}"; then
|
|
init="$inittest"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# No init on rootmount
|
|
if ! validate_init "${init}" ; then
|
|
panic "No init found. Try passing init= bootarg."
|
|
fi
|
|
fi
|
|
|
|
maybe_break init
|
|
|
|
# don't leak too much of env - some init(8) don't clear it
|
|
# (keep init, rootmnt)
|
|
unset debug
|
|
unset MODPROBE_OPTIONS
|
|
unset DPKG_ARCH
|
|
unset ROOTFLAGS
|
|
unset ROOTFSTYPE
|
|
unset ROOTDELAY
|
|
unset ROOT
|
|
unset IP
|
|
unset BOOT
|
|
unset BOOTIF
|
|
unset UBIMTD
|
|
unset blacklist
|
|
unset break
|
|
unset noresume
|
|
unset panic
|
|
unset quiet
|
|
unset readonly
|
|
unset resume
|
|
unset resume_offset
|
|
|
|
# Chain to real filesystem
|
|
exec run-init ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console
|
|
panic "Could not execute run-init."
|