summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2017-02-07 00:40:29 +0200
committerRobert Mustacchi <rm@joyent.com>2018-06-01 17:19:41 +0000
commitfe12dc752b42da16028a16f4226e5295506fdb28 (patch)
treeb35ccf170aa71b8ae14b63e5cf117aa74f5957ba
parente53a4a814812099ec255c98f18f7ae1d0639ae57 (diff)
downloadillumos-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.c78
-rw-r--r--usr/src/lib/libdiskmgt/common/slice.c555
-rw-r--r--usr/src/lib/libefi/common/rdwr_efi.c31
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);