From 9ec09476ba6f1c1dc66862ada740d2f33f881f22 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Thu, 24 Mar 2016 23:51:06 +0100 Subject: [PATCH] Fix handling of unmountable filesystems. --- ext/extfs.cpp | 3 ++- libmount/ext2.c | 11 ++++++++++- libmount/include/mount/ext2.h | 22 ++++++++++++++++++---- sysinstall/devices.c | 20 ++++++++++---------- sysinstall/sysinstall.c | 14 +++++++++++--- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/ext/extfs.cpp b/ext/extfs.cpp index 591dc60c..560134e4 100644 --- a/ext/extfs.cpp +++ b/ext/extfs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, 2015 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -49,6 +49,7 @@ #include "inode.h" #include "ioleast.h" +// These must be kept up to date with libmount/ext2.c. static const uint32_t EXT2_FEATURE_COMPAT_SUPPORTED = 0; static const uint32_t EXT2_FEATURE_INCOMPAT_SUPPORTED = \ EXT2_FEATURE_INCOMPAT_FILETYPE; diff --git a/libmount/ext2.c b/libmount/ext2.c index 50c0e71d..b031e55a 100644 --- a/libmount/ext2.c +++ b/libmount/ext2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Jonas 'Sortie' Termansen. + * Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,6 +30,13 @@ #include "util.h" +// These must be kept up to date with ext/extfs.cpp. +#define EXT2_FEATURE_COMPAT_SUPPORTED 0 +#define EXT2_FEATURE_INCOMPAT_SUPPORTED \ + (EXT2_FEATURE_INCOMPAT_FILETYPE) +#define EXT2_FEATURE_RO_COMPAT_SUPPORTED \ + (EXT2_FEATURE_RO_COMPAT_LARGE_FILE) + void ext2_superblock_decode(struct ext2_superblock* sb) { sb->s_inodes_count = le32toh(sb->s_inodes_count); @@ -141,6 +148,8 @@ static enum filesystem_error ext2_inspect(struct filesystem** fs_ptr, fs->fstype_name = "ext2"; fs->fsck = "fsck.ext2"; fs->driver = "extfs"; + if ( sb->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED ) + fs->driver = NULL; fs->flags |= FILESYSTEM_FLAG_UUID; memcpy(&fs->uuid, sb->s_uuid, 16); struct timespec now; diff --git a/libmount/include/mount/ext2.h b/libmount/include/mount/ext2.h index 0f000e60..25b3c869 100644 --- a/libmount/include/mount/ext2.h +++ b/libmount/include/mount/ext2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Jonas 'Sortie' Termansen. + * Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,9 +24,23 @@ #include -static const uint16_t EXT2_SUPER_MAGIC = 0xEF53; -static const uint16_t EXT2_VALID_FS = 1; -static const uint16_t EXT2_ERROR_FS = 2; +#define EXT2_SUPER_MAGIC 0xEF53 +#define EXT2_VALID_FS 1 +#define EXT2_ERROR_FS 2 +#define EXT2_FEATURE_COMPAT_DIR_PREALLOC (1U << 0U) +#define EXT2_FEATURE_COMPAT_IMAGIC_INODES (1U << 1U) +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL (1U << 2U) +#define EXT2_FEATURE_COMPAT_EXT_ATTR (1U << 3U) +#define EXT2_FEATURE_COMPAT_RESIZE_INO (1U << 4U) +#define EXT2_FEATURE_COMPAT_DIR_INDEX (1U << 5U) +#define EXT2_FEATURE_INCOMPAT_COMPRESSION (1U << 0U) +#define EXT2_FEATURE_INCOMPAT_FILETYPE (1U << 1U) +#define EXT2_FEATURE_INCOMPAT_RECOVER (1U << 2U) +#define EXT2_FEATURE_INCOMPAT_JOURNAL_DEV (1U << 3U) +#define EXT2_FEATURE_INCOMPAT_META_BG (1U << 4U) +#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER (1U << 0U) +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE (1U << 1U) +#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR (1U << 2U) struct ext2_superblock { diff --git a/sysinstall/devices.c b/sysinstall/devices.c index f4b9e184..7ad033ea 100644 --- a/sysinstall/devices.c +++ b/sysinstall/devices.c @@ -378,20 +378,20 @@ void mountpoint_mount(struct mountpoint* mountpoint) { mountpoint->pid = -1; if ( WIFSIGNALED(code) ) - err(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, - strsignal(WTERMSIG(code))); + errx(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, + strsignal(WTERMSIG(code))); else if ( !WIFEXITED(code) ) - err(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, - "Unexpected unusual termination"); + errx(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, + "Unexpected unusual termination"); else if ( WEXITSTATUS(code) == 127 ) - err(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, - "Filesystem driver is absent"); + errx(2, "%s: Mount failed: %s: %s", bdev_path, fs->driver, + "Filesystem driver is absent"); else if ( WEXITSTATUS(code) == 0 ) - err(2, "%s: Mount failed: %s: Unexpected successful exit", - bdev_path, fs->driver); + errx(2, "%s: Mount failed: %s: Unexpected successful exit", + bdev_path, fs->driver); else - err(2, "%s: Mount failed: %s: Exited with status %i", bdev_path, - fs->driver, WEXITSTATUS(code)); + errx(2, "%s: Mount failed: %s: Exited with status %i", bdev_path, + fs->driver, WEXITSTATUS(code)); } struct timespec delay = timespec_make(0, 50L * 1000L * 1000L); nanosleep(&delay, NULL); diff --git a/sysinstall/sysinstall.c b/sysinstall/sysinstall.c index 26164677..b2074a7d 100644 --- a/sysinstall/sysinstall.c +++ b/sysinstall/sysinstall.c @@ -597,24 +597,32 @@ int main(void) continue; } root_filesystem = NULL; + bool cant_mount = false; for ( size_t i = 0; i < mountpoints_used; i++ ) { struct mountpoint* mnt = &mountpoints[i]; const char* spec = mnt->entry.fs_spec; if ( !(mnt->fs = search_for_filesystem_by_spec(spec)) ) { - warnx("fstab: Found no filesystem matching `%s'", spec); + warnx("fstab: %s: Found no mountable filesystem matching `%s'", + mnt->entry.fs_file, spec); + cant_mount = true; continue; } if ( !mnt->fs->driver ) { - textf("Don't know how to mount a root filesystem of type %s. " - "Try again.\n", mnt->fs->fstype_name); + warnx("fstab: %s: %s: Don't know how to mount this %s filesystem", + mnt->entry.fs_file, + path_of_blockdevice(mnt->fs->bdev), + mnt->fs->fstype_name); + cant_mount = true; continue; } if ( !strcmp(mnt->entry.fs_file, "/") ) root_filesystem = mnt->fs; } + if ( cant_mount ) + continue; assert(root_filesystem); if ( !strcasecmp(accept_grub, "yes") && missing_bios_boot_partition(root_filesystem) )