initrd: Detect filesystem type before doing fsck/mount
BusyBox doesn't handle the "auto" filesystem type very well: fsck will just ignore such filesystems, and mount will only work properly if the required kernel module is already loaded. Therefore, use blkid to determine the filesystem type. Also generate an /etc/fstab in the initrd rootfs on the fly. This is useful if you're dropped into an emergency shell since it allows you to say "fsck /dev/sda1" or "mount /dev/sda" and have the right thing happen.
This commit is contained in:
parent
7acfd8ec20
commit
76c74cd7c7
|
@ -205,7 +205,9 @@ in
|
||||||
else
|
else
|
||||||
[ config.boot.kernelPackages.aufs ];
|
[ config.boot.kernelPackages.aufs ];
|
||||||
|
|
||||||
boot.initrd.kernelModules = [ "aufs" "squashfs" "iso9660" "loop" ];
|
boot.initrd.availableKernelModules = [ "aufs" "squashfs" "iso9660" ];
|
||||||
|
|
||||||
|
boot.initrd.kernelModules = [ "loop" ];
|
||||||
|
|
||||||
boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars";
|
boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars";
|
||||||
|
|
||||||
|
|
|
@ -184,21 +184,28 @@ onACPower() {
|
||||||
|
|
||||||
# Check the specified file system, if appropriate.
|
# Check the specified file system, if appropriate.
|
||||||
checkFS() {
|
checkFS() {
|
||||||
|
local device="$1"
|
||||||
|
local fsType="$2"
|
||||||
|
|
||||||
# Only check block devices.
|
# Only check block devices.
|
||||||
if ! test -b "$device"; then return 0; fi
|
if [ ! -b "$device" ]; then return 0; fi
|
||||||
|
|
||||||
FSTYPE=$(blkid -o value -s TYPE "$device" || true)
|
|
||||||
|
|
||||||
# Don't check ROM filesystems.
|
# Don't check ROM filesystems.
|
||||||
if test "$FSTYPE" = iso9660 -o "$FSTYPE" = udf; then return 0; fi
|
if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi
|
||||||
|
|
||||||
|
# If we couldn't figure out the FS type, then skip fsck.
|
||||||
|
if [ "$fsType" = auto ]; then
|
||||||
|
echo 'cannot check filesystem with type "auto"!'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
# Optionally, skip fsck on journaling filesystems. This option is
|
# Optionally, skip fsck on journaling filesystems. This option is
|
||||||
# a hack - it's mostly because e2fsck on ext3 takes much longer to
|
# a hack - it's mostly because e2fsck on ext3 takes much longer to
|
||||||
# recover the journal than the ext3 implementation in the kernel
|
# recover the journal than the ext3 implementation in the kernel
|
||||||
# does (minutes versus seconds).
|
# does (minutes versus seconds).
|
||||||
if test -z "@checkJournalingFS@" -a \
|
if test -z "@checkJournalingFS@" -a \
|
||||||
\( "$FSTYPE" = ext3 -o "$FSTYPE" = ext4 -o "$FSTYPE" = reiserfs \
|
\( "$fsType" = ext3 -o "$fsType" = ext4 -o "$fsType" = reiserfs \
|
||||||
-o "$FSTYPE" = xfs -o "$FSTYPE" = jfs \)
|
-o "$fsType" = xfs -o "$fsType" = jfs \)
|
||||||
then
|
then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
@ -210,7 +217,9 @@ checkFS() {
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FSTAB_FILE="/etc/mtab" fsck -V -C -a "$device"
|
echo "checking $device..."
|
||||||
|
|
||||||
|
fsck -V -a "$device"
|
||||||
fsckResult=$?
|
fsckResult=$?
|
||||||
|
|
||||||
if test $(($fsckResult | 2)) = $fsckResult; then
|
if test $(($fsckResult | 2)) = $fsckResult; then
|
||||||
|
@ -240,7 +249,16 @@ mountFS() {
|
||||||
local options="$3"
|
local options="$3"
|
||||||
local fsType="$4"
|
local fsType="$4"
|
||||||
|
|
||||||
checkFS "$device"
|
if [ "$fsType" = auto ]; then
|
||||||
|
fsType=$(blkid -o value -s TYPE "$device")
|
||||||
|
if [ -z "$fsType" ]; then fsType=auto; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$device /mnt-root$mountPoint $fsType $options" >> /etc/fstab
|
||||||
|
|
||||||
|
checkFS "$device" "$fsType"
|
||||||
|
|
||||||
|
echo "mounting $device on $mountPoint..."
|
||||||
|
|
||||||
mkdir -p "/mnt-root$mountPoint" || true
|
mkdir -p "/mnt-root$mountPoint" || true
|
||||||
|
|
||||||
|
@ -250,7 +268,7 @@ mountFS() {
|
||||||
if [ "$fsType" = "nfs" ]; then
|
if [ "$fsType" = "nfs" ]; then
|
||||||
nfsmount "$device" "/mnt-root$mountPoint" && break
|
nfsmount "$device" "/mnt-root$mountPoint" && break
|
||||||
else
|
else
|
||||||
mount -t "$fsType" -o "$options" "$device" "/mnt-root$mountPoint" && break
|
mount "/mnt-root$mountPoint" && break
|
||||||
fi
|
fi
|
||||||
if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
|
if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
|
||||||
echo "retrying..."
|
echo "retrying..."
|
||||||
|
@ -311,8 +329,6 @@ while read -u 3 mountPoint; do
|
||||||
# doing something with $device right now.
|
# doing something with $device right now.
|
||||||
udevadm settle || true
|
udevadm settle || true
|
||||||
|
|
||||||
echo "mounting $device on $mountPoint..."
|
|
||||||
|
|
||||||
mountFS "$device" "$mountPoint" "$options" "$fsType"
|
mountFS "$device" "$mountPoint" "$options" "$fsType"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue