diff options
author | Toomas Soome <tsoome@me.com> | 2019-04-07 10:19:09 +0300 |
---|---|---|
committer | Toomas Soome <tsoome@me.com> | 2019-06-18 20:44:04 +0300 |
commit | 9a34674dce796d46567833216389d6d430925bb2 (patch) | |
tree | 103748ad29f2aa2a18132be2c0469a50f24a2740 | |
parent | a8412dc108558a7a3635b7ab4f3b1b743bdff9e8 (diff) | |
download | illumos-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.c | 2 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/common/disk.c | 92 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/common/disk.h | 31 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/efipart.c | 4 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/loader/main.c | 6 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/biosdisk.c | 8 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/uboot/common/main.c | 43 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/uboot/lib/disk.c | 4 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/usb/storage/umass_loader.c | 4 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/userboot/userboot/main.c | 8 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c | 4 |
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); |