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.
This commit is contained in:
parent
2f53a9ed1f
commit
cf5f7ee788
7 changed files with 640 additions and 490 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
||||||
|
2012-02-03 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2012-02-01 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-02-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/fs/zfs/zfscrypt.c: Add link to documentation.
|
* grub-core/fs/zfs/zfscrypt.c: Add link to documentation.
|
||||||
|
|
|
@ -30,7 +30,7 @@ enum grub_dev_abstraction_types {
|
||||||
};
|
};
|
||||||
|
|
||||||
char *grub_find_device (const char *dir, dev_t dev);
|
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);
|
int grub_util_get_dev_abstraction (const char *os_dev);
|
||||||
char *grub_util_get_grub_dev (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);
|
char *grub_make_system_path_relative_to_its_root (const char *path);
|
||||||
|
|
|
@ -80,6 +80,4 @@ extern char * canonicalize_file_name (const char *path);
|
||||||
int grub_device_mapper_supported (void);
|
int grub_device_mapper_supported (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot);
|
|
||||||
|
|
||||||
#endif /* GRUB_EMU_MISC_H */
|
#endif /* GRUB_EMU_MISC_H */
|
||||||
|
|
355
util/getroot.c
355
util/getroot.c
|
@ -180,6 +180,149 @@ xgetcwd (void)
|
||||||
return path;
|
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__
|
#ifdef __linux__
|
||||||
|
|
||||||
#define ESCAPED_PATH_MAX (4 * PATH_MAX)
|
#define ESCAPED_PATH_MAX (4 * PATH_MAX)
|
||||||
|
@ -219,13 +362,13 @@ unescape (char *str)
|
||||||
*optr = 0;
|
*optr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char **
|
||||||
grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
|
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char *ret = NULL;
|
char **ret = NULL;
|
||||||
int entry_len = 0, entry_max = 4;
|
int entry_len = 0, entry_max = 4;
|
||||||
struct mountinfo_entry *entries;
|
struct mountinfo_entry *entries;
|
||||||
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
|
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
|
||||||
|
@ -328,9 +471,33 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
|
||||||
if (!*entries[i].device)
|
if (!*entries[i].device)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = strdup (entries[i].device);
|
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)
|
if (relroot)
|
||||||
*relroot = strdup (entries[i].enc_root);
|
*relroot = strdup (entries[i].enc_root);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,10 +509,10 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
static char *
|
static char **
|
||||||
find_root_device_from_libzfs (const char *dir)
|
find_root_devices_from_libzfs (const char *dir)
|
||||||
{
|
{
|
||||||
char *device = NULL;
|
char **device = NULL;
|
||||||
char *poolname;
|
char *poolname;
|
||||||
char *poolfs;
|
char *poolfs;
|
||||||
|
|
||||||
|
@ -353,119 +520,7 @@ find_root_device_from_libzfs (const char *dir)
|
||||||
if (! poolname)
|
if (! poolname)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
device = find_root_devices_from_poolname (poolname);
|
||||||
{
|
|
||||||
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
|
|
||||||
|
|
||||||
free (poolname);
|
free (poolname);
|
||||||
if (poolfs)
|
if (poolfs)
|
||||||
|
@ -706,10 +761,10 @@ grub_find_device (const char *path, dev_t dev)
|
||||||
|
|
||||||
#endif /* __CYGWIN__ */
|
#endif /* __CYGWIN__ */
|
||||||
|
|
||||||
char *
|
char **
|
||||||
grub_guess_root_device (const char *dir)
|
grub_guess_root_devices (const char *dir)
|
||||||
{
|
{
|
||||||
char *os_dev = NULL;
|
char **os_dev = NULL;
|
||||||
#ifdef __GNU__
|
#ifdef __GNU__
|
||||||
file_t file;
|
file_t file;
|
||||||
mach_port_t *ports;
|
mach_port_t *ports;
|
||||||
|
@ -743,9 +798,11 @@ grub_guess_root_device (const char *dir)
|
||||||
if (data[name_len - 1] != '\0')
|
if (data[name_len - 1] != '\0')
|
||||||
grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir);
|
grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir);
|
||||||
|
|
||||||
os_dev = xmalloc (strlen ("/dev/") + data_len);
|
os_dev = xmalloc (2 * sizeof (os_dev[0]));
|
||||||
memcpy (os_dev, "/dev/", strlen ("/dev/"));
|
os_dev[0] = xmalloc (strlen ("/dev/") + data_len);
|
||||||
memcpy (os_dev + strlen ("/dev/"), data, 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)
|
if (ports && num_ports > 0)
|
||||||
{
|
{
|
||||||
|
@ -772,32 +829,37 @@ grub_guess_root_device (const char *dir)
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (!os_dev)
|
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__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
if (!os_dev)
|
if (!os_dev)
|
||||||
os_dev = find_root_device_from_libzfs (dir);
|
os_dev = find_root_devices_from_libzfs (dir);
|
||||||
|
|
||||||
if (os_dev)
|
if (os_dev)
|
||||||
{
|
{
|
||||||
char *tmp = os_dev;
|
char **cur;
|
||||||
os_dev = canonicalize_file_name (os_dev);
|
for (cur = os_dev; *cur; cur++)
|
||||||
|
{
|
||||||
|
char *tmp = *cur;
|
||||||
|
int root, dm;
|
||||||
|
*cur = canonicalize_file_name (*cur);
|
||||||
free (tmp);
|
free (tmp);
|
||||||
}
|
root = (strcmp (*cur, "/dev/root") == 0);
|
||||||
|
dm = (strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0);
|
||||||
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)
|
if (!dm && !root)
|
||||||
return os_dev;
|
continue;
|
||||||
if (stat (os_dev, &st) >= 0)
|
if (stat (*cur, &st) < 0)
|
||||||
{
|
break;
|
||||||
free (os_dev);
|
free (*cur);
|
||||||
dev = st.st_rdev;
|
dev = st.st_rdev;
|
||||||
return grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
|
*cur = grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
|
||||||
}
|
}
|
||||||
|
if (!*cur)
|
||||||
|
return os_dev;
|
||||||
|
for (cur = os_dev; *cur; cur++)
|
||||||
|
free (*cur);
|
||||||
free (os_dev);
|
free (os_dev);
|
||||||
|
os_dev = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat (dir, &st) < 0)
|
if (stat (dir, &st) < 0)
|
||||||
|
@ -805,15 +867,18 @@ grub_guess_root_device (const char *dir)
|
||||||
|
|
||||||
dev = st.st_dev;
|
dev = st.st_dev;
|
||||||
|
|
||||||
|
os_dev = xmalloc (2 * sizeof (os_dev[0]));
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
/* Cygwin specific function. */
|
/* Cygwin specific function. */
|
||||||
os_dev = grub_find_device (dir, dev);
|
os_dev[0] = grub_find_device (dir, dev);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* This might be truly slow, but is there any better way? */
|
/* 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
|
#endif
|
||||||
|
os_dev[1] = 0;
|
||||||
#endif /* !__GNU__ */
|
#endif /* !__GNU__ */
|
||||||
|
|
||||||
return os_dev;
|
return os_dev;
|
||||||
|
@ -2412,7 +2477,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
{
|
{
|
||||||
char *bind;
|
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])
|
if (bind && bind[0] && bind[1])
|
||||||
{
|
{
|
||||||
buf3 = bind;
|
buf3 = bind;
|
||||||
|
@ -2445,7 +2510,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
{
|
{
|
||||||
char *bind;
|
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])
|
if (bind && bind[0] && bind[1])
|
||||||
{
|
{
|
||||||
char *temp = buf3;
|
char *temp = buf3;
|
||||||
|
|
|
@ -473,7 +473,7 @@ if ! test -f "${grubdir}"/grubenv; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create the core image. First, auto-detect the filesystem module.
|
# 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
|
if test "x$fs_module" = x ; then
|
||||||
echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2
|
echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2
|
||||||
echo "Try with --recheck." 1>&2
|
echo "Try with --recheck." 1>&2
|
||||||
|
@ -485,7 +485,7 @@ fi
|
||||||
# this command is allowed to fail (--target=fs already grants us that the
|
# this command is allowed to fail (--target=fs already grants us that the
|
||||||
# filesystem will be accessible).
|
# filesystem will be accessible).
|
||||||
partmap_module=
|
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
|
case "$x" in
|
||||||
netbsd | openbsd)
|
netbsd | openbsd)
|
||||||
partmap_module="$partmap_module part_bsd";;
|
partmap_module="$partmap_module part_bsd";;
|
||||||
|
@ -496,7 +496,7 @@ for x in `"$grub_probe" --device-map="${device_map}" --target=partmap --device "
|
||||||
done
|
done
|
||||||
|
|
||||||
# Device abstraction module, if any (lvm, raid).
|
# 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
|
if [ "x$disk_module" = xata ]; then
|
||||||
disk_module=pata
|
disk_module=pata
|
||||||
|
@ -538,14 +538,14 @@ if [ "x${devabstraction_module}" = "x" ] ; then
|
||||||
fi
|
fi
|
||||||
install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
|
install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
|
||||||
fi
|
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
|
# Strip partition number
|
||||||
grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
|
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/'`"
|
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
|
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)
|
# 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${uuid}" = "x" ] ; then
|
||||||
if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; 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
|
echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
|
||||||
|
@ -559,15 +559,15 @@ if [ "x${devabstraction_module}" = "x" ] ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
|
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
|
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
|
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
|
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
|
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
|
else
|
||||||
echo "No hints available for your platform. Expect reduced performance"
|
echo "No hints available for your platform. Expect reduced performance"
|
||||||
hints=
|
hints=
|
||||||
|
@ -587,7 +587,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
|
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"
|
echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
|
||||||
done
|
done
|
||||||
config_opt="-c ${grubdir}/load.cfg "
|
config_opt="-c ${grubdir}/load.cfg "
|
||||||
|
|
|
@ -313,52 +313,105 @@ probe_abstraction (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
probe (const char *path, char *device_name)
|
probe (const char *path, char **device_names, char delim)
|
||||||
{
|
{
|
||||||
char *drive_name = NULL;
|
char **drives_names = NULL;
|
||||||
|
char **curdev, **curdrive;
|
||||||
char *grub_path = NULL;
|
char *grub_path = NULL;
|
||||||
char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
|
int ndev = 0;
|
||||||
grub_device_t dev = NULL;
|
|
||||||
grub_fs_t fs;
|
|
||||||
|
|
||||||
if (path == NULL)
|
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
|
|
||||||
{
|
{
|
||||||
grub_path = canonicalize_file_name (path);
|
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);
|
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
|
||||||
|
|
||||||
if (print == PRINT_DEVICE)
|
if (print == PRINT_DEVICE)
|
||||||
{
|
{
|
||||||
printf ("%s\n", device_name);
|
for (curdev = device_names; *curdev; curdev++)
|
||||||
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);
|
printf ("%s", *curdev);
|
||||||
|
putchar (delim);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
putchar (delim);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
putchar (delim);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
putchar (delim);
|
||||||
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_util_info ("opening %s", drive_name);
|
for (curdrive = drives_names, curdev = device_names; *curdrive;
|
||||||
dev = grub_device_open (drive_name);
|
curdrive++, curdev++)
|
||||||
|
{
|
||||||
|
grub_device_t dev = NULL;
|
||||||
|
|
||||||
|
grub_util_info ("opening %s", *curdrive);
|
||||||
|
dev = grub_device_open (*curdrive);
|
||||||
if (! dev)
|
if (! dev)
|
||||||
grub_util_error ("%s", _(grub_errmsg));
|
grub_util_error ("%s", _(grub_errmsg));
|
||||||
|
|
||||||
|
@ -376,7 +429,7 @@ probe (const char *path, char *device_name)
|
||||||
printf ("' ");
|
printf ("' ");
|
||||||
}
|
}
|
||||||
|
|
||||||
biosname = guess_bios_drive (device_name);
|
biosname = guess_bios_drive (*curdev);
|
||||||
if (biosname)
|
if (biosname)
|
||||||
{
|
{
|
||||||
printf ("--hint-bios=");
|
printf ("--hint-bios=");
|
||||||
|
@ -385,7 +438,7 @@ probe (const char *path, char *device_name)
|
||||||
}
|
}
|
||||||
free (biosname);
|
free (biosname);
|
||||||
|
|
||||||
efi = guess_efi_drive (device_name);
|
efi = guess_efi_drive (*curdev);
|
||||||
if (efi)
|
if (efi)
|
||||||
{
|
{
|
||||||
printf ("--hint-efi=");
|
printf ("--hint-efi=");
|
||||||
|
@ -394,7 +447,7 @@ probe (const char *path, char *device_name)
|
||||||
}
|
}
|
||||||
free (efi);
|
free (efi);
|
||||||
|
|
||||||
bare = guess_baremetal_drive (device_name);
|
bare = guess_baremetal_drive (*curdev);
|
||||||
if (bare)
|
if (bare)
|
||||||
{
|
{
|
||||||
printf ("--hint-baremetal=");
|
printf ("--hint-baremetal=");
|
||||||
|
@ -414,7 +467,8 @@ probe (const char *path, char *device_name)
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
|
if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
|
||||||
|
@ -423,8 +477,8 @@ probe (const char *path, char *device_name)
|
||||||
&& dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
|
&& dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
|
||||||
{
|
{
|
||||||
print_full_name (dev->disk->name, dev);
|
print_full_name (dev->disk->name, dev);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_COMPATIBILITY_HINT)
|
if (print == PRINT_COMPATIBILITY_HINT)
|
||||||
|
@ -435,26 +489,37 @@ probe (const char *path, char *device_name)
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
print_full_name (map, dev);
|
print_full_name (map, dev);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
/* Compatibility hint is one device only. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
biosname = guess_bios_drive (device_name);
|
biosname = guess_bios_drive (*curdev);
|
||||||
if (biosname)
|
if (biosname)
|
||||||
|
{
|
||||||
print_full_name (biosname, dev);
|
print_full_name (biosname, dev);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
|
}
|
||||||
free (biosname);
|
free (biosname);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
/* Compatibility hint is one device only. */
|
||||||
|
if (biosname)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_BIOS_HINT)
|
if (print == PRINT_BIOS_HINT)
|
||||||
{
|
{
|
||||||
char *biosname;
|
char *biosname;
|
||||||
biosname = guess_bios_drive (device_name);
|
biosname = guess_bios_drive (*curdev);
|
||||||
if (biosname)
|
if (biosname)
|
||||||
|
{
|
||||||
print_full_name (biosname, dev);
|
print_full_name (biosname, dev);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
|
}
|
||||||
free (biosname);
|
free (biosname);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (print == PRINT_IEEE1275_HINT)
|
if (print == PRINT_IEEE1275_HINT)
|
||||||
{
|
{
|
||||||
|
@ -465,41 +530,41 @@ probe (const char *path, char *device_name)
|
||||||
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (map, dev);
|
print_full_name (map, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofpath)
|
if (ofpath)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (ofpath, dev);
|
print_full_name (ofpath, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("\n");
|
grub_device_close (dev);
|
||||||
goto end;
|
continue;
|
||||||
}
|
}
|
||||||
if (print == PRINT_EFI_HINT)
|
if (print == PRINT_EFI_HINT)
|
||||||
{
|
{
|
||||||
char *biosname;
|
char *biosname;
|
||||||
char *name;
|
char *name;
|
||||||
const char *map;
|
const char *map;
|
||||||
biosname = guess_efi_drive (device_name);
|
biosname = guess_efi_drive (*curdev);
|
||||||
|
|
||||||
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (map, dev);
|
print_full_name (map, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
if (biosname)
|
if (biosname)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (biosname, dev);
|
print_full_name (biosname, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("\n");
|
|
||||||
free (biosname);
|
free (biosname);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_BAREMETAL_HINT)
|
if (print == PRINT_BAREMETAL_HINT)
|
||||||
|
@ -508,23 +573,23 @@ probe (const char *path, char *device_name)
|
||||||
char *name;
|
char *name;
|
||||||
const char *map;
|
const char *map;
|
||||||
|
|
||||||
biosname = guess_baremetal_drive (device_name);
|
biosname = guess_baremetal_drive (*curdev);
|
||||||
|
|
||||||
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (map, dev);
|
print_full_name (map, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
if (biosname)
|
if (biosname)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (biosname, dev);
|
print_full_name (biosname, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("\n");
|
|
||||||
free (biosname);
|
free (biosname);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_ARC_HINT)
|
if (print == PRINT_ARC_HINT)
|
||||||
|
@ -534,36 +599,38 @@ probe (const char *path, char *device_name)
|
||||||
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
printf (" ");
|
|
||||||
print_full_name (map, dev);
|
print_full_name (map, dev);
|
||||||
|
putchar (delim);
|
||||||
}
|
}
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
|
grub_device_close (dev);
|
||||||
goto end;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_ABSTRACTION)
|
if (print == PRINT_ABSTRACTION)
|
||||||
{
|
{
|
||||||
probe_abstraction (dev->disk);
|
probe_abstraction (dev->disk);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_CRYPTODISK_UUID)
|
if (print == PRINT_CRYPTODISK_UUID)
|
||||||
{
|
{
|
||||||
probe_cryptodisk_uuid (dev->disk);
|
probe_cryptodisk_uuid (dev->disk);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_PARTMAP)
|
if (print == PRINT_PARTMAP)
|
||||||
{
|
{
|
||||||
/* Check if dev->disk itself is contained in a partmap. */
|
/* Check if dev->disk itself is contained in a partmap. */
|
||||||
probe_partmap (dev->disk);
|
probe_partmap (dev->disk);
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_MSDOS_PARTTYPE)
|
if (print == PRINT_MSDOS_PARTTYPE)
|
||||||
|
@ -572,48 +639,16 @@ probe (const char *path, char *device_name)
|
||||||
&& strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
|
&& strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
|
||||||
printf ("%02x", dev->disk->partition->msdostype);
|
printf ("%02x", dev->disk->partition->msdostype);
|
||||||
|
|
||||||
printf ("\n");
|
putchar (delim);
|
||||||
goto end;
|
grub_device_close (dev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (dev)
|
for (curdrive = drives_names; *curdrive; curdrive++)
|
||||||
grub_device_close (dev);
|
free (*curdrive);
|
||||||
free (grub_path);
|
free (drives_names);
|
||||||
free (filebuf_via_grub);
|
|
||||||
free (filebuf_via_sys);
|
|
||||||
free (drive_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct option options[] =
|
static struct option options[] =
|
||||||
|
@ -658,7 +693,8 @@ int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *dev_map = 0;
|
char *dev_map = 0;
|
||||||
char *argument;
|
int zero_delim = 0;
|
||||||
|
char delim;
|
||||||
|
|
||||||
set_program_name (argv[0]);
|
set_program_name (argv[0]);
|
||||||
|
|
||||||
|
@ -667,7 +703,7 @@ main (int argc, char *argv[])
|
||||||
/* Check for options. */
|
/* Check for options. */
|
||||||
while (1)
|
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)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -726,6 +762,10 @@ main (int argc, char *argv[])
|
||||||
usage (0);
|
usage (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
zero_delim = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
|
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -750,14 +790,12 @@ main (int argc, char *argv[])
|
||||||
usage (1);
|
usage (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind + 1 != argc)
|
if (optind + 1 != argc && !argument_is_device)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
|
fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
|
||||||
usage (1);
|
usage (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
argument = argv[optind];
|
|
||||||
|
|
||||||
/* Initialize the emulated biosdisk driver. */
|
/* Initialize the emulated biosdisk driver. */
|
||||||
grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
|
grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
|
||||||
|
|
||||||
|
@ -774,11 +812,28 @@ main (int argc, char *argv[])
|
||||||
grub_mdraid1x_init ();
|
grub_mdraid1x_init ();
|
||||||
grub_lvm_init ();
|
grub_lvm_init ();
|
||||||
|
|
||||||
|
if (print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
|
||||||
|
|| print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
|
||||||
|
|| print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
|
||||||
|
delim = ' ';
|
||||||
|
else
|
||||||
|
delim = '\n';
|
||||||
|
|
||||||
|
if (zero_delim)
|
||||||
|
delim = '\0';
|
||||||
|
|
||||||
/* Do it. */
|
/* Do it. */
|
||||||
if (argument_is_device)
|
if (argument_is_device)
|
||||||
probe (NULL, argument);
|
probe (NULL, argv + optind, delim);
|
||||||
else
|
else
|
||||||
probe (argument, NULL);
|
probe (argv[optind], NULL, delim);
|
||||||
|
|
||||||
|
if (!zero_delim && (print == PRINT_COMPATIBILITY_HINT
|
||||||
|
|| print == PRINT_BIOS_HINT
|
||||||
|
|| print == PRINT_IEEE1275_HINT
|
||||||
|
|| print == PRINT_BAREMETAL_HINT
|
||||||
|
|| print == PRINT_EFI_HINT || print == PRINT_ARC_HINT))
|
||||||
|
putchar ('\n');
|
||||||
|
|
||||||
/* Free resources. */
|
/* Free resources. */
|
||||||
grub_gcry_fini_all ();
|
grub_gcry_fini_all ();
|
||||||
|
|
|
@ -133,15 +133,16 @@ write_rootdev (char *core_img, grub_device_t root_dev,
|
||||||
static void
|
static void
|
||||||
setup (const char *dir,
|
setup (const char *dir,
|
||||||
const char *boot_file, const char *core_file,
|
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)
|
int fs_probe, int allow_floppy)
|
||||||
{
|
{
|
||||||
char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
|
char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
|
||||||
char *boot_img, *core_img;
|
char *boot_img, *core_img;
|
||||||
|
char *root = 0;
|
||||||
size_t boot_size, core_size;
|
size_t boot_size, core_size;
|
||||||
grub_uint16_t core_sectors;
|
grub_uint16_t core_sectors;
|
||||||
grub_device_t root_dev, dest_dev;
|
grub_device_t root_dev = 0, dest_dev;
|
||||||
struct grub_boot_blocklist *first_block, *block;
|
struct grub_boot_blocklist *first_block, *block, *last_block;
|
||||||
char *tmp_img;
|
char *tmp_img;
|
||||||
int i;
|
int i;
|
||||||
grub_disk_addr_t first_sector;
|
grub_disk_addr_t first_sector;
|
||||||
|
@ -235,17 +236,56 @@ setup (const char *dir,
|
||||||
- sizeof (*block));
|
- sizeof (*block));
|
||||||
grub_util_info ("root is `%s', dest is `%s'", root, dest);
|
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");
|
grub_util_info ("Opening dest");
|
||||||
dest_dev = grub_device_open (dest);
|
dest_dev = grub_device_open (dest);
|
||||||
if (! dest_dev)
|
if (! dest_dev)
|
||||||
grub_util_error ("%s", _(grub_errmsg));
|
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);
|
grub_util_info ("setting the root device to `%s'", root);
|
||||||
if (grub_env_set ("root", root) != GRUB_ERR_NONE)
|
if (grub_env_set ("root", root) != GRUB_ERR_NONE)
|
||||||
grub_util_error ("%s", _(grub_errmsg));
|
grub_util_error ("%s", _(grub_errmsg));
|
||||||
|
@ -636,11 +676,12 @@ unable_to_embed:
|
||||||
boot_devpath = (char *) (boot_img
|
boot_devpath = (char *) (boot_img
|
||||||
+ GRUB_BOOT_AOUT_HEADER_SIZE
|
+ GRUB_BOOT_AOUT_HEADER_SIZE
|
||||||
+ GRUB_BOOT_MACHINE_BOOT_DEVPATH);
|
+ 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;
|
const char *dest_ofpath;
|
||||||
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);
|
grub_util_info ("dest_ofpath is `%s'", dest_ofpath);
|
||||||
strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
|
strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
|
||||||
- GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1);
|
- GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1);
|
||||||
|
@ -741,7 +782,6 @@ struct arguments
|
||||||
char *core_file;
|
char *core_file;
|
||||||
char *dir;
|
char *dir;
|
||||||
char *dev_map;
|
char *dev_map;
|
||||||
char *root_dev;
|
|
||||||
int force;
|
int force;
|
||||||
int fs_probe;
|
int fs_probe;
|
||||||
int allow_floppy;
|
int allow_floppy;
|
||||||
|
@ -802,13 +842,6 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||||
arguments->dev_map = xstrdup (arg);
|
arguments->dev_map = xstrdup (arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
|
||||||
if (arguments->root_dev)
|
|
||||||
free (arguments->root_dev);
|
|
||||||
|
|
||||||
arguments->root_dev = xstrdup (arg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
arguments->force = 1;
|
arguments->force = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -935,38 +968,11 @@ main (int argc, char *argv[])
|
||||||
grub_util_info ("Using `%s' as GRUB device", dest_dev);
|
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. */
|
/* Do the real work. */
|
||||||
setup (arguments.dir ? : DEFAULT_DIRECTORY,
|
setup (arguments.dir ? : DEFAULT_DIRECTORY,
|
||||||
arguments.boot_file ? : DEFAULT_BOOT_FILE,
|
arguments.boot_file ? : DEFAULT_BOOT_FILE,
|
||||||
arguments.core_file ? : DEFAULT_CORE_FILE,
|
arguments.core_file ? : DEFAULT_CORE_FILE,
|
||||||
root_dev, dest_dev, arguments.force,
|
dest_dev, arguments.force,
|
||||||
arguments.fs_probe, arguments.allow_floppy);
|
arguments.fs_probe, arguments.allow_floppy);
|
||||||
|
|
||||||
/* Free resources. */
|
/* Free resources. */
|
||||||
|
@ -976,7 +982,6 @@ main (int argc, char *argv[])
|
||||||
free (arguments.boot_file);
|
free (arguments.boot_file);
|
||||||
free (arguments.core_file);
|
free (arguments.core_file);
|
||||||
free (arguments.dir);
|
free (arguments.dir);
|
||||||
free (arguments.root_dev);
|
|
||||||
free (arguments.dev_map);
|
free (arguments.dev_map);
|
||||||
free (arguments.device);
|
free (arguments.device);
|
||||||
free (root_dev);
|
free (root_dev);
|
||||||
|
|
Loading…
Reference in a new issue