1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 30*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <strings.h> 35*7c478bd9Sstevel@tonic-gate #include <stropts.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 41*7c478bd9Sstevel@tonic-gate #include <volmgt.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/efi_partition.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include "libdiskmgt.h" 45*7c478bd9Sstevel@tonic-gate #include "disks_private.h" 46*7c478bd9Sstevel@tonic-gate #include "partition.h" 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define IOCTLRETRIES 2 49*7c478bd9Sstevel@tonic-gate #define IOCTLRETRYINTERVAL 1 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate static descriptor_t **apply_filter(descriptor_t **media, int filter[], 52*7c478bd9Sstevel@tonic-gate int *errp); 53*7c478bd9Sstevel@tonic-gate static int get_attrs(disk_t *dp, int fd, nvlist_t *attrs); 54*7c478bd9Sstevel@tonic-gate static int get_non_volm_name(disk_t *dp, char *mname, int size); 55*7c478bd9Sstevel@tonic-gate static int get_media_type(uint_t media_type); 56*7c478bd9Sstevel@tonic-gate static int desc_ok(descriptor_t *dp); 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate * This function gets the descriptors we are associated with. 60*7c478bd9Sstevel@tonic-gate */ 61*7c478bd9Sstevel@tonic-gate descriptor_t ** 62*7c478bd9Sstevel@tonic-gate media_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, 63*7c478bd9Sstevel@tonic-gate int *errp) 64*7c478bd9Sstevel@tonic-gate { 65*7c478bd9Sstevel@tonic-gate if (!desc_ok(desc)) { 66*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 67*7c478bd9Sstevel@tonic-gate return (NULL); 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate switch (type) { 71*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 72*7c478bd9Sstevel@tonic-gate return (drive_get_assocs(desc, errp)); 73*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 74*7c478bd9Sstevel@tonic-gate return (partition_get_assocs(desc, errp)); 75*7c478bd9Sstevel@tonic-gate case DM_SLICE: 76*7c478bd9Sstevel@tonic-gate return (slice_get_assocs(desc, errp)); 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 80*7c478bd9Sstevel@tonic-gate return (NULL); 81*7c478bd9Sstevel@tonic-gate } 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * Get the media descriptors for the given drive/partition/slice. 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate descriptor_t ** 87*7c478bd9Sstevel@tonic-gate media_get_assocs(descriptor_t *dp, int *errp) 88*7c478bd9Sstevel@tonic-gate { 89*7c478bd9Sstevel@tonic-gate descriptor_t **media; 90*7c478bd9Sstevel@tonic-gate char mname[MAXPATHLEN]; 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { 93*7c478bd9Sstevel@tonic-gate /* For drives, this means no media but slice/part. require media. */ 94*7c478bd9Sstevel@tonic-gate if (dp->type == DM_DRIVE) { 95*7c478bd9Sstevel@tonic-gate return (libdiskmgt_empty_desc_array(errp)); 96*7c478bd9Sstevel@tonic-gate } else { 97*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 98*7c478bd9Sstevel@tonic-gate return (NULL); 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* make the snapshot */ 103*7c478bd9Sstevel@tonic-gate media = (descriptor_t **)calloc(2, sizeof (descriptor_t *)); 104*7c478bd9Sstevel@tonic-gate if (media == NULL) { 105*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 106*7c478bd9Sstevel@tonic-gate return (NULL); 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate media[0] = cache_get_desc(DM_MEDIA, dp->p.disk, mname, NULL, errp); 110*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 111*7c478bd9Sstevel@tonic-gate free(media); 112*7c478bd9Sstevel@tonic-gate return (NULL); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate media[1] = NULL; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate *errp = 0; 117*7c478bd9Sstevel@tonic-gate return (media); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate nvlist_t * 121*7c478bd9Sstevel@tonic-gate media_get_attributes(descriptor_t *dp, int *errp) 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL; 124*7c478bd9Sstevel@tonic-gate int fd; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate if (!desc_ok(dp)) { 127*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 128*7c478bd9Sstevel@tonic-gate return (NULL); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { 132*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 133*7c478bd9Sstevel@tonic-gate return (NULL); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate fd = drive_open_disk(dp->p.disk, NULL, 0); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate if ((*errp = get_attrs(dp->p.disk, fd, attrs)) != 0) { 139*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 140*7c478bd9Sstevel@tonic-gate attrs = NULL; 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate if (fd >= 0) { 144*7c478bd9Sstevel@tonic-gate (void) close(fd); 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate return (attrs); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate descriptor_t * 151*7c478bd9Sstevel@tonic-gate media_get_descriptor_by_name(char *name, int *errp) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate descriptor_t **media; 154*7c478bd9Sstevel@tonic-gate int i; 155*7c478bd9Sstevel@tonic-gate descriptor_t *medium = NULL; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate media = cache_get_descriptors(DM_MEDIA, errp); 158*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 159*7c478bd9Sstevel@tonic-gate return (NULL); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate for (i = 0; media[i]; i++) { 163*7c478bd9Sstevel@tonic-gate if (libdiskmgt_str_eq(name, media[i]->name)) { 164*7c478bd9Sstevel@tonic-gate medium = media[i]; 165*7c478bd9Sstevel@tonic-gate } else { 166*7c478bd9Sstevel@tonic-gate /* clean up the unused descriptors */ 167*7c478bd9Sstevel@tonic-gate cache_free_descriptor(media[i]); 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate free(media); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (medium == NULL) { 173*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate return (medium); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate descriptor_t ** 180*7c478bd9Sstevel@tonic-gate media_get_descriptors(int filter[], int *errp) 181*7c478bd9Sstevel@tonic-gate { 182*7c478bd9Sstevel@tonic-gate descriptor_t **media; 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate media = cache_get_descriptors(DM_MEDIA, errp); 185*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 186*7c478bd9Sstevel@tonic-gate return (NULL); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate if (filter != NULL && filter[0] != DM_FILTER_END) { 190*7c478bd9Sstevel@tonic-gate descriptor_t **found; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate found = apply_filter(media, filter, errp); 193*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 194*7c478bd9Sstevel@tonic-gate media = NULL; 195*7c478bd9Sstevel@tonic-gate } else { 196*7c478bd9Sstevel@tonic-gate media = found; 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate return (media); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate char * 204*7c478bd9Sstevel@tonic-gate media_get_name(descriptor_t *desc) 205*7c478bd9Sstevel@tonic-gate { 206*7c478bd9Sstevel@tonic-gate return (desc->name); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 210*7c478bd9Sstevel@tonic-gate nvlist_t * 211*7c478bd9Sstevel@tonic-gate media_get_stats(descriptor_t *dp, int stat_type, int *errp) 212*7c478bd9Sstevel@tonic-gate { 213*7c478bd9Sstevel@tonic-gate /* There are no stat types defined for media */ 214*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 215*7c478bd9Sstevel@tonic-gate return (NULL); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate /* 219*7c478bd9Sstevel@tonic-gate * Get the removable media volume manager devpath for the disk. This is the 220*7c478bd9Sstevel@tonic-gate * name we need to open that will work with vold. 221*7c478bd9Sstevel@tonic-gate * Return 1 if under volm control, 0 if not under volm control. 222*7c478bd9Sstevel@tonic-gate * The string in mediapath will be empty if the drive is under volm control 223*7c478bd9Sstevel@tonic-gate * but there is no media loaded. 224*7c478bd9Sstevel@tonic-gate */ 225*7c478bd9Sstevel@tonic-gate int 226*7c478bd9Sstevel@tonic-gate media_get_volm_path(disk_t *diskp, char *mediapath, int size) 227*7c478bd9Sstevel@tonic-gate { 228*7c478bd9Sstevel@tonic-gate char vname[MAXPATHLEN]; 229*7c478bd9Sstevel@tonic-gate char *volname; 230*7c478bd9Sstevel@tonic-gate char *media_name; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (!diskp->removable || !volmgt_running()) { 233*7c478bd9Sstevel@tonic-gate return (0); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /* 237*7c478bd9Sstevel@tonic-gate * The volume manager is running, so we have to check if this removable 238*7c478bd9Sstevel@tonic-gate * drive is under volm control or not. 239*7c478bd9Sstevel@tonic-gate */ 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * We must check if this drive is under volume management control and 243*7c478bd9Sstevel@tonic-gate * what devpath to use. 244*7c478bd9Sstevel@tonic-gate * Note that we have to do this every time for drives that are not 245*7c478bd9Sstevel@tonic-gate * under the control of the volume manager, since the volume manager 246*7c478bd9Sstevel@tonic-gate * might have taken control since the last time we checked. 247*7c478bd9Sstevel@tonic-gate */ 248*7c478bd9Sstevel@tonic-gate if (diskp->volm_path_set == 0) { 249*7c478bd9Sstevel@tonic-gate alias_t *ap; 250*7c478bd9Sstevel@tonic-gate slice_t *dp; 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate if ((ap = diskp->aliases) == NULL) { 253*7c478bd9Sstevel@tonic-gate return (0); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* Check each devpath to see if it is under volm control. */ 257*7c478bd9Sstevel@tonic-gate dp = ap->devpaths; 258*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 259*7c478bd9Sstevel@tonic-gate slice_rdsk2dsk(dp->devpath, vname, sizeof (vname)); 260*7c478bd9Sstevel@tonic-gate if (volmgt_inuse(vname)) { 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate dp = dp->next; 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate if (dp != NULL) { 268*7c478bd9Sstevel@tonic-gate /* Volume manager is managing the devpath that dp points to. */ 269*7c478bd9Sstevel@tonic-gate diskp->volm_path = dp->devpath; 270*7c478bd9Sstevel@tonic-gate diskp->volm_path_set = 1; 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate if (diskp->volm_path_set == 0) { 275*7c478bd9Sstevel@tonic-gate /* The volume manager is not managing any of the devpaths. */ 276*7c478bd9Sstevel@tonic-gate return (0); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate if (dm_debug > 1) { 280*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "INFO: chk vol: %s\n", diskp->volm_path); 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate slice_rdsk2dsk(diskp->volm_path, vname, sizeof (vname)); 284*7c478bd9Sstevel@tonic-gate volname = volmgt_symname(vname); 285*7c478bd9Sstevel@tonic-gate if (volname == NULL) { 286*7c478bd9Sstevel@tonic-gate mediapath[0] = 0; 287*7c478bd9Sstevel@tonic-gate return (1); 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate media_name = media_findname(volname); 291*7c478bd9Sstevel@tonic-gate free(volname); 292*7c478bd9Sstevel@tonic-gate if (media_name == NULL) { 293*7c478bd9Sstevel@tonic-gate mediapath[0] = 0; 294*7c478bd9Sstevel@tonic-gate return (1); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate (void) strlcpy(mediapath, media_name, size); 298*7c478bd9Sstevel@tonic-gate free(media_name); 299*7c478bd9Sstevel@tonic-gate return (1); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate int 303*7c478bd9Sstevel@tonic-gate media_make_descriptors() 304*7c478bd9Sstevel@tonic-gate { 305*7c478bd9Sstevel@tonic-gate int error; 306*7c478bd9Sstevel@tonic-gate disk_t *dp; 307*7c478bd9Sstevel@tonic-gate char mname[MAXPATHLEN]; 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate dp = cache_get_disklist(); 310*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 311*7c478bd9Sstevel@tonic-gate if (media_read_name(dp, mname, sizeof (mname))) { 312*7c478bd9Sstevel@tonic-gate cache_load_desc(DM_MEDIA, dp, mname, NULL, &error); 313*7c478bd9Sstevel@tonic-gate if (error != 0) { 314*7c478bd9Sstevel@tonic-gate return (error); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate dp = dp->next; 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate return (0); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* 325*7c478bd9Sstevel@tonic-gate * Read the media information. 326*7c478bd9Sstevel@tonic-gate */ 327*7c478bd9Sstevel@tonic-gate int 328*7c478bd9Sstevel@tonic-gate media_read_info(int fd, struct dk_minfo *minfo) 329*7c478bd9Sstevel@tonic-gate { 330*7c478bd9Sstevel@tonic-gate int status; 331*7c478bd9Sstevel@tonic-gate int tries = 0; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate minfo->dki_media_type = 0; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* 336*7c478bd9Sstevel@tonic-gate * This ioctl can fail if the media is not loaded or spun up. 337*7c478bd9Sstevel@tonic-gate * Retrying can sometimes succeed since the first ioctl will have 338*7c478bd9Sstevel@tonic-gate * started the media before the ioctl timed out so the media may be 339*7c478bd9Sstevel@tonic-gate * spun up on the subsequent attempt. 340*7c478bd9Sstevel@tonic-gate */ 341*7c478bd9Sstevel@tonic-gate while ((status = ioctl(fd, DKIOCGMEDIAINFO, minfo)) < 0) { 342*7c478bd9Sstevel@tonic-gate tries++; 343*7c478bd9Sstevel@tonic-gate if (tries >= IOCTLRETRIES) { 344*7c478bd9Sstevel@tonic-gate break; 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate (void) sleep(IOCTLRETRYINTERVAL); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate if (status < 0) { 350*7c478bd9Sstevel@tonic-gate return (0); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate return (1); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* return 1 if there is media, 0 if not. */ 357*7c478bd9Sstevel@tonic-gate int 358*7c478bd9Sstevel@tonic-gate media_read_name(disk_t *dp, char *mname, int size) 359*7c478bd9Sstevel@tonic-gate { 360*7c478bd9Sstevel@tonic-gate int under_volm; 361*7c478bd9Sstevel@tonic-gate char rmmedia_devpath[MAXPATHLEN]; 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate mname[0] = 0; 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate if (!dp->removable) { 366*7c478bd9Sstevel@tonic-gate /* not removable, so media name is devid */ 367*7c478bd9Sstevel@tonic-gate if (dp->device_id != NULL) { 368*7c478bd9Sstevel@tonic-gate (void) strlcpy(mname, dp->device_id, size); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate return (1); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate /* This is a removable media drive. */ 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate /* Get 1 if under volm control, 0 if not */ 376*7c478bd9Sstevel@tonic-gate under_volm = media_get_volm_path(dp, rmmedia_devpath, 377*7c478bd9Sstevel@tonic-gate sizeof (rmmedia_devpath)); 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate if (under_volm) { 380*7c478bd9Sstevel@tonic-gate /* under volm control */ 381*7c478bd9Sstevel@tonic-gate if (rmmedia_devpath[0] == 0) { 382*7c478bd9Sstevel@tonic-gate /* no media */ 383*7c478bd9Sstevel@tonic-gate return (0); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate (void) strlcpy(mname, rmmedia_devpath, size); 386*7c478bd9Sstevel@tonic-gate return (1); 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate } else { 389*7c478bd9Sstevel@tonic-gate /* not under volm control */ 390*7c478bd9Sstevel@tonic-gate return (get_non_volm_name(dp, mname, size)); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate static descriptor_t ** 395*7c478bd9Sstevel@tonic-gate apply_filter(descriptor_t **media, int filter[], int *errp) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate descriptor_t **found; 398*7c478bd9Sstevel@tonic-gate int i; 399*7c478bd9Sstevel@tonic-gate int cnt = 0; 400*7c478bd9Sstevel@tonic-gate int pos; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate /* count the number of media in the snapshot */ 403*7c478bd9Sstevel@tonic-gate for (i = 0; media[i]; i++) { 404*7c478bd9Sstevel@tonic-gate cnt++; 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate found = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); 408*7c478bd9Sstevel@tonic-gate if (found == NULL) { 409*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 410*7c478bd9Sstevel@tonic-gate cache_free_descriptors(media); 411*7c478bd9Sstevel@tonic-gate return (NULL); 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate pos = 0; 415*7c478bd9Sstevel@tonic-gate for (i = 0; media[i]; i++) { 416*7c478bd9Sstevel@tonic-gate int fd; 417*7c478bd9Sstevel@tonic-gate struct dk_minfo minfo; 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate if ((fd = drive_open_disk(media[i]->p.disk, NULL, 0)) < 0) { 420*7c478bd9Sstevel@tonic-gate continue; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate if (media_read_info(fd, &minfo)) { 424*7c478bd9Sstevel@tonic-gate int mtype; 425*7c478bd9Sstevel@tonic-gate int j; 426*7c478bd9Sstevel@tonic-gate int match; 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate mtype = get_media_type(minfo.dki_media_type); 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate match = 0; 431*7c478bd9Sstevel@tonic-gate for (j = 0; filter[j] != DM_FILTER_END; j++) { 432*7c478bd9Sstevel@tonic-gate if (mtype == filter[j]) { 433*7c478bd9Sstevel@tonic-gate found[pos++] = media[i]; 434*7c478bd9Sstevel@tonic-gate match = 1; 435*7c478bd9Sstevel@tonic-gate break; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate if (!match) { 440*7c478bd9Sstevel@tonic-gate cache_free_descriptor(media[i]); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate #ifdef i386 444*7c478bd9Sstevel@tonic-gate /* XXX Work around bug 4725434 */ 445*7c478bd9Sstevel@tonic-gate else if (!media[i]->p.disk->removable) { 446*7c478bd9Sstevel@tonic-gate int j; 447*7c478bd9Sstevel@tonic-gate int match; 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate match = 0; 450*7c478bd9Sstevel@tonic-gate for (j = 0; filter[j] != DM_FILTER_END; j++) { 451*7c478bd9Sstevel@tonic-gate if (DM_MT_FIXED == filter[j]) { 452*7c478bd9Sstevel@tonic-gate found[pos++] = media[i]; 453*7c478bd9Sstevel@tonic-gate match = 1; 454*7c478bd9Sstevel@tonic-gate break; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate if (!match) { 459*7c478bd9Sstevel@tonic-gate cache_free_descriptor(media[i]); 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate #endif 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate (void) close(fd); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate found[pos] = NULL; 467*7c478bd9Sstevel@tonic-gate free(media); 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate *errp = 0; 470*7c478bd9Sstevel@tonic-gate return (found); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate /* return 1 if the media descriptor is still valid, 0 if not. */ 474*7c478bd9Sstevel@tonic-gate static int 475*7c478bd9Sstevel@tonic-gate desc_ok(descriptor_t *dp) 476*7c478bd9Sstevel@tonic-gate { 477*7c478bd9Sstevel@tonic-gate /* First verify the media name for removable media */ 478*7c478bd9Sstevel@tonic-gate if (dp->p.disk->removable) { 479*7c478bd9Sstevel@tonic-gate char mname[MAXPATHLEN]; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { 482*7c478bd9Sstevel@tonic-gate return (0); 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate if (mname[0] == 0) { 486*7c478bd9Sstevel@tonic-gate return (libdiskmgt_str_eq(dp->name, NULL)); 487*7c478bd9Sstevel@tonic-gate } else { 488*7c478bd9Sstevel@tonic-gate return (libdiskmgt_str_eq(dp->name, mname)); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate return (1); 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate static int 496*7c478bd9Sstevel@tonic-gate get_attrs(disk_t *dp, int fd, nvlist_t *attrs) 497*7c478bd9Sstevel@tonic-gate { 498*7c478bd9Sstevel@tonic-gate struct dk_minfo minfo; 499*7c478bd9Sstevel@tonic-gate struct dk_geom geometry; 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate if (fd < 0) { 502*7c478bd9Sstevel@tonic-gate return (ENODEV); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate bzero(&minfo, sizeof (struct dk_minfo)); 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate /* The first thing to do is read the media */ 508*7c478bd9Sstevel@tonic-gate if (!media_read_info(fd, &minfo)) { 509*7c478bd9Sstevel@tonic-gate /* XXX Work around bug 4725434 */ 510*7c478bd9Sstevel@tonic-gate #ifdef i386 511*7c478bd9Sstevel@tonic-gate if (dp->removable) 512*7c478bd9Sstevel@tonic-gate #endif 513*7c478bd9Sstevel@tonic-gate return (ENODEV); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate if (partition_has_fdisk(dp, fd)) { 517*7c478bd9Sstevel@tonic-gate if (nvlist_add_boolean(attrs, DM_FDISK) != 0) { 518*7c478bd9Sstevel@tonic-gate return (ENOMEM); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate if (dp->removable) { 523*7c478bd9Sstevel@tonic-gate if (nvlist_add_boolean(attrs, DM_REMOVABLE) != 0) { 524*7c478bd9Sstevel@tonic-gate return (ENOMEM); 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate if (nvlist_add_boolean(attrs, DM_LOADED) != 0) { 528*7c478bd9Sstevel@tonic-gate return (ENOMEM); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(attrs, DM_SIZE, minfo.dki_capacity) != 0) { 533*7c478bd9Sstevel@tonic-gate return (ENOMEM); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BLOCKSIZE, minfo.dki_lbsize) != 0) { 537*7c478bd9Sstevel@tonic-gate return (ENOMEM); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_MTYPE, 541*7c478bd9Sstevel@tonic-gate get_media_type(minfo.dki_media_type)) != 0) { 542*7c478bd9Sstevel@tonic-gate return (ENOMEM); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate /* only for disks < 1TB */ 546*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &geometry) >= 0) { 547*7c478bd9Sstevel@tonic-gate struct vtoc vtoc; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(attrs, DM_START, 0) != 0) { 550*7c478bd9Sstevel@tonic-gate return (ENOMEM); 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(attrs, DM_NACCESSIBLE, 553*7c478bd9Sstevel@tonic-gate geometry.dkg_ncyl * geometry.dkg_nhead * geometry.dkg_nsect) 554*7c478bd9Sstevel@tonic-gate != 0) { 555*7c478bd9Sstevel@tonic-gate return (ENOMEM); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NCYLINDERS, geometry.dkg_ncyl) 558*7c478bd9Sstevel@tonic-gate != 0) { 559*7c478bd9Sstevel@tonic-gate return (ENOMEM); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NPHYSCYLINDERS, geometry.dkg_pcyl) 562*7c478bd9Sstevel@tonic-gate != 0) { 563*7c478bd9Sstevel@tonic-gate return (ENOMEM); 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NALTCYLINDERS, geometry.dkg_acyl) 566*7c478bd9Sstevel@tonic-gate != 0) { 567*7c478bd9Sstevel@tonic-gate return (ENOMEM); 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NHEADS, geometry.dkg_nhead) != 0) { 570*7c478bd9Sstevel@tonic-gate return (ENOMEM); 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NSECTORS, geometry.dkg_nsect) 573*7c478bd9Sstevel@tonic-gate != 0) { 574*7c478bd9Sstevel@tonic-gate return (ENOMEM); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate if (read_vtoc(fd, &vtoc) >= 0 && vtoc.v_volume[0] != 0) { 578*7c478bd9Sstevel@tonic-gate char label[LEN_DKL_VVOL + 1]; 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate (void) snprintf(label, sizeof (label), "%.*s", LEN_DKL_VVOL, 581*7c478bd9Sstevel@tonic-gate vtoc.v_volume); 582*7c478bd9Sstevel@tonic-gate if (nvlist_add_string(attrs, DM_LABEL, label) != 0) { 583*7c478bd9Sstevel@tonic-gate return (ENOMEM); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate } else { 588*7c478bd9Sstevel@tonic-gate /* check for disks > 1TB for accessible size */ 589*7c478bd9Sstevel@tonic-gate struct dk_gpt *efip; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if (efi_alloc_and_read(fd, &efip) >= 0) { 592*7c478bd9Sstevel@tonic-gate diskaddr_t p8size = 0; 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate if (nvlist_add_boolean(attrs, DM_EFI) != 0) { 595*7c478bd9Sstevel@tonic-gate return (ENOMEM); 596*7c478bd9Sstevel@tonic-gate } 597*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(attrs, DM_START, efip->efi_first_u_lba) 598*7c478bd9Sstevel@tonic-gate != 0) { 599*7c478bd9Sstevel@tonic-gate return (ENOMEM); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate /* partition 8 is reserved on EFI labels */ 602*7c478bd9Sstevel@tonic-gate if (efip->efi_nparts >= 9) { 603*7c478bd9Sstevel@tonic-gate p8size = efip->efi_parts[8].p_size; 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(attrs, DM_NACCESSIBLE, 606*7c478bd9Sstevel@tonic-gate (efip->efi_last_u_lba - p8size) - efip->efi_first_u_lba) 607*7c478bd9Sstevel@tonic-gate != 0) { 608*7c478bd9Sstevel@tonic-gate efi_free(efip); 609*7c478bd9Sstevel@tonic-gate return (ENOMEM); 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate efi_free(efip); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate /* This ioctl seems to be mainly for intel-based drives. */ 616*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCG_PHYGEOM, &geometry) >= 0) { 617*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NACTUALCYLINDERS, geometry.dkg_ncyl) 618*7c478bd9Sstevel@tonic-gate != 0) { 619*7c478bd9Sstevel@tonic-gate return (ENOMEM); 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate return (0); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate static int 627*7c478bd9Sstevel@tonic-gate get_media_type(uint_t media_type) 628*7c478bd9Sstevel@tonic-gate { 629*7c478bd9Sstevel@tonic-gate switch (media_type) { 630*7c478bd9Sstevel@tonic-gate case DK_UNKNOWN: 631*7c478bd9Sstevel@tonic-gate return (DM_MT_UNKNOWN); 632*7c478bd9Sstevel@tonic-gate case DK_MO_ERASABLE: 633*7c478bd9Sstevel@tonic-gate return (DM_MT_MO_ERASABLE); 634*7c478bd9Sstevel@tonic-gate case DK_MO_WRITEONCE: 635*7c478bd9Sstevel@tonic-gate return (DM_MT_MO_WRITEONCE); 636*7c478bd9Sstevel@tonic-gate case DK_AS_MO: 637*7c478bd9Sstevel@tonic-gate return (DM_MT_AS_MO); 638*7c478bd9Sstevel@tonic-gate case DK_CDROM: 639*7c478bd9Sstevel@tonic-gate return (DM_MT_CDROM); 640*7c478bd9Sstevel@tonic-gate case DK_CDR: 641*7c478bd9Sstevel@tonic-gate return (DM_MT_CDR); 642*7c478bd9Sstevel@tonic-gate case DK_CDRW: 643*7c478bd9Sstevel@tonic-gate return (DM_MT_CDRW); 644*7c478bd9Sstevel@tonic-gate case DK_DVDROM: 645*7c478bd9Sstevel@tonic-gate return (DM_MT_DVDROM); 646*7c478bd9Sstevel@tonic-gate case DK_DVDR: 647*7c478bd9Sstevel@tonic-gate return (DM_MT_DVDR); 648*7c478bd9Sstevel@tonic-gate case DK_DVDRAM: 649*7c478bd9Sstevel@tonic-gate return (DM_MT_DVDRAM); 650*7c478bd9Sstevel@tonic-gate case DK_FIXED_DISK: 651*7c478bd9Sstevel@tonic-gate return (DM_MT_FIXED); 652*7c478bd9Sstevel@tonic-gate case DK_FLOPPY: 653*7c478bd9Sstevel@tonic-gate return (DM_MT_FLOPPY); 654*7c478bd9Sstevel@tonic-gate case DK_ZIP: 655*7c478bd9Sstevel@tonic-gate return (DM_MT_ZIP); 656*7c478bd9Sstevel@tonic-gate case DK_JAZ: 657*7c478bd9Sstevel@tonic-gate return (DM_MT_JAZ); 658*7c478bd9Sstevel@tonic-gate default: 659*7c478bd9Sstevel@tonic-gate return (DM_MT_UNKNOWN); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate /* 664*7c478bd9Sstevel@tonic-gate * This function handles removable media not under volume management. 665*7c478bd9Sstevel@tonic-gate */ 666*7c478bd9Sstevel@tonic-gate static int 667*7c478bd9Sstevel@tonic-gate get_non_volm_name(disk_t *dp, char *mname, int size) 668*7c478bd9Sstevel@tonic-gate { 669*7c478bd9Sstevel@tonic-gate int loaded; 670*7c478bd9Sstevel@tonic-gate int fd; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate loaded = 0; 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) { 675*7c478bd9Sstevel@tonic-gate struct dk_minfo minfo; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate if ((loaded = media_read_info(fd, &minfo))) { 678*7c478bd9Sstevel@tonic-gate struct vtoc vtoc; 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate if (read_vtoc(fd, &vtoc) >= 0) { 681*7c478bd9Sstevel@tonic-gate if (vtoc.v_volume[0] != NULL) { 682*7c478bd9Sstevel@tonic-gate if (LEN_DKL_VVOL < size) { 683*7c478bd9Sstevel@tonic-gate (void) strlcpy(mname, vtoc.v_volume, LEN_DKL_VVOL); 684*7c478bd9Sstevel@tonic-gate } else { 685*7c478bd9Sstevel@tonic-gate (void) strlcpy(mname, vtoc.v_volume, size); 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate (void) close(fd); 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate return (loaded); 695*7c478bd9Sstevel@tonic-gate } 696