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 */ 21*7563SPrasad.Singamsetty@Sun.COM 220Sstevel@tonic-gate /* 237087Ssk102515 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* 280Sstevel@tonic-gate * get dev_t list 290Sstevel@tonic-gate */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <meta.h> 320Sstevel@tonic-gate 330Sstevel@tonic-gate #include <sys/mhd.h> 340Sstevel@tonic-gate #include <strings.h> 350Sstevel@tonic-gate 360Sstevel@tonic-gate /* 370Sstevel@tonic-gate * private version of minor(), able to handle 64 bit and 32 bit devices. 380Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 390Sstevel@tonic-gate */ 400Sstevel@tonic-gate minor_t 410Sstevel@tonic-gate meta_getminor(md_dev64_t dev64) 420Sstevel@tonic-gate { 430Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 440Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 450Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN64)); 460Sstevel@tonic-gate } else { 470Sstevel@tonic-gate if (getenv("META_DEBUG")) 480Sstevel@tonic-gate (void) printf( 490Sstevel@tonic-gate "meta_getminor called with 32 bit dev: 0x%llx\n", 504492Spetede dev64); 510Sstevel@tonic-gate return ((minor_t)(dev64 & MAXMIN32)); 520Sstevel@tonic-gate } 530Sstevel@tonic-gate } 540Sstevel@tonic-gate 550Sstevel@tonic-gate /* 560Sstevel@tonic-gate * private version of major(), able to handle 64 bit and 32 bit devices. 570Sstevel@tonic-gate * print a warning out in case a 32 bit dev is specified. 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate major_t 600Sstevel@tonic-gate meta_getmajor(md_dev64_t dev64) 610Sstevel@tonic-gate { 620Sstevel@tonic-gate /* check if it's a real 64 bit dev */ 630Sstevel@tonic-gate if ((dev64 >> NBITSMAJOR64) > 0) { 640Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR64) & MAXMAJ64)); 650Sstevel@tonic-gate } else { 660Sstevel@tonic-gate if (getenv("META_DEBUG")) 670Sstevel@tonic-gate (void) printf( 680Sstevel@tonic-gate "meta_getmajor called with 32 bit dev: 0x%llx\n", 694492Spetede dev64); 700Sstevel@tonic-gate return ((major_t)((dev64 >> NBITSMINOR32) & MAXMAJ32)); 710Sstevel@tonic-gate } 720Sstevel@tonic-gate } 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* 750Sstevel@tonic-gate * private version of cmpldev(), able to handle 64 bit and 32 bit devices. 760Sstevel@tonic-gate */ 770Sstevel@tonic-gate dev32_t 780Sstevel@tonic-gate meta_cmpldev(md_dev64_t dev64) 790Sstevel@tonic-gate { 800Sstevel@tonic-gate minor_t minor; 810Sstevel@tonic-gate major_t major; 820Sstevel@tonic-gate 830Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 840Sstevel@tonic-gate if (major == 0) { 850Sstevel@tonic-gate return ((dev32_t)dev64); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate minor = (dev32_t)dev64 & MAXMIN32; 880Sstevel@tonic-gate return ((major << NBITSMINOR32) | minor); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate /* 920Sstevel@tonic-gate * private version of expldev(), able to handle 64 bit and 32 bit devices. 930Sstevel@tonic-gate */ 940Sstevel@tonic-gate md_dev64_t 950Sstevel@tonic-gate meta_expldev(md_dev64_t dev64) 960Sstevel@tonic-gate { 970Sstevel@tonic-gate minor_t minor; 980Sstevel@tonic-gate major_t major; 990Sstevel@tonic-gate 1000Sstevel@tonic-gate major = (major_t)(dev64 >> NBITSMAJOR64); 1010Sstevel@tonic-gate if (major > 0) { /* a 64 bit device was given, return unchanged */ 1020Sstevel@tonic-gate return (dev64); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate minor = (minor_t)(dev64) & MAXMIN32; 1050Sstevel@tonic-gate major = ((major_t)dev64 >> NBITSMINOR32) & MAXMAJ32; 1060Sstevel@tonic-gate return (((md_dev64_t)major << NBITSMINOR64) | minor); 1070Sstevel@tonic-gate } 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate /* 1100Sstevel@tonic-gate * get underlying devices (recursively) 1110Sstevel@tonic-gate */ 1120Sstevel@tonic-gate int 1130Sstevel@tonic-gate meta_getdevs( 1140Sstevel@tonic-gate mdsetname_t *sp, 1150Sstevel@tonic-gate mdname_t *namep, 1160Sstevel@tonic-gate mdnamelist_t **nlpp, 1170Sstevel@tonic-gate md_error_t *ep 1180Sstevel@tonic-gate ) 1190Sstevel@tonic-gate { 1200Sstevel@tonic-gate char *miscname; 1210Sstevel@tonic-gate md_dev64_t *mydevs = NULL; 1220Sstevel@tonic-gate md_getdevs_params_t mgd; 1230Sstevel@tonic-gate size_t i; 1240Sstevel@tonic-gate int rval = -1; 1250Sstevel@tonic-gate md_sys_error_t *ip; 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate /* must have local set */ 1280Sstevel@tonic-gate assert(sp != NULL); 1290Sstevel@tonic-gate 1301623Stw21770 /* if no valid name then return an error */ 1311623Stw21770 if (namep == NULL) 1321623Stw21770 return (-1); 1331623Stw21770 1340Sstevel@tonic-gate /* just add regular devices */ 1350Sstevel@tonic-gate if (! metaismeta(namep)) { 1360Sstevel@tonic-gate mdnamelist_t *p; 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate /* 1390Sstevel@tonic-gate * If the dev_t is in the array already 1400Sstevel@tonic-gate * then let's continue. 1410Sstevel@tonic-gate */ 1420Sstevel@tonic-gate for (p = *nlpp; (p != NULL); p = p->next) { 1430Sstevel@tonic-gate if (strcmp(namep->bname, p->namep->bname) == 0) { 1440Sstevel@tonic-gate rval = 0; 1450Sstevel@tonic-gate goto out; 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate /* add to list */ 1500Sstevel@tonic-gate (void) metanamelist_append(nlpp, namep); 1510Sstevel@tonic-gate rval = 0; 1520Sstevel@tonic-gate goto out; 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* get MD misc module */ 1560Sstevel@tonic-gate if ((miscname = metagetmiscname(namep, ep)) == NULL) 1570Sstevel@tonic-gate goto out; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate /* get count of underlying devices */ 1600Sstevel@tonic-gate (void) memset(&mgd, '\0', sizeof (mgd)); 1610Sstevel@tonic-gate MD_SETDRIVERNAME(&mgd, miscname, sp->setno); 1620Sstevel@tonic-gate mgd.mnum = meta_getminor(namep->dev); 1630Sstevel@tonic-gate mgd.cnt = 0; 1640Sstevel@tonic-gate mgd.devs = NULL; 1650Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 1660Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 1670Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 1680Sstevel@tonic-gate if (ip->errnum == ENODEV) { 1690Sstevel@tonic-gate rval = 0; 1700Sstevel@tonic-gate goto out; 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate } 1730Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 1740Sstevel@tonic-gate goto out; 1750Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 1760Sstevel@tonic-gate assert(mgd.cnt >= 0); 1770Sstevel@tonic-gate rval = 0; 1780Sstevel@tonic-gate goto out; 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate /* get underlying devices */ 1820Sstevel@tonic-gate mydevs = Zalloc(sizeof (*mydevs) * mgd.cnt); 1830Sstevel@tonic-gate mgd.devs = (uintptr_t)mydevs; 1840Sstevel@tonic-gate if (metaioctl(MD_IOCGET_DEVS, &mgd, &mgd.mde, namep->cname) != 0) { 1850Sstevel@tonic-gate if (mgd.mde.info.errclass == MDEC_SYS) { 1860Sstevel@tonic-gate ip = &mgd.mde.info.md_error_info_t_u.sys_error; 1870Sstevel@tonic-gate if (ip->errnum == ENODEV) { 1880Sstevel@tonic-gate rval = 0; 1890Sstevel@tonic-gate goto out; 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate (void) mdstealerror(ep, &mgd.mde); 1930Sstevel@tonic-gate goto out; 1940Sstevel@tonic-gate } else if (mgd.cnt <= 0) { 1950Sstevel@tonic-gate assert(mgd.cnt >= 0); 1960Sstevel@tonic-gate rval = 0; 1970Sstevel@tonic-gate goto out; 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate /* recurse */ 2000Sstevel@tonic-gate for (i = 0; (i < mgd.cnt); ++i) { 2010Sstevel@tonic-gate mdname_t *devnp; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate if (mydevs[i] == NODEV64) { 2040Sstevel@tonic-gate continue; 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate if ((devnp = metadevname(&sp, mydevs[i], ep)) == NULL) { 2077087Ssk102515 if (mdissyserror(ep, ENOENT)) { 2087087Ssk102515 mdclrerror(ep); 2097087Ssk102515 /* 2107087Ssk102515 * If the device doesn't exist, it could be 2117087Ssk102515 * that we have a wrong dev_t/name 2127087Ssk102515 * combination in the namespace, so 2137087Ssk102515 * meta_fix_compnames try to check this 2147087Ssk102515 * with the unit structure and fix this. 2157087Ssk102515 */ 2167087Ssk102515 if (meta_fix_compnames(sp, namep, 2177087Ssk102515 mydevs[i], ep) == 0) 2187087Ssk102515 continue; 2197087Ssk102515 } 2200Sstevel@tonic-gate goto out; 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate if (meta_getdevs(sp, devnp, nlpp, ep) != 0) 2230Sstevel@tonic-gate goto out; 2240Sstevel@tonic-gate } 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate /* success */ 2270Sstevel@tonic-gate rval = 0; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* cleanup, return error */ 2300Sstevel@tonic-gate out: 2310Sstevel@tonic-gate if (mydevs != NULL) 2320Sstevel@tonic-gate Free(mydevs); 2330Sstevel@tonic-gate return (rval); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate /* 2370Sstevel@tonic-gate * get all dev_t for a set 2380Sstevel@tonic-gate */ 2390Sstevel@tonic-gate int 2400Sstevel@tonic-gate meta_getalldevs( 2410Sstevel@tonic-gate mdsetname_t *sp, /* set to look in */ 2420Sstevel@tonic-gate mdnamelist_t **nlpp, /* returned devices */ 2430Sstevel@tonic-gate int check_db, 2440Sstevel@tonic-gate md_error_t *ep 2450Sstevel@tonic-gate ) 2460Sstevel@tonic-gate { 2470Sstevel@tonic-gate md_replicalist_t *rlp, *rp; 2480Sstevel@tonic-gate mdnamelist_t *nlp, *np; 2490Sstevel@tonic-gate mdhspnamelist_t *hspnlp, *hspp; 2500Sstevel@tonic-gate int rval = 0; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate assert(sp != NULL); 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate /* 2550Sstevel@tonic-gate * Get a replica namelist, 2560Sstevel@tonic-gate * and then get all the devs within the replicas. 2570Sstevel@tonic-gate */ 2580Sstevel@tonic-gate if (check_db == TRUE) { 2590Sstevel@tonic-gate rlp = NULL; 2600Sstevel@tonic-gate if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 2610Sstevel@tonic-gate rval = -1; 2620Sstevel@tonic-gate for (rp = rlp; (rp != NULL); rp = rp->rl_next) { 2630Sstevel@tonic-gate if (meta_getdevs(sp, rp->rl_repp->r_namep, 2640Sstevel@tonic-gate nlpp, ep) != 0) 2650Sstevel@tonic-gate rval = -1; 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate metafreereplicalist(rlp); 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate /* 2710Sstevel@tonic-gate * Get a stripe namelist, 2720Sstevel@tonic-gate * and then get all the devs within the stripes. 2730Sstevel@tonic-gate */ 2740Sstevel@tonic-gate nlp = NULL; 2750Sstevel@tonic-gate if (meta_get_stripe_names(sp, &nlp, 0, ep) < 0) 2760Sstevel@tonic-gate rval = -1; 2770Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2780Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2790Sstevel@tonic-gate rval = -1; 2800Sstevel@tonic-gate } 2810Sstevel@tonic-gate metafreenamelist(nlp); 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate /* 2840Sstevel@tonic-gate * Get a mirror namelist, 2850Sstevel@tonic-gate * and then get all the devs within the mirrors. 2860Sstevel@tonic-gate */ 2870Sstevel@tonic-gate nlp = NULL; 2880Sstevel@tonic-gate if (meta_get_mirror_names(sp, &nlp, 0, ep) < 0) 2890Sstevel@tonic-gate rval = -1; 2900Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2910Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2920Sstevel@tonic-gate rval = -1; 2930Sstevel@tonic-gate } 2940Sstevel@tonic-gate metafreenamelist(nlp); 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate /* 2970Sstevel@tonic-gate * Get a trans namelist, 2980Sstevel@tonic-gate * and then get all the devs within the trans. 2990Sstevel@tonic-gate */ 3000Sstevel@tonic-gate nlp = NULL; 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate if (meta_get_trans_names(sp, &nlp, 0, ep) < 0) 3030Sstevel@tonic-gate rval = -1; 3040Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3050Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3060Sstevel@tonic-gate rval = -1; 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate metafreenamelist(nlp); 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate /* 3110Sstevel@tonic-gate * Get a hot spare pool namelist, 3120Sstevel@tonic-gate * and then get all the devs within the hot spare pools. 3130Sstevel@tonic-gate */ 3140Sstevel@tonic-gate hspnlp = NULL; 3150Sstevel@tonic-gate if (meta_get_hsp_names(sp, &hspnlp, 0, ep) < 0) 3160Sstevel@tonic-gate rval = -1; 3170Sstevel@tonic-gate for (hspp = hspnlp; (hspp != NULL); hspp = hspp->next) { 3180Sstevel@tonic-gate md_hsp_t *hsp; 3190Sstevel@tonic-gate uint_t i; 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate if ((hsp = meta_get_hsp(sp, hspp->hspnamep, ep)) == NULL) 3220Sstevel@tonic-gate rval = -1; 3230Sstevel@tonic-gate else for (i = 0; (i < hsp->hotspares.hotspares_len); ++i) { 3240Sstevel@tonic-gate md_hs_t *hs = &hsp->hotspares.hotspares_val[i]; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate if (meta_getdevs(sp, hs->hsnamep, nlpp, ep) != 0) 3270Sstevel@tonic-gate rval = -1; 3280Sstevel@tonic-gate } 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate metafreehspnamelist(hspnlp); 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate /* 3330Sstevel@tonic-gate * Get a raid namelist, 3340Sstevel@tonic-gate * and then get all the devs within the raids. 3350Sstevel@tonic-gate */ 3360Sstevel@tonic-gate nlp = NULL; 3370Sstevel@tonic-gate if (meta_get_raid_names(sp, &nlp, 0, ep) < 0) 3380Sstevel@tonic-gate rval = -1; 3390Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3400Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3410Sstevel@tonic-gate rval = -1; 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate metafreenamelist(nlp); 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate /* 3460Sstevel@tonic-gate * Get a soft partition namelist, 3470Sstevel@tonic-gate * and then get all the devs within the softpartitions 3480Sstevel@tonic-gate */ 3490Sstevel@tonic-gate nlp = NULL; 3500Sstevel@tonic-gate if (meta_get_sp_names(sp, &nlp, 0, ep) < 0) 3510Sstevel@tonic-gate rval = -1; 3520Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3530Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3540Sstevel@tonic-gate rval = -1; 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate metafreenamelist(nlp); 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate return (rval); 3590Sstevel@tonic-gate } 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate /* 3620Sstevel@tonic-gate * get vtoc from a device already opened. 3630Sstevel@tonic-gate * returns 3640Sstevel@tonic-gate * 0 on success, 3650Sstevel@tonic-gate * -1 on error. If the error was ENOTSUP, partno will be set to 3660Sstevel@tonic-gate * VT_ENOTSUP if possible. 3670Sstevel@tonic-gate */ 3680Sstevel@tonic-gate int 3690Sstevel@tonic-gate meta_getvtoc( 3700Sstevel@tonic-gate int fd, /* fd for named device */ 3710Sstevel@tonic-gate char *devname, /* name of device */ 372*7563SPrasad.Singamsetty@Sun.COM struct extvtoc *vtocbufp, /* vtoc buffer to fill */ 3730Sstevel@tonic-gate int *partno, /* return partno here */ 3740Sstevel@tonic-gate md_error_t *ep 3750Sstevel@tonic-gate ) 3760Sstevel@tonic-gate { 3770Sstevel@tonic-gate int part; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate (void) memset(vtocbufp, 0, sizeof (*vtocbufp)); 380*7563SPrasad.Singamsetty@Sun.COM if ((part = read_extvtoc(fd, vtocbufp)) < 0) { 3810Sstevel@tonic-gate int err = errno; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate if (ioctl(fd, MHIOCSTATUS, NULL) == 1) 3840Sstevel@tonic-gate err = EACCES; 3850Sstevel@tonic-gate else if (part == VT_EINVAL) 3860Sstevel@tonic-gate err = EINVAL; 3870Sstevel@tonic-gate else if (part == VT_EIO) 3880Sstevel@tonic-gate err = EIO; 3890Sstevel@tonic-gate else if (part == VT_ENOTSUP) { 3900Sstevel@tonic-gate if (partno) { 3910Sstevel@tonic-gate *partno = VT_ENOTSUP; 3920Sstevel@tonic-gate return (-1); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate /* Slice number for *p0 partition (whole disk on x86) is 16 */ 3990Sstevel@tonic-gate if (part >= V_NUMPAR) 4000Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, devname)); 4010Sstevel@tonic-gate 402*7563SPrasad.Singamsetty@Sun.COM /* Slice number for *p0 partition (whole disk on x86) is 16 */ 403*7563SPrasad.Singamsetty@Sun.COM if (part >= V_NUMPAR) 404*7563SPrasad.Singamsetty@Sun.COM return (mdsyserror(ep, EINVAL, devname)); 405*7563SPrasad.Singamsetty@Sun.COM 4060Sstevel@tonic-gate if (partno) 4070Sstevel@tonic-gate *partno = part; 4080Sstevel@tonic-gate return (0); 4090Sstevel@tonic-gate } 4100Sstevel@tonic-gate /* 4110Sstevel@tonic-gate * set mdvtoc for a meta devices 4120Sstevel@tonic-gate */ 4130Sstevel@tonic-gate int 4140Sstevel@tonic-gate meta_setmdvtoc( 4150Sstevel@tonic-gate int fd, /* fd for named device */ 4160Sstevel@tonic-gate char *devname, /* name of device */ 4170Sstevel@tonic-gate mdvtoc_t *mdvtocp, /* mdvtoc buffer to fill */ 4180Sstevel@tonic-gate md_error_t *ep 4190Sstevel@tonic-gate ) 4200Sstevel@tonic-gate { 4210Sstevel@tonic-gate uint_t i; 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate /* 4240Sstevel@tonic-gate * Sanity-check the mdvtoc 4250Sstevel@tonic-gate */ 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate if (mdvtocp->nparts > V_NUMPAR) { 4280Sstevel@tonic-gate return (-1); 4290Sstevel@tonic-gate } 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate /* 4320Sstevel@tonic-gate * since many drivers won't allow opening a device make sure 4330Sstevel@tonic-gate * all partitions aren't being set to zero. If all are zero then 4340Sstevel@tonic-gate * we have no way to set them to something else 4350Sstevel@tonic-gate */ 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate for (i = 0; i < mdvtocp->nparts; i++) 4380Sstevel@tonic-gate if (mdvtocp->parts[i].size > 0) 4390Sstevel@tonic-gate break; 4400Sstevel@tonic-gate if (i == mdvtocp->nparts) 4410Sstevel@tonic-gate return (-1); 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate /* 4440Sstevel@tonic-gate * Write the mdvtoc 4450Sstevel@tonic-gate */ 4460Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, (caddr_t)mdvtocp) == -1) { 4470Sstevel@tonic-gate return (mdsyserror(ep, errno, devname)); 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate return (0); 4510Sstevel@tonic-gate } 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate /* 4540Sstevel@tonic-gate * set vtoc 4550Sstevel@tonic-gate */ 4560Sstevel@tonic-gate int 4570Sstevel@tonic-gate meta_setvtoc( 4580Sstevel@tonic-gate int fd, /* fd for named device */ 4590Sstevel@tonic-gate char *devname, /* name of device */ 460*7563SPrasad.Singamsetty@Sun.COM struct extvtoc *vtocbufp, /* vtoc buffer to fill */ 4610Sstevel@tonic-gate md_error_t *ep 4620Sstevel@tonic-gate ) 4630Sstevel@tonic-gate { 4640Sstevel@tonic-gate int part; 4650Sstevel@tonic-gate int err; 4660Sstevel@tonic-gate 467*7563SPrasad.Singamsetty@Sun.COM if ((part = write_extvtoc(fd, vtocbufp)) < 0) { 4680Sstevel@tonic-gate if (part == VT_EINVAL) 4690Sstevel@tonic-gate err = EINVAL; 4700Sstevel@tonic-gate else if (part == VT_EIO) 4710Sstevel@tonic-gate err = EIO; 4720Sstevel@tonic-gate else 4730Sstevel@tonic-gate err = errno; 4740Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate return (0); 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate /* 4810Sstevel@tonic-gate * FUNCTION: meta_get_names() 4820Sstevel@tonic-gate * INPUT: drivername - char string containing the driver name 4830Sstevel@tonic-gate * sp - the set name to get soft partitions from 4840Sstevel@tonic-gate * options - options from the command line 4850Sstevel@tonic-gate * OUTPUT: nlpp - list of all soft partition names 4860Sstevel@tonic-gate * ep - return error pointer 4870Sstevel@tonic-gate * RETURNS: int - -1 if error, 0 success 4880Sstevel@tonic-gate * PURPOSE: returns a list of all specified devices in the metadb 4890Sstevel@tonic-gate * for all devices in the specified set 4900Sstevel@tonic-gate */ 4910Sstevel@tonic-gate int 4920Sstevel@tonic-gate meta_get_names( 4930Sstevel@tonic-gate char *drivername, 4940Sstevel@tonic-gate mdsetname_t *sp, 4950Sstevel@tonic-gate mdnamelist_t **nlpp, 4960Sstevel@tonic-gate mdprtopts_t options, 4970Sstevel@tonic-gate md_error_t *ep 4980Sstevel@tonic-gate ) 4990Sstevel@tonic-gate { 5000Sstevel@tonic-gate md_i_getnum_t gn; /* MD_IOCGET_NUM params */ 5010Sstevel@tonic-gate mdnamelist_t **tailpp = nlpp; 5020Sstevel@tonic-gate minor_t *minors = NULL; 5030Sstevel@tonic-gate minor_t *m_ptr; 5040Sstevel@tonic-gate int i; 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate (void) memset(&gn, '\0', sizeof (gn)); 5070Sstevel@tonic-gate MD_SETDRIVERNAME(&gn, drivername, sp->setno); 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate /* get number of devices */ 5100Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 5110Sstevel@tonic-gate if (mdiserror(&gn.mde, MDE_UNIT_NOT_FOUND)) { 5120Sstevel@tonic-gate mdclrerror(&gn.mde); 5130Sstevel@tonic-gate } else { 5140Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 5150Sstevel@tonic-gate return (-1); 5160Sstevel@tonic-gate } 5170Sstevel@tonic-gate } 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate if (gn.size > 0) { 5200Sstevel@tonic-gate /* malloc minor number buffer to be filled by ioctl */ 5210Sstevel@tonic-gate if ((minors = (minor_t *)malloc( 5224492Spetede gn.size * sizeof (minor_t))) == 0) { 5230Sstevel@tonic-gate return (ENOMEM); 5240Sstevel@tonic-gate } 5250Sstevel@tonic-gate gn.minors = (uintptr_t)minors; 5260Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 5270Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 5280Sstevel@tonic-gate free(minors); 5290Sstevel@tonic-gate return (-1); 5300Sstevel@tonic-gate } 5310Sstevel@tonic-gate m_ptr = minors; 5320Sstevel@tonic-gate for (i = 0; i < gn.size; i++) { 5330Sstevel@tonic-gate mdname_t *np; 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate /* get name */ 5360Sstevel@tonic-gate np = metamnumname(&sp, *m_ptr, 5374492Spetede ((options & PRINT_FAST) ? 1 : 0), ep); 5384492Spetede 5394492Spetede /* 5404492Spetede * np can be NULL if the /dev/md namespace entries 5415525Spetede * do not exist. This could have happened due to 5425525Spetede * devfsadmd not having created them. 5435525Spetede * Therefore assume devfsadmd has not run and tell 5445525Spetede * it to run for the specific device that is missing. 5455525Spetede * Ignore any error return from meta_update_devtree 5465525Spetede * as a failure to create the device nodes will be 5475525Spetede * picked up in the metamnumname() call. Note that 5485525Spetede * the call to meta_update_devtree should not return 5495525Spetede * until the /dev/md links have been created or if 5505525Spetede * there has been a failure of some sort. 5514492Spetede */ 5525525Spetede if (np == NULL) { 5534492Spetede (void) meta_update_devtree(*m_ptr); 5544492Spetede np = metamnumname(&sp, *m_ptr, 5554492Spetede ((options & PRINT_FAST) ? 1 : 0), ep); 5564492Spetede } 5574492Spetede 5580Sstevel@tonic-gate if (np == NULL) 5590Sstevel@tonic-gate goto out; 5600Sstevel@tonic-gate 5614492Spetede tailpp = meta_namelist_append_wrapper(tailpp, np); 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate /* next device */ 5640Sstevel@tonic-gate m_ptr++; 5650Sstevel@tonic-gate } 5660Sstevel@tonic-gate free(minors); 5670Sstevel@tonic-gate } 5680Sstevel@tonic-gate return (gn.size); 5690Sstevel@tonic-gate 5700Sstevel@tonic-gate out: 5710Sstevel@tonic-gate if (minors != NULL) 5720Sstevel@tonic-gate free(minors); 5730Sstevel@tonic-gate metafreenamelist(*nlpp); 5740Sstevel@tonic-gate *nlpp = NULL; 5750Sstevel@tonic-gate return (-1); 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate /* 5790Sstevel@tonic-gate * Wrap lib/libdevid/devid_deviceid_to_nmlist. We want to take the 5800Sstevel@tonic-gate * results from that function and filter out the c[t]dp style names that 5810Sstevel@tonic-gate * we typically see on x86 so that we never see them. 5820Sstevel@tonic-gate */ 5830Sstevel@tonic-gate int 5840Sstevel@tonic-gate meta_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name, 5850Sstevel@tonic-gate devid_nmlist_t **retlist) 5860Sstevel@tonic-gate { 5870Sstevel@tonic-gate int res; 5880Sstevel@tonic-gate devid_nmlist_t *dp; 5890Sstevel@tonic-gate devid_nmlist_t *tmp_retlist; 5900Sstevel@tonic-gate int i = 1; 5910Sstevel@tonic-gate devid_nmlist_t *rp; 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate res = devid_deviceid_to_nmlist(search_path, devid, minor_name, retlist); 5940Sstevel@tonic-gate if (res != 0) { 5950Sstevel@tonic-gate return (res); 5960Sstevel@tonic-gate } 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate 5990Sstevel@tonic-gate /* first count the number of non c[t]dp items in retlist */ 6000Sstevel@tonic-gate for (dp = *retlist; dp->dev != NODEV; dp++) { 6010Sstevel@tonic-gate uint_t s; 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 6040Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 6050Sstevel@tonic-gate i++; 6060Sstevel@tonic-gate } 6070Sstevel@tonic-gate } 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate /* create an array to hold the non c[t]dp items */ 6100Sstevel@tonic-gate tmp_retlist = Malloc(sizeof (devid_nmlist_t) * i); 6110Sstevel@tonic-gate /* copy the non c[t]dp items to the array */ 6120Sstevel@tonic-gate for (dp = *retlist, rp = tmp_retlist; dp->dev != NODEV; dp++) { 6130Sstevel@tonic-gate uint_t s; 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 6160Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 6170Sstevel@tonic-gate /* nope, so copy and go to the next */ 6180Sstevel@tonic-gate rp->dev = dp->dev; 6190Sstevel@tonic-gate rp->devname = Strdup(dp->devname); 6200Sstevel@tonic-gate rp++; 6210Sstevel@tonic-gate } 6220Sstevel@tonic-gate /* if it is c[t]dp, just skip the element */ 6230Sstevel@tonic-gate } 6240Sstevel@tonic-gate /* copy the list terminator */ 6250Sstevel@tonic-gate rp->dev = NODEV; 6260Sstevel@tonic-gate rp->devname = NULL; 6270Sstevel@tonic-gate devid_free_nmlist (*retlist); 6280Sstevel@tonic-gate *retlist = tmp_retlist; 6290Sstevel@tonic-gate return (res); 6300Sstevel@tonic-gate } 6317087Ssk102515 6327087Ssk102515 /* 6337087Ssk102515 * Check each real device that makes up a metadevice so that 6347087Ssk102515 * un_dev entries can be matched against the entries in the 6357087Ssk102515 * namespace. 6367087Ssk102515 * 6377087Ssk102515 * RETURN: 6387087Ssk102515 * -1 error 6397087Ssk102515 * 0 success 6407087Ssk102515 */ 6417087Ssk102515 int 6427087Ssk102515 meta_fix_compnames( 6437087Ssk102515 mdsetname_t *sp, 6447087Ssk102515 mdname_t *namep, 6457087Ssk102515 md_dev64_t dev, 6467087Ssk102515 md_error_t *ep 6477087Ssk102515 ) 6487087Ssk102515 { 6497087Ssk102515 int ret = 0; 6507087Ssk102515 char *miscname; 6517087Ssk102515 6527087Ssk102515 /* get miscname and unit */ 6537087Ssk102515 if ((miscname = metagetmiscname(namep, ep)) == NULL) 6547087Ssk102515 return (-1); 6557087Ssk102515 if (strcmp(miscname, MD_STRIPE) == 0) { 6567087Ssk102515 if (meta_stripe_check_component(sp, namep, dev, ep) < 0) { 6577087Ssk102515 ret = -1; 6587087Ssk102515 } 6597087Ssk102515 } else if (strcmp(miscname, MD_SP) == 0) { 6607087Ssk102515 if (meta_sp_check_component(sp, namep, ep) < 0) { 6617087Ssk102515 ret = -1; 6627087Ssk102515 } 6637087Ssk102515 } else if (strcmp(miscname, MD_RAID) == 0) { 6647087Ssk102515 if (meta_raid_check_component(sp, namep, dev, ep) < 0) { 6657087Ssk102515 ret = -1; 6667087Ssk102515 } 6677087Ssk102515 } else { 6687087Ssk102515 (void) mdmderror(ep, MDE_INVAL_UNIT, 0, namep->cname); 6697087Ssk102515 return (-1); 6707087Ssk102515 } 6717087Ssk102515 return (ret); 6727087Ssk102515 } 673