diff options
author | Vladimir 'phcoder' Serbinenko <phcoder@gmail.com> | 2012-02-03 10:35:28 +0100 |
---|---|---|
committer | Vladimir 'phcoder' Serbinenko <phcoder@gmail.com> | 2012-02-03 10:35:28 +0100 |
commit | cf5f7ee788494ed671b07134522bb930b4fb3418 (patch) | |
tree | 2039b66eabcf9e0406f21e527e58ddb0987dfb60 /util/grub-setup.c | |
parent | 2f53a9ed1fb87fdab0b319e08f29d3861002eaec (diff) |
Support install on multi-device filesystems.
* include/grub/emu/getroot.h (grub_guess_root_device): Renamed to ...
(grub_guess_root_devices): ...this. Return char **. All users updated.
* include/grub/emu/misc.h (grub_find_root_device_from_mountinfo):
Removed.
* util/getroot.c (find_root_device_from_libzfs): Moved pool logic to ...
(find_root_devices_from_poolname): ... here.
(grub_find_root_devices_from_mountinfo): Return char **. Make static.
Support zfs-fuse.
(grub_guess_root_device): Rename to ...
(grub_guess_root_devices): ... this. Return char **. All users updated.
* util/grub-install.in: Handle multi-device filesystems.
* util/grub-probe.c (probe). Make device_names a char **. Add delim
argument. All users updated.
Handle multi-device filesystems.
Use 'delim' as separator.
Remove device check to allow filesystems on file.
(main): Support -0 argument. Handle multi-device.
* util/grub-setup.c (setup): Remove root argument. Handle multi-device.
Fix a cross-device check while on it.
(arguments): Remove root_dev.
(argp_parser): Remove -r.
(main): Remove root_dev.
Diffstat (limited to 'util/grub-setup.c')
-rw-r--r-- | util/grub-setup.c | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/util/grub-setup.c b/util/grub-setup.c index 3db3d1f96..a50b0efed 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -133,15 +133,16 @@ write_rootdev (char *core_img, grub_device_t root_dev, static void setup (const char *dir, const char *boot_file, const char *core_file, - const char *root, const char *dest, int force, + const char *dest, int force, int fs_probe, int allow_floppy) { char *boot_path, *core_path, *core_path_dev, *core_path_dev_full; char *boot_img, *core_img; + char *root = 0; size_t boot_size, core_size; grub_uint16_t core_sectors; - grub_device_t root_dev, dest_dev; - struct grub_boot_blocklist *first_block, *block; + grub_device_t root_dev = 0, dest_dev; + struct grub_boot_blocklist *first_block, *block, *last_block; char *tmp_img; int i; grub_disk_addr_t first_sector; @@ -235,17 +236,56 @@ setup (const char *dir, - sizeof (*block)); grub_util_info ("root is `%s', dest is `%s'", root, dest); - /* Open the root device and the destination device. */ - grub_util_info ("Opening root"); - root_dev = grub_device_open (root); - if (! root_dev) - grub_util_error ("%s", _(grub_errmsg)); - grub_util_info ("Opening dest"); dest_dev = grub_device_open (dest); if (! dest_dev) grub_util_error ("%s", _(grub_errmsg)); + { + char **root_devices = grub_guess_root_devices (dir); + char **cur; + int found = 0; + + for (cur = root_devices; *cur; cur++) + { + char *drive; + grub_device_t try_dev; + + drive = grub_util_get_grub_dev (*cur); + if (!drive) + continue; + try_dev = grub_device_open (drive); + if (! try_dev) + continue; + if (!found && try_dev->disk->id == dest_dev->disk->id + && try_dev->disk->dev->id == dest_dev->disk->dev->id) + { + if (root_dev) + grub_device_close (root_dev); + free (root); + root_dev = try_dev; + root = drive; + found = 1; + continue; + } + if (!root_dev) + { + root_dev = try_dev; + root = drive; + continue; + } + grub_device_close (try_dev); + free (drive); + } + if (!root_dev) + { + grub_util_error ("guessing the root device failed, because of `%s'", + grub_errmsg); + } + grub_util_info ("guessed root_dev `%s' from " + "dir `%s'", root_dev->disk->name, dir); + } + grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", _(grub_errmsg)); @@ -636,11 +676,12 @@ unable_to_embed: boot_devpath = (char *) (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + GRUB_BOOT_MACHINE_BOOT_DEVPATH); - if (file->device->disk->id != dest_dev->disk->id) + if (dest_dev->disk->id != root_dev->disk->id + || dest_dev->disk->dev->id != root_dev->disk->dev->id) { const char *dest_ofpath; dest_ofpath - = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (file->device->disk)); + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_dev->disk)); grub_util_info ("dest_ofpath is `%s'", dest_ofpath); strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1); @@ -741,7 +782,6 @@ struct arguments char *core_file; char *dir; char *dev_map; - char *root_dev; int force; int fs_probe; int allow_floppy; @@ -802,13 +842,6 @@ argp_parser (int key, char *arg, struct argp_state *state) arguments->dev_map = xstrdup (arg); break; - case 'r': - if (arguments->root_dev) - free (arguments->root_dev); - - arguments->root_dev = xstrdup (arg); - break; - case 'f': arguments->force = 1; break; @@ -935,38 +968,11 @@ main (int argc, char *argv[]) grub_util_info ("Using `%s' as GRUB device", dest_dev); } - if (arguments.root_dev) - { - root_dev = get_device_name (arguments.root_dev); - - if (! root_dev) - grub_util_error (_("invalid root device `%s'"), arguments.root_dev); - - root_dev = xstrdup (root_dev); - } - else - { - char *root_device = - grub_guess_root_device (arguments.dir ? : DEFAULT_DIRECTORY); - - root_dev = grub_util_get_grub_dev (root_device); - if (! root_dev) - { - grub_util_info ("guessing the root device failed, because of `%s'", - grub_errmsg); - grub_util_error (_("cannot guess the root device. Specify the option " - "`--root-device'")); - } - grub_util_info ("guessed root device `%s' and root_dev `%s' from " - "dir `%s'", root_device, root_dev, - arguments.dir ? : DEFAULT_DIRECTORY); - } - /* Do the real work. */ setup (arguments.dir ? : DEFAULT_DIRECTORY, arguments.boot_file ? : DEFAULT_BOOT_FILE, arguments.core_file ? : DEFAULT_CORE_FILE, - root_dev, dest_dev, arguments.force, + dest_dev, arguments.force, arguments.fs_probe, arguments.allow_floppy); /* Free resources. */ @@ -976,7 +982,6 @@ main (int argc, char *argv[]) free (arguments.boot_file); free (arguments.core_file); free (arguments.dir); - free (arguments.root_dev); free (arguments.dev_map); free (arguments.device); free (root_dev); |