summaryrefslogtreecommitdiff
path: root/usr/src/grub
diff options
context:
space:
mode:
authorLin Ling <Lin.Ling@Sun.COM>2009-06-04 17:15:02 -0700
committerLin Ling <Lin.Ling@Sun.COM>2009-06-04 17:15:02 -0700
commit21ecdf64e1e200cd74cadf771fc7ddc3d0062080 (patch)
treeaab7042a0ca5ddba6c62fe4d425612f6713edcf0 /usr/src/grub
parentf0d4deecc693927742796b7b0bb1a751ff9b0b54 (diff)
downloadillumos-gate-21ecdf64e1e200cd74cadf771fc7ddc3d0062080.tar.gz
6747441 GRUB/vdev_get_bootpath, spa_get_rootconf, zpool_get_physpath should take care of spare vdev
6844158 assertion failed: vd->vdev_ops == &vdev_mirror_ops, file: ../../common/fs/zfs/zvol.c, line: 1054 6846024 allow grub to findroot /boot/grub/menu.lst if opening menu.lst from the boot device fails
Diffstat (limited to 'usr/src/grub')
-rw-r--r--usr/src/grub/grub-0.97/stage2/builtins.c7
-rw-r--r--usr/src/grub/grub-0.97/stage2/fsys_zfs.c24
2 files changed, 19 insertions, 12 deletions
diff --git a/usr/src/grub/grub-0.97/stage2/builtins.c b/usr/src/grub/grub-0.97/stage2/builtins.c
index f9f41b8cde..baffcc1b93 100644
--- a/usr/src/grub/grub-0.97/stage2/builtins.c
+++ b/usr/src/grub/grub-0.97/stage2/builtins.c
@@ -1619,7 +1619,7 @@ find_common (char *arg, char *root, int for_root, int flags)
grub_sprintf(bootsign, "%s/%s", BOOTSIGN_DIR, arg);
filename = bootsign;
goto harddisk;
- } else if (for_root) {
+ } else if (for_root && !grub_strchr(arg, '/')) {
/* Boot signature without partition/slice information */
grub_sprintf(bootsign, "%s/%s", BOOTSIGN_DIR, arg);
filename = bootsign;
@@ -4163,11 +4163,6 @@ findroot_func (char *arg, int flags)
return 1;
}
- if (grub_strchr(arg, '/')) {
- errnum = ERR_BAD_ARGUMENT;
- return 1;
- }
-
find_best_root = 1;
best_drive = 0;
best_part = 0;
diff --git a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
index 9371b9f821..aad75733cf 100644
--- a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
+++ b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
@@ -1140,11 +1140,12 @@ vdev_validate(char *nv)
}
/*
- * Get a list of valid vdev pathname from the boot device.
+ * Get a valid vdev pathname/devid from the boot device.
* The caller should already allocate MAXPATHLEN memory for bootpath and devid.
*/
-int
-vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath)
+static int
+vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath,
+ int is_spare)
{
char type[16];
@@ -1165,6 +1166,15 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath)
if (guid != inguid)
return (ERR_NO_BOOTPATH);
+ /* for a spare vdev, pick the disk labeled with "is_spare" */
+ if (is_spare) {
+ uint64_t spare = 0;
+ (void) nvlist_lookup_value(nv, ZPOOL_CONFIG_IS_SPARE,
+ &spare, DATA_TYPE_UINT64, NULL);
+ if (!spare)
+ return (ERR_NO_BOOTPATH);
+ }
+
if (nvlist_lookup_value(nv, ZPOOL_CONFIG_PHYS_PATH,
bootpath, DATA_TYPE_STRING, NULL) != 0)
bootpath[0] = '\0';
@@ -1179,7 +1189,9 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath)
return (0);
- } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) {
+ } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
+ strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
+ (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
int nelm, i;
char *child;
@@ -1192,7 +1204,7 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath)
child_i = nvlist_array(child, i);
if (vdev_get_bootpath(child_i, inguid, devid,
- bootpath) == 0)
+ bootpath, is_spare) == 0)
return (0);
}
}
@@ -1259,7 +1271,7 @@ check_pool_label(int label, char *stack, char *outdevid, char *outpath)
if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_GUID, &diskguid,
DATA_TYPE_UINT64, NULL))
return (ERR_FSYS_CORRUPT);
- if (vdev_get_bootpath(nv, diskguid, outdevid, outpath))
+ if (vdev_get_bootpath(nv, diskguid, outdevid, outpath, 0))
return (ERR_NO_BOOTPATH);
return (0);
}