10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51623Stw21770 * Common Development and Distribution License (the "License"). 61623Stw21770 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*7087Ssk102515 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate /* 290Sstevel@tonic-gate * get dev_t list 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <meta.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate #include <sys/mhd.h> 350Sstevel@tonic-gate #include <strings.h> 360Sstevel@tonic-gate 370Sstevel@tonic-gate /* 380Sstevel@tonic-gate * private version of minor(), able to handle 64 bit and 32 bit devices. 390Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate minor_t 420Sstevel@tonic-gate meta_getminor(md_dev64_t dev64) 430Sstevel@tonic-gate { 440Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 450Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 460Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN64)); 470Sstevel@tonic-gate } else { 480Sstevel@tonic-gate if (getenv("META_DEBUG")) 490Sstevel@tonic-gate (void) printf( 500Sstevel@tonic-gate "meta_getminor called with 32 bit dev: 0x%llx\n", 514492Spetede dev64); 520Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN32)); 530Sstevel@tonic-gate } 540Sstevel@tonic-gate } 550Sstevel@tonic-gate 560Sstevel@tonic-gate /* 570Sstevel@tonic-gate * private version of major(), able to handle 64 bit and 32 bit devices. 580Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 590Sstevel@tonic-gate */ 600Sstevel@tonic-gate major_t 610Sstevel@tonic-gate meta_getmajor(md_dev64_t dev64) 620Sstevel@tonic-gate { 630Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 640Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 650Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR64) & MAXMAJ64)); 660Sstevel@tonic-gate } else { 670Sstevel@tonic-gate if (getenv("META_DEBUG")) 680Sstevel@tonic-gate (void) printf( 690Sstevel@tonic-gate "meta_getmajor called with 32 bit dev: 0x%llx\n", 704492Spetede dev64); 710Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR32) & MAXMAJ32)); 720Sstevel@tonic-gate } 730Sstevel@tonic-gate } 740Sstevel@tonic-gate 750Sstevel@tonic-gate /* 760Sstevel@tonic-gate * private version of cmpldev(), able to handle 64 bit and 32 bit devices. 770Sstevel@tonic-gate */ 780Sstevel@tonic-gate dev32_t 790Sstevel@tonic-gate meta_cmpldev(md_dev64_t dev64) 800Sstevel@tonic-gate { 810Sstevel@tonic-gate minor_t minor; 820Sstevel@tonic-gate major_t major; 830Sstevel@tonic-gate 840Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 850Sstevel@tonic-gate if (major == 0) { 860Sstevel@tonic-gate return ((dev32_t)dev64); 870Sstevel@tonic-gate } 880Sstevel@tonic-gate minor = (dev32_t)dev64 & MAXMIN32; 890Sstevel@tonic-gate return ((major << NBITSMINOR32) | minor); 900Sstevel@tonic-gate } 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * private version of expldev(), able to handle 64 bit and 32 bit devices. 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate md_dev64_t 960Sstevel@tonic-gate meta_expldev(md_dev64_t dev64) 970Sstevel@tonic-gate { 980Sstevel@tonic-gate minor_t minor; 990Sstevel@tonic-gate major_t major; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 1020Sstevel@tonic-gate if (major > 0) { /* a 64 bit device was given, return unchanged */ 1030Sstevel@tonic-gate return (dev64); 1040Sstevel@tonic-gate } 1050Sstevel@tonic-gate minor = (minor_t)(dev64) & MAXMIN32; 1060Sstevel@tonic-gate major = ((major_t)dev64 >> NBITSMINOR32) & MAXMAJ32; 1070Sstevel@tonic-gate return (((md_dev64_t)major << NBITSMINOR64) | minor); 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate /* 1110Sstevel@tonic-gate * get underlying devices (recursively) 1120Sstevel@tonic-gate */ 1130Sstevel@tonic-gate int 1140Sstevel@tonic-gate meta_getdevs( 1150Sstevel@tonic-gate mdsetname_t *sp, 1160Sstevel@tonic-gate mdname_t *namep, 1170Sstevel@tonic-gate mdnamelist_t **nlpp, 1180Sstevel@tonic-gate md_error_t *ep 1190Sstevel@tonic-gate ) 1200Sstevel@tonic-gate { 1210Sstevel@tonic-gate char *miscname; 1220Sstevel@tonic-gate md_dev64_t *mydevs = NULL; 1230Sstevel@tonic-gate md_getdevs_params_t mgd; 1240Sstevel@tonic-gate size_t i; 1250Sstevel@tonic-gate int rval = -1; 1260Sstevel@tonic-gate md_sys_error_t *ip; 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate /* must have local set */ 1290Sstevel@tonic-gate assert(sp != NULL); 1300Sstevel@tonic-gate 1311623Stw21770 /* if no valid name then return an error */ 1321623Stw21770 if (namep == NULL) 1331623Stw21770 return (-1); 1341623Stw21770 1350Sstevel@tonic-gate /* just add regular devices */ 1360Sstevel@tonic-gate if (! metaismeta(namep)) { 1370Sstevel@tonic-gate mdnamelist_t *p; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate /* 1400Sstevel@tonic-gate * If the dev_t is in the array already 1410Sstevel@tonic-gate * then let's continue. 1420Sstevel@tonic-gate */ 1430Sstevel@tonic-gate for (p = *nlpp; (p != NULL); p = p->next) { 1440Sstevel@tonic-gate if (strcmp(namep->bname, p->namep->bname) == 0) { 1450Sstevel@tonic-gate rval = 0; 1460Sstevel@tonic-gate goto out; 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate /* add to list */ 1510Sstevel@tonic-gate (void) metanamelist_append(nlpp, namep); 1520Sstevel@tonic-gate rval = 0; 1530Sstevel@tonic-gate goto out; 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* get MD misc module */ 1570Sstevel@tonic-gate if ((miscname = metagetmiscname(namep, ep)) == NULL) 1580Sstevel@tonic-gate goto out; 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate /* get count of underlying devices */ 1610Sstevel@tonic-gate (void) memset(&mgd, '\0', sizeof (mgd)); 1620Sstevel@tonic-gate MD_SETDRIVERNAME(&mgd, miscname, sp->setno); 1630Sstevel@tonic-gate mgd.mnum = meta_getminor(namep->dev); 1640Sstevel@tonic-gate mgd.cnt = 0; 1650Sstevel@tonic-gate mgd.devs = NULL; 1660Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 1670Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 1680Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 1690Sstevel@tonic-gate if (ip->errnum == ENODEV) { 1700Sstevel@tonic-gate rval = 0; 1710Sstevel@tonic-gate goto out; 1720Sstevel@tonic-gate } 1730Sstevel@tonic-gate } 1740Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 1750Sstevel@tonic-gate goto out; 1760Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 1770Sstevel@tonic-gate assert(mgd.cnt >= 0); 1780Sstevel@tonic-gate rval = 0; 1790Sstevel@tonic-gate goto out; 1800Sstevel@tonic-gate } 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate /* get underlying devices */ 1830Sstevel@tonic-gate mydevs = Zalloc(sizeof (*mydevs) * mgd.cnt); 1840Sstevel@tonic-gate mgd.devs = (uintptr_t)mydevs; 1850Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 1860Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 1870Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 1880Sstevel@tonic-gate if (ip->errnum == ENODEV) { 1890Sstevel@tonic-gate rval = 0; 1900Sstevel@tonic-gate goto out; 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 1940Sstevel@tonic-gate goto out; 1950Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 1960Sstevel@tonic-gate assert(mgd.cnt >= 0); 1970Sstevel@tonic-gate rval = 0; 1980Sstevel@tonic-gate goto out; 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate /* recurse */ 2010Sstevel@tonic-gate for (i = 0; (i < mgd.cnt); ++i) { 2020Sstevel@tonic-gate mdname_t *devnp; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate if (mydevs[i] == NODEV64) { 2050Sstevel@tonic-gate continue; 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate if ((devnp = metadevname(&sp, mydevs[i], ep)) == NULL) { 208*7087Ssk102515 if (mdissyserror(ep, ENOENT)) { 209*7087Ssk102515 mdclrerror(ep); 210*7087Ssk102515 /* 211*7087Ssk102515 * If the device doesn't exist, it could be 212*7087Ssk102515 * that we have a wrong dev_t/name 213*7087Ssk102515 * combination in the namespace, so 214*7087Ssk102515 * meta_fix_compnames try to check this 215*7087Ssk102515 * with the unit structure and fix this. 216*7087Ssk102515 */ 217*7087Ssk102515 if (meta_fix_compnames(sp, namep, 218*7087Ssk102515 mydevs[i], ep) == 0) 219*7087Ssk102515 continue; 220*7087Ssk102515 } 2210Sstevel@tonic-gate goto out; 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate if (meta_getdevs(sp, devnp, nlpp, ep) != 0) 2240Sstevel@tonic-gate goto out; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate /* success */ 2280Sstevel@tonic-gate rval = 0; 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate /* cleanup, return error */ 2310Sstevel@tonic-gate out: 2320Sstevel@tonic-gate if (mydevs != NULL) 2330Sstevel@tonic-gate Free(mydevs); 2340Sstevel@tonic-gate return (rval); 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate /* 2380Sstevel@tonic-gate * get all dev_t for a set 2390Sstevel@tonic-gate */ 2400Sstevel@tonic-gate int 2410Sstevel@tonic-gate meta_getalldevs( 2420Sstevel@tonic-gate mdsetname_t *sp, /* set to look in */ 2430Sstevel@tonic-gate mdnamelist_t **nlpp, /* returned devices */ 2440Sstevel@tonic-gate int check_db, 2450Sstevel@tonic-gate md_error_t *ep 2460Sstevel@tonic-gate ) 2470Sstevel@tonic-gate { 2480Sstevel@tonic-gate md_replicalist_t *rlp, *rp; 2490Sstevel@tonic-gate mdnamelist_t *nlp, *np; 2500Sstevel@tonic-gate mdhspnamelist_t *hspnlp, *hspp; 2510Sstevel@tonic-gate int rval = 0; 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate assert(sp != NULL); 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate /* 2560Sstevel@tonic-gate * Get a replica namelist, 2570Sstevel@tonic-gate * and then get all the devs within the replicas. 2580Sstevel@tonic-gate */ 2590Sstevel@tonic-gate if (check_db == TRUE) { 2600Sstevel@tonic-gate rlp = NULL; 2610Sstevel@tonic-gate if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 2620Sstevel@tonic-gate rval = -1; 2630Sstevel@tonic-gate for (rp = rlp; (rp != NULL); rp = rp->rl_next) { 2640Sstevel@tonic-gate if (meta_getdevs(sp, rp->rl_repp->r_namep, 2650Sstevel@tonic-gate nlpp, ep) != 0) 2660Sstevel@tonic-gate rval = -1; 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate metafreereplicalist(rlp); 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate /* 2720Sstevel@tonic-gate * Get a stripe namelist, 2730Sstevel@tonic-gate * and then get all the devs within the stripes. 2740Sstevel@tonic-gate */ 2750Sstevel@tonic-gate nlp = NULL; 2760Sstevel@tonic-gate if (meta_get_stripe_names(sp, &nlp, 0, ep) < 0) 2770Sstevel@tonic-gate rval = -1; 2780Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2790Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2800Sstevel@tonic-gate rval = -1; 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate metafreenamelist(nlp); 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate /* 2850Sstevel@tonic-gate * Get a mirror namelist, 2860Sstevel@tonic-gate * and then get all the devs within the mirrors. 2870Sstevel@tonic-gate */ 2880Sstevel@tonic-gate nlp = NULL; 2890Sstevel@tonic-gate if (meta_get_mirror_names(sp, &nlp, 0, ep) < 0) 2900Sstevel@tonic-gate rval = -1; 2910Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2920Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2930Sstevel@tonic-gate rval = -1; 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate metafreenamelist(nlp); 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate /* 2980Sstevel@tonic-gate * Get a trans namelist, 2990Sstevel@tonic-gate * and then get all the devs within the trans. 3000Sstevel@tonic-gate */ 3010Sstevel@tonic-gate nlp = NULL; 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate if (meta_get_trans_names(sp, &nlp, 0, ep) < 0) 3040Sstevel@tonic-gate rval = -1; 3050Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3060Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3070Sstevel@tonic-gate rval = -1; 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate metafreenamelist(nlp); 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate /* 3120Sstevel@tonic-gate * Get a hot spare pool namelist, 3130Sstevel@tonic-gate * and then get all the devs within the hot spare pools. 3140Sstevel@tonic-gate */ 3150Sstevel@tonic-gate hspnlp = NULL; 3160Sstevel@tonic-gate if (meta_get_hsp_names(sp, &hspnlp, 0, ep) < 0) 3170Sstevel@tonic-gate rval = -1; 3180Sstevel@tonic-gate for (hspp = hspnlp; (hspp != NULL); hspp = hspp->next) { 3190Sstevel@tonic-gate md_hsp_t *hsp; 3200Sstevel@tonic-gate uint_t i; 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate if ((hsp = meta_get_hsp(sp, hspp->hspnamep, ep)) == NULL) 3230Sstevel@tonic-gate rval = -1; 3240Sstevel@tonic-gate else for (i = 0; (i < hsp->hotspares.hotspares_len); ++i) { 3250Sstevel@tonic-gate md_hs_t *hs = &hsp->hotspares.hotspares_val[i]; 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate if (meta_getdevs(sp, hs->hsnamep, nlpp, ep) != 0) 3280Sstevel@tonic-gate rval = -1; 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate metafreehspnamelist(hspnlp); 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate /* 3340Sstevel@tonic-gate * Get a raid namelist, 3350Sstevel@tonic-gate * and then get all the devs within the raids. 3360Sstevel@tonic-gate */ 3370Sstevel@tonic-gate nlp = NULL; 3380Sstevel@tonic-gate if (meta_get_raid_names(sp, &nlp, 0, ep) < 0) 3390Sstevel@tonic-gate rval = -1; 3400Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3410Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3420Sstevel@tonic-gate rval = -1; 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate metafreenamelist(nlp); 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate /* 3470Sstevel@tonic-gate * Get a soft partition namelist, 3480Sstevel@tonic-gate * and then get all the devs within the softpartitions 3490Sstevel@tonic-gate */ 3500Sstevel@tonic-gate nlp = NULL; 3510Sstevel@tonic-gate if (meta_get_sp_names(sp, &nlp, 0, ep) < 0) 3520Sstevel@tonic-gate rval = -1; 3530Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3540Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3550Sstevel@tonic-gate rval = -1; 3560Sstevel@tonic-gate } 3570Sstevel@tonic-gate metafreenamelist(nlp); 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate return (rval); 3600Sstevel@tonic-gate } 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate /* 3630Sstevel@tonic-gate * get vtoc from a device already opened. 3640Sstevel@tonic-gate * returns 3650Sstevel@tonic-gate * 0 on success, 3660Sstevel@tonic-gate * -1 on error. If the error was ENOTSUP, partno will be set to 3670Sstevel@tonic-gate * VT_ENOTSUP if possible. 3680Sstevel@tonic-gate */ 3690Sstevel@tonic-gate int 3700Sstevel@tonic-gate meta_getvtoc( 3710Sstevel@tonic-gate int fd, /* fd for named device */ 3720Sstevel@tonic-gate char *devname, /* name of device */ 3730Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 3740Sstevel@tonic-gate int *partno, /* return partno here */ 3750Sstevel@tonic-gate md_error_t *ep 3760Sstevel@tonic-gate ) 3770Sstevel@tonic-gate { 3780Sstevel@tonic-gate int part; 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate (void) memset(vtocbufp, 0, sizeof (*vtocbufp)); 3810Sstevel@tonic-gate if ((part = read_vtoc(fd, vtocbufp)) < 0) { 3820Sstevel@tonic-gate int err = errno; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate if (ioctl(fd, MHIOCSTATUS, NULL) == 1) 3850Sstevel@tonic-gate err = EACCES; 3860Sstevel@tonic-gate else if (part == VT_EINVAL) 3870Sstevel@tonic-gate err = EINVAL; 3880Sstevel@tonic-gate else if (part == VT_EIO) 3890Sstevel@tonic-gate err = EIO; 3900Sstevel@tonic-gate else if (part == VT_ENOTSUP) { 3910Sstevel@tonic-gate if (partno) { 3920Sstevel@tonic-gate *partno = VT_ENOTSUP; 3930Sstevel@tonic-gate return (-1); 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate } 3960Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 3970Sstevel@tonic-gate } 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate /* Slice number for *p0 partition (whole disk on x86) is 16 */ 4000Sstevel@tonic-gate if (part >= V_NUMPAR) 4010Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, devname)); 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate if (partno) 4040Sstevel@tonic-gate *partno = part; 4050Sstevel@tonic-gate return (0); 4060Sstevel@tonic-gate } 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * set mdvtoc for a meta devices 4090Sstevel@tonic-gate */ 4100Sstevel@tonic-gate int 4110Sstevel@tonic-gate meta_setmdvtoc( 4120Sstevel@tonic-gate int fd, /* fd for named device */ 4130Sstevel@tonic-gate char *devname, /* name of device */ 4140Sstevel@tonic-gate mdvtoc_t *mdvtocp, /* mdvtoc buffer to fill */ 4150Sstevel@tonic-gate md_error_t *ep 4160Sstevel@tonic-gate ) 4170Sstevel@tonic-gate { 4180Sstevel@tonic-gate uint_t i; 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate /* 4210Sstevel@tonic-gate * Sanity-check the mdvtoc 4220Sstevel@tonic-gate */ 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate if (mdvtocp->nparts > V_NUMPAR) { 4250Sstevel@tonic-gate return (-1); 4260Sstevel@tonic-gate } 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate /* 4290Sstevel@tonic-gate * since many drivers won't allow opening a device make sure 4300Sstevel@tonic-gate * all partitions aren't being set to zero. If all are zero then 4310Sstevel@tonic-gate * we have no way to set them to something else 4320Sstevel@tonic-gate */ 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate for (i = 0; i < mdvtocp->nparts; i++) 4350Sstevel@tonic-gate if (mdvtocp->parts[i].size > 0) 4360Sstevel@tonic-gate break; 4370Sstevel@tonic-gate if (i == mdvtocp->nparts) 4380Sstevel@tonic-gate return (-1); 4390Sstevel@tonic-gate 4400Sstevel@tonic-gate /* 4410Sstevel@tonic-gate * Write the mdvtoc 4420Sstevel@tonic-gate */ 4430Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, (caddr_t)mdvtocp) == -1) { 4440Sstevel@tonic-gate return (mdsyserror(ep, errno, devname)); 4450Sstevel@tonic-gate } 4460Sstevel@tonic-gate 4470Sstevel@tonic-gate return (0); 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate /* 4510Sstevel@tonic-gate * set vtoc 4520Sstevel@tonic-gate */ 4530Sstevel@tonic-gate int 4540Sstevel@tonic-gate meta_setvtoc( 4550Sstevel@tonic-gate int fd, /* fd for named device */ 4560Sstevel@tonic-gate char *devname, /* name of device */ 4570Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 4580Sstevel@tonic-gate md_error_t *ep 4590Sstevel@tonic-gate ) 4600Sstevel@tonic-gate { 4610Sstevel@tonic-gate int part; 4620Sstevel@tonic-gate int err; 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate if ((part = write_vtoc(fd, vtocbufp)) < 0) { 4650Sstevel@tonic-gate if (part == VT_EINVAL) 4660Sstevel@tonic-gate err = EINVAL; 4670Sstevel@tonic-gate else if (part == VT_EIO) 4680Sstevel@tonic-gate err = EIO; 4690Sstevel@tonic-gate else 4700Sstevel@tonic-gate err = errno; 4710Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate return (0); 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate /* 4780Sstevel@tonic-gate * FUNCTION: meta_get_names() 4790Sstevel@tonic-gate * INPUT: drivername - char string containing the driver name 4800Sstevel@tonic-gate * sp - the set name to get soft partitions from 4810Sstevel@tonic-gate * options - options from the command line 4820Sstevel@tonic-gate * OUTPUT: nlpp - list of all soft partition names 4830Sstevel@tonic-gate * ep - return error pointer 4840Sstevel@tonic-gate * RETURNS: int - -1 if error, 0 success 4850Sstevel@tonic-gate * PURPOSE: returns a list of all specified devices in the metadb 4860Sstevel@tonic-gate * for all devices in the specified set 4870Sstevel@tonic-gate */ 4880Sstevel@tonic-gate int 4890Sstevel@tonic-gate meta_get_names( 4900Sstevel@tonic-gate char *drivername, 4910Sstevel@tonic-gate mdsetname_t *sp, 4920Sstevel@tonic-gate mdnamelist_t **nlpp, 4930Sstevel@tonic-gate mdprtopts_t options, 4940Sstevel@tonic-gate md_error_t *ep 4950Sstevel@tonic-gate ) 4960Sstevel@tonic-gate { 4970Sstevel@tonic-gate md_i_getnum_t gn; /* MD_IOCGET_NUM params */ 4980Sstevel@tonic-gate mdnamelist_t **tailpp = nlpp; 4990Sstevel@tonic-gate minor_t *minors = NULL; 5000Sstevel@tonic-gate minor_t *m_ptr; 5010Sstevel@tonic-gate int i; 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate (void) memset(&gn, '\0', sizeof (gn)); 5040Sstevel@tonic-gate MD_SETDRIVERNAME(&gn, drivername, sp->setno); 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate /* get number of devices */ 5070Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 5080Sstevel@tonic-gate if (mdiserror(&gn.mde, MDE_UNIT_NOT_FOUND)) { 5090Sstevel@tonic-gate mdclrerror(&gn.mde); 5100Sstevel@tonic-gate } else { 5110Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 5120Sstevel@tonic-gate return (-1); 5130Sstevel@tonic-gate } 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate if (gn.size > 0) { 5170Sstevel@tonic-gate /* malloc minor number buffer to be filled by ioctl */ 5180Sstevel@tonic-gate if ((minors = (minor_t *)malloc( 5194492Spetede gn.size * sizeof (minor_t))) == 0) { 5200Sstevel@tonic-gate return (ENOMEM); 5210Sstevel@tonic-gate } 5220Sstevel@tonic-gate gn.minors = (uintptr_t)minors; 5230Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 5240Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 5250Sstevel@tonic-gate free(minors); 5260Sstevel@tonic-gate return (-1); 5270Sstevel@tonic-gate } 5280Sstevel@tonic-gate m_ptr = minors; 5290Sstevel@tonic-gate for (i = 0; i < gn.size; i++) { 5300Sstevel@tonic-gate mdname_t *np; 5310Sstevel@tonic-gate 5320Sstevel@tonic-gate /* get name */ 5330Sstevel@tonic-gate np = metamnumname(&sp, *m_ptr, 5344492Spetede ((options & PRINT_FAST) ? 1 : 0), ep); 5354492Spetede 5364492Spetede /* 5374492Spetede * np can be NULL if the /dev/md namespace entries 5385525Spetede * do not exist. This could have happened due to 5395525Spetede * devfsadmd not having created them. 5405525Spetede * Therefore assume devfsadmd has not run and tell 5415525Spetede * it to run for the specific device that is missing. 5425525Spetede * Ignore any error return from meta_update_devtree 5435525Spetede * as a failure to create the device nodes will be 5445525Spetede * picked up in the metamnumname() call. Note that 5455525Spetede * the call to meta_update_devtree should not return 5465525Spetede * until the /dev/md links have been created or if 5475525Spetede * there has been a failure of some sort. 5484492Spetede */ 5495525Spetede if (np == NULL) { 5504492Spetede (void) meta_update_devtree(*m_ptr); 5514492Spetede np = metamnumname(&sp, *m_ptr, 5524492Spetede ((options & PRINT_FAST) ? 1 : 0), ep); 5534492Spetede } 5544492Spetede 5550Sstevel@tonic-gate if (np == NULL) 5560Sstevel@tonic-gate goto out; 5570Sstevel@tonic-gate 5584492Spetede tailpp = meta_namelist_append_wrapper(tailpp, np); 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate /* next device */ 5610Sstevel@tonic-gate m_ptr++; 5620Sstevel@tonic-gate } 5630Sstevel@tonic-gate free(minors); 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate return (gn.size); 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate out: 5680Sstevel@tonic-gate if (minors != NULL) 5690Sstevel@tonic-gate free(minors); 5700Sstevel@tonic-gate metafreenamelist(*nlpp); 5710Sstevel@tonic-gate *nlpp = NULL; 5720Sstevel@tonic-gate return (-1); 5730Sstevel@tonic-gate } 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate /* 5760Sstevel@tonic-gate * Wrap lib/libdevid/devid_deviceid_to_nmlist. We want to take the 5770Sstevel@tonic-gate * results from that function and filter out the c[t]dp style names that 5780Sstevel@tonic-gate * we typically see on x86 so that we never see them. 5790Sstevel@tonic-gate */ 5800Sstevel@tonic-gate int 5810Sstevel@tonic-gate meta_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name, 5820Sstevel@tonic-gate devid_nmlist_t **retlist) 5830Sstevel@tonic-gate { 5840Sstevel@tonic-gate int res; 5850Sstevel@tonic-gate devid_nmlist_t *dp; 5860Sstevel@tonic-gate devid_nmlist_t *tmp_retlist; 5870Sstevel@tonic-gate int i = 1; 5880Sstevel@tonic-gate devid_nmlist_t *rp; 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate res = devid_deviceid_to_nmlist(search_path, devid, minor_name, retlist); 5910Sstevel@tonic-gate if (res != 0) { 5920Sstevel@tonic-gate return (res); 5930Sstevel@tonic-gate } 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate 5960Sstevel@tonic-gate /* first count the number of non c[t]dp items in retlist */ 5970Sstevel@tonic-gate for (dp = *retlist; dp->dev != NODEV; dp++) { 5980Sstevel@tonic-gate uint_t s; 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 6010Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 6020Sstevel@tonic-gate i++; 6030Sstevel@tonic-gate } 6040Sstevel@tonic-gate } 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate /* create an array to hold the non c[t]dp items */ 6070Sstevel@tonic-gate tmp_retlist = Malloc(sizeof (devid_nmlist_t) * i); 6080Sstevel@tonic-gate /* copy the non c[t]dp items to the array */ 6090Sstevel@tonic-gate for (dp = *retlist, rp = tmp_retlist; dp->dev != NODEV; dp++) { 6100Sstevel@tonic-gate uint_t s; 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 6130Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 6140Sstevel@tonic-gate /* nope, so copy and go to the next */ 6150Sstevel@tonic-gate rp->dev = dp->dev; 6160Sstevel@tonic-gate rp->devname = Strdup(dp->devname); 6170Sstevel@tonic-gate rp++; 6180Sstevel@tonic-gate } 6190Sstevel@tonic-gate /* if it is c[t]dp, just skip the element */ 6200Sstevel@tonic-gate } 6210Sstevel@tonic-gate /* copy the list terminator */ 6220Sstevel@tonic-gate rp->dev = NODEV; 6230Sstevel@tonic-gate rp->devname = NULL; 6240Sstevel@tonic-gate devid_free_nmlist (*retlist); 6250Sstevel@tonic-gate *retlist = tmp_retlist; 6260Sstevel@tonic-gate return (res); 6270Sstevel@tonic-gate } 628*7087Ssk102515 629*7087Ssk102515 /* 630*7087Ssk102515 * Check each real device that makes up a metadevice so that 631*7087Ssk102515 * un_dev entries can be matched against the entries in the 632*7087Ssk102515 * namespace. 633*7087Ssk102515 * 634*7087Ssk102515 * RETURN: 635*7087Ssk102515 * -1 error 636*7087Ssk102515 * 0 success 637*7087Ssk102515 */ 638*7087Ssk102515 int 639*7087Ssk102515 meta_fix_compnames( 640*7087Ssk102515 mdsetname_t *sp, 641*7087Ssk102515 mdname_t *namep, 642*7087Ssk102515 md_dev64_t dev, 643*7087Ssk102515 md_error_t *ep 644*7087Ssk102515 ) 645*7087Ssk102515 { 646*7087Ssk102515 int ret = 0; 647*7087Ssk102515 char *miscname; 648*7087Ssk102515 649*7087Ssk102515 /* get miscname and unit */ 650*7087Ssk102515 if ((miscname = metagetmiscname(namep, ep)) == NULL) 651*7087Ssk102515 return (-1); 652*7087Ssk102515 if (strcmp(miscname, MD_STRIPE) == 0) { 653*7087Ssk102515 if (meta_stripe_check_component(sp, namep, dev, ep) < 0) { 654*7087Ssk102515 ret = -1; 655*7087Ssk102515 } 656*7087Ssk102515 } else if (strcmp(miscname, MD_SP) == 0) { 657*7087Ssk102515 if (meta_sp_check_component(sp, namep, ep) < 0) { 658*7087Ssk102515 ret = -1; 659*7087Ssk102515 } 660*7087Ssk102515 } else if (strcmp(miscname, MD_RAID) == 0) { 661*7087Ssk102515 if (meta_raid_check_component(sp, namep, dev, ep) < 0) { 662*7087Ssk102515 ret = -1; 663*7087Ssk102515 } 664*7087Ssk102515 } else { 665*7087Ssk102515 (void) mdmderror(ep, MDE_INVAL_UNIT, 0, namep->cname); 666*7087Ssk102515 return (-1); 667*7087Ssk102515 } 668*7087Ssk102515 return (ret); 669*7087Ssk102515 } 670