From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Cc: Richard Laager <rlaager@wiktel.com>,
Zachary Bedell <pendorbound@gmail.com>
Subject: Re: [Patch] Robustly search for ZFS labels & uberblocks
Date: Sat, 28 Jan 2012 13:51:08 +0100 [thread overview]
Message-ID: <4F23EF3C.9050407@gmail.com> (raw)
In-Reply-To: <1327719035.9477.68.camel@watermelon.coderich.net>
[-- Attachment #1: Type: text/plain, Size: 6412 bytes --]
On 28.01.2012 03:50, Richard Laager wrote:
> On Fri, 2012-01-27 at 14:04 -0500, Zachary Bedell wrote:
>> > I've had to forward port the other changes necessary to support build on Linux.
I attach my zfs-related changed. I'll commit them before your patch and
it already covers most of issues
> Attached is the work I've done on this front. This includes the "allow
> spaces in zpools" patch I previously submitted to grub-devel. And, the
> changes in 10_linux.in are from dajhorn's Ubuntu packages.
I already commented on 10_linux.in changes. They are pretty sloppy.
(mostly is "it works for me and I don't care about other legitimate
configs")
>
>
> zfs-on-linux.patch
>
>
> Index: grub/util/grub.d/10_linux.in
> ===================================================================
> --- grub.orig/util/grub.d/10_linux.in 2012-01-24 23:44:10.530591000 -0600
> +++ grub/util/grub.d/10_linux.in 2012-01-24 23:44:10.706928000 -0600
> @@ -56,8 +56,10 @@
> LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
> fi
>
> -if [ "x`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" = xbtrfs ] \
> - || [ "x`stat -f --printf=%T /`" = xbtrfs ]; then
> +LINUX_ROOT_FS=`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`
> +LINUX_ROOT_STAT=`stat -f --printf=%T / || true`
> +
> +if [ "x${LINUX_ROOT_FS}" = xbtrfs -o "x${LINUX_ROOT_STAT}" = xbtrfs ]; then
> rootsubvol="`make_system_path_relative_to_its_root /`"
> rootsubvol="${rootsubvol#/}"
> if [ "x${rootsubvol}" != x ]; then
> @@ -76,6 +78,10 @@
> GRUB_CMDLINE_EXTRA="$GRUB_CMDLINE_EXTRA crashkernel=384M-2G:64M,2G-:128M"
> fi
>
> +if [ "x${LINUX_ROOT_FS}" = xzfs ]; then
> + GRUB_CMDLINE_LINUX="boot=zfs \$bootfs ${GRUB_CMDLINE_LINUX}"
> +fi
> +
> linux_entry ()
> {
> os="$1"
> @@ -114,6 +120,12 @@
> fi
> printf '%s\n' "${prepare_boot_cache}"
> fi
> + if [ "x${LINUX_ROOT_FS}" = xzfs ]; then
> + cat<< EOF
> + insmod zfsinfo
> + zfs-bootfs (\$root) bootfs
This makes 3 wrong assumptions in a row:
- / and /boot may be different.
- Linux may be in a non-root subvolume. Then the subvolid points to
wrong one.
- / may be unaccessible to GRUB altogether.
In short: this command line part has to be generated on grub-mkconfig
time and have a stable representation. I'd recommend UUID and subvolume
name.
> +EOF
> + fi
> if [ "x$5" != "xquiet" ]; then
> message="$(gettext_printf "Loading Linux %s ..." ${version})"
> cat<< EOF
> Index: grub/util/getroot.c
> ===================================================================
> --- grub.orig/util/getroot.c 2012-01-24 23:44:04.105772000 -0600
> +++ grub/util/getroot.c 2012-01-27 20:48:50.875006000 -0600
> @@ -52,6 +52,8 @@
> #endif
>
> #ifdef __linux__
> +# include<stdio.h>
> +# include<mntent.h>
> # include<sys/types.h>
> # include<sys/wait.h>
> #endif
> @@ -115,6 +117,8 @@
> return path;
> }
>
> +static char *find_device_from_pool (const char *poolname);
> +
> #ifdef __linux__
>
> #define ESCAPED_PATH_MAX (4 * PATH_MAX)
> @@ -263,7 +267,32 @@
> if (!*entries[i].device)
> continue;
>
> - ret = strdup (entries[i].device);
> + if (strcmp (entries[i].fstype, "zfs") == 0)
> + {
> + char *poolname = entries[i].device;
> + char *poolname_i = poolname;
> + char *poolname_j = poolname;
> + /* Replace \040 with a space. Cut at the first slash. */
> + while (*poolname_j)
> + {
> + if (*poolname_j == '/')
> + break;
> + if (strncmp (poolname_j, "\\040", 4) == 0)
> + {
> + *poolname_i = ' ';
> + poolname_i++;
> + poolname_j += 4;
> + continue;
> + }
> + *poolname_i = *poolname_j;
> + poolname_i++;
> + poolname_j++;
> + }
> + *poolname_i = '\0';
> + ret = find_device_from_pool (poolname);
> + }
> + else
> + ret = strdup (entries[i].device);
This is the same as what I've done for zfs-fuse except that:
- unescaping is done before here since already many revisions.
- It forgets subvolume handling.
> if (relroot)
> *relroot = strdup (entries[i].enc_root);
> break;
> @@ -280,13 +309,25 @@
> static char *
> find_root_device_from_libzfs (const char *dir)
> {
> - char *device = NULL;
> + char *device;
> char *poolname;
> char *poolfs;
>
> grub_find_zpool_from_dir (dir,&poolname,&poolfs);
> if (! poolname)
> return NULL;
> + if (poolfs)
> + free (poolfs);
> +
> + device = find_device_from_pool(poolname);
> + free(poolname);
> + return device;
> +}
> +
> +static char *
> +find_device_from_pool (const char *poolname)
> +{
> + char *device = NULL;
>
Same as my fuse work.
> #if defined(HAVE_LIBZFS)&& defined(HAVE_LIBNVPAIR)
> {
> @@ -357,7 +398,7 @@
> char cksum[257], notes[257];
> unsigned int dummy;
>
> - cmd = xasprintf ("zpool status %s", poolname);
> + cmd = xasprintf ("zpool status \"%s\"", poolname);
> fp = popen (cmd, "r");
> free (cmd);
>
> @@ -382,7 +423,10 @@
> st++;
> break;
> case 1:
> - if (!strcmp (name, poolname))
> + /* Use strncmp() because poolname can technically have trailing
> + spaces, which the sscanf() above will not catch. Since we've
> + asked about this pool specifically, this should be safe. */
> + if (!strncmp (name, poolname, strlen(name)))
> st++;
> break;
> case 2:
> @@ -395,17 +439,71 @@
>
> free (line);
> }
> +
> +#ifdef __linux__
> + /* The name returned by zpool isn't necessarily directly under /dev. */
> + {
> + const char *disk_naming_schemes[] = {
> + "/dev/disk/by-id/%s",
> + "/dev/disk/by-path/%s",
> + "/dev/disk/by-uuid/%s",
> + "/dev/disk/by-partuuid/%s",
> + "/dev/disk/by-label/%s",
> + "/dev/disk/by-partlabel/%s",
> + "/dev/%s",
Such a list is difficult to maintain. It's better to scan /dev/disk if
/dev/<name> is unavailable.
+ mnttab = fopen ("/proc/mounts", "r");
+ if (! mnttab)
+ mnttab = fopen ("/etc/mtab", "r");
+ if (! mnttab)
+ return;
/etc/mtab is unreliable. As for /proc/mounts : is there a reason to suppose that /proc/mounts would work when /proc/self/mountinfo doesn't
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: zfs.diff --]
[-- Type: text/x-diff, Size: 40652 bytes --]
=== modified file 'include/grub/emu/getroot.h'
--- include/grub/emu/getroot.h 2011-04-25 12:52:07 +0000
+++ include/grub/emu/getroot.h 2012-01-27 15:41:19 +0000
@@ -30,7 +30,7 @@
};
char *grub_find_device (const char *dir, dev_t dev);
-char *grub_guess_root_device (const char *dir);
+char **grub_guess_root_devices (const char *dir);
int grub_util_get_dev_abstraction (const char *os_dev);
char *grub_util_get_grub_dev (const char *os_dev);
char *grub_make_system_path_relative_to_its_root (const char *path);
=== modified file 'include/grub/emu/misc.h'
--- include/grub/emu/misc.h 2011-12-13 13:51:41 +0000
+++ include/grub/emu/misc.h 2012-01-27 15:23:40 +0000
@@ -80,6 +80,4 @@
int grub_device_mapper_supported (void);
#endif
-char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot);
-
#endif /* GRUB_EMU_MISC_H */
=== modified file 'util/getroot.c'
--- util/getroot.c 2011-12-23 18:25:24 +0000
+++ util/getroot.c 2012-01-27 16:57:59 +0000
@@ -115,6 +115,149 @@
return path;
}
+static char **
+find_root_devices_from_poolname (char *poolname)
+{
+ char **devices = 0;
+ size_t ndevices = 0;
+ size_t devices_allocated = 0;
+
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+ zpool_handle_t *zpool;
+ libzfs_handle_t *libzfs;
+ nvlist_t *config, *vdev_tree;
+ nvlist_t **children, **path;
+ unsigned int nvlist_count;
+ unsigned int i;
+ char *device = 0;
+
+ libzfs = grub_get_libzfs_handle ();
+ if (! libzfs)
+ return NULL;
+
+ zpool = zpool_open (libzfs, poolname);
+ config = zpool_get_config (zpool, NULL);
+
+ if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
+ error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
+
+ if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
+ error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
+ assert (nvlist_count > 0);
+
+ while (nvlist_lookup_nvlist_array (children[0], "children",
+ &children, &nvlist_count) == 0)
+ assert (nvlist_count > 0);
+
+ for (i = 0; i < nvlist_count; i++)
+ {
+ if (nvlist_lookup_string (children[i], "path", &device) != 0)
+ error (1, errno, "nvlist_lookup_string (\"path\")");
+
+ struct stat st;
+ if (stat (device, &st) == 0)
+ {
+#ifdef __sun__
+ if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1)
+ == 0)
+ device = xasprintf ("/dev/rdsk/%s",
+ device + sizeof ("/dev/dsk/") - 1);
+ else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1)
+ == 0
+ && grub_memcmp (device + strlen (device) - 4,
+ ",raw", 4) != 0)
+ device = xasprintf ("%s,raw", device);
+ else
+#endif
+ device = xstrdup (device);
+ if (ndevices >= devices_allocated)
+ {
+ devices_allocated = 2 * (devices_allocated + 8);
+ devices = xrealloc (devices, sizeof (devices[0])
+ * devices_allocated);
+ }
+ devices[ndevices++] = device;
+ }
+
+ device = NULL;
+ }
+
+ zpool_close (zpool);
+#else
+ char *cmd;
+ FILE *fp;
+ int ret;
+ char *line;
+ size_t len;
+ int st;
+
+ char name[PATH_MAX + 1], state[257], readlen[257], writelen[257];
+ char cksum[257], notes[257];
+ unsigned int dummy;
+
+ cmd = xasprintf ("zpool status %s", poolname);
+ fp = popen (cmd, "r");
+ free (cmd);
+
+ st = 0;
+ while (1)
+ {
+ line = NULL;
+ ret = getline (&line, &len, fp);
+ if (ret == -1)
+ break;
+
+ if (sscanf (line, " %s %256s %256s %256s %256s %256s",
+ name, state, readlen, writelen, cksum, notes) >= 5)
+ switch (st)
+ {
+ case 0:
+ if (!strcmp (name, "NAME")
+ && !strcmp (state, "STATE")
+ && !strcmp (readlen, "READ")
+ && !strcmp (writelen, "WRITE")
+ && !strcmp (cksum, "CKSUM"))
+ st++;
+ break;
+ case 1:
+ if (!strcmp (name, poolname))
+ st++;
+ break;
+ case 2:
+ if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy)
+ && !sscanf (name, "raidz%u", &dummy)
+ && !strcmp (state, "ONLINE"))
+ {
+ char *tmp;
+ if (ndevices >= devices_allocated)
+ {
+ devices_allocated = 2 * (devices_allocated + 8);
+ devices = xrealloc (devices, sizeof (devices[0])
+ * devices_allocated);
+ }
+ devices[ndevices++] = xasprintf ("/dev/%s", name);
+ }
+ break;
+ }
+
+ free (line);
+ }
+
+ pclose (fp);
+#endif
+ if (devices)
+ {
+ if (ndevices >= devices_allocated)
+ {
+ devices_allocated = 2 * (devices_allocated + 8);
+ devices = xrealloc (devices, sizeof (devices[0])
+ * devices_allocated);
+ }
+ devices[ndevices++] = 0;
+ }
+ return devices;
+}
+
#ifdef __linux__
#define ESCAPED_PATH_MAX (4 * PATH_MAX)
@@ -154,13 +297,13 @@
*optr = 0;
}
-char *
-grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
+static char **
+grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
{
FILE *fp;
char *buf = NULL;
size_t len = 0;
- char *ret = NULL;
+ char **ret = NULL;
int entry_len = 0, entry_max = 4;
struct mountinfo_entry *entries;
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
@@ -263,9 +406,33 @@
if (!*entries[i].device)
continue;
- ret = strdup (entries[i].device);
- if (relroot)
- *relroot = strdup (entries[i].enc_root);
+ if (grub_strcmp (entries[i].fstype, "fuse.zfs") == 0)
+ {
+ char *slash;
+ slash = strchr (entries[i].device, '/');
+ if (slash)
+ *slash = 0;
+ ret = find_root_devices_from_poolname (entries[i].device);
+ if (slash)
+ *slash = '/';
+ if (relroot)
+ {
+ if (!slash)
+ *relroot = xasprintf ("/@%s", entries[i].enc_root);
+ else if (strchr (slash + 1, '@'))
+ *relroot = xasprintf ("/%s%s", slash + 1, entries[i].enc_root);
+ else
+ *relroot = xasprintf ("/%s@%s", slash + 1, entries[i].enc_root);
+ }
+ }
+ else
+ {
+ ret = xmalloc (2 * sizeof (ret[0]));
+ ret[0] = strdup (entries[i].device);
+ ret[1] = 0;
+ if (relroot)
+ *relroot = strdup (entries[i].enc_root);
+ }
break;
}
@@ -277,10 +444,10 @@
#endif /* __linux__ */
-static char *
-find_root_device_from_libzfs (const char *dir)
+static char **
+find_root_devices_from_libzfs (const char *dir)
{
- char *device = NULL;
+ char **device = NULL;
char *poolname;
char *poolfs;
@@ -288,119 +455,7 @@
if (! poolname)
return NULL;
-#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
- {
- zpool_handle_t *zpool;
- libzfs_handle_t *libzfs;
- nvlist_t *config, *vdev_tree;
- nvlist_t **children, **path;
- unsigned int nvlist_count;
- unsigned int i;
-
- libzfs = grub_get_libzfs_handle ();
- if (! libzfs)
- return NULL;
-
- zpool = zpool_open (libzfs, poolname);
- config = zpool_get_config (zpool, NULL);
-
- if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
- error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
-
- if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
- error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
- assert (nvlist_count > 0);
-
- while (nvlist_lookup_nvlist_array (children[0], "children",
- &children, &nvlist_count) == 0)
- assert (nvlist_count > 0);
-
- for (i = 0; i < nvlist_count; i++)
- {
- if (nvlist_lookup_string (children[i], "path", &device) != 0)
- error (1, errno, "nvlist_lookup_string (\"path\")");
-
- struct stat st;
- if (stat (device, &st) == 0)
- {
-#ifdef __sun__
- if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1)
- == 0)
- device = xasprintf ("/dev/rdsk/%s",
- device + sizeof ("/dev/dsk/") - 1);
- else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1)
- == 0
- && grub_memcmp (device + strlen (device) - 4,
- ",raw", 4) != 0)
- device = xasprintf ("%s,raw", device);
- else
-#endif
- device = xstrdup (device);
- break;
- }
-
- device = NULL;
- }
-
- zpool_close (zpool);
- }
-#else
- {
- char *cmd;
- FILE *fp;
- int ret;
- char *line;
- size_t len;
- int st;
-
- char name[PATH_MAX + 1], state[257], readlen[257], writelen[257];
- char cksum[257], notes[257];
- unsigned int dummy;
-
- cmd = xasprintf ("zpool status %s", poolname);
- fp = popen (cmd, "r");
- free (cmd);
-
- st = 0;
- while (st < 3)
- {
- line = NULL;
- ret = getline (&line, &len, fp);
- if (ret == -1)
- goto fail;
-
- if (sscanf (line, " %s %256s %256s %256s %256s %256s",
- name, state, readlen, writelen, cksum, notes) >= 5)
- switch (st)
- {
- case 0:
- if (!strcmp (name, "NAME")
- && !strcmp (state, "STATE")
- && !strcmp (readlen, "READ")
- && !strcmp (writelen, "WRITE")
- && !strcmp (cksum, "CKSUM"))
- st++;
- break;
- case 1:
- if (!strcmp (name, poolname))
- st++;
- break;
- case 2:
- if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy)
- && !sscanf (name, "raidz%u", &dummy)
- && !strcmp (state, "ONLINE"))
- st++;
- break;
- }
-
- free (line);
- }
- device = xasprintf ("/dev/%s", name);
-
- fail:
- pclose (fp);
- }
-#endif
+ device = find_root_devices_from_poolname (poolname);
free (poolname);
if (poolfs)
@@ -641,10 +696,10 @@
#endif /* __CYGWIN__ */
-char *
-grub_guess_root_device (const char *dir)
+char **
+grub_guess_root_devices (const char *dir)
{
- char *os_dev = NULL;
+ char **os_dev = NULL;
#ifdef __GNU__
file_t file;
mach_port_t *ports;
@@ -678,9 +733,11 @@
if (data[name_len - 1] != '\0')
grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir);
- os_dev = xmalloc (strlen ("/dev/") + data_len);
- memcpy (os_dev, "/dev/", strlen ("/dev/"));
- memcpy (os_dev + strlen ("/dev/"), data, data_len);
+ os_dev = xmalloc (2 * sizeof (os_dev[0]));
+ os_dev[0] = xmalloc (strlen ("/dev/") + data_len);
+ memcpy (os_dev[0], "/dev/", strlen ("/dev/"));
+ memcpy (os_dev[0] + strlen ("/dev/"), data, data_len);
+ os_dev[1] = 0;
if (ports && num_ports > 0)
{
@@ -707,48 +764,56 @@
#ifdef __linux__
if (!os_dev)
- os_dev = grub_find_root_device_from_mountinfo (dir, NULL);
+ os_dev = grub_find_root_devices_from_mountinfo (dir, NULL);
#endif /* __linux__ */
if (!os_dev)
- os_dev = find_root_device_from_libzfs (dir);
-
- if (os_dev)
- {
- char *tmp = os_dev;
- os_dev = canonicalize_file_name (os_dev);
- free (tmp);
- }
-
- if (os_dev)
- {
- int dm = (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0);
- int root = (strcmp (os_dev, "/dev/root") == 0);
- if (!dm && !root)
+ os_dev = find_root_devices_from_libzfs (dir);
+
+ if (os_dev)
+ {
+ char **cur;
+ for (cur = os_dev; *cur; cur++)
+ {
+ char *tmp = *cur;
+ int root, dm;
+ *cur = canonicalize_file_name (*cur);
+ free (tmp);
+ root = (strcmp (*cur, "/dev/root") == 0);
+ dm = (strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0);
+ if (!dm && !root)
+ continue;
+ if (stat (*cur, &st) < 0)
+ break;
+ free (*cur);
+ dev = st.st_rdev;
+ *cur = grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
+ }
+ if (!*cur)
return os_dev;
- if (stat (os_dev, &st) >= 0)
- {
- free (os_dev);
- dev = st.st_rdev;
- return grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
- }
+ for (cur = os_dev; *cur; cur++)
+ free (*cur);
free (os_dev);
+ os_dev = 0;
}
if (stat (dir, &st) < 0)
grub_util_error (_("cannot stat `%s'"), dir);
dev = st.st_dev;
+
+ os_dev = xmalloc (2 * sizeof (os_dev[0]));
#ifdef __CYGWIN__
/* Cygwin specific function. */
- os_dev = grub_find_device (dir, dev);
+ os_dev[0] = grub_find_device (dir, dev);
#else
/* This might be truly slow, but is there any better way? */
- os_dev = grub_find_device ("/dev", dev);
+ os_dev[0] = grub_find_device ("/dev", dev);
#endif
+ os_dev[1] = 0;
#endif /* !__GNU__ */
return os_dev;
@@ -1565,7 +1630,7 @@
#ifdef __linux__
{
char *bind;
- grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
+ grub_free (grub_find_root_devices_from_mountinfo (buf2, &bind));
if (bind && bind[0] && bind[1])
{
buf3 = bind;
@@ -1598,7 +1663,7 @@
#ifdef __linux__
{
char *bind;
- grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
+ grub_free (grub_find_root_devices_from_mountinfo (buf2, &bind));
if (bind && bind[0] && bind[1])
{
char *temp = buf3;
=== modified file 'util/grub-install.in'
--- util/grub-install.in 2012-01-27 12:12:00 +0000
+++ util/grub-install.in 2012-01-27 18:29:29 +0000
@@ -473,7 +473,7 @@
fi
# Create the core image. First, auto-detect the filesystem module.
-fs_module="`"$grub_probe" --device-map="${device_map}" --target=fs --device "${grub_device}"`"
+fs_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs --device `"
if test "x$fs_module" = x ; then
echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2
echo "Try with --recheck." 1>&2
@@ -485,7 +485,7 @@
# this command is allowed to fail (--target=fs already grants us that the
# filesystem will be accessible).
partmap_module=
-for x in `"$grub_probe" --device-map="${device_map}" --target=partmap --device "${grub_device}" 2> /dev/null`; do
+for x in `echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=partmap --device 2> /dev/null`; do
case "$x" in
netbsd | openbsd)
partmap_module="$partmap_module part_bsd";;
@@ -496,7 +496,7 @@
done
# Device abstraction module, if any (lvm, raid).
-devabstraction_module="`"$grub_probe" --device-map="${device_map}" --target=abstraction --device "${grub_device}"`"
+devabstraction_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=abstraction --device`"
if [ "x$disk_module" = xata ]; then
disk_module=pata
@@ -538,14 +538,14 @@
fi
install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
fi
- grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
+ grub_drive="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=drive --device`" || exit 1
# Strip partition number
grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then
# generic method (used on coreboot and ata mod)
- uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
+ uuid="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs_uuid --device`"
if [ "x${uuid}" = "x" ] ; then
if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then
echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
@@ -559,15 +559,15 @@
fi
if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
- hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+ hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
elif [ x"$platform" = xpc ]; then
- hints="`"$grub_probe" --device-map="${device_map}" --target=bios_hints --device "${grub_device}"`"
+ hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=bios_hints --device`"
elif [ x"$platform" = xefi ]; then
- hints="`"$grub_probe" --device-map="${device_map}" --target=efi_hints --device "${grub_device}"`"
+ hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=efi_hints --device`"
elif [ x"$platform" = xieee1275 ]; then
- hints="`"$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device "${grub_device}"`"
+ hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device`"
elif [ x"$platform" = xloongson ] || [ x"$platform" = xqemu ] || [ x"$platform" = xcoreboot ] || [ x"$platform" = xmultiboot ] || [ x"$platform" = xqemu-mips ]; then
- hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+ hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
else
echo "No hints available for your platform. Expect reduced performance"
hints=
@@ -587,7 +587,7 @@
fi
else
if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
- for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
+ for uuid in "`echo "${grub_device}" | xargs "${grub_probe}" --target=cryptodisk_uuid --device`"; do
echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
done
config_opt="-c ${grubdir}/load.cfg "
=== modified file 'util/grub-probe.c'
--- util/grub-probe.c 2012-01-23 18:33:40 +0000
+++ util/grub-probe.c 2012-01-27 18:16:06 +0000
@@ -300,299 +300,343 @@
printf ("raid6rec ");
}
+static inline void
+delim (int zdelim)
+{
+ if (zdelim)
+ putchar ('\0');
+ else
+ putchar ('\n');
+}
+
static void
-probe (const char *path, char *device_name)
+probe (const char *path, char **device_names, int zdelim)
{
- char *drive_name = NULL;
+ char **drives_names = NULL;
+ char **curdev, **curdrive;
char *grub_path = NULL;
- char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
- grub_device_t dev = NULL;
- grub_fs_t fs;
+ int ndev = 0;
- if (path == NULL)
- {
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__)
- if (! grub_util_check_char_device (device_name))
- grub_util_error (_("%s is not a character device"), device_name);
-#else
- if (! grub_util_check_block_device (device_name))
- grub_util_error (_("%s is not a block device"), device_name);
-#endif
- }
- else
+ if (path != NULL)
{
grub_path = canonicalize_file_name (path);
- device_name = grub_guess_root_device (grub_path);
+ device_names = grub_guess_root_devices (grub_path);
+ free (grub_path);
}
- if (! device_name)
+ if (! device_names)
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
if (print == PRINT_DEVICE)
{
- printf ("%s\n", device_name);
- goto end;
- }
-
- drive_name = grub_util_get_grub_dev (device_name);
- if (! drive_name)
- grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
- device_name);
-
- if (print == PRINT_DRIVE)
- {
- printf ("(%s)\n", drive_name);
- goto end;
- }
-
- grub_util_info ("opening %s", drive_name);
- dev = grub_device_open (drive_name);
- if (! dev)
- grub_util_error ("%s", _(grub_errmsg));
-
- if (print == PRINT_HINT_STR)
- {
- const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
- const char *orig_path = grub_util_devname_to_ofpath (osdev);
- char *biosname, *bare, *efi;
- const char *map;
-
- if (orig_path)
- {
+ for (curdev = device_names; *curdev; curdev++)
+ {
+ printf ("%s", *curdev);
+ delim (zdelim);
+ }
+ return;
+ }
+
+ for (curdev = device_names; *curdev; curdev++)
+ {
+ grub_util_pull_device (*curdev);
+ ndev++;
+ }
+
+ drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1));
+
+ for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
+ curdrive++)
+ {
+ *curdrive = grub_util_get_grub_dev (*curdev);
+ if (! *curdrive)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ *curdev);
+ }
+ *curdrive = 0;
+
+ if (print == PRINT_FS || print == PRINT_FS_UUID
+ || print == PRINT_FS_LABEL)
+ {
+ grub_device_t dev = NULL;
+ grub_fs_t fs;
+
+ grub_util_info ("opening %s", drives_names[0]);
+ dev = grub_device_open (drives_names[0]);
+ if (! dev)
+ grub_util_error ("%s", _(grub_errmsg));
+
+ fs = grub_fs_probe (dev);
+ if (! fs)
+ grub_util_error ("%s", _(grub_errmsg));
+
+ if (print == PRINT_FS)
+ {
+ printf ("%s", fs->name);
+ delim (zdelim);
+ }
+ else if (print == PRINT_FS_UUID)
+ {
+ char *uuid;
+ if (! fs->uuid)
+ grub_util_error (_("%s does not support UUIDs"), fs->name);
+
+ if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
+ grub_util_error ("%s", grub_errmsg);
+
+ printf ("%s", uuid);
+ delim (zdelim);
+ }
+ else if (print == PRINT_FS_LABEL)
+ {
+ char *label;
+ if (! fs->label)
+ grub_util_error (_("%s does not support labels"), fs->name);
+
+ if (fs->label (dev, &label) != GRUB_ERR_NONE)
+ grub_util_error ("%s", _(grub_errmsg));
+
+ printf ("%s", label);
+ delim (zdelim);
+ }
+ goto end;
+ }
+
+ for (curdrive = drives_names, curdev = device_names; *curdrive;
+ curdrive++, curdev++)
+ {
+ grub_device_t dev = NULL;
+
+ grub_util_info ("opening %s", *curdrive);
+ dev = grub_device_open (*curdrive);
+ if (! dev)
+ grub_util_error ("%s", _(grub_errmsg));
+
+ if (print == PRINT_HINT_STR)
+ {
+ const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
+ const char *orig_path = grub_util_devname_to_ofpath (osdev);
+ char *biosname, *bare, *efi;
+ const char *map;
+
+ if (orig_path)
+ {
+ char *ofpath = escape_of_path (orig_path);
+ printf ("--hint-ieee1275='");
+ print_full_name (ofpath, dev);
+ printf ("' ");
+ free (ofpath);
+ }
+
+ biosname = guess_bios_drive (*curdev);
+ if (biosname)
+ {
+ printf ("--hint-bios=");
+ print_full_name (biosname, dev);
+ printf (" ");
+ }
+ free (biosname);
+
+ efi = guess_efi_drive (*curdev);
+ if (efi)
+ {
+ printf ("--hint-efi=");
+ print_full_name (efi, dev);
+ printf (" ");
+ }
+ free (efi);
+
+ bare = guess_baremetal_drive (*curdev);
+ if (bare)
+ {
+ printf ("--hint-baremetal=");
+ print_full_name (bare, dev);
+ printf (" ");
+ }
+ free (bare);
+
+ /* FIXME: Add ARC hint. */
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ printf ("--hint='");
+ print_full_name (map, dev);
+ printf ("' ");
+ }
+ printf ("\n");
+
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_COMPATIBILITY_HINT)
+ {
+ const char *map;
+ char *biosname;
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ print_full_name (map, dev);
+ delim (zdelim);
+ grub_device_close (dev);
+ /* Compatibility hint is one device only. */
+ break;
+ }
+ biosname = guess_bios_drive (*curdev);
+ if (biosname)
+ print_full_name (biosname, dev);
+ delim (zdelim);
+ free (biosname);
+ grub_device_close (dev);
+ /* Compatibility hint is one device only. */
+ if (biosname)
+ break;
+ continue;
+ }
+
+ if (print == PRINT_BIOS_HINT)
+ {
+ char *biosname;
+ biosname = guess_bios_drive (*curdev);
+ if (biosname)
+ print_full_name (biosname, dev);
+ delim (zdelim);
+ free (biosname);
+ grub_device_close (dev);
+ continue;
+ }
+ if (print == PRINT_IEEE1275_HINT)
+ {
+ const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
+ const char *orig_path = grub_util_devname_to_ofpath (osdev);
char *ofpath = escape_of_path (orig_path);
- printf ("--hint-ieee1275='");
+ const char *map;
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ printf (" ");
+ print_full_name (map, dev);
+ }
+
+ printf (" ");
print_full_name (ofpath, dev);
- printf ("' ");
+
+ delim (zdelim);
free (ofpath);
- }
-
- biosname = guess_bios_drive (device_name);
- if (biosname)
- {
- printf ("--hint-bios=");
- print_full_name (biosname, dev);
- printf (" ");
- }
- free (biosname);
-
- efi = guess_efi_drive (device_name);
- if (efi)
- {
- printf ("--hint-efi=");
- print_full_name (efi, dev);
- printf (" ");
- }
- free (efi);
-
- bare = guess_baremetal_drive (device_name);
- if (bare)
- {
- printf ("--hint-baremetal=");
- print_full_name (bare, dev);
- printf (" ");
- }
- free (bare);
-
- /* FIXME: Add ARC hint. */
-
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- printf ("--hint='");
- print_full_name (map, dev);
- printf ("' ");
- }
- printf ("\n");
-
- goto end;
- }
-
- if (print == PRINT_COMPATIBILITY_HINT)
- {
- const char *map;
- char *biosname;
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- print_full_name (map, dev);
- printf ("\n");
- goto end;
- }
- biosname = guess_bios_drive (device_name);
- if (biosname)
- print_full_name (biosname, dev);
- printf ("\n");
- free (biosname);
- goto end;
- }
-
- if (print == PRINT_BIOS_HINT)
- {
- char *biosname;
- biosname = guess_bios_drive (device_name);
- if (biosname)
- print_full_name (biosname, dev);
- printf ("\n");
- free (biosname);
- goto end;
- }
- if (print == PRINT_IEEE1275_HINT)
- {
- const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
- const char *orig_path = grub_util_devname_to_ofpath (osdev);
- char *ofpath = escape_of_path (orig_path);
- const char *map;
-
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- printf (" ");
- print_full_name (map, dev);
- }
-
- printf (" ");
- print_full_name (ofpath, dev);
-
- printf ("\n");
- free (ofpath);
- goto end;
- }
- if (print == PRINT_EFI_HINT)
- {
- char *biosname;
- char *name;
- const char *map;
- biosname = guess_efi_drive (device_name);
-
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- printf (" ");
- print_full_name (map, dev);
- }
- if (biosname)
- {
- printf (" ");
- print_full_name (biosname, dev);
- }
-
- printf ("\n");
- free (biosname);
- goto end;
- }
-
- if (print == PRINT_BAREMETAL_HINT)
- {
- char *biosname;
- char *name;
- const char *map;
-
- biosname = guess_baremetal_drive (device_name);
-
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- printf (" ");
- print_full_name (map, dev);
- }
- if (biosname)
- {
- printf (" ");
- print_full_name (biosname, dev);
- }
-
- printf ("\n");
- free (biosname);
- goto end;
- }
-
- if (print == PRINT_ARC_HINT)
- {
- const char *map;
-
- map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
- if (map)
- {
- printf (" ");
- print_full_name (map, dev);
- }
- printf ("\n");
-
- /* FIXME */
-
- goto end;
- }
-
- if (print == PRINT_ABSTRACTION)
- {
- probe_abstraction (dev->disk);
- printf ("\n");
- goto end;
- }
-
- if (print == PRINT_CRYPTODISK_UUID)
- {
- probe_cryptodisk_uuid (dev->disk);
- printf ("\n");
- goto end;
- }
-
- if (print == PRINT_PARTMAP)
- {
- /* Check if dev->disk itself is contained in a partmap. */
- probe_partmap (dev->disk);
- printf ("\n");
- goto end;
- }
-
- if (print == PRINT_MSDOS_PARTTYPE)
- {
- if (dev->disk->partition
- && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
- printf ("%02x", dev->disk->partition->msdostype);
-
- printf ("\n");
- goto end;
- }
-
- fs = grub_fs_probe (dev);
- if (! fs)
- grub_util_error ("%s", _(grub_errmsg));
-
- if (print == PRINT_FS)
- {
- printf ("%s\n", fs->name);
- }
- else if (print == PRINT_FS_UUID)
- {
- char *uuid;
- if (! fs->uuid)
- grub_util_error (_("%s does not support UUIDs"), fs->name);
-
- if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
- grub_util_error ("%s", grub_errmsg);
-
- printf ("%s\n", uuid);
- }
- else if (print == PRINT_FS_LABEL)
- {
- char *label;
- if (! fs->label)
- grub_util_error (_("%s does not support labels"), fs->name);
-
- if (fs->label (dev, &label) != GRUB_ERR_NONE)
- grub_util_error ("%s", _(grub_errmsg));
-
- printf ("%s\n", label);
+ grub_device_close (dev);
+ continue;
+ }
+ if (print == PRINT_EFI_HINT)
+ {
+ char *biosname;
+ char *name;
+ const char *map;
+ biosname = guess_efi_drive (*curdev);
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ printf (" ");
+ print_full_name (map, dev);
+ }
+ if (biosname)
+ {
+ printf (" ");
+ print_full_name (biosname, dev);
+ }
+
+ delim (zdelim);
+ free (biosname);
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_BAREMETAL_HINT)
+ {
+ char *biosname;
+ char *name;
+ const char *map;
+
+ biosname = guess_baremetal_drive (*curdev);
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ printf (" ");
+ print_full_name (map, dev);
+ }
+ if (biosname)
+ {
+ printf (" ");
+ print_full_name (biosname, dev);
+ }
+
+ delim (zdelim);
+ free (biosname);
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_ARC_HINT)
+ {
+ const char *map;
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+ if (map)
+ {
+ printf (" ");
+ print_full_name (map, dev);
+ }
+ delim (zdelim);
+
+ /* FIXME */
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_ABSTRACTION)
+ {
+ probe_abstraction (dev->disk);
+ delim (zdelim);
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_CRYPTODISK_UUID)
+ {
+ probe_cryptodisk_uuid (dev->disk);
+ delim (zdelim);
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_PARTMAP)
+ {
+ /* Check if dev->disk itself is contained in a partmap. */
+ probe_partmap (dev->disk);
+ delim (zdelim);
+ grub_device_close (dev);
+ continue;
+ }
+
+ if (print == PRINT_MSDOS_PARTTYPE)
+ {
+ if (dev->disk->partition
+ && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
+ printf ("%02x", dev->disk->partition->msdostype);
+
+ delim (zdelim);
+ grub_device_close (dev);
+ continue;
+ }
}
end:
- if (dev)
- grub_device_close (dev);
- free (grub_path);
- free (filebuf_via_grub);
- free (filebuf_via_sys);
- free (drive_name);
+ for (curdrive = drives_names; *curdrive; curdrive++)
+ free (*curdrive);
+ free (drives_names);
}
static struct option options[] =
@@ -637,7 +681,7 @@
main (int argc, char *argv[])
{
char *dev_map = 0;
- char *argument;
+ int zero_delim = 0;
set_program_name (argv[0]);
@@ -646,7 +690,7 @@
/* Check for options. */
while (1)
{
- int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
+ int c = getopt_long (argc, argv, "dm:t:hVv0", options, 0);
if (c == -1)
break;
@@ -705,6 +749,10 @@
usage (0);
break;
+ case '0':
+ zero_delim = 1;
+ break;
+
case 'V':
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0;
@@ -729,14 +777,12 @@
usage (1);
}
- if (optind + 1 != argc)
+ if (optind + 1 != argc && !argument_is_device)
{
fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
usage (1);
}
- argument = argv[optind];
-
/* Initialize the emulated biosdisk driver. */
grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
@@ -755,9 +801,9 @@
/* Do it. */
if (argument_is_device)
- probe (NULL, argument);
+ probe (NULL, argv + optind, zero_delim);
else
- probe (argument, NULL);
+ probe (argv[optind], NULL, zero_delim);
/* Free resources. */
grub_gcry_fini_all ();
=== modified file 'util/grub-setup.c'
--- util/grub-setup.c 2012-01-24 13:39:29 +0000
+++ util/grub-setup.c 2012-01-27 18:31:20 +0000
@@ -133,15 +139,16 @@
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 *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 +241,56 @@
- 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));
@@ -485,16 +530,24 @@
unable_to_embed:
- if (must_embed)
- grub_util_error (_("embedding is not possible, but this is required when "
- "the root device is on a RAID array or LVM volume"));
-
#ifdef GRUB_MACHINE_PCBIOS
- if (dest_dev->disk->id != root_dev->disk->id)
+ if (dest_dev->disk->id != root_dev->disk->id
+ || dest_dev->disk->dev->id != root_dev->disk->dev->id)
grub_util_error (_("embedding is not possible, but this is required for "
"cross-disk install"));
#endif
+ {
+ grub_fs_t fs;
+ fs = grub_fs_probe (root_dev);
+ if (!fs)
+ grub_util_error (_("can't determine filesystem"));
+
+ if (!fs->blocklist_install)
+ grub_util_error (_("filesystem '%s' doesn't support blocklists"),
+ fs->name);
+ }
+
grub_util_warn (_("Embedding is not possible. GRUB can only be installed in this "
"setup by using blocklists. However, blocklists are UNRELIABLE and "
"their use is discouraged."));
@@ -617,11 +783,12 @@
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);
@@ -722,7 +959,6 @@
char *core_file;
char *dir;
char *dev_map;
- char *root_dev;
int force;
int fs_probe;
int allow_floppy;
@@ -783,13 +1019,6 @@
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;
@@ -853,7 +1082,6 @@
{
char *root_dev = NULL;
char *dest_dev = NULL;
- int must_embed = 0;
struct arguments arguments;
set_program_name (argv[0]);
@@ -917,80 +1145,12 @@
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);
- }
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- if (grub_util_lvm_isvolume (root_dev))
- must_embed = 1;
-#endif
-
-#ifdef __linux__
- if (root_dev[0] == 'm' && root_dev[1] == 'd'
- && ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/'))
- {
- /* FIXME: we can avoid this on RAID1. */
- must_embed = 1;
- }
-
- if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
- && ((dest_dev[2] >= '0' && dest_dev[2] <= '9') || dest_dev[2] == '/'))
- {
- char **devicelist;
- int i;
-
- if (arguments.device[0] == '/')
- devicelist = grub_util_raid_getmembers (arguments.device, 1);
- else
- {
- char *devname;
- devname = xasprintf ("/dev/%s", dest_dev);
- devicelist = grub_util_raid_getmembers (dest_dev, 1);
- free (devname);
- }
-
- for (i = 0; devicelist[i]; i++)
- {
- setup (arguments.dir ? : DEFAULT_DIRECTORY,
- arguments.boot_file ? : DEFAULT_BOOT_FILE,
- arguments.core_file ? : DEFAULT_CORE_FILE,
- root_dev, grub_util_get_grub_dev (devicelist[i]), 1,
- arguments.force, arguments.fs_probe,
- arguments.allow_floppy);
- }
- }
- else
-#endif
- /* 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, must_embed, arguments.force,
- arguments.fs_probe, arguments.allow_floppy);
+ /* Do the real work. */
+ setup (arguments.dir ? : DEFAULT_DIRECTORY,
+ arguments.boot_file ? : DEFAULT_BOOT_FILE,
+ arguments.core_file ? : DEFAULT_CORE_FILE,
+ dest_dev, arguments.force,
+ arguments.fs_probe, arguments.allow_floppy);
/* Free resources. */
grub_fini_all ();
@@ -999,7 +1159,6 @@
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);
next prev parent reply other threads:[~2012-01-28 12:51 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-19 18:45 [Patch] Robustly search for ZFS labels & uberblocks Zachary Bedell
2011-09-28 21:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-19 11:36 ` Richard Laager
2012-01-22 14:18 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-22 20:31 ` Richard Laager
2012-01-24 7:12 ` Richard Laager
2012-01-27 19:04 ` Zachary Bedell
2012-01-27 22:22 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-28 2:50 ` Richard Laager
2012-01-28 12:51 ` Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2012-01-28 16:50 ` Richard Laager
2012-01-28 17:06 ` Darik Horn
2012-01-28 17:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-28 18:33 ` Richard Laager
2012-01-28 19:21 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-29 22:42 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-31 8:45 ` Richard Laager
2012-02-02 11:13 ` Richard Laager
2012-02-03 10:02 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-03 9:52 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-03 11:20 ` Richard Laager
2012-01-28 18:40 ` Darik Horn
2012-01-28 19:27 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-01-30 1:22 ` Richard Laager
2012-01-30 1:43 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-11-03 14:45 ` Vladimir 'φ-coder/phcoder' Serbinenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F23EF3C.9050407@gmail.com \
--to=phcoder@gmail.com \
--cc=grub-devel@gnu.org \
--cc=pendorbound@gmail.com \
--cc=rlaager@wiktel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).