diff --git a/usr/share/archboot/base/init b/usr/share/archboot/base/init index 3abf02763..70db6c44b 100755 --- a/usr/share/archboot/base/init +++ b/usr/share/archboot/base/init @@ -16,6 +16,9 @@ export root="" export init="" echo "/sbin/modprobe" > /proc/sys/kernel/modprobe +# set default mount handler +mount_handler="default_mount_handler" + # if available, start udevd at this stage if [ -x /sbin/udevd ]; then msg ":: Starting udevd..." @@ -96,7 +99,7 @@ fi if [ "${break}" = "y" ]; then echo ":: Break requested, type 'exit' to resume operation" - PS1="ramfs$ " /bin/sh -i + launch_interactive_shell fi if [ "${root}" = "" -a "${ip}" = "" ]; then @@ -107,82 +110,26 @@ else msg "$(cat /message)" fi + # Mount root at /new_root mkdir -p /new_root - if [ -z "${nfsroot}" -a "${root}" != "/dev/nfs" ]; then - if [ ${root:0:5} != "/dev/" ] || ! poll_device "${root}" ${rootdelay}; then - msg "\nRoot device '${root}' doesn't exist. Attempting to create it." - rootdev="" - if [ ${root:0:5} = "/dev/" ]; then - # It might be a block device (/dev/sda) - if [ -f /sys/block/${root:5}/dev ]; then - rootdev="$(cat /sys/block/${root:5}/dev | sed 's|:| |')" - # It might be a partition on any block device (/dev/sda1) - else - for dir in /sys/block/*; do - if [ -f ${dir}/${root:5}/dev ]; then - rootdev="$(cat ${dir}/${root:5}/dev | sed 's|:| |')" - break - fi - done - fi - # It might be a major/minor pair (8:1) - elif echo ${root} | grep -q :; then - rootdev="$(echo ${root} | sed 's|:| |')" - root="/dev/root" - # It might be major/minor encoded as a single hex-number (lilo-style) (801) - elif [ ${#root} -le 4 -a ${#root} -gt 2 ] && echo "${root}" | grep -qe '^[A-Fa-f0-9]*$'; then - str_offset=$((${#root}-2)) - major=$(printf "%d" 0x${root:0:${str_offset}}) - minor=$(printf "%d" 0x${root:${str_offset}}) - rootdev="${major} ${minor}" - root="/dev/root" - fi - if [ -n "${rootdev}" ]; then - msg "Creating root device ${root} with major $(echo "${rootdev}" | cut -d\ -f1) and minor $(echo "${rootdev}" | cut -d\ -f2)." - mknod ${root} b ${rootdev} - else - err "Unable to determine major/minor number of root device '${root}'." - echo "You are being dropped to a recovery shell" - echo " Type 'exit' to try and continue booting" - PS1="ramfs$ " /bin/sh -i - msg "Trying to continue (this will most likely fail) ..." - fi - fi - # We didn't build filesystem support into busybox, - # instead we use util-linux-ng's blkid for best compatibility - if [ -n "${rootfstype}" ]; then - fstype="${rootfstype}" - else - fstype=$(eval $(/sbin/blkid -o udev -p "${root}"); echo $ID_FS_TYPE) - if [ -z "${fstype}" ]; then - err "Unable to determine the file system type of ${root}:" - echo "Either it contains no filesystem, an unknown filesystem," - echo "or more than one valid file system signature was found." - echo - echo "Try adding" - echo " rootfstype=your_filesystem_type" - echo "to the kernel command line." - echo - echo "You are now being dropped into an emergency shell." - launch_interactive_shell - msg "Trying to continue (this will most likely fail) ..." - fi - fi - if [ "${readwrite}" = "yes" ]; then - rwopt="rw" - else - rwopt="ro" - fi - mount ${fstype:+-t ${fstype}} -o ${rwopt}${rootflags:+,${rootflags}} "${root}" /new_root - else - if [ -z "$nfs_server" -o -z "$nfs_path" ]; then - err "Unable to mount root filesystem over NFS: wrong parameters." - echo "You are being dropped to a recovery shell" - echo " Type 'exit' to try and continue booting" - launch_interactive_shell - msg "Trying to continue (this will most likely fail) ..." - fi - nfsmount ${nfs_option:+-o ${nfs_option}} "${nfs_server}:${nfs_path}" /new_root + ${mount_handler} /new_root + + [ -z "${init}" ] && init="/sbin/init" + if [ "$(stat -f -c %i /)" = "$(stat -f -c %i /new_root)" ]; then + # Nothing got mounted on /new_root. This is the end, we don't know what to do anymore + # We fall back into a shell, but the shell has now PID 1 + # This way, manual recovery is still possible. + err "Failed to mount the real root device." + echo "Bailing out, you are on your own. Good luck." + echo + launch_interactive_shell --exec + elif [ ! -f "/new_root${init}" ]; then + # Successfully mounted /new_root, but ${init} is missing + # The same logic as above applies + err "Root device mounted successfully, but ${init} does not exist." + echo "Bailing out, you are on your own. Good luck." + echo + launch_interactive_shell --exec fi #Special handling if udev is running @@ -190,12 +137,13 @@ else if [ -n "${udevpid}" ]; then # Settle pending uevents, then kill udev /sbin/udevadm settle - /bin/kill -9 ${udevpid} > /dev/null 2>&1 - /bin/sleep 0.01 + /bin/kill ${udevpid} > /dev/null 2>&1 + while /bin/pidof udevd >/dev/null; do + sleep 0.1 + done fi umount /proc umount /sys - [ -z "${init}" ] && init="/sbin/init" exec /sbin/switch_root -c /dev/console /new_root ${init} "$@" fi \ No newline at end of file