diff --git a/ChangeLog b/ChangeLog index daee3ea4c..81f3ba601 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-10-25 Robert Millan + + * include/grub/fs.h [GRUB_UTIL] (struct grub_fs): Add + `reserved_first_sector' member. + * fs/ext2.c [GRUB_UTIL] (grub_ext2_fs): Initialize + `reserved_first_sector' to 1. + * fs/fat.c [GRUB_UTIL] (grub_fat_fs): Likewise. + * fs/ntfs.c [GRUB_UTIL] (grub_ntfs_fs): Likewise. + * fs/hfsplus.c [GRUB_UTIL] (grub_hfsplus_fs): Likewise. + * util/i386/pc/grub-setup.c (setup): Add safety check that probes for + filesystems which begin at first sector. + (options): New option --skip-fs-probe. + (main): Handle --skip-fs-probe and pass it to setup(). + 2009-10-25 Robert Millan * include/grub/misc.h: Fix wrong evaluation of APPLE_CC. diff --git a/fs/ext2.c b/fs/ext2.c index 8d8c6939e..e7a20a43b 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -927,6 +927,9 @@ static struct grub_fs grub_ext2_fs = .label = grub_ext2_label, .uuid = grub_ext2_uuid, .mtime = grub_ext2_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif .next = 0 }; diff --git a/fs/fat.c b/fs/fat.c index 8440e43fa..e7f01629e 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -855,6 +855,9 @@ static struct grub_fs grub_fat_fs = .close = grub_fat_close, .label = grub_fat_label, .uuid = grub_fat_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif .next = 0 }; diff --git a/fs/hfsplus.c b/fs/hfsplus.c index 5e0ab093f..b306e8d6a 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -1021,6 +1021,9 @@ static struct grub_fs grub_hfsplus_fs = .label = grub_hfsplus_label, .mtime = grub_hfsplus_mtime, .uuid = grub_hfsplus_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif .next = 0 }; diff --git a/fs/ntfs.c b/fs/ntfs.c index f1d0a374e..163f3e0a8 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -1081,15 +1081,19 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) return grub_errno; } -static struct grub_fs grub_ntfs_fs = { - .name = "ntfs", - .dir = grub_ntfs_dir, - .open = grub_ntfs_open, - .read = grub_ntfs_read, - .close = grub_ntfs_close, - .label = grub_ntfs_label, - .uuid = grub_ntfs_uuid, - .next = 0 +static struct grub_fs grub_ntfs_fs = + { + .name = "ntfs", + .dir = grub_ntfs_dir, + .open = grub_ntfs_open, + .read = grub_ntfs_read, + .close = grub_ntfs_close, + .label = grub_ntfs_label, + .uuid = grub_ntfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif + .next = 0 }; GRUB_MOD_INIT (ntfs) diff --git a/include/grub/fs.h b/include/grub/fs.h index 41732e48d..132ab4755 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -68,6 +68,11 @@ struct grub_fs /* Get writing time of filesystem. */ grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); +#ifdef GRUB_UTIL + /* Whether this filesystem reserves first sector for DOS-style boot. */ + int reserved_first_sector; +#endif + /* The next filesystem. */ struct grub_fs *next; }; diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index ccfbd1d25..5a46e9e24 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -86,7 +86,7 @@ grub_refresh (void) static void setup (const char *dir, const char *boot_file, const char *core_file, - const char *root, const char *dest, int must_embed, int force) + const char *root, const char *dest, int must_embed, int force, int fs_probe) { char *boot_path, *core_path, *core_path_dev; char *boot_img, *core_img; @@ -251,6 +251,21 @@ setup (const char *dir, if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) grub_util_error ("%s", grub_errmsg); + if (dest_dev->disk->partition && fs_probe) + { + grub_fs_t fs; + fs = grub_fs_probe (dest_dev); + if (! fs) + grub_util_error ("Unable to identify a filesystem in %s; safety check can't be performed."); + + if (! fs->reserved_first_sector) + grub_util_error ("%s appears to contain a %s filesystem which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk).", dest_dev->disk->name, fs->name); + } + /* Copy the possible DOS BPB. */ memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, tmp_img + GRUB_BOOT_MACHINE_BPB_START, @@ -556,6 +571,7 @@ static struct option options[] = {"device-map", required_argument, 0, 'm'}, {"root-device", required_argument, 0, 'r'}, {"force", no_argument, 0, 'f'}, + {"skip-fs-probe", no_argument, 0, 's'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -580,6 +596,7 @@ DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\ -m, --device-map=FILE use FILE as the device map [default=%s]\n\ -r, --root-device=DEV use DEV as the root device [default=guessed]\n\ -f, --force install even if problems are detected\n\ + -s, --skip-fs-probe do not probe for filesystems in DEVICE\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -613,7 +630,7 @@ main (int argc, char *argv[]) char *dev_map = 0; char *root_dev = 0; char *dest_dev; - int must_embed = 0, force = 0; + int must_embed = 0, force = 0, fs_probe = 1; progname = "grub-setup"; @@ -666,6 +683,10 @@ main (int argc, char *argv[]) force = 1; break; + case 's': + fs_probe = 0; + break; + case 'h': usage (0); break; @@ -767,7 +788,7 @@ main (int argc, char *argv[]) setup (dir ? : DEFAULT_DIRECTORY, boot_file ? : DEFAULT_BOOT_FILE, core_file ? : DEFAULT_CORE_FILE, - root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force); + root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force, fs_probe); } } else @@ -776,7 +797,7 @@ main (int argc, char *argv[]) setup (dir ? : DEFAULT_DIRECTORY, boot_file ? : DEFAULT_BOOT_FILE, core_file ? : DEFAULT_CORE_FILE, - root_dev, dest_dev, must_embed, force); + root_dev, dest_dev, must_embed, force, fs_probe); /* Free resources. */ grub_fini_all ();