From 76c74cd7c718da9d3cc6e1d76fb78a86c363406c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 28 Jun 2012 10:55:44 -0400 Subject: [PATCH] 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. --- modules/installer/cd-dvd/iso-image.nix | 4 ++- modules/system/boot/stage-1-init.sh | 38 ++++++++++++++++++-------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index 7b050f8dd6a..cf76151c2ae 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -205,7 +205,9 @@ in else [ 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"; diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 33eaee826aa..cc12ccaa738 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -184,21 +184,28 @@ onACPower() { # Check the specified file system, if appropriate. checkFS() { + local device="$1" + local fsType="$2" + # Only check block devices. - if ! test -b "$device"; then return 0; fi - - FSTYPE=$(blkid -o value -s TYPE "$device" || true) + if [ ! -b "$device" ]; then return 0; fi # 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 # a hack - it's mostly because e2fsck on ext3 takes much longer to # recover the journal than the ext3 implementation in the kernel # does (minutes versus seconds). if test -z "@checkJournalingFS@" -a \ - \( "$FSTYPE" = ext3 -o "$FSTYPE" = ext4 -o "$FSTYPE" = reiserfs \ - -o "$FSTYPE" = xfs -o "$FSTYPE" = jfs \) + \( "$fsType" = ext3 -o "$fsType" = ext4 -o "$fsType" = reiserfs \ + -o "$fsType" = xfs -o "$fsType" = jfs \) then return 0 fi @@ -210,7 +217,9 @@ checkFS() { return 0 fi - FSTAB_FILE="/etc/mtab" fsck -V -C -a "$device" + echo "checking $device..." + + fsck -V -a "$device" fsckResult=$? if test $(($fsckResult | 2)) = $fsckResult; then @@ -240,7 +249,16 @@ mountFS() { local options="$3" 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 @@ -250,7 +268,7 @@ mountFS() { if [ "$fsType" = "nfs" ]; then nfsmount "$device" "/mnt-root$mountPoint" && break else - mount -t "$fsType" -o "$options" "$device" "/mnt-root$mountPoint" && break + mount "/mnt-root$mountPoint" && break fi if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi echo "retrying..." @@ -311,8 +329,6 @@ while read -u 3 mountPoint; do # doing something with $device right now. udevadm settle || true - echo "mounting $device on $mountPoint..." - mountFS "$device" "$mountPoint" "$options" "$fsType" done