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 5*1623Stw21770 * Common Development and Distribution License (the "License"). 6*1623Stw21770 * 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*1623Stw21770 * Copyright 2006 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", 510Sstevel@tonic-gate 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", 700Sstevel@tonic-gate 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 131*1623Stw21770 /* if no valid name then return an error */ 132*1623Stw21770 if (namep == NULL) 133*1623Stw21770 return (-1); 134*1623Stw21770 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) { 2080Sstevel@tonic-gate goto out; 2090Sstevel@tonic-gate } 2100Sstevel@tonic-gate if (meta_getdevs(sp, devnp, nlpp, ep) != 0) 2110Sstevel@tonic-gate goto out; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* success */ 2150Sstevel@tonic-gate rval = 0; 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate /* cleanup, return error */ 2180Sstevel@tonic-gate out: 2190Sstevel@tonic-gate if (mydevs != NULL) 2200Sstevel@tonic-gate Free(mydevs); 2210Sstevel@tonic-gate return (rval); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate /* 2250Sstevel@tonic-gate * get all dev_t for a set 2260Sstevel@tonic-gate */ 2270Sstevel@tonic-gate int 2280Sstevel@tonic-gate meta_getalldevs( 2290Sstevel@tonic-gate mdsetname_t *sp, /* set to look in */ 2300Sstevel@tonic-gate mdnamelist_t **nlpp, /* returned devices */ 2310Sstevel@tonic-gate int check_db, 2320Sstevel@tonic-gate md_error_t *ep 2330Sstevel@tonic-gate ) 2340Sstevel@tonic-gate { 2350Sstevel@tonic-gate md_replicalist_t *rlp, *rp; 2360Sstevel@tonic-gate mdnamelist_t *nlp, *np; 2370Sstevel@tonic-gate mdhspnamelist_t *hspnlp, *hspp; 2380Sstevel@tonic-gate int rval = 0; 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate assert(sp != NULL); 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* 2430Sstevel@tonic-gate * Get a replica namelist, 2440Sstevel@tonic-gate * and then get all the devs within the replicas. 2450Sstevel@tonic-gate */ 2460Sstevel@tonic-gate if (check_db == TRUE) { 2470Sstevel@tonic-gate rlp = NULL; 2480Sstevel@tonic-gate if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 2490Sstevel@tonic-gate rval = -1; 2500Sstevel@tonic-gate for (rp = rlp; (rp != NULL); rp = rp->rl_next) { 2510Sstevel@tonic-gate if (meta_getdevs(sp, rp->rl_repp->r_namep, 2520Sstevel@tonic-gate nlpp, ep) != 0) 2530Sstevel@tonic-gate rval = -1; 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate metafreereplicalist(rlp); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate /* 2590Sstevel@tonic-gate * Get a stripe namelist, 2600Sstevel@tonic-gate * and then get all the devs within the stripes. 2610Sstevel@tonic-gate */ 2620Sstevel@tonic-gate nlp = NULL; 2630Sstevel@tonic-gate if (meta_get_stripe_names(sp, &nlp, 0, ep) < 0) 2640Sstevel@tonic-gate rval = -1; 2650Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2660Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2670Sstevel@tonic-gate rval = -1; 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate metafreenamelist(nlp); 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate /* 2720Sstevel@tonic-gate * Get a mirror namelist, 2730Sstevel@tonic-gate * and then get all the devs within the mirrors. 2740Sstevel@tonic-gate */ 2750Sstevel@tonic-gate nlp = NULL; 2760Sstevel@tonic-gate if (meta_get_mirror_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 trans namelist, 2860Sstevel@tonic-gate * and then get all the devs within the trans. 2870Sstevel@tonic-gate */ 2880Sstevel@tonic-gate nlp = NULL; 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate if (meta_get_trans_names(sp, &nlp, 0, ep) < 0) 2910Sstevel@tonic-gate rval = -1; 2920Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 2930Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 2940Sstevel@tonic-gate rval = -1; 2950Sstevel@tonic-gate } 2960Sstevel@tonic-gate metafreenamelist(nlp); 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate /* 2990Sstevel@tonic-gate * Get a hot spare pool namelist, 3000Sstevel@tonic-gate * and then get all the devs within the hot spare pools. 3010Sstevel@tonic-gate */ 3020Sstevel@tonic-gate hspnlp = NULL; 3030Sstevel@tonic-gate if (meta_get_hsp_names(sp, &hspnlp, 0, ep) < 0) 3040Sstevel@tonic-gate rval = -1; 3050Sstevel@tonic-gate for (hspp = hspnlp; (hspp != NULL); hspp = hspp->next) { 3060Sstevel@tonic-gate md_hsp_t *hsp; 3070Sstevel@tonic-gate uint_t i; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate if ((hsp = meta_get_hsp(sp, hspp->hspnamep, ep)) == NULL) 3100Sstevel@tonic-gate rval = -1; 3110Sstevel@tonic-gate else for (i = 0; (i < hsp->hotspares.hotspares_len); ++i) { 3120Sstevel@tonic-gate md_hs_t *hs = &hsp->hotspares.hotspares_val[i]; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate if (meta_getdevs(sp, hs->hsnamep, nlpp, ep) != 0) 3150Sstevel@tonic-gate rval = -1; 3160Sstevel@tonic-gate } 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate metafreehspnamelist(hspnlp); 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate /* 3210Sstevel@tonic-gate * Get a raid namelist, 3220Sstevel@tonic-gate * and then get all the devs within the raids. 3230Sstevel@tonic-gate */ 3240Sstevel@tonic-gate nlp = NULL; 3250Sstevel@tonic-gate if (meta_get_raid_names(sp, &nlp, 0, ep) < 0) 3260Sstevel@tonic-gate rval = -1; 3270Sstevel@tonic-gate for (np = nlp; (np != NULL); np = np->next) { 3280Sstevel@tonic-gate if (meta_getdevs(sp, np->namep, nlpp, ep) != 0) 3290Sstevel@tonic-gate rval = -1; 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate metafreenamelist(nlp); 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate /* 3340Sstevel@tonic-gate * Get a soft partition namelist, 3350Sstevel@tonic-gate * and then get all the devs within the softpartitions 3360Sstevel@tonic-gate */ 3370Sstevel@tonic-gate nlp = NULL; 3380Sstevel@tonic-gate if (meta_get_sp_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 return (rval); 3470Sstevel@tonic-gate } 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate /* 3500Sstevel@tonic-gate * get vtoc from a device already opened. 3510Sstevel@tonic-gate * returns 3520Sstevel@tonic-gate * 0 on success, 3530Sstevel@tonic-gate * -1 on error. If the error was ENOTSUP, partno will be set to 3540Sstevel@tonic-gate * VT_ENOTSUP if possible. 3550Sstevel@tonic-gate */ 3560Sstevel@tonic-gate int 3570Sstevel@tonic-gate meta_getvtoc( 3580Sstevel@tonic-gate int fd, /* fd for named device */ 3590Sstevel@tonic-gate char *devname, /* name of device */ 3600Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 3610Sstevel@tonic-gate int *partno, /* return partno here */ 3620Sstevel@tonic-gate md_error_t *ep 3630Sstevel@tonic-gate ) 3640Sstevel@tonic-gate { 3650Sstevel@tonic-gate int part; 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate (void) memset(vtocbufp, 0, sizeof (*vtocbufp)); 3680Sstevel@tonic-gate if ((part = read_vtoc(fd, vtocbufp)) < 0) { 3690Sstevel@tonic-gate int err = errno; 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate if (ioctl(fd, MHIOCSTATUS, NULL) == 1) 3720Sstevel@tonic-gate err = EACCES; 3730Sstevel@tonic-gate else if (part == VT_EINVAL) 3740Sstevel@tonic-gate err = EINVAL; 3750Sstevel@tonic-gate else if (part == VT_EIO) 3760Sstevel@tonic-gate err = EIO; 3770Sstevel@tonic-gate else if (part == VT_ENOTSUP) { 3780Sstevel@tonic-gate if (partno) { 3790Sstevel@tonic-gate *partno = VT_ENOTSUP; 3800Sstevel@tonic-gate return (-1); 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate } 3830Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 3840Sstevel@tonic-gate } 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate /* Slice number for *p0 partition (whole disk on x86) is 16 */ 3870Sstevel@tonic-gate if (part >= V_NUMPAR) 3880Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, devname)); 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate if (partno) 3910Sstevel@tonic-gate *partno = part; 3920Sstevel@tonic-gate return (0); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate /* 3950Sstevel@tonic-gate * set mdvtoc for a meta devices 3960Sstevel@tonic-gate */ 3970Sstevel@tonic-gate int 3980Sstevel@tonic-gate meta_setmdvtoc( 3990Sstevel@tonic-gate int fd, /* fd for named device */ 4000Sstevel@tonic-gate char *devname, /* name of device */ 4010Sstevel@tonic-gate mdvtoc_t *mdvtocp, /* mdvtoc buffer to fill */ 4020Sstevel@tonic-gate md_error_t *ep 4030Sstevel@tonic-gate ) 4040Sstevel@tonic-gate { 4050Sstevel@tonic-gate uint_t i; 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * Sanity-check the mdvtoc 4090Sstevel@tonic-gate */ 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate if (mdvtocp->nparts > V_NUMPAR) { 4120Sstevel@tonic-gate return (-1); 4130Sstevel@tonic-gate } 4140Sstevel@tonic-gate 4150Sstevel@tonic-gate /* 4160Sstevel@tonic-gate * since many drivers won't allow opening a device make sure 4170Sstevel@tonic-gate * all partitions aren't being set to zero. If all are zero then 4180Sstevel@tonic-gate * we have no way to set them to something else 4190Sstevel@tonic-gate */ 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate for (i = 0; i < mdvtocp->nparts; i++) 4220Sstevel@tonic-gate if (mdvtocp->parts[i].size > 0) 4230Sstevel@tonic-gate break; 4240Sstevel@tonic-gate if (i == mdvtocp->nparts) 4250Sstevel@tonic-gate return (-1); 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate /* 4280Sstevel@tonic-gate * Write the mdvtoc 4290Sstevel@tonic-gate */ 4300Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, (caddr_t)mdvtocp) == -1) { 4310Sstevel@tonic-gate return (mdsyserror(ep, errno, devname)); 4320Sstevel@tonic-gate } 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate return (0); 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate /* 4380Sstevel@tonic-gate * set vtoc 4390Sstevel@tonic-gate */ 4400Sstevel@tonic-gate int 4410Sstevel@tonic-gate meta_setvtoc( 4420Sstevel@tonic-gate int fd, /* fd for named device */ 4430Sstevel@tonic-gate char *devname, /* name of device */ 4440Sstevel@tonic-gate struct vtoc *vtocbufp, /* vtoc buffer to fill */ 4450Sstevel@tonic-gate md_error_t *ep 4460Sstevel@tonic-gate ) 4470Sstevel@tonic-gate { 4480Sstevel@tonic-gate int part; 4490Sstevel@tonic-gate int err; 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate if ((part = write_vtoc(fd, vtocbufp)) < 0) { 4520Sstevel@tonic-gate if (part == VT_EINVAL) 4530Sstevel@tonic-gate err = EINVAL; 4540Sstevel@tonic-gate else if (part == VT_EIO) 4550Sstevel@tonic-gate err = EIO; 4560Sstevel@tonic-gate else 4570Sstevel@tonic-gate err = errno; 4580Sstevel@tonic-gate return (mdsyserror(ep, err, devname)); 4590Sstevel@tonic-gate } 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate return (0); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate /* 4650Sstevel@tonic-gate * FUNCTION: meta_get_names() 4660Sstevel@tonic-gate * INPUT: drivername - char string containing the driver name 4670Sstevel@tonic-gate * sp - the set name to get soft partitions from 4680Sstevel@tonic-gate * options - options from the command line 4690Sstevel@tonic-gate * OUTPUT: nlpp - list of all soft partition names 4700Sstevel@tonic-gate * ep - return error pointer 4710Sstevel@tonic-gate * RETURNS: int - -1 if error, 0 success 4720Sstevel@tonic-gate * PURPOSE: returns a list of all specified devices in the metadb 4730Sstevel@tonic-gate * for all devices in the specified set 4740Sstevel@tonic-gate */ 4750Sstevel@tonic-gate int 4760Sstevel@tonic-gate meta_get_names( 4770Sstevel@tonic-gate char *drivername, 4780Sstevel@tonic-gate mdsetname_t *sp, 4790Sstevel@tonic-gate mdnamelist_t **nlpp, 4800Sstevel@tonic-gate mdprtopts_t options, 4810Sstevel@tonic-gate md_error_t *ep 4820Sstevel@tonic-gate ) 4830Sstevel@tonic-gate { 4840Sstevel@tonic-gate md_i_getnum_t gn; /* MD_IOCGET_NUM params */ 4850Sstevel@tonic-gate mdnamelist_t **tailpp = nlpp; 4860Sstevel@tonic-gate minor_t *minors = NULL; 4870Sstevel@tonic-gate minor_t *m_ptr; 4880Sstevel@tonic-gate int i; 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate (void) memset(&gn, '\0', sizeof (gn)); 4910Sstevel@tonic-gate MD_SETDRIVERNAME(&gn, drivername, sp->setno); 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate /* get number of devices */ 4940Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 4950Sstevel@tonic-gate if (mdiserror(&gn.mde, MDE_UNIT_NOT_FOUND)) { 4960Sstevel@tonic-gate mdclrerror(&gn.mde); 4970Sstevel@tonic-gate } else { 4980Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 4990Sstevel@tonic-gate return (-1); 5000Sstevel@tonic-gate } 5010Sstevel@tonic-gate } 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate if (gn.size > 0) { 5040Sstevel@tonic-gate /* malloc minor number buffer to be filled by ioctl */ 5050Sstevel@tonic-gate if ((minors = (minor_t *)malloc( 5060Sstevel@tonic-gate gn.size * sizeof (minor_t))) == 0) { 5070Sstevel@tonic-gate return (ENOMEM); 5080Sstevel@tonic-gate } 5090Sstevel@tonic-gate gn.minors = (uintptr_t)minors; 5100Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NUM, &gn, &gn.mde, NULL) != 0) { 5110Sstevel@tonic-gate (void) mdstealerror(ep, &gn.mde); 5120Sstevel@tonic-gate free(minors); 5130Sstevel@tonic-gate return (-1); 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate m_ptr = minors; 5160Sstevel@tonic-gate for (i = 0; i < gn.size; i++) { 5170Sstevel@tonic-gate mdname_t *np; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate /* get name */ 5200Sstevel@tonic-gate np = metamnumname(&sp, *m_ptr, 5210Sstevel@tonic-gate ((options & PRINT_FAST) ? 1 : 0), ep); 5220Sstevel@tonic-gate if (np == NULL) 5230Sstevel@tonic-gate goto out; 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate tailpp = meta_namelist_append_wrapper( 5260Sstevel@tonic-gate tailpp, np); 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate /* next device */ 5290Sstevel@tonic-gate m_ptr++; 5300Sstevel@tonic-gate } 5310Sstevel@tonic-gate free(minors); 5320Sstevel@tonic-gate } 5330Sstevel@tonic-gate return (gn.size); 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate out: 5360Sstevel@tonic-gate if (minors != NULL) 5370Sstevel@tonic-gate free(minors); 5380Sstevel@tonic-gate metafreenamelist(*nlpp); 5390Sstevel@tonic-gate *nlpp = NULL; 5400Sstevel@tonic-gate return (-1); 5410Sstevel@tonic-gate } 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate /* 5440Sstevel@tonic-gate * Wrap lib/libdevid/devid_deviceid_to_nmlist. We want to take the 5450Sstevel@tonic-gate * results from that function and filter out the c[t]dp style names that 5460Sstevel@tonic-gate * we typically see on x86 so that we never see them. 5470Sstevel@tonic-gate */ 5480Sstevel@tonic-gate int 5490Sstevel@tonic-gate meta_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name, 5500Sstevel@tonic-gate devid_nmlist_t **retlist) 5510Sstevel@tonic-gate { 5520Sstevel@tonic-gate int res; 5530Sstevel@tonic-gate devid_nmlist_t *dp; 5540Sstevel@tonic-gate devid_nmlist_t *tmp_retlist; 5550Sstevel@tonic-gate int i = 1; 5560Sstevel@tonic-gate devid_nmlist_t *rp; 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate res = devid_deviceid_to_nmlist(search_path, devid, minor_name, retlist); 5590Sstevel@tonic-gate if (res != 0) { 5600Sstevel@tonic-gate return (res); 5610Sstevel@tonic-gate } 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate /* first count the number of non c[t]dp items in retlist */ 5650Sstevel@tonic-gate for (dp = *retlist; dp->dev != NODEV; dp++) { 5660Sstevel@tonic-gate uint_t s; 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 5690Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 5700Sstevel@tonic-gate i++; 5710Sstevel@tonic-gate } 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate /* create an array to hold the non c[t]dp items */ 5750Sstevel@tonic-gate tmp_retlist = Malloc(sizeof (devid_nmlist_t) * i); 5760Sstevel@tonic-gate /* copy the non c[t]dp items to the array */ 5770Sstevel@tonic-gate for (dp = *retlist, rp = tmp_retlist; dp->dev != NODEV; dp++) { 5780Sstevel@tonic-gate uint_t s; 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate /* Check if this is a c[t]dp style name. */ 5810Sstevel@tonic-gate if (parse_ctd(basename(dp->devname), &s) != 1) { 5820Sstevel@tonic-gate /* nope, so copy and go to the next */ 5830Sstevel@tonic-gate rp->dev = dp->dev; 5840Sstevel@tonic-gate rp->devname = Strdup(dp->devname); 5850Sstevel@tonic-gate rp++; 5860Sstevel@tonic-gate } 5870Sstevel@tonic-gate /* if it is c[t]dp, just skip the element */ 5880Sstevel@tonic-gate } 5890Sstevel@tonic-gate /* copy the list terminator */ 5900Sstevel@tonic-gate rp->dev = NODEV; 5910Sstevel@tonic-gate rp->devname = NULL; 5920Sstevel@tonic-gate devid_free_nmlist (*retlist); 5930Sstevel@tonic-gate *retlist = tmp_retlist; 5940Sstevel@tonic-gate return (res); 5950Sstevel@tonic-gate } 596