changeset 18838:13a6e5cc485b

libefi: efi_alloc_and_read should check for PMBR illumos issue #9529
author Toomas Soome <tsoome@me.com>
date Mon, 16 Jul 2018 11:56:55 +0300
parents 87a07e983e42
children 6948264e7927
files usr/src/cmd/fs.d/ufs/mkfs/mkfs.c usr/src/lib/libdiskmgt/common/slice.c usr/src/lib/libefi/common/rdwr_efi.c
diffstat 3 files changed, 438 insertions(+), 367 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c	Tue Mar 13 15:23:29 2018 +0200
+++ b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c	Mon Jul 16 11:56:55 2018 +0300
@@ -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 @@
 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		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 @@
 		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 @@
 	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 @@
 	}
 
 	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 @@
 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 @@
 		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 @@
 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 @@
 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 @@
 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 @@
 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) ||
--- a/usr/src/lib/libdiskmgt/common/slice.c	Tue Mar 13 15:23:29 2018 +0200
+++ b/usr/src/lib/libdiskmgt/common/slice.c	Mon Jul 16 11:56:55 2018 +0300
@@ -79,15 +79,15 @@
     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;
@@ -105,8 +105,8 @@
 {
 	/* 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));
@@ -120,13 +120,13 @@
 	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 */
@@ -134,12 +134,12 @@
 	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);
@@ -161,7 +161,7 @@
 			char	mname[MAXPATHLEN];
 
 			if (*errp != 0) {
-			    return (NULL);
+				return (NULL);
 			}
 
 			mname[0] = 0;
@@ -196,15 +196,15 @@
 	char		*str;
 
 	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) {
@@ -214,50 +214,56 @@
 
 	/* if no cluster use, check for a use of the local name */
 	if (nvlist_lookup_string(stats, DM_USED_BY, &str) != 0) {
-	    disk_t	*diskp;
+		disk_t	*diskp;
+
+		diskp = dp->p.disk;
+		if (diskp->aliases != NULL && diskp->aliases->cluster) {
+			slice_t		*sp;
+			int		snum = -1;
+			struct dk_minfo	minfo;
+			struct dk_cinfo	dkinfo;
+			char		devpath[MAXPATHLEN];
+			int		fd;
 
-	    diskp = dp->p.disk;
-	    if (diskp->aliases != NULL && diskp->aliases->cluster) {
-		slice_t		*sp;
-		int		snum = -1;
-		struct dk_minfo	minfo;
-		struct dk_cinfo	dkinfo;
-		char		devpath[MAXPATHLEN];
-		int		fd;
+			/*
+			 * dp->name is /dev/dsk, need to convert back to
+			 * /dev/rdsk
+			 */
+			dsk2rdsk(dp->name, devpath, sizeof (devpath));
+			fd = open(devpath, O_RDONLY|O_NDELAY);
 
-		/* dp->name is /dev/dsk, need to convert back to /dev/rdsk */
-		dsk2rdsk(dp->name, devpath, sizeof (devpath));
-		fd = open(devpath, O_RDONLY|O_NDELAY);
-
-		if (fd >= 0 && media_read_info(fd, &minfo) &&
-		    ioctl(fd, DKIOCINFO, &dkinfo) >= 0) {
-		    snum = dkinfo.dki_partition;
-		}
+			if (fd >= 0 && media_read_info(fd, &minfo) &&
+			    ioctl(fd, DKIOCINFO, &dkinfo) >= 0) {
+				snum = dkinfo.dki_partition;
+			}
 
-		if (fd >= 0) {
-		    (void) close(fd);
-		}
+			if (fd >= 0) {
+				(void) close(fd);
+			}
 
-		if (snum >= 0) {
-		    for (sp = diskp->aliases->orig_paths; sp != NULL;
-			sp = sp->next) {
+			if (snum >= 0) {
+				for (sp = diskp->aliases->orig_paths;
+				    sp != NULL; sp = sp->next) {
 
-			if (sp->slice_num == snum) {
-			    char	localpath[MAXPATHLEN];
+					if (sp->slice_num == snum) {
+						char	localpath[MAXPATHLEN];
 
-			    slice_rdsk2dsk(sp->devpath, localpath,
-				sizeof (localpath));
+						slice_rdsk2dsk(sp->devpath,
+						    localpath,
+						    sizeof (localpath));
 
-			    if ((*errp = add_inuse(localpath, stats)) != 0) {
-				nvlist_free(stats);
-				return (NULL);
-			    }
+						*errp = add_inuse(localpath,
+						    stats);
+						if (*errp != 0) {
+							nvlist_free(stats);
+							return (NULL);
+						}
 
-			    break;
+						break;
+					}
+				}
 			}
-		    }
 		}
-	    }
 	}
 
 	return (stats);
@@ -274,14 +280,14 @@
 
 	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);
@@ -296,18 +302,18 @@
 	(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);
 	}
 }
 
@@ -321,12 +327,12 @@
 	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);
@@ -338,17 +344,17 @@
 {
 	/* 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));
+		}
 	}
 
 	/*
@@ -371,25 +377,25 @@
 	/* 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';
 	}
 }
 
@@ -411,110 +417,110 @@
 	int		mntpnt = 0;
 
 	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_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_SIZE, vtoc.v_part[snum].p_size)
+		    != 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_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);
-	    }
+		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);
-	    }
-	    mntpnt = 1;
+		if (error != 0) {
+			return (error);
+		}
+		mntpnt = 1;
 	}
 
 	/*
@@ -525,47 +531,53 @@
 	localpath[0] = 0;
 	diskp = dp->p.disk;
 	if (diskp->aliases != NULL && diskp->aliases->cluster) {
-	    slice_t *sp;
+		slice_t *sp;
 
-	    for (sp = diskp->aliases->orig_paths; sp != NULL; sp = sp->next) {
-		if (sp->slice_num == -1) {
-		    /* determine the slice number for this path */
-		    int			sfd;
-		    struct dk_cinfo	dkinfo;
+		for (sp = diskp->aliases->orig_paths; sp != NULL;
+		    sp = sp->next) {
+			if (sp->slice_num == -1) {
+				/* determine the slice number for this path */
+				int			sfd;
+				struct dk_cinfo	dkinfo;
 
-		    if ((sfd = open(sp->devpath, O_RDONLY|O_NDELAY)) >= 0) {
-			if (ioctl(sfd, DKIOCINFO, &dkinfo) >= 0) {
-			    sp->slice_num = dkinfo.dki_partition;
+				sfd = open(sp->devpath, O_RDONLY|O_NDELAY);
+				if (sfd >= 0) {
+					if (ioctl(sfd, DKIOCINFO, &dkinfo)
+					    >= 0) {
+						sp->slice_num =
+						    dkinfo.dki_partition;
+					}
+					(void) close(sfd);
+				}
 			}
-			(void) close(sfd);
-		    }
-		}
 
-		if (sp->slice_num == snum) {
-		    slice_rdsk2dsk(sp->devpath, localpath, sizeof (localpath));
+			if (sp->slice_num == snum) {
+				slice_rdsk2dsk(sp->devpath, localpath,
+				    sizeof (localpath));
 
-		    if (nvlist_add_string(attrs, DM_LOCALNAME, localpath)
-			!= 0) {
-			return (ENOMEM);
-		    }
+				if (nvlist_add_string(attrs, DM_LOCALNAME,
+				    localpath) != 0) {
+					return (ENOMEM);
+				}
 
-		    if (mntpnt == 0) {
-			if (inuse_mnt(localpath, attrs, &error)) {
-			    if (error != 0) {
-				return (error);
-			    }
+				if (mntpnt == 0) {
+					if (inuse_mnt(localpath, attrs,
+					    &error)) {
+						if (error != 0) {
+							return (error);
+						}
+					}
+				}
+
+				break;
 			}
-		    }
-
-		    break;
 		}
-	    }
 	}
 
 	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);
+		}
 	}
 
 	/*
@@ -575,39 +587,40 @@
 	 * device.
 	 */
 	if (localpath[0] != 0) {
-	    cooked_fd = open(localpath, O_RDONLY|O_NDELAY);
+		cooked_fd = open(localpath, O_RDONLY|O_NDELAY);
 	} else {
-	    cooked_fd = open(dp->name, O_RDONLY|O_NDELAY);
+		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);
@@ -628,84 +641,85 @@
 	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];
+		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_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;
-		}
-	    }
 
-	    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);
+		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;
+			}
 		}
-		return (NULL);
-	    }
-	    pos++;
+
+		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);
+		}
+		pos++;
 	}
 	slices[pos] = NULL;
 
 	if (data_format == FMT_EFI) {
-	    efi_free(efip);
+		efi_free(efip);
 	}
 
 	*errp = 0;
@@ -717,15 +731,15 @@
 {
 	/* 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);
@@ -744,63 +758,63 @@
 
 	/* 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];
+		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;
-	    }
+		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 (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 ((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);
+			}
 		}
-	    }
 
-	    /* can't get slice data, so no need to keep trying the drive */
-	    if (data_format == FMT_UNKNOWN) {
-		break;
-	    }
-
-	    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);
@@ -824,32 +838,32 @@
 
 	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);
 	}
 
 	/*
@@ -860,40 +874,46 @@
 	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;
--- a/usr/src/lib/libefi/common/rdwr_efi.c	Tue Mar 13 15:23:29 2018 +0200
+++ b/usr/src/lib/libefi/common/rdwr_efi.c	Mon Jul 16 11:56:55 2018 +0300
@@ -207,6 +207,37 @@
 	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);