summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2019-04-07 10:19:09 +0300
committerToomas Soome <tsoome@me.com>2019-06-18 20:44:04 +0300
commit9a34674dce796d46567833216389d6d430925bb2 (patch)
tree103748ad29f2aa2a18132be2c0469a50f24a2740
parenta8412dc108558a7a3635b7ab4f3b1b743bdff9e8 (diff)
downloadillumos-joyent-9a34674dce796d46567833216389d6d430925bb2.tar.gz
11182 loader: Distinguish between "no partition" and "choose best partition" with a constant.
Reviewed by: John Levon <john.levon@joyent.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/boot/lib/libstand/zfs/zfs.c2
-rw-r--r--usr/src/boot/sys/boot/common/disk.c92
-rw-r--r--usr/src/boot/sys/boot/common/disk.h31
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efipart.c4
-rw-r--r--usr/src/boot/sys/boot/efi/loader/main.c6
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biosdisk.c8
-rw-r--r--usr/src/boot/sys/boot/uboot/common/main.c43
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/disk.c4
-rw-r--r--usr/src/boot/sys/boot/usb/storage/umass_loader.c4
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/main.c8
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c4
11 files changed, 129 insertions, 77 deletions
diff --git a/usr/src/boot/lib/libstand/zfs/zfs.c b/usr/src/boot/lib/libstand/zfs/zfs.c
index 471fd6b32f..77ec5dbbad 100644
--- a/usr/src/boot/lib/libstand/zfs/zfs.c
+++ b/usr/src/boot/lib/libstand/zfs/zfs.c
@@ -543,7 +543,7 @@ zfs_probe_dev(const char *devname, uint64_t *pool_guid)
int slice = dev->d_slice;
free(dev);
- if (partition != -1 && slice != -1) {
+ if (partition != D_PARTNONE && slice != D_SLICENONE) {
ret = zfs_probe(pa.fd, pool_guid);
if (ret == 0)
return (0);
diff --git a/usr/src/boot/sys/boot/common/disk.c b/usr/src/boot/sys/boot/common/disk.c
index f77e4a3a93..08912cc4e1 100644
--- a/usr/src/boot/sys/boot/common/disk.c
+++ b/usr/src/boot/sys/boot/common/disk.c
@@ -140,7 +140,7 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
dev.dd.d_dev = pa->dev->dd.d_dev;
dev.dd.d_unit = pa->dev->dd.d_unit;
dev.d_slice = part->index;
- dev.d_partition = -1;
+ dev.d_partition = D_PARTNONE;
if (disk_open(&dev, partsize, sectsize) == 0) {
table = ptable_open(&dev, partsize, sectsize, ptblread);
if (table != NULL) {
@@ -227,6 +227,7 @@ disk_ioctl(struct disk_devdesc *dev, unsigned long cmd, void *data)
int
disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
{
+ struct disk_devdesc partdev;
struct open_disk *od;
struct ptable *table;
struct ptable_entry part;
@@ -237,14 +238,6 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
return (ENXIO);
}
rc = 0;
- /*
- * While we are reading disk metadata, make sure we do it relative
- * to the start of the disk
- */
- dev->d_offset = 0;
- table = NULL;
- slice = dev->d_slice;
- partition = dev->d_partition;
od = (struct open_disk *)malloc(sizeof (struct open_disk));
if (od == NULL) {
DPRINTF("no memory");
@@ -254,11 +247,25 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
od->entrysize = 0;
od->mediasize = mediasize;
od->sectorsize = sectorsize;
+ /*
+ * While we are reading disk metadata, make sure we do it relative
+ * to the start of the disk
+ */
+ memcpy(&partdev, dev, sizeof(partdev));
+ partdev.d_offset = 0;
+ partdev.d_slice = D_SLICENONE;
+ partdev.d_partition = D_PARTNONE;
+
+ dev->d_offset = 0;
+ table = NULL;
+ slice = dev->d_slice;
+ partition = dev->d_partition;
+
DPRINTF("%s unit %d, slice %d, partition %d => %p", disk_fmtdev(dev),
dev->dd.d_unit, dev->d_slice, dev->d_partition, od);
/* Determine disk layout. */
- od->table = ptable_open(dev, mediasize / sectorsize, sectorsize,
+ od->table = ptable_open(&partdev, mediasize / sectorsize, sectorsize,
ptblread);
if (od->table == NULL) {
DPRINTF("Can't read partition table");
@@ -272,7 +279,8 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
}
od->mediasize = mediasize;
- if (ptable_gettype(od->table) == PTABLE_BSD &&
+ if ((ptable_gettype(od->table) == PTABLE_BSD ||
+ ptable_gettype(od->table) == PTABLE_VTOC) &&
partition >= 0) {
/* It doesn't matter what value has d_slice */
rc = ptable_getpart(od->table, &part, partition);
@@ -295,24 +303,38 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
od->entrysize = part.end - part.start + 1;
slice = part.index;
if (ptable_gettype(od->table) == PTABLE_GPT) {
- partition = 255;
+ partition = D_PARTISGPT;
goto out; /* Nothing more to do */
- } else if (partition == 255) {
+ } else if (partition == D_PARTISGPT) {
/*
* When we try to open GPT partition, but partition
- * table isn't GPT, reset d_partition value to -1
- * and try to autodetect appropriate value.
+ * table isn't GPT, reset partition value to
+ * D_PARTWILD and try to autodetect appropriate value.
*/
- partition = -1;
+ partition = D_PARTWILD;
}
+
/*
- * If d_partition < 0 and we are looking at a BSD/VTOC slice,
- * then try to read label, otherwise return the
- * whole MBR slice.
+ * If partition is D_PARTNONE, then disk_open() was called
+ * to open raw MBR slice.
*/
- if (partition == -1 &&
- (part.type != PART_FREEBSD || part.type != PART_SOLARIS2))
+ if (partition == D_PARTNONE)
goto out;
+
+ /*
+ * If partition is D_PARTWILD and we are looking at a
+ * BSD/VTOC slice, then try to read label, otherwise return
+ * the whole MBR slice.
+ */
+ if (partition == D_PARTWILD) {
+ switch (part.type) {
+ case PART_FREEBSD:
+ case PART_SOLARIS2:
+ break;
+ default:
+ goto out;
+ }
+ }
/* Try to read label */
table = ptable_open(dev, part.end - part.start + 1,
od->sectorsize, ptblread);
@@ -322,12 +344,12 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
goto out;
}
/*
- * If slice contains BSD/VTOC label and d_partition < 0, then
+ * If slice contains BSD/VTOC label and partition < 0, then
* assume the 'a' partition. Otherwise just return the
* whole MBR slice, because it can contain ZFS.
*/
if (partition < 0) {
- if (ptable_gettype(table) != PTABLE_BSD ||
+ if (ptable_gettype(table) != PTABLE_BSD &&
ptable_gettype(table) != PTABLE_VTOC)
goto out;
partition = 0;
@@ -376,9 +398,9 @@ disk_fmtdev(struct disk_devdesc *dev)
char *cp;
cp = buf + sprintf(buf, "%s%d", dev->dd.d_dev->dv_name, dev->dd.d_unit);
- if (dev->d_slice >= 0) {
+ if (dev->d_slice > D_SLICENONE) {
#ifdef LOADER_GPT_SUPPORT
- if (dev->d_partition == 255) {
+ if (dev->d_partition == D_PARTISGPT) {
sprintf(cp, "p%d:", dev->d_slice);
return (buf);
} else
@@ -387,7 +409,7 @@ disk_fmtdev(struct disk_devdesc *dev)
cp += sprintf(cp, "s%d", dev->d_slice);
#endif
}
- if (dev->d_partition >= 0)
+ if (dev->d_partition > D_PARTNONE)
cp += sprintf(cp, "%c", dev->d_partition + 'a');
strcat(cp, ":");
return (buf);
@@ -401,7 +423,21 @@ disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path)
char *cp;
np = devspec;
- unit = slice = partition = -1;
+ unit = -1;
+ /*
+ * If there is path/file info after the device info, then any missing
+ * slice or partition info should be considered a request to search for
+ * an appropriate partition. Otherwise we want to open the raw device
+ * itself and not try to fill in missing info by searching.
+ */
+ if ((cp = strchr(np, ':')) != NULL && cp[1] != '\0') {
+ slice = D_SLICEWILD;
+ partition = D_PARTWILD;
+ } else {
+ slice = D_SLICENONE;
+ partition = D_PARTNONE;
+ }
+
if (*np != '\0' && *np != ':') {
unit = strtol(np, &cp, 10);
if (cp == np)
@@ -415,7 +451,7 @@ disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path)
/* we don't support nested partitions on GPT */
if (*cp != '\0' && *cp != ':')
return (EINVAL);
- partition = 255;
+ partition = D_PARTISGPT;
} else
#endif
#ifdef LOADER_MBR_SUPPORT
diff --git a/usr/src/boot/sys/boot/common/disk.h b/usr/src/boot/sys/boot/common/disk.h
index cfdfbf4a95..81d002314f 100644
--- a/usr/src/boot/sys/boot/common/disk.h
+++ b/usr/src/boot/sys/boot/common/disk.h
@@ -30,37 +30,40 @@
*
* Whole disk access:
*
- * d_slice = -1
- * d_partition = -1
+ * d_slice = D_SLICENONE
+ * d_partition = <doesn't matter>
*
* Whole MBR slice:
*
* d_slice = MBR slice number (typically 1..4)
- * d_partition = -1
+ * d_partition = D_PARTNONE
*
* VTOC disklabel partition within an MBR slice:
*
* d_slice = MBR slice number (typically 1..4)
- * d_partition = disklabel partition (typically 0..19)
+ * d_partition = disklabel partition (typically 0..19 or D_PARTWILD)
*
* BSD disklabel partition within an MBR slice:
*
* d_slice = MBR slice number (typically 1..4)
- * d_partition = disklabel partition (typically 0..19)
+ * d_partition = disklabel partition (typically 0..19 or D_PARTWILD)
*
* BSD disklabel partition on the true dedicated disk:
*
- * d_slice = -1
- * d_partition = disklabel partition (typically 0..19)
+ * d_slice = D_SLICENONE
+ * d_partition = disklabel partition (typically 0..19 or D_PARTWILD)
*
* GPT partition:
*
* d_slice = GPT partition number (typically 1..N)
- * d_partition = 255
+ * d_partition = D_PARTISGPT
*
- * For both MBR and GPT, to automatically find the 'best' slice or partition,
- * set d_slice to zero. This uses the partition type to decide which partition
- * to use according to the following list of preferences:
+ * For MBR, setting d_partition to D_PARTWILD will automatically use the first
+ * partition within the slice.
+ *
+ * For both MBR and GPT, to automatically find the 'best' slice and partition,
+ * set d_slice to D_SLICEWILD. This uses the partition type to decide which
+ * partition to use according to the following list of preferences:
*
* Solaris2 (active)
* Solaris2 (inactive)
@@ -84,6 +87,12 @@
#ifndef _DISK_H
#define _DISK_H
+#define D_SLICENONE -1
+#define D_SLICEWILD 0
+#define D_PARTNONE -1
+#define D_PARTWILD -2
+#define D_PARTISGPT 255
+
struct disk_devdesc {
struct devdesc dd; /* Must be first. */
int d_slice;
diff --git a/usr/src/boot/sys/boot/efi/libefi/efipart.c b/usr/src/boot/sys/boot/efi/libefi/efipart.c
index 7a277d3c07..1af5f9dcf4 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efipart.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c
@@ -794,8 +794,8 @@ efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose)
pd->pd_blkio = blkio;
pd_dev.dd.d_dev = dev;
pd_dev.dd.d_unit = pd->pd_unit;
- pd_dev.d_slice = -1;
- pd_dev.d_partition = -1;
+ pd_dev.d_slice = D_SLICENONE;
+ pd_dev.d_partition = D_PARTNONE;
ret = disk_open(&pd_dev, blkio->Media->BlockSize *
(blkio->Media->LastBlock + 1),
blkio->Media->BlockSize);
diff --git a/usr/src/boot/sys/boot/efi/loader/main.c b/usr/src/boot/sys/boot/efi/loader/main.c
index 2cb24357af..0c01a85fe3 100644
--- a/usr/src/boot/sys/boot/efi/loader/main.c
+++ b/usr/src/boot/sys/boot/efi/loader/main.c
@@ -269,12 +269,12 @@ set_currdev_pdinfo(pdinfo_t *dp)
currdev.dd.d_dev = dp->pd_devsw;
if (dp->pd_parent == NULL) {
currdev.dd.d_unit = dp->pd_unit;
- currdev.d_slice = -1;
- currdev.d_partition = -1;
+ currdev.d_slice = D_SLICENONE;
+ currdev.d_partition = D_PARTNONE;
} else {
currdev.dd.d_unit = dp->pd_parent->pd_unit;
currdev.d_slice = dp->pd_unit;
- currdev.d_partition = 255; /* Assumes GPT */
+ currdev.d_partition = D_PARTISGPT; /* Assumes GPT */
}
set_currdev_devdesc((struct devdesc *)&currdev);
} else {
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
index 0b8e90c4d7..e1259509ad 100644
--- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
+++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
@@ -686,8 +686,8 @@ bd_print_common(struct devsw *dev, bdinfo_list_t *bdi, int verbose)
devd.dd.d_dev = dev;
devd.dd.d_unit = i;
- devd.d_slice = -1;
- devd.d_partition = -1;
+ devd.d_slice = D_SLICENONE;
+ devd.d_partition = D_PARTNONE;
if (disk_open(&devd,
bd->bd_sectorsize * bd->bd_sectors,
bd->bd_sectorsize) == 0) {
@@ -740,8 +740,8 @@ bd_disk_get_sectors(struct disk_devdesc *dev)
disk.dd.d_dev = dev->dd.d_dev;
disk.dd.d_unit = dev->dd.d_unit;
- disk.d_slice = -1;
- disk.d_partition = -1;
+ disk.d_slice = D_SLICENONE;
+ disk.d_partition = D_PARTNONE;
disk.d_offset = 0;
size = bd->bd_sectors * bd->bd_sectorsize;
diff --git a/usr/src/boot/sys/boot/uboot/common/main.c b/usr/src/boot/sys/boot/uboot/common/main.c
index 704a5a8708..841f2b560d 100644
--- a/usr/src/boot/sys/boot/uboot/common/main.c
+++ b/usr/src/boot/sys/boot/uboot/common/main.c
@@ -197,10 +197,10 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
const char *p;
char *endp;
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
- *slice = 0;
- *partition = -1;
+ *slice = D_SLICEWILD;
+ *partition = D_PARTWILD;
devstr = ub_env_get("loaderdev");
if (devstr == NULL) {
@@ -222,7 +222,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
/* Malformed unit number. */
if (!isdigit(*p)) {
- *type = -1;
+ *type = DEV_TYP_NONE;
return;
}
@@ -237,7 +237,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
/* Device string is malformed beyond unit number. */
if (*p != ':') {
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
return;
}
@@ -250,7 +250,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
/* Only DEV_TYP_STOR devices can have a slice specification. */
if (!(*type & DEV_TYP_STOR)) {
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
return;
}
@@ -259,9 +259,9 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
/* Malformed slice number. */
if (p == endp) {
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
- *slice = 0;
+ *slice = D_SLICEWILD;
return;
}
@@ -273,9 +273,9 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
/* Device string is malformed beyond slice number. */
if (*p != '.') {
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
- *slice = 0;
+ *slice = D_SLICEWILD;
return;
}
@@ -293,10 +293,10 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
return;
/* Junk beyond partition number. */
- *type = -1;
+ *type = DEV_TYP_NONE;
*unit = -1;
- *slice = 0;
- *partition = -1;
+ *slice = D_SLICEWILD;
+ *partition = D_PARTWILD;
}
static void
@@ -305,15 +305,22 @@ print_disk_probe_info()
char slice[32];
char partition[32];
- if (currdev.d_disk.slice > 0)
- sprintf(slice, "%d", currdev.d_disk.slice);
+ if (currdev.d_disk.slice == D_SLICENONE)
+ strlcpy(slice, "<none>", sizeof(slice));
+ else if (currdev.d_disk.d_slice == D_SLICEWILD)
+ strlcpy(slice, "<auto>", sizeof(slice));
else
- strcpy(slice, "<auto>");
+ snprintf(slice, sizeof(slice), "%d", currdev.d_disk.d_slice);
- if (currdev.d_disk.partition >= 0)
+ if (currdev.d_disk.partition == D_PARTNONE)
+ strlcpy(partition, "<none>", sizeof(partition));
+ else if (currdev.d_disk.d_partition == D_PARTWILD)
+ strlcpy(partition, "<auto>", sizeof(partition));
+ else
sprintf(partition, "%d", currdev.d_disk.partition);
else
- strcpy(partition, "<auto>");
+ snprintf(partition, sizeof(partition), "%d",
+ currdev.d_disk.d_partition);
printf(" Checking unit=%d slice=%s partition=%s...",
currdev.dd.d_unit, slice, partition);
diff --git a/usr/src/boot/sys/boot/uboot/lib/disk.c b/usr/src/boot/sys/boot/uboot/lib/disk.c
index c2c625ee9a..088101aab6 100644
--- a/usr/src/boot/sys/boot/uboot/lib/disk.c
+++ b/usr/src/boot/sys/boot/uboot/lib/disk.c
@@ -253,8 +253,8 @@ stor_print(int verbose)
for (i = 0; i < stor_info_no; i++) {
dev.dd.d_dev = &uboot_storage;
dev.dd.d_unit = i;
- dev.d_slice = -1;
- dev.d_partition = -1;
+ dev.d_slice = D_SLICENONE;
+ dev.d_partition = D_PARTNONE;
sprintf(line, "\tdisk%d (%s)\n", i,
ub_stor_type(SI(&dev).type));
pager_output(line);
diff --git a/usr/src/boot/sys/boot/usb/storage/umass_loader.c b/usr/src/boot/sys/boot/usb/storage/umass_loader.c
index 963e00b61b..cb9d632ebe 100644
--- a/usr/src/boot/sys/boot/usb/storage/umass_loader.c
+++ b/usr/src/boot/sys/boot/usb/storage/umass_loader.c
@@ -184,8 +184,8 @@ umass_disk_print(int verbose)
pager_output(" umass0 UMASS device\n");
dev.d_dev = &umass_disk;
dev.d_unit = 0;
- dev.d_slice = -1;
- dev.d_partition = -1;
+ dev.d_slice = D_SLICENONE;
+ dev.d_partition = D_PARTNONE;
if (umass_disk_open_sub(&dev) == 0) {
disk_print(&dev, " umass0", verbose);
diff --git a/usr/src/boot/sys/boot/userboot/userboot/main.c b/usr/src/boot/sys/boot/userboot/userboot/main.c
index cb8d87ec59..7fa4331e36 100644
--- a/usr/src/boot/sys/boot/userboot/userboot/main.c
+++ b/usr/src/boot/sys/boot/userboot/userboot/main.c
@@ -159,15 +159,15 @@ extract_currdev(void)
} else if (userboot_disk_maxunit > 0) {
dev.dd.d_dev = &userboot_disk;
dev.dd.d_unit = 0;
- dev.d_slice = 0;
- dev.d_partition = 0;
+ dev.d_slice = D_SLICEWILD;
+ dev.d_partition = D_SLICEWILD;
/*
* If we cannot auto-detect the partition type then
* access the disk as a raw device.
*/
if (dev.dd.d_dev->dv_open(NULL, &dev)) {
- dev.d_slice = -1;
- dev.d_partition = -1;
+ dev.d_slice = D_SLICENONE;
+ dev.d_partition = D_SLICENONE;
}
} else {
dev.dd.d_dev = &host_dev;
diff --git a/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c b/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c
index 5e87ef1e25..2742bc11f4 100644
--- a/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c
+++ b/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c
@@ -128,8 +128,8 @@ userdisk_print(int verbose)
pager_output(line);
dev.dd.d_dev = &userboot_disk;
dev.dd.d_unit = i;
- dev.d_slice = -1;
- dev.d_partition = -1;
+ dev.d_slice = D_SLICENONE;
+ dev.d_partition = D_SLICENONE;
if (disk_open(&dev, ud_info[i].mediasize,
ud_info[i].sectorsize) == 0) {
sprintf(line, " disk%d", i);