diff options
author | Toomas Soome <tsoome@me.com> | 2017-02-07 00:40:29 +0200 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2018-06-01 17:19:41 +0000 |
commit | fe12dc752b42da16028a16f4226e5295506fdb28 (patch) | |
tree | b35ccf170aa71b8ae14b63e5cf117aa74f5957ba | |
parent | e53a4a814812099ec255c98f18f7ae1d0639ae57 (diff) | |
download | illumos-joyent-fe12dc752b42da16028a16f4226e5295506fdb28.tar.gz |
9529 libefi: efi_alloc_and_read should check for PMBR
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/cmd/fs.d/ufs/mkfs/mkfs.c | 78 | ||||
-rw-r--r-- | usr/src/lib/libdiskmgt/common/slice.c | 555 | ||||
-rw-r--r-- | usr/src/lib/libefi/common/rdwr_efi.c | 31 |
3 files changed, 361 insertions, 303 deletions
diff --git a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c index 7cf5e1c5a0..6b5439d47c 100644 --- a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c +++ b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c @@ -24,7 +24,7 @@ */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 @@ -64,7 +64,7 @@ * bsize - block size * fragsize - fragment size * cgsize - The number of disk cylinders per cylinder group. - * free - minimum free space + * free - minimum free space * rps - rotational speed (rev/sec). * nbpi - number of data bytes per allocated inode * opt - optimization (space, time) @@ -248,7 +248,7 @@ #include <sys/statvfs.h> #include <locale.h> #include <fcntl.h> -#include <sys/isa_defs.h> /* for ENDIAN defines */ +#include <sys/isa_defs.h> /* for ENDIAN defines */ #include <sys/vtoc.h> #include <sys/dkio.h> @@ -508,9 +508,9 @@ long ntrack = DFLNTRAK; /* tracks per cylinder group */ int ntrack_flag = RC_DEFAULT; long bsize = DESBLKSIZE; /* filesystem block size */ int bsize_flag = RC_DEFAULT; -long fragsize = DESFRAGSIZE; /* filesystem fragment size */ +long fragsize = DESFRAGSIZE; /* filesystem fragment size */ int fragsize_flag = RC_DEFAULT; -long minfree = MINFREE; /* fs_minfree */ +long minfree = MINFREE; /* fs_minfree */ int minfree_flag = RC_DEFAULT; long rps = DEFHZ; /* revolutions/second of drive */ int rps_flag = RC_DEFAULT; @@ -611,8 +611,8 @@ void wlockfs(void); void clockfs(void); void wtsb(void); static int64_t checkfragallocated(daddr32_t); -static struct csum *read_summaryinfo(struct fs *); -static diskaddr_t probe_summaryinfo(); +static struct csum *read_summaryinfo(struct fs *); +static diskaddr_t probe_summaryinfo(); int main(int argc, char *argv[]) @@ -765,7 +765,7 @@ main(int argc, char *argv[]) case 'G': /* grow the file system */ grow = 1; break; - case 'P': /* probe the file system growing size */ + case 'P': /* probe the file system growing size */ Pflag = 1; grow = 1; /* probe mode implies fs growing */ break; @@ -2379,6 +2379,17 @@ grow50: return (0); } +static diskaddr_t +get_device_size(int fd) +{ + struct dk_minfo disk_info; + + if ((ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info)) == -1) + return (0); + + return (disk_info.dki_capacity); +} + /* * Figure out how big the partition we're dealing with is. * The value returned is in disk blocks (sectors); @@ -2403,23 +2414,32 @@ get_max_size(int fd) } if (index < 0) { - switch (index) { - case VT_ERROR: - break; - case VT_EIO: - errno = EIO; - break; - case VT_EINVAL: - errno = EINVAL; + /* + * Since both attempts to read the label failed, we're + * going to use DKIOCGMEDIAINFO to get device size. + */ + + label_type = LABEL_TYPE_OTHER; + slicesize = get_device_size(fd); + if (slicesize == 0) { + switch (index) { + case VT_ERROR: + break; + case VT_EIO: + errno = EIO; + break; + case VT_EINVAL: + errno = EINVAL; + } + perror(gettext("Can not determine partition size")); + lockexit(32); } - perror(gettext("Can not determine partition size")); - lockexit(32); } if (label_type == LABEL_TYPE_EFI) { slicesize = efi_vtoc->efi_parts[index].p_size; efi_free(efi_vtoc); - } else { + } else if (label_type == LABEL_TYPE_VTOC) { /* * In the vtoc struct, p_size is a 32-bit signed quantity. * In the dk_gpt struct (efi's version of the vtoc), p_size @@ -3265,8 +3285,8 @@ static void awtfs(diskaddr_t bno, int size, char *bf, int release) { int n; - aio_trans *transp; - sigset_t old_mask; + aio_trans *transp; + sigset_t old_mask; if (fso == -1) return; @@ -4452,9 +4472,9 @@ findcsfragino() dp = gdinode((ino_t)i); switch (dp->di_mode & IFMT) { case IFSHAD : - case IFLNK : - case IFDIR : - case IFREG : break; + case IFLNK : + case IFDIR : + case IFREG : break; default : continue; } @@ -4537,7 +4557,7 @@ fixcsfragino() static struct csum * read_summaryinfo(struct fs *fsp) { - struct csum *csp; + struct csum *csp; int i; if ((csp = malloc((size_t)fsp->fs_cssize)) == NULL) { @@ -4565,7 +4585,7 @@ read_summaryinfo(struct fs *fsp) int64_t checkfragallocated(daddr32_t frag) { - struct csfrag *cfp; + struct csfrag *cfp; /* * Since the lists are sorted we can break the search if the asked * frag is smaller then the one in the list. @@ -4601,12 +4621,12 @@ diskaddr_t probe_summaryinfo() { /* fragments by which the csum block can be extended. */ - int64_t growth_csum_frags = 0; + int64_t growth_csum_frags = 0; /* fragments by which the filesystem can be extended. */ int64_t growth_fs_frags = 0; int64_t new_fs_cssize; /* size of csum blk in the new FS */ int64_t new_fs_ncg; /* number of cg in the new FS */ - int64_t spare_csum; + int64_t spare_csum; daddr32_t oldfrag_daddr; daddr32_t newfrag_daddr; daddr32_t daddr; @@ -5690,7 +5710,7 @@ in_64bit_mode(void) static int validate_size(int fd, diskaddr_t size) { - char buf[DEV_BSIZE]; + char buf[DEV_BSIZE]; int rc; if ((llseek(fd, (offset_t)((size - 1) * DEV_BSIZE), SEEK_SET) == -1) || diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c index 311b8285e6..979145f9eb 100644 --- a/usr/src/lib/libdiskmgt/common/slice.c +++ b/usr/src/lib/libdiskmgt/common/slice.c @@ -83,15 +83,15 @@ slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, int *errp) { if (!desc_ok(desc)) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } switch (type) { case DM_MEDIA: - return (media_get_assocs(desc, errp)); + return (media_get_assocs(desc, errp)); case DM_PARTITION: - return (partition_get_assocs(desc, errp)); + return (partition_get_assocs(desc, errp)); } *errp = EINVAL; @@ -109,8 +109,8 @@ slice_get_assocs(descriptor_t *desc, int *errp) { /* Just check the first drive name. */ if (desc->p.disk->aliases == NULL) { - *errp = 0; - return (libdiskmgt_empty_desc_array(errp)); + *errp = 0; + return (libdiskmgt_empty_desc_array(errp)); } return (get_fixed_assocs(desc, errp)); @@ -124,13 +124,13 @@ slice_get_attributes(descriptor_t *dp, int *errp) char devpath[MAXPATHLEN]; if (!desc_ok(dp)) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { - *errp = ENOMEM; - return (NULL); + *errp = ENOMEM; + return (NULL); } /* dp->name is /dev/dsk, need to convert back to /dev/rdsk */ @@ -138,12 +138,12 @@ slice_get_attributes(descriptor_t *dp, int *errp) fd = open(devpath, O_RDONLY|O_NDELAY); if ((*errp = get_attrs(dp, fd, attrs)) != 0) { - nvlist_free(attrs); - attrs = NULL; + nvlist_free(attrs); + attrs = NULL; } if (fd >= 0) { - (void) close(fd); + (void) close(fd); } return (attrs); @@ -165,7 +165,7 @@ slice_get_descriptor_by_name(char *name, int *errp) char mname[MAXPATHLEN]; if (*errp != 0) { - return (NULL); + return (NULL); } mname[0] = 0; @@ -199,15 +199,15 @@ slice_get_stats(descriptor_t *dp, int stat_type, int *errp) nvlist_t *stats; if (stat_type != DM_SLICE_STAT_USE) { - *errp = EINVAL; - return (NULL); + *errp = EINVAL; + return (NULL); } *errp = 0; if (nvlist_alloc(&stats, NVATTRS_STAT, 0) != 0) { - *errp = ENOMEM; - return (NULL); + *errp = ENOMEM; + return (NULL); } if ((*errp = add_inuse(dp->name, stats)) != 0) { @@ -229,14 +229,14 @@ slice_make_descriptors() dp = cache_get_disklist(); while (dp != NULL) { - int error; + int error; - error = make_fixed_descriptors(dp); - if (error != 0) { - return (error); - } + error = make_fixed_descriptors(dp); + if (error != 0) { + return (error); + } - dp = dp->next; + dp = dp->next; } return (0); @@ -251,18 +251,18 @@ slice_rdsk2dsk(char *rdsk, char *dsk, int size) (void) strlcpy(dsk, rdsk, size); if ((strp = strstr(dsk, "/rdsk/")) == NULL) { - /* not rdsk, check for floppy */ - strp = strstr(dsk, "/rdiskette"); + /* not rdsk, check for floppy */ + strp = strstr(dsk, "/rdiskette"); } if (strp != NULL) { - strp++; /* move ptr to the r in rdsk or rdiskette */ + strp++; /* move ptr to the r in rdsk or rdiskette */ - /* move the succeeding chars over by one */ - do { - *strp = *(strp + 1); - strp++; - } while (*strp); + /* move the succeeding chars over by one */ + do { + *strp = *(strp + 1); + strp++; + } while (*strp); } } @@ -276,12 +276,12 @@ add_inuse(char *name, nvlist_t *attrs) int error; for (i = 0; detectors[i] != NULL; i ++) { - if (detectors[i](name, attrs, &error) || error != 0) { - if (error != 0) { - return (error); + if (detectors[i](name, attrs, &error) || error != 0) { + if (error != 0) { + return (error); + } + break; } - break; - } } return (0); @@ -293,17 +293,17 @@ desc_ok(descriptor_t *dp) { /* First verify the media name for removable media */ if (dp->p.disk->removable) { - char mname[MAXPATHLEN]; + char mname[MAXPATHLEN]; - if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { - return (0); - } + if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { + return (0); + } - if (mname[0] == 0) { - return (libdiskmgt_str_eq(dp->secondary_name, NULL)); - } else { - return (libdiskmgt_str_eq(dp->secondary_name, mname)); - } + if (mname[0] == 0) { + return (libdiskmgt_str_eq(dp->secondary_name, NULL)); + } else { + return (libdiskmgt_str_eq(dp->secondary_name, mname)); + } } /* @@ -326,25 +326,25 @@ dsk2rdsk(char *dsk, char *rdsk, int size) /* make sure there is enough room to add the r to dsk */ len = strlen(dsk); if (len + 2 > size) { - return; + return; } if ((slashp = strstr(rdsk, "/dsk/")) == NULL) { - /* not dsk, check for floppy */ - slashp = strstr(rdsk, "/diskette"); + /* not dsk, check for floppy */ + slashp = strstr(rdsk, "/diskette"); } if (slashp != NULL) { - char *endp; + char *endp; - endp = rdsk + len; /* point to terminating 0 */ - /* move the succeeding chars over by one */ - do { - *(endp + 1) = *endp; - endp--; - } while (endp != slashp); + endp = rdsk + len; /* point to terminating 0 */ + /* move the succeeding chars over by one */ + do { + *(endp + 1) = *endp; + endp--; + } while (endp != slashp); - *(endp + 1) = 'r'; + *(endp + 1) = 'r'; } } @@ -363,114 +363,113 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs) struct stat buf; if (fd < 0) { - return (ENODEV); + return (ENODEV); } /* First make sure media is inserted and spun up. */ if (!media_read_info(fd, &minfo)) { - return (ENODEV); + return (ENODEV); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; + data_format = FMT_VTOC; } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - if (nvlist_add_boolean(attrs, DM_EFI) != 0) { - efi_free(efip); - return (ENOMEM); - } + data_format = FMT_EFI; + if (nvlist_add_boolean(attrs, DM_EFI) != 0) { + efi_free(efip); + return (ENOMEM); + } } if (data_format == FMT_UNKNOWN) { - return (ENODEV); + return (ENODEV); } if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { - snum = dkinfo.dki_partition; + snum = dkinfo.dki_partition; } /* check the slice */ if (data_format == FMT_VTOC) { - if (snum < 0 || snum >= vtoc.v_nparts || - vtoc.v_part[snum].p_size == 0) { - return (ENODEV); - } + if (snum < 0 || snum >= vtoc.v_nparts || + vtoc.v_part[snum].p_size == 0) { + return (ENODEV); + } } else { /* data_format == FMT_EFI */ - if (snum < 0 || snum >= efip->efi_nparts || - efip->efi_parts[snum].p_size == 0) { - efi_free(efip); - return (ENODEV); - } + if (snum < 0 || snum >= efip->efi_nparts || + efip->efi_parts[snum].p_size == 0) { + efi_free(efip); + return (ENODEV); + } } /* the slice exists */ if (nvlist_add_uint32(attrs, DM_INDEX, snum) != 0) { - if (data_format == FMT_EFI) { - efi_free(efip); - } - return (ENOMEM); + if (data_format == FMT_EFI) { + efi_free(efip); + } + return (ENOMEM); } if (data_format == FMT_VTOC) { - if (nvlist_add_uint64(attrs, DM_START, vtoc.v_part[snum].p_start) - != 0) { - return (ENOMEM); - } - - if (nvlist_add_uint64(attrs, DM_SIZE, vtoc.v_part[snum].p_size) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_START, + vtoc.v_part[snum].p_start) != 0) { + return (ENOMEM); + } - if (nvlist_add_uint32(attrs, DM_TAG, vtoc.v_part[snum].p_tag) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_SIZE, + vtoc.v_part[snum].p_size) != 0) { + return (ENOMEM); + } - if (nvlist_add_uint32(attrs, DM_FLAG, vtoc.v_part[snum].p_flag) - != 0) { - return (ENOMEM); - } + if (nvlist_add_uint32(attrs, DM_TAG, + vtoc.v_part[snum].p_tag) != 0) { + return (ENOMEM); + } + if (nvlist_add_uint32(attrs, DM_FLAG, + vtoc.v_part[snum].p_flag) != 0) { + return (ENOMEM); + } } else { /* data_format == FMT_EFI */ - if (nvlist_add_uint64(attrs, DM_START, - efip->efi_parts[snum].p_start) != 0) { - efi_free(efip); - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_START, + efip->efi_parts[snum].p_start) != 0) { + efi_free(efip); + return (ENOMEM); + } - if (nvlist_add_uint64(attrs, DM_SIZE, efip->efi_parts[snum].p_size) - != 0) { - efi_free(efip); - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_SIZE, + efip->efi_parts[snum].p_size) != 0) { + efi_free(efip); + return (ENOMEM); + } - if (efip->efi_parts[snum].p_name[0] != 0) { - char label[EFI_PART_NAME_LEN + 1]; + if (efip->efi_parts[snum].p_name[0] != 0) { + char label[EFI_PART_NAME_LEN + 1]; - (void) snprintf(label, sizeof (label), "%.*s", - EFI_PART_NAME_LEN, efip->efi_parts[snum].p_name); - if (nvlist_add_string(attrs, DM_EFI_NAME, label) != 0) { - efi_free(efip); - return (ENOMEM); + (void) snprintf(label, sizeof (label), "%.*s", + EFI_PART_NAME_LEN, efip->efi_parts[snum].p_name); + if (nvlist_add_string(attrs, DM_EFI_NAME, label) != 0) { + efi_free(efip); + return (ENOMEM); + } } - } } if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } if (inuse_mnt(dp->name, attrs, &error)) { - if (error != 0) - return (error); + if (error != 0) + return (error); } if (fstat(fd, &buf) != -1) { - if (nvlist_add_uint64(attrs, DM_DEVT, buf.st_rdev) != 0) { - return (ENOMEM); - } + if (nvlist_add_uint64(attrs, DM_DEVT, buf.st_rdev) != 0) { + return (ENOMEM); + } } /* @@ -480,33 +479,34 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs) cooked_fd = open(dp->name, O_RDONLY|O_NDELAY); if (cooked_fd >= 0) { - int no_mem = 0; - ddi_devid_t devid; + int no_mem = 0; + ddi_devid_t devid; - if (devid_get(cooked_fd, &devid) == 0) { - char *minor; + if (devid_get(cooked_fd, &devid) == 0) { + char *minor; - if (devid_get_minor_name(cooked_fd, &minor) == 0) { - char *devidstr; + if (devid_get_minor_name(cooked_fd, &minor) == 0) { + char *devidstr; - if ((devidstr = devid_str_encode(devid, minor)) != 0) { + devidstr = devid_str_encode(devid, minor); + if (devidstr != NULL) { - if (nvlist_add_string(attrs, DM_DEVICEID, devidstr) - != 0) { - no_mem = 1; - } + if (nvlist_add_string(attrs, + DM_DEVICEID, devidstr) != 0) { + no_mem = 1; + } - devid_str_free(devidstr); - } - devid_str_free(minor); + devid_str_free(devidstr); + } + devid_str_free(minor); + } + devid_free(devid); } - devid_free(devid); - } - (void) close(cooked_fd); + (void) close(cooked_fd); - if (no_mem) { - return (ENOMEM); - } + if (no_mem) { + return (ENOMEM); + } } return (0); @@ -527,84 +527,85 @@ get_fixed_assocs(descriptor_t *desc, int *errp) descriptor_t **slices; if ((fd = drive_open_disk(desc->p.disk, NULL, 0)) < 0) { - *errp = ENODEV; - return (NULL); + *errp = ENODEV; + return (NULL); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; + data_format = FMT_VTOC; } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; + data_format = FMT_EFI; } else { - (void) close(fd); - *errp = 0; - return (libdiskmgt_empty_desc_array(errp)); + (void) close(fd); + *errp = 0; + return (libdiskmgt_empty_desc_array(errp)); } (void) close(fd); /* count the number of slices */ - for (cnt = 0, devp = desc->p.disk->aliases->devpaths; devp != NULL; - devp = devp->next, cnt++); + devp = desc->p.disk->aliases->devpaths; + for (cnt = 0; devp != NULL; devp = devp->next) + cnt++; /* allocate the array for the descriptors */ slices = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); if (slices == NULL) { - if (data_format == FMT_EFI) { - efi_free(efip); - } - *errp = ENOMEM; - return (NULL); + if (data_format == FMT_EFI) { + efi_free(efip); + } + *errp = ENOMEM; + return (NULL); } /* get the media name from the descriptor */ if (desc->type == DM_MEDIA) { - media_name = desc->name; + media_name = desc->name; } else { - /* must be a DM_PARTITION */ - media_name = desc->secondary_name; + /* must be a DM_PARTITION */ + media_name = desc->secondary_name; } pos = 0; for (devp = desc->p.disk->aliases->devpaths; devp != NULL; devp = devp->next) { - int slice_num; - char devpath[MAXPATHLEN]; - - slice_num = get_slice_num(devp); - /* can't get slicenum, so no need to keep trying the drive */ - if (slice_num == -1) { - break; - } + int slice_num; + char devpath[MAXPATHLEN]; - if (data_format == FMT_VTOC) { - if (slice_num >= vtoc.v_nparts || - vtoc.v_part[slice_num].p_size == 0) { - continue; + slice_num = get_slice_num(devp); + /* can't get slicenum, so no need to keep trying the drive */ + if (slice_num == -1) { + break; } - } else { /* data_format == FMT_EFI */ - if (slice_num >= efip->efi_nparts || - efip->efi_parts[slice_num].p_size == 0) { - continue; + + if (data_format == FMT_VTOC) { + if (slice_num >= vtoc.v_nparts || + vtoc.v_part[slice_num].p_size == 0) { + continue; + } + } else { /* data_format == FMT_EFI */ + if (slice_num >= efip->efi_nparts || + efip->efi_parts[slice_num].p_size == 0) { + continue; + } } - } - slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); - slices[pos] = cache_get_desc(DM_SLICE, desc->p.disk, devpath, - media_name, errp); - if (*errp != 0) { - cache_free_descriptors(slices); - if (data_format == FMT_EFI) { - efi_free(efip); + slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); + slices[pos] = cache_get_desc(DM_SLICE, desc->p.disk, devpath, + media_name, errp); + if (*errp != 0) { + cache_free_descriptors(slices); + if (data_format == FMT_EFI) { + efi_free(efip); + } + return (NULL); } - return (NULL); - } - pos++; + pos++; } slices[pos] = NULL; if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } *errp = 0; @@ -616,15 +617,15 @@ get_slice_num(slice_t *devp) { /* check if we already determined the devpath slice number */ if (devp->slice_num == -1) { - int fd; + int fd; - if ((fd = open(devp->devpath, O_RDONLY|O_NDELAY)) >= 0) { - struct dk_cinfo dkinfo; - if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { - devp->slice_num = dkinfo.dki_partition; + if ((fd = open(devp->devpath, O_RDONLY|O_NDELAY)) >= 0) { + struct dk_cinfo dkinfo; + if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) { + devp->slice_num = dkinfo.dki_partition; + } + (void) close(fd); } - (void) close(fd); - } } return (devp->slice_num); @@ -643,63 +644,63 @@ make_fixed_descriptors(disk_t *dp) /* Just check the first drive name. */ if ((ap = dp->aliases) == NULL) { - return (0); + return (0); } mname[0] = 0; (void) media_read_name(dp, mname, sizeof (mname)); for (devp = ap->devpaths; devp != NULL; devp = devp->next) { - int slice_num; - char devpath[MAXPATHLEN]; - - slice_num = get_slice_num(devp); - /* can't get slicenum, so no need to keep trying the drive */ - if (slice_num == -1) { - break; - } - - if (data_format == FMT_UNKNOWN) { - int fd; - int status; - - if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) { - if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && - efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; - } - (void) close(fd); + int slice_num; + char devpath[MAXPATHLEN]; + + slice_num = get_slice_num(devp); + /* can't get slicenum, so no need to keep trying the drive */ + if (slice_num == -1) { + break; } - } - /* can't get slice data, so no need to keep trying the drive */ - if (data_format == FMT_UNKNOWN) { - break; - } + if (data_format == FMT_UNKNOWN) { + int fd; + int status; + + if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) { + if ((status = read_extvtoc(fd, &vtoc)) >= 0) { + data_format = FMT_VTOC; + } else if (status == VT_ENOTSUP && + efi_alloc_and_read(fd, &efip) >= 0) { + data_format = FMT_EFI; + } + (void) close(fd); + } + } - if (data_format == FMT_VTOC) { - if (slice_num >= vtoc.v_nparts || - vtoc.v_part[slice_num].p_size == 0) { - continue; + /* can't get slice data, so no need to keep trying the drive */ + if (data_format == FMT_UNKNOWN) { + break; } - } else { /* data_format == FMT_EFI */ - if (slice_num >= efip->efi_nparts || - efip->efi_parts[slice_num].p_size == 0) { - continue; + + if (data_format == FMT_VTOC) { + if (slice_num >= vtoc.v_nparts || + vtoc.v_part[slice_num].p_size == 0) { + continue; + } + } else { /* data_format == FMT_EFI */ + if (slice_num >= efip->efi_nparts || + efip->efi_parts[slice_num].p_size == 0) { + continue; + } } - } - slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); - cache_load_desc(DM_SLICE, dp, devpath, mname, &error); - if (error != 0) { - break; - } + slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath)); + cache_load_desc(DM_SLICE, dp, devpath, mname, &error); + if (error != 0) { + break; + } } if (data_format == FMT_EFI) { - efi_free(efip); + efi_free(efip); } return (error); @@ -723,32 +724,32 @@ match_fixed_name(disk_t *diskp, char *name, int *errp) ap = diskp->aliases; while (ap != NULL) { - slice_t *devp; + slice_t *devp; - devp = ap->devpaths; - while (devp != NULL) { - char path[MAXPATHLEN]; + devp = ap->devpaths; + while (devp != NULL) { + char path[MAXPATHLEN]; - slice_rdsk2dsk(devp->devpath, path, sizeof (path)); - if (libdiskmgt_str_eq(path, name)) { - /* found it */ - dp = devp; - break; - } + slice_rdsk2dsk(devp->devpath, path, sizeof (path)); + if (libdiskmgt_str_eq(path, name)) { + /* found it */ + dp = devp; + break; + } - devp = devp->next; - } + devp = devp->next; + } - if (dp != NULL) { - break; - } + if (dp != NULL) { + break; + } - ap = ap->next; + ap = ap->next; } if (dp == NULL) { - *errp = 0; - return (0); + *errp = 0; + return (0); } /* @@ -759,40 +760,46 @@ match_fixed_name(disk_t *diskp, char *name, int *errp) slice_num = get_slice_num(dp); /* can't get slicenum, so no slice */ if (slice_num == -1) { - *errp = ENODEV; - return (1); + *errp = ENODEV; + return (1); } if ((fd = drive_open_disk(diskp, NULL, 0)) < 0) { - *errp = ENODEV; - return (1); + *errp = ENODEV; + return (1); } if ((status = read_extvtoc(fd, &vtoc)) >= 0) { - data_format = FMT_VTOC; - } else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) { - data_format = FMT_EFI; + data_format = FMT_VTOC; + } else if (status == VT_ENOTSUP) { + status = efi_alloc_and_read(fd, &efip); + if (status >= 0) { + data_format = FMT_EFI; + } else if (status == VT_ERROR && errno == ENOTTY) { + *errp = 0; + return (1); + } } else { - (void) close(fd); - *errp = ENODEV; - return (1); + (void) close(fd); + *errp = ENODEV; + return (1); } (void) close(fd); if (data_format == FMT_VTOC) { - if (slice_num < vtoc.v_nparts && - vtoc.v_part[slice_num].p_size > 0) { - *errp = 0; - return (1); - } + if (slice_num < vtoc.v_nparts && + vtoc.v_part[slice_num].p_size > 0) { + *errp = 0; + return (1); + } } else { /* data_format == FMT_EFI */ - if (slice_num < efip->efi_nparts && - efip->efi_parts[slice_num].p_size > 0) { + if (slice_num < efip->efi_nparts && + efip->efi_parts[slice_num].p_size > 0) { + efi_free(efip); + *errp = 0; + return (1); + } efi_free(efip); - *errp = 0; - return (1); - } - efi_free(efip); } *errp = ENODEV; diff --git a/usr/src/lib/libefi/common/rdwr_efi.c b/usr/src/lib/libefi/common/rdwr_efi.c index e40f4f9b38..a878cb50d2 100644 --- a/usr/src/lib/libefi/common/rdwr_efi.c +++ b/usr/src/lib/libefi/common/rdwr_efi.c @@ -211,6 +211,37 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc) int rval; uint32_t nparts; int length; + struct mboot *mbr; + struct ipart *ipart; + diskaddr_t capacity; + uint_t lbsize; + int i; + + if (read_disk_info(fd, &capacity, &lbsize) != 0) + return (VT_ERROR); + + if ((mbr = calloc(lbsize, 1)) == NULL) + return (VT_ERROR); + + if ((ioctl(fd, DKIOCGMBOOT, (caddr_t)mbr)) == -1) { + free(mbr); + return (VT_ERROR); + } + + if (mbr->signature != MBB_MAGIC) { + free(mbr); + return (VT_EINVAL); + } + ipart = (struct ipart *)(uintptr_t)mbr->parts; + + /* Check if we have partition with ID EFI_PMBR */ + for (i = 0; i < FD_NUMPART; i++) { + if (ipart[i].systid == EFI_PMBR) + break; + } + free(mbr); + if (i == FD_NUMPART) + return (VT_EINVAL); /* figure out the number of entries that would fit into 16K */ nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t); |