1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * get dev_t list 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <meta.h> 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #include <sys/mhd.h> 36*0Sstevel@tonic-gate #include <strings.h> 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate /* 39*0Sstevel@tonic-gate * private version of minor(), able to handle 64 bit and 32 bit devices. 40*0Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 41*0Sstevel@tonic-gate */ 42*0Sstevel@tonic-gate minor_t 43*0Sstevel@tonic-gate meta_getminor(md_dev64_t dev64) 44*0Sstevel@tonic-gate { 45*0Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 46*0Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 47*0Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN64)); 48*0Sstevel@tonic-gate } else { 49*0Sstevel@tonic-gate if (getenv("META_DEBUG")) 50*0Sstevel@tonic-gate (void) printf( 51*0Sstevel@tonic-gate "meta_getminor called with 32 bit dev: 0x%llx\n", 52*0Sstevel@tonic-gate dev64); 53*0Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN32)); 54*0Sstevel@tonic-gate } 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate /* 58*0Sstevel@tonic-gate * private version of major(), able to handle 64 bit and 32 bit devices. 59*0Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 60*0Sstevel@tonic-gate */ 61*0Sstevel@tonic-gate major_t 62*0Sstevel@tonic-gate meta_getmajor(md_dev64_t dev64) 63*0Sstevel@tonic-gate { 64*0Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 65*0Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 66*0Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR64) & MAXMAJ64)); 67*0Sstevel@tonic-gate } else { 68*0Sstevel@tonic-gate if (getenv("META_DEBUG")) 69*0Sstevel@tonic-gate (void) printf( 70*0Sstevel@tonic-gate "meta_getmajor called with 32 bit dev: 0x%llx\n", 71*0Sstevel@tonic-gate dev64); 72*0Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR32) & MAXMAJ32)); 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate /* 77*0Sstevel@tonic-gate * private version of cmpldev(), able to handle 64 bit and 32 bit devices. 78*0Sstevel@tonic-gate */ 79*0Sstevel@tonic-gate dev32_t 80*0Sstevel@tonic-gate meta_cmpldev(md_dev64_t dev64) 81*0Sstevel@tonic-gate { 82*0Sstevel@tonic-gate minor_t minor; 83*0Sstevel@tonic-gate major_t major; 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 86*0Sstevel@tonic-gate if (major == 0) { 87*0Sstevel@tonic-gate return ((dev32_t)dev64); 88*0Sstevel@tonic-gate } 89*0Sstevel@tonic-gate minor = (dev32_t)dev64 & MAXMIN32; 90*0Sstevel@tonic-gate return ((major << NBITSMINOR32) | minor); 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate /* 94*0Sstevel@tonic-gate * private version of expldev(), able to handle 64 bit and 32 bit devices. 95*0Sstevel@tonic-gate */ 96*0Sstevel@tonic-gate md_dev64_t 97*0Sstevel@tonic-gate meta_expldev(md_dev64_t dev64) 98*0Sstevel@tonic-gate { 99*0Sstevel@tonic-gate minor_t minor; 100*0Sstevel@tonic-gate major_t major; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 103*0Sstevel@tonic-gate if (major > 0) { /* a 64 bit device was given, return unchanged */ 104*0Sstevel@tonic-gate return (dev64); 105*0Sstevel@tonic-gate } 106*0Sstevel@tonic-gate minor = (minor_t)(dev64) & MAXMIN32; 107*0Sstevel@tonic-gate major = ((major_t)dev64 >> NBITSMINOR32) & MAXMAJ32; 108*0Sstevel@tonic-gate return (((md_dev64_t)major << NBITSMINOR64) | minor); 109*0Sstevel@tonic-gate } 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate /* 112*0Sstevel@tonic-gate * get underlying devices (recursively) 113*0Sstevel@tonic-gate */ 114*0Sstevel@tonic-gate int 115*0Sstevel@tonic-gate meta_getdevs( 116*0Sstevel@tonic-gate mdsetname_t *sp, 117*0Sstevel@tonic-gate mdname_t *namep, 118*0Sstevel@tonic-gate mdnamelist_t **nlpp, 119*0Sstevel@tonic-gate md_error_t *ep 120*0Sstevel@tonic-gate ) 121*0Sstevel@tonic-gate { 122*0Sstevel@tonic-gate char *miscname; 123*0Sstevel@tonic-gate md_dev64_t *mydevs = NULL; 124*0Sstevel@tonic-gate md_getdevs_params_t mgd; 125*0Sstevel@tonic-gate size_t i; 126*0Sstevel@tonic-gate int rval = -1; 127*0Sstevel@tonic-gate md_sys_error_t *ip; 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate /* must have local set */ 130*0Sstevel@tonic-gate assert(sp != NULL); 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate /* just add regular devices */ 133*0Sstevel@tonic-gate if (! metaismeta(namep)) { 134*0Sstevel@tonic-gate mdnamelist_t *p; 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate /* 137*0Sstevel@tonic-gate * If the dev_t is in the array already 138*0Sstevel@tonic-gate * then let's continue. 139*0Sstevel@tonic-gate */ 140*0Sstevel@tonic-gate for (p = *nlpp; (p != NULL); p = p->next) { 141*0Sstevel@tonic-gate if (strcmp(namep->bname, p->namep->bname) == 0) { 142*0Sstevel@tonic-gate rval = 0; 143*0Sstevel@tonic-gate goto out; 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* add to list */ 148*0Sstevel@tonic-gate (void) metanamelist_append(nlpp, namep); 149*0Sstevel@tonic-gate rval = 0; 150*0Sstevel@tonic-gate goto out; 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate /* get MD misc module */ 154*0Sstevel@tonic-gate if ((miscname = metagetmiscname(namep, ep)) == NULL) 155*0Sstevel@tonic-gate goto out; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate /* get count of underlying devices */ 158*0Sstevel@tonic-gate (void) memset(&mgd, '\0', sizeof (mgd)); 159*0Sstevel@tonic-gate MD_SETDRIVERNAME(&mgd, miscname, sp->setno); 160*0Sstevel@tonic-gate mgd.mnum = meta_getminor(namep->dev); 161*0Sstevel@tonic-gate mgd.cnt = 0; 162*0Sstevel@tonic-gate mgd.devs = NULL; 163*0Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 164*0Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 165*0Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 166*0Sstevel@tonic-gate if (ip->errnum == ENODEV) { 167*0Sstevel@tonic-gate rval = 0; 168*0Sstevel@tonic-gate goto out; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 172*0Sstevel@tonic-gate goto out; 173*0Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 174*0Sstevel@tonic-gate assert(mgd.cnt >= 0); 175*0Sstevel@tonic-gate rval = 0; 176*0Sstevel@tonic-gate goto out; 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate /* get underlying devices */ 180*0Sstevel@tonic-gate mydevs = Zalloc(sizeof (*mydevs) * mgd.cnt); 181*0Sstevel@tonic-gate mgd.devs = (uintptr_t)mydevs; 182*0Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 183*0Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 184*0Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 185*0Sstevel@tonic-gate if (ip->errnum == ENODEV) { 186*0Sstevel@tonic-gate rval = 0; 187*0Sstevel@tonic-gate goto out; 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 191*0Sstevel@tonic-gate goto out; 192*0Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 193*0Sstevel@tonic-gate assert(mgd.cnt >= 0); 194*0Sstevel@tonic-gate rval = 0; 195*0Sstevel@tonic-gate goto out; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate /* recurse */ 198*0Sstevel@tonic-gate for (i = 0; (i < mgd.cnt); ++i) { 199*0Sstevel@tonic-gate mdname_t *devnp; 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate if (mydevs[i] == NODEV64) { 202*0Sstevel@tonic-gate continue; 203*0Sstevel@tonic-gate } 204*0Sstevel@tonic-gate if ((devnp = metadevname(&sp, mydevs[i], ep)) == NULL) { 205*0Sstevel@tonic-gate goto out; 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate if (meta_getdevs(sp, devnp, nlpp, ep) != 0) 208*0Sstevel@tonic-gate goto out; 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate /* success */ 212*0Sstevel@tonic-gate rval = 0; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate /* cleanup, return error */ 215*0Sstevel@tonic-gate out: 216*0Sstevel@tonic-gate if (mydevs != NULL) 217*0Sstevel@tonic-gate Free(mydevs); 218*0Sstevel@tonic-gate return (rval); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate /* 222*0Sstevel@tonic-gate * get all dev_t for a set 223*0Sstevel@tonic-gate */ 224*0Sstevel@tonic-gate int 225*0Sstevel@tonic-gate meta_getalldevs( 226*0Sstevel@tonic-gate mdsetname_t *sp, /* set to look in */ 227*0Sstevel@tonic-gate mdnamelist_t **nlpp, /* returned devices */ 228*0Sstevel@tonic-gate int check_db, 229*0Sstevel@tonic-gate md_error_t *ep 230*0Sstevel@tonic-gate ) 231*0Sstevel@tonic-gate { 232*0Sstevel@tonic-gate md_replicalist_t *rlp, *rp; 233*0Sstevel@tonic-gate mdnamelist_t *nlp, *np; 234*0Sstevel@tonic-gate mdhspnamelist_t *hspnlp, *hspp; 235*0Sstevel@tonic-gate int rval = 0; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate assert(sp != NULL); 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate /* 240*0Sstevel@tonic-gate * Get a replica namelist, 241*0Sstevel@tonic-gate * and then get all the devs within the replicas. 242*0Sstevel@tonic-gate */ 243*0Sstevel@tonic-gate if (check_db == TRUE) { 244*0Sstevel@tonic-gate rlp = NULL; 245*0Sstevel@tonic-gate if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 246*0Sstevel@tonic-gate rval = -1; 247*0Sstevel@tonic-gate for (rp = rlp; (rp != NULL); rp = rp->rl_next) { 248*0Sstevel@tonic-gate if (meta_getdevs(sp, rp->rl_repp->r_namep, 249*0Sstevel@tonic-gate nlpp, ep) != 0) 250*0Sstevel@tonic-gate rval = -1; 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate metafreereplicalist(rlp); 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate /* 256*0Sstevel@tonic-gate * Get a stripe namelist, 257*0Sstevel@tonic-gate * and then get all the devs within the stripes. 258*0Sstevel@tonic-gate */ 259*0Sstevel@tonic-gate nlp = NULL; 260*0Sstevel@tonic-gate if (meta_get_stripe_names(sp, &nlp, 0, ep) < 0) 261*0Sstevel@tonic-gate rval = -1; 262*0Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 263*0Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 264*0Sstevel@tonic-gate rval = -1; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate metafreenamelist(nlp); 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate /* 269*0Sstevel@tonic-gate * Get a mirror namelist, 270*0Sstevel@tonic-gate * and then get all the devs within the mirrors. 271*0Sstevel@tonic-gate */ 272*0Sstevel@tonic-gate nlp = NULL; 273*0Sstevel@tonic-gate if (meta_get_mirror_names(sp, &nlp, 0, ep) < 0) 274*0Sstevel@tonic-gate rval = -1; 275*0Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 276*0Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 277*0Sstevel@tonic-gate rval = -1; 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate metafreenamelist(nlp); 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate /* 282*0Sstevel@tonic-gate * Get a trans namelist, 283*0Sstevel@tonic-gate * and then get all the devs within the trans. 284*0Sstevel@tonic-gate */ 285*0Sstevel@tonic-gate nlp = NULL; 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate if (meta_get_trans_names(sp, &nlp, 0, ep) < 0) 288*0Sstevel@tonic-gate rval = -1; 289*0Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 290*0Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 291*0Sstevel@tonic-gate rval = -1; 292*0Sstevel@tonic-gate } 293*0Sstevel@tonic-gate metafreenamelist(nlp); 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate /* 296*0Sstevel@tonic-gate * Get a hot spare pool namelist, 297*0Sstevel@tonic-gate * and then get all the devs within the hot spare pools. 298*0Sstevel@tonic-gate */ 299*0Sstevel@tonic-gate hspnlp = NULL; 300*0Sstevel@tonic-gate if (meta_get_hsp_names(sp, &hspnlp, 0, ep) < 0) 301*0Sstevel@tonic-gate rval = -1; 302*0Sstevel@tonic-gate for (hspp = hspnlp; (hspp != NULL); hspp = hspp->next) { 303*0Sstevel@tonic-gate md_hsp_t *hsp; 304*0Sstevel@tonic-gate uint_t i; 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate if ((hsp = meta_get_hsp(sp, hspp->hspnamep, ep)) == NULL) 307*0Sstevel@tonic-gate rval = -1; 308*0Sstevel@tonic-gate else for (i = 0; (i < hsp->hotspares.hotspares_len); ++i) { 309*0Sstevel@tonic-gate md_hs_t *hs = &hsp->hotspares.hotspares_val[i]; 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate if (meta_getdevs(sp, hs->hsnamep, nlpp, ep) != 0) 312*0Sstevel@tonic-gate rval = -1; 313*0Sstevel@tonic-gate } 314*0Sstevel@tonic-gate } 315*0Sstevel@tonic-gate metafreehspnamelist(hspnlp); 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate /* 318*0Sstevel@tonic-gate * Get a raid namelist, 319*0Sstevel@tonic-gate * and then get all the devs within the raids. 320*0Sstevel@tonic-gate */ 321*0Sstevel@tonic-gate nlp = NULL; 322*0Sstevel@tonic-gate if (meta_get_raid_names(sp, &nlp, 0, ep) < 0) 323*0Sstevel@tonic-gate rval = -1; 324*0Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 325*0Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 326*0Sstevel@tonic-gate rval = -1; 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate metafreenamelist(nlp); 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate /* 331*0Sstevel@tonic-gate * Get a soft partition namelist, 332*0Sstevel@tonic-gate * and then get all the devs within the softpartitions 333*0Sstevel@tonic-gate */ 334*0Sstevel@tonic-gate nlp = NULL; 335*0Sstevel@tonic-gate if (meta_get_sp_names(sp, &nlp, 0, ep) < 0) 336*0Sstevel@tonic-gate rval = -1; 337*0Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 338*0Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 339*0Sstevel@tonic-gate rval = -1; 340*0Sstevel@tonic-gate } 341*0Sstevel@tonic-gate metafreenamelist(nlp); 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate return (rval); 344*0Sstevel@tonic-gate } 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate /* 347*0Sstevel@tonic-gate * get vtoc from a device already opened. 348*0Sstevel@tonic-gate * returns 349*0Sstevel@tonic-gate * 0 on success, 350*0Sstevel@tonic-gate * -1 on error. If the error was ENOTSUP, partno will be set to 351*0Sstevel@tonic-gate * VT_ENOTSUP if possible. 352*0Sstevel@tonic-gate */ 353*0Sstevel@tonic-gate int 354*0Sstevel@tonic-gate meta_getvtoc( 355*0Sstevel@tonic-gate int fd, /* fd for named device */ 356*0Sstevel@tonic-gate char *devname, /* name of device */ 357*0Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 358*0Sstevel@tonic-gate int *partno, /* return partno here */ 359*0Sstevel@tonic-gate md_error_t *ep 360*0Sstevel@tonic-gate ) 361*0Sstevel@tonic-gate { 362*0Sstevel@tonic-gate int part; 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate (void) memset(vtocbufp, 0, sizeof (*vtocbufp)); 365*0Sstevel@tonic-gate if ((part = read_vtoc(fd, vtocbufp)) < 0) { 366*0Sstevel@tonic-gate int err = errno; 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gate if (ioctl(fd, MHIOCSTATUS, NULL) == 1) 369*0Sstevel@tonic-gate err = EACCES; 370*0Sstevel@tonic-gate else if (part == VT_EINVAL) 371*0Sstevel@tonic-gate err = EINVAL; 372*0Sstevel@tonic-gate else if (part == VT_EIO) 373*0Sstevel@tonic-gate err = EIO; 374*0Sstevel@tonic-gate else if (part == VT_ENOTSUP) { 375*0Sstevel@tonic-gate if (partno) { 376*0Sstevel@tonic-gate *partno = VT_ENOTSUP; 377*0Sstevel@tonic-gate return (-1); 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate /* Slice number for *p0 partition (whole disk on x86) is 16 */ 384*0Sstevel@tonic-gate if (part >= V_NUMPAR) 385*0Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, devname)); 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate if (partno) 388*0Sstevel@tonic-gate *partno = part; 389*0Sstevel@tonic-gate return (0); 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate /* 392*0Sstevel@tonic-gate * set mdvtoc for a meta devices 393*0Sstevel@tonic-gate */ 394*0Sstevel@tonic-gate int 395*0Sstevel@tonic-gate meta_setmdvtoc( 396*0Sstevel@tonic-gate int fd, /* fd for named device */ 397*0Sstevel@tonic-gate char *devname, /* name of device */ 398*0Sstevel@tonic-gate mdvtoc_t *mdvtocp, /* mdvtoc buffer to fill */ 399*0Sstevel@tonic-gate md_error_t *ep 400*0Sstevel@tonic-gate ) 401*0Sstevel@tonic-gate { 402*0Sstevel@tonic-gate uint_t i; 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate /* 405*0Sstevel@tonic-gate * Sanity-check the mdvtoc 406*0Sstevel@tonic-gate */ 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate if (mdvtocp->nparts > V_NUMPAR) { 409*0Sstevel@tonic-gate return (-1); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate /* 413*0Sstevel@tonic-gate * since many drivers won't allow opening a device make sure 414*0Sstevel@tonic-gate * all partitions aren't being set to zero. If all are zero then 415*0Sstevel@tonic-gate * we have no way to set them to something else 416*0Sstevel@tonic-gate */ 417*0Sstevel@tonic-gate 418*0Sstevel@tonic-gate for (i = 0; i < mdvtocp->nparts; i++) 419*0Sstevel@tonic-gate if (mdvtocp->parts[i].size > 0) 420*0Sstevel@tonic-gate break; 421*0Sstevel@tonic-gate if (i == mdvtocp->nparts) 422*0Sstevel@tonic-gate return (-1); 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate /* 425*0Sstevel@tonic-gate * Write the mdvtoc 426*0Sstevel@tonic-gate */ 427*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, (caddr_t)mdvtocp) == -1) { 428*0Sstevel@tonic-gate return (mdsyserror(ep, errno, devname)); 429*0Sstevel@tonic-gate } 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate return (0); 432*0Sstevel@tonic-gate } 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate /* 435*0Sstevel@tonic-gate * set vtoc 436*0Sstevel@tonic-gate */ 437*0Sstevel@tonic-gate int 438*0Sstevel@tonic-gate meta_setvtoc( 439*0Sstevel@tonic-gate int fd, /* fd for named device */ 440*0Sstevel@tonic-gate char *devname, /* name of device */ 441*0Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 442*0Sstevel@tonic-gate md_error_t *ep 443*0Sstevel@tonic-gate ) 444*0Sstevel@tonic-gate { 445*0Sstevel@tonic-gate int part; 446*0Sstevel@tonic-gate int err; 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate if ((part = write_vtoc(fd, vtocbufp)) < 0) { 449*0Sstevel@tonic-gate if (part == VT_EINVAL) 450*0Sstevel@tonic-gate err = EINVAL; 451*0Sstevel@tonic-gate else if (part == VT_EIO) 452*0Sstevel@tonic-gate err = EIO; 453*0Sstevel@tonic-gate else 454*0Sstevel@tonic-gate err = errno; 455*0Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 456*0Sstevel@tonic-gate } 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gate return (0); 459*0Sstevel@tonic-gate } 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate /* 462*0Sstevel@tonic-gate * FUNCTION: meta_get_names() 463*0Sstevel@tonic-gate * INPUT: drivername - char string containing the driver name 464*0Sstevel@tonic-gate * sp - the set name to get soft partitions from 465*0Sstevel@tonic-gate * options - options from the command line 466*0Sstevel@tonic-gate * OUTPUT: nlpp - list of all soft partition names 467*0Sstevel@tonic-gate * ep - return error pointer 468*0Sstevel@tonic-gate * RETURNS: int - -1 if error, 0 success 469*0Sstevel@tonic-gate * PURPOSE: returns a list of all specified devices in the metadb 470*0Sstevel@tonic-gate * for all devices in the specified set 471*0Sstevel@tonic-gate */ 472*0Sstevel@tonic-gate int 473*0Sstevel@tonic-gate meta_get_names( 474*0Sstevel@tonic-gate char *drivername, 475*0Sstevel@tonic-gate mdsetname_t *sp, 476*0Sstevel@tonic-gate mdnamelist_t **nlpp, 477*0Sstevel@tonic-gate mdprtopts_t options, 478*0Sstevel@tonic-gate md_error_t *ep 479*0Sstevel@tonic-gate ) 480*0Sstevel@tonic-gate { 481*0Sstevel@tonic-gate md_i_getnum_t gn; /* MD_IOCGET_NUM params */ 482*0Sstevel@tonic-gate mdnamelist_t **tailpp = nlpp; 483*0Sstevel@tonic-gate minor_t *minors = NULL; 484*0Sstevel@tonic-gate minor_t *m_ptr; 485*0Sstevel@tonic-gate int i; 486*0Sstevel@tonic-gate 487*0Sstevel@tonic-gate (void) memset(&gn, '\0', sizeof (gn)); 488*0Sstevel@tonic-gate MD_SETDRIVERNAME(&gn, drivername, sp->setno); 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate /* get number of devices */ 491*0Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 492*0Sstevel@tonic-gate if (mdiserror(&gn.mde, MDE_UNIT_NOT_FOUND)) { 493*0Sstevel@tonic-gate mdclrerror(&gn.mde); 494*0Sstevel@tonic-gate } else { 495*0Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 496*0Sstevel@tonic-gate return (-1); 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate if (gn.size > 0) { 501*0Sstevel@tonic-gate /* malloc minor number buffer to be filled by ioctl */ 502*0Sstevel@tonic-gate if ((minors = (minor_t *)malloc( 503*0Sstevel@tonic-gate gn.size * sizeof (minor_t))) == 0) { 504*0Sstevel@tonic-gate return (ENOMEM); 505*0Sstevel@tonic-gate } 506*0Sstevel@tonic-gate gn.minors = (uintptr_t)minors; 507*0Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 508*0Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 509*0Sstevel@tonic-gate free(minors); 510*0Sstevel@tonic-gate return (-1); 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate m_ptr = minors; 513*0Sstevel@tonic-gate for (i = 0; i < gn.size; i++) { 514*0Sstevel@tonic-gate mdname_t *np; 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate /* get name */ 517*0Sstevel@tonic-gate np = metamnumname(&sp, *m_ptr, 518*0Sstevel@tonic-gate ((options & PRINT_FAST) ? 1 : 0), ep); 519*0Sstevel@tonic-gate if (np == NULL) 520*0Sstevel@tonic-gate goto out; 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate tailpp = meta_namelist_append_wrapper( 523*0Sstevel@tonic-gate tailpp, np); 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate /* next device */ 526*0Sstevel@tonic-gate m_ptr++; 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate free(minors); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate return (gn.size); 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate out: 533*0Sstevel@tonic-gate if (minors != NULL) 534*0Sstevel@tonic-gate free(minors); 535*0Sstevel@tonic-gate metafreenamelist(*nlpp); 536*0Sstevel@tonic-gate *nlpp = NULL; 537*0Sstevel@tonic-gate return (-1); 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate /* 541*0Sstevel@tonic-gate * Wrap lib/libdevid/devid_deviceid_to_nmlist. We want to take the 542*0Sstevel@tonic-gate * results from that function and filter out the c[t]dp style names that 543*0Sstevel@tonic-gate * we typically see on x86 so that we never see them. 544*0Sstevel@tonic-gate */ 545*0Sstevel@tonic-gate int 546*0Sstevel@tonic-gate meta_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name, 547*0Sstevel@tonic-gate devid_nmlist_t **retlist) 548*0Sstevel@tonic-gate { 549*0Sstevel@tonic-gate int res; 550*0Sstevel@tonic-gate devid_nmlist_t *dp; 551*0Sstevel@tonic-gate devid_nmlist_t *tmp_retlist; 552*0Sstevel@tonic-gate int i = 1; 553*0Sstevel@tonic-gate devid_nmlist_t *rp; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate res = devid_deviceid_to_nmlist(search_path, devid, minor_name, retlist); 556*0Sstevel@tonic-gate if (res != 0) { 557*0Sstevel@tonic-gate return (res); 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate /* first count the number of non c[t]dp items in retlist */ 562*0Sstevel@tonic-gate for (dp = *retlist; dp->dev != NODEV; dp++) { 563*0Sstevel@tonic-gate uint_t s; 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 566*0Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 567*0Sstevel@tonic-gate i++; 568*0Sstevel@tonic-gate } 569*0Sstevel@tonic-gate } 570*0Sstevel@tonic-gate 571*0Sstevel@tonic-gate /* create an array to hold the non c[t]dp items */ 572*0Sstevel@tonic-gate tmp_retlist = Malloc(sizeof (devid_nmlist_t) * i); 573*0Sstevel@tonic-gate /* copy the non c[t]dp items to the array */ 574*0Sstevel@tonic-gate for (dp = *retlist, rp = tmp_retlist; dp->dev != NODEV; dp++) { 575*0Sstevel@tonic-gate uint_t s; 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 578*0Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 579*0Sstevel@tonic-gate /* nope, so copy and go to the next */ 580*0Sstevel@tonic-gate rp->dev = dp->dev; 581*0Sstevel@tonic-gate rp->devname = Strdup(dp->devname); 582*0Sstevel@tonic-gate rp++; 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate /* if it is c[t]dp, just skip the element */ 585*0Sstevel@tonic-gate } 586*0Sstevel@tonic-gate /* copy the list terminator */ 587*0Sstevel@tonic-gate rp->dev = NODEV; 588*0Sstevel@tonic-gate rp->devname = NULL; 589*0Sstevel@tonic-gate devid_free_nmlist (*retlist); 590*0Sstevel@tonic-gate *retlist = tmp_retlist; 591*0Sstevel@tonic-gate return (res); 592*0Sstevel@tonic-gate } 593