Index: bootadm/usr/src/cmd/boot/bootadm/Makefile =================================================================== --- bootadm.orig/usr/src/cmd/boot/bootadm/Makefile 2013-01-12 18:30:39.777698514 +0400 +++ bootadm/usr/src/cmd/boot/bootadm/Makefile 2013-01-12 19:13:35.399844029 +0400 @@ -36,7 +36,7 @@ .KEEP_STATE: LDLIBS_i386= -lfdisk -LDLIBS += -lnvpair -lgen -ladm -lefi -lscf -lz $(LDLIBS_$(MACH)) +LDLIBS += -lnvpair -lgen -lefi -lscf -lz $(LDLIBS_$(MACH)) # Writing into string literals is incorrect. We need to match gcc's # behavior, which causes us to take SIGSEGV on such a write. Index: bootadm/usr/src/cmd/boot/bootadm/bootadm.c =================================================================== --- bootadm.orig/usr/src/cmd/boot/bootadm/bootadm.c 2013-01-12 18:30:40.181503527 +0400 +++ bootadm/usr/src/cmd/boot/bootadm/bootadm.c 2013-01-12 19:13:56.279332395 +0400 @@ -63,6 +63,7 @@ #include #include #include +#include #ifdef i386 #include #endif @@ -79,6 +80,87 @@ #include #include +/* From libadm. + * Read VTOC - return partition number. + */ +static int +__read_vtoc(int fd, struct vtoc *vtoc) +{ + struct dk_cinfo dki_info; + + /* + * Read the vtoc. + */ + if (ioctl(fd, DKIOCGVTOC, (caddr_t)vtoc) == -1) { + switch (errno) { + case EIO: + return (VT_EIO); + case EINVAL: + return (VT_EINVAL); + case ENOTSUP: + /* GPT labeled or disk > 1TB with no extvtoc support */ + return (VT_ENOTSUP); + case EOVERFLOW: + return (VT_EOVERFLOW); + default: + return (VT_ERROR); + } + } + + /* + * Sanity-check the vtoc. + */ + if (vtoc->v_sanity != VTOC_SANE) { + return (VT_EINVAL); + } + + /* + * Convert older-style vtoc's. + */ + switch (vtoc->v_version) { + case 0: + /* + * No vtoc information. Install default + * nparts/sectorsz and version. We are + * assuming that the driver returns the + * current partition information correctly. + */ + + vtoc->v_version = V_VERSION; + if (vtoc->v_nparts == 0) + vtoc->v_nparts = V_NUMPAR; + if (vtoc->v_sectorsz == 0) + vtoc->v_sectorsz = DEV_BSIZE; + + break; + + case V_VERSION: + break; + + default: + return (VT_EINVAL); + } + + /* + * Return partition number for this file descriptor. + */ + if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) { + switch (errno) { + case EIO: + return (VT_EIO); + case EINVAL: + return (VT_EINVAL); + default: + return (VT_ERROR); + } + } + if (dki_info.dki_partition > V_NUMPAR) { + return (VT_EINVAL); + } + return ((int)dki_info.dki_partition); +} + + #include "message.h" #include "bootadm.h" @@ -6119,7 +6201,7 @@ } e_flag = v_flag = 0; - retval = ((err = read_vtoc(fd, &vtoc)) >= 0) ? 0 : err; + retval = ((err = __read_vtoc(fd, &vtoc)) >= 0) ? 0 : err; switch (retval) { case VT_EIO: BAM_DPRINTF((D_VTOC_READ_FAIL, fcn, s0path));