summaryrefslogtreecommitdiff
path: root/util/grub-setup.c
diff options
context:
space:
mode:
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>2012-02-03 10:35:28 +0100
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>2012-02-03 10:35:28 +0100
commitcf5f7ee788494ed671b07134522bb930b4fb3418 (patch)
tree2039b66eabcf9e0406f21e527e58ddb0987dfb60 /util/grub-setup.c
parent2f53a9ed1fb87fdab0b319e08f29d3861002eaec (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.c101
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);