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*9017SJohn.Wren.Kennedy@Sun.COM 220Sstevel@tonic-gate /* 23*9017SJohn.Wren.Kennedy@Sun.COM * Copyright 2009 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 * Just in case we're not in a build environment, make sure that 290Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 320Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 330Sstevel@tonic-gate #endif 340Sstevel@tonic-gate 350Sstevel@tonic-gate /* 360Sstevel@tonic-gate * check componets 370Sstevel@tonic-gate */ 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <meta.h> 400Sstevel@tonic-gate #include "meta_lib_prv.h" 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <sys/mnttab.h> 430Sstevel@tonic-gate #include <sys/swap.h> 440Sstevel@tonic-gate #include <devid.h> 450Sstevel@tonic-gate #include <sys/dumpadm.h> 460Sstevel@tonic-gate 47127Shshaw /* possible returns from meta_check_samedrive */ 48127Shshaw #define CANT_TELL -1 49127Shshaw #define NOT_SAMEDRIVE 0 50127Shshaw #define IDENTICAL_NAME_DEVT 1 51127Shshaw #define IDENTICAL_DEVIDS 2 52127Shshaw 530Sstevel@tonic-gate /* 540Sstevel@tonic-gate * static list(s) 550Sstevel@tonic-gate */ 560Sstevel@tonic-gate typedef struct dev_list { 570Sstevel@tonic-gate char *dev_name; 580Sstevel@tonic-gate ddi_devid_t devid; 590Sstevel@tonic-gate struct dev_list *dev_nxt; 600Sstevel@tonic-gate } dev_list_t; 610Sstevel@tonic-gate 620Sstevel@tonic-gate static dev_list_t *devnamelist = NULL; 630Sstevel@tonic-gate 64*9017SJohn.Wren.Kennedy@Sun.COM static char *skip_these_mntents[] = { 65*9017SJohn.Wren.Kennedy@Sun.COM "nfs", 66*9017SJohn.Wren.Kennedy@Sun.COM "autofs", 67*9017SJohn.Wren.Kennedy@Sun.COM "proc", 68*9017SJohn.Wren.Kennedy@Sun.COM "tmpfs", 69*9017SJohn.Wren.Kennedy@Sun.COM "cachefs", 70*9017SJohn.Wren.Kennedy@Sun.COM "rfs", 71*9017SJohn.Wren.Kennedy@Sun.COM "fd", 72*9017SJohn.Wren.Kennedy@Sun.COM "mntfs", 73*9017SJohn.Wren.Kennedy@Sun.COM "lofs", 74*9017SJohn.Wren.Kennedy@Sun.COM "devfs", 75*9017SJohn.Wren.Kennedy@Sun.COM "dev", 76*9017SJohn.Wren.Kennedy@Sun.COM "ctfs", 77*9017SJohn.Wren.Kennedy@Sun.COM "objfs", 78*9017SJohn.Wren.Kennedy@Sun.COM "sharefs", 79*9017SJohn.Wren.Kennedy@Sun.COM NULL 80*9017SJohn.Wren.Kennedy@Sun.COM }; 81*9017SJohn.Wren.Kennedy@Sun.COM 820Sstevel@tonic-gate /* 830Sstevel@tonic-gate * free swap info 840Sstevel@tonic-gate */ 850Sstevel@tonic-gate static void 860Sstevel@tonic-gate free_swapinfo( 870Sstevel@tonic-gate struct swaptable *swtp 880Sstevel@tonic-gate ) 890Sstevel@tonic-gate { 900Sstevel@tonic-gate int i; 910Sstevel@tonic-gate 920Sstevel@tonic-gate if (swtp == NULL) 930Sstevel@tonic-gate return; 940Sstevel@tonic-gate 950Sstevel@tonic-gate for (i = 0; (i < swtp->swt_n); ++i) { 960Sstevel@tonic-gate if (swtp->swt_ent[i].ste_path != NULL) 970Sstevel@tonic-gate Free(swtp->swt_ent[i].ste_path); 980Sstevel@tonic-gate } 990Sstevel@tonic-gate 1000Sstevel@tonic-gate Free(swtp); 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate /* 1040Sstevel@tonic-gate * get swap info 1050Sstevel@tonic-gate */ 1060Sstevel@tonic-gate static int 1070Sstevel@tonic-gate get_swapinfo( 1080Sstevel@tonic-gate struct swaptable **swtpp, 1090Sstevel@tonic-gate int *nswap, 1100Sstevel@tonic-gate md_error_t *ep 1110Sstevel@tonic-gate ) 1120Sstevel@tonic-gate { 1130Sstevel@tonic-gate int i; 1140Sstevel@tonic-gate size_t swtsize; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate *swtpp = NULL; 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate /* get number of entries */ 1190Sstevel@tonic-gate if ((*nswap = swapctl(SC_GETNSWP, NULL)) < 0) { 1200Sstevel@tonic-gate return (mdsyserror(ep, errno, "swapctl(SC_GETNSWP)")); 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate /* allocate structure */ 1240Sstevel@tonic-gate swtsize = sizeof ((*swtpp)->swt_n) + 1250Sstevel@tonic-gate ((*nswap) * sizeof ((*swtpp)->swt_ent[0])); 1260Sstevel@tonic-gate *swtpp = (struct swaptable *)Zalloc(swtsize); 1270Sstevel@tonic-gate (*swtpp)->swt_n = *nswap; 1280Sstevel@tonic-gate for (i = 0; (i < (*nswap)); ++i) 1290Sstevel@tonic-gate (*swtpp)->swt_ent[i].ste_path = Zalloc(MAXPATHLEN); 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate /* get info */ 1320Sstevel@tonic-gate if (((*nswap) = swapctl(SC_LIST, (*swtpp))) < 0) { 1330Sstevel@tonic-gate (void) mdsyserror(ep, errno, "swapctl(SC_LIST)"); 1340Sstevel@tonic-gate free_swapinfo(*swtpp); 1350Sstevel@tonic-gate return (-1); 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate /* return success */ 1390Sstevel@tonic-gate return (0); 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate /* 1430Sstevel@tonic-gate * check whether device is swapped on 1440Sstevel@tonic-gate */ 1450Sstevel@tonic-gate static int 1460Sstevel@tonic-gate meta_check_swapped( 1470Sstevel@tonic-gate mdsetname_t *sp, 1480Sstevel@tonic-gate mdname_t *np, 1490Sstevel@tonic-gate md_error_t *ep 1500Sstevel@tonic-gate ) 1510Sstevel@tonic-gate { 1520Sstevel@tonic-gate struct swaptable *swtp; 1530Sstevel@tonic-gate int nswap; 1540Sstevel@tonic-gate int i; 1550Sstevel@tonic-gate int rval = 0; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate /* should have a set */ 1580Sstevel@tonic-gate assert(sp != NULL); 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate /* get swap info */ 1610Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 1620Sstevel@tonic-gate return (-1); 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate /* look for match */ 1650Sstevel@tonic-gate for (i = 0; ((i < nswap) && (rval == 0)); ++i) { 1660Sstevel@tonic-gate mdname_t *snp; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 1691623Stw21770 UNKNOWN, ep)) == NULL) { 1700Sstevel@tonic-gate mdclrerror(ep); 1710Sstevel@tonic-gate continue; 1720Sstevel@tonic-gate } 1730Sstevel@tonic-gate if (np->dev == snp->dev) { 1740Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, 1750Sstevel@tonic-gate np->dev, np->cname); 1760Sstevel@tonic-gate } else { /* not swap - does it overlap */ 1770Sstevel@tonic-gate rval = meta_check_overlap(snp->cname, np, 0, -1, 1780Sstevel@tonic-gate snp, 0, -1, ep); 1790Sstevel@tonic-gate if (rval != 0) { 1800Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_SWAP, 181*9017SJohn.Wren.Kennedy@Sun.COM np->cname, NULL, snp->cname); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate free_swapinfo(swtp); 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate /* return success */ 1880Sstevel@tonic-gate return (rval); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate /* 1920Sstevel@tonic-gate * Is a driver currently swapped on? 1930Sstevel@tonic-gate */ 1940Sstevel@tonic-gate int 1950Sstevel@tonic-gate meta_check_driveswapped( 1960Sstevel@tonic-gate mdsetname_t *sp, 1970Sstevel@tonic-gate mddrivename_t *dnp, 1980Sstevel@tonic-gate md_error_t *ep 1990Sstevel@tonic-gate ) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate struct swaptable *swtp; 2020Sstevel@tonic-gate int nswap; 2030Sstevel@tonic-gate int i; 2040Sstevel@tonic-gate int rval = 0; 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate /* should have a set */ 2070Sstevel@tonic-gate assert(sp != NULL); 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate /* get swap info */ 2100Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 2110Sstevel@tonic-gate return (-1); 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate /* look for match */ 2140Sstevel@tonic-gate for (i = 0; (i < nswap); ++i) { 2150Sstevel@tonic-gate mdname_t *snp; 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 2181623Stw21770 LOGICAL_DEVICE, ep)) == NULL) { 2190Sstevel@tonic-gate mdclrerror(ep); 2200Sstevel@tonic-gate continue; 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) { 2240Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64, 2250Sstevel@tonic-gate dnp->cname); 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate free_swapinfo(swtp); 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate /* return success */ 2310Sstevel@tonic-gate return (rval); 2320Sstevel@tonic-gate } 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate /* 2350Sstevel@tonic-gate * check whether device is a dump device 2360Sstevel@tonic-gate */ 2370Sstevel@tonic-gate static int 2380Sstevel@tonic-gate meta_check_dump( 2390Sstevel@tonic-gate mdsetname_t *sp, 2400Sstevel@tonic-gate mdname_t *np, 2410Sstevel@tonic-gate md_error_t *ep 2420Sstevel@tonic-gate ) 2430Sstevel@tonic-gate { 2440Sstevel@tonic-gate int rval = 0; 2450Sstevel@tonic-gate int dump_fd; 2460Sstevel@tonic-gate char device[MAXPATHLEN]; 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0) 2500Sstevel@tonic-gate return (mdsyserror(ep, errno, "/dev/dump")); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate if (ioctl(dump_fd, DIOCGETDEV, device) != -1) { 2530Sstevel@tonic-gate mdname_t *dump_np; 2540Sstevel@tonic-gate 2551623Stw21770 if ((dump_np = metaname(&sp, device, UNKNOWN, ep)) == NULL) { 2560Sstevel@tonic-gate mdclrerror(ep); 2570Sstevel@tonic-gate (void) close(dump_fd); 2580Sstevel@tonic-gate return (0); 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate if (np->dev == dump_np->dev) { 2620Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_DUMP, 2630Sstevel@tonic-gate np->dev, np->cname); 2640Sstevel@tonic-gate } else { /* not a dump device - but does it overlap? */ 2650Sstevel@tonic-gate rval = meta_check_overlap(dump_np->cname, np, 0, -1, 2660Sstevel@tonic-gate dump_np, 0, -1, ep); 2670Sstevel@tonic-gate if (rval != 0) { 2680Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_DUMP, 269*9017SJohn.Wren.Kennedy@Sun.COM np->cname, NULL, dump_np->cname); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate (void) close(dump_fd); 2740Sstevel@tonic-gate return (rval); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate /* 2780Sstevel@tonic-gate * check whether device is mounted 2790Sstevel@tonic-gate */ 2800Sstevel@tonic-gate static int 2810Sstevel@tonic-gate meta_check_mounted( 2820Sstevel@tonic-gate mdsetname_t *sp, 2830Sstevel@tonic-gate mdname_t *np, 2840Sstevel@tonic-gate md_error_t *ep 2850Sstevel@tonic-gate ) 2860Sstevel@tonic-gate { 2870Sstevel@tonic-gate FILE *mfp; 2880Sstevel@tonic-gate struct mnttab m; 2890Sstevel@tonic-gate int rval = 0; 2900Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 2910Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate /* should have a set */ 2940Sstevel@tonic-gate assert(sp != NULL); 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate /* look in mnttab */ 2970Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 2980Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 2990Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 300*9017SJohn.Wren.Kennedy@Sun.COM char **fstype = skip_these_mntents; 301*9017SJohn.Wren.Kennedy@Sun.COM int skipit = 0; 3020Sstevel@tonic-gate mdname_t *mnp; 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 3050Sstevel@tonic-gate continue; 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 3080Sstevel@tonic-gate continue; 3090Sstevel@tonic-gate 310*9017SJohn.Wren.Kennedy@Sun.COM while (*fstype != NULL) 311*9017SJohn.Wren.Kennedy@Sun.COM if (strcmp(m.mnt_fstype, *fstype++) == 0) { 312*9017SJohn.Wren.Kennedy@Sun.COM skipit++; 313*9017SJohn.Wren.Kennedy@Sun.COM break; 314*9017SJohn.Wren.Kennedy@Sun.COM } 315*9017SJohn.Wren.Kennedy@Sun.COM 316*9017SJohn.Wren.Kennedy@Sun.COM if (skipit == 1) 3170Sstevel@tonic-gate continue; 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 3200Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 3210Sstevel@tonic-gate 3221623Stw21770 if ((mnp = metaname(&sp, mnt_special, UNKNOWN, ep)) == NULL) { 3230Sstevel@tonic-gate mdclrerror(ep); 3240Sstevel@tonic-gate continue; 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate if (np->dev == mnp->dev) { 3280Sstevel@tonic-gate rval = mduseerror(ep, MDE_IS_MOUNTED, 3290Sstevel@tonic-gate np->dev, mountp, np->cname); 3300Sstevel@tonic-gate } else { /* device isn't in mnttab - does it overlap? */ 3310Sstevel@tonic-gate rval = meta_check_overlap(mnp->cname, np, 0, -1, 3320Sstevel@tonic-gate mnp, 0, -1, ep); 3330Sstevel@tonic-gate if (rval != 0) { 3340Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED, 335*9017SJohn.Wren.Kennedy@Sun.COM np->cname, mountp, mnp->cname); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate /* return success */ 3410Sstevel@tonic-gate return (rval); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate /* 3460Sstevel@tonic-gate * Is a file system currently mounted on this disk drive? 3470Sstevel@tonic-gate */ 3480Sstevel@tonic-gate int 3490Sstevel@tonic-gate meta_check_drivemounted( 3500Sstevel@tonic-gate mdsetname_t *sp, 3510Sstevel@tonic-gate mddrivename_t *dnp, 3520Sstevel@tonic-gate md_error_t *ep 3530Sstevel@tonic-gate ) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate FILE *mfp; 3560Sstevel@tonic-gate struct mnttab m; 3570Sstevel@tonic-gate int rval = 0; 3580Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 3590Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate /* should have a set */ 3620Sstevel@tonic-gate assert(sp != NULL); 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate /* look in mnttab */ 3650Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 3660Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 3670Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 368*9017SJohn.Wren.Kennedy@Sun.COM char **fstype = skip_these_mntents; 369*9017SJohn.Wren.Kennedy@Sun.COM int skipit = 0; 3700Sstevel@tonic-gate mdname_t *mnp; 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 3730Sstevel@tonic-gate continue; 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 3760Sstevel@tonic-gate continue; 3770Sstevel@tonic-gate 378*9017SJohn.Wren.Kennedy@Sun.COM while (*fstype != NULL) 379*9017SJohn.Wren.Kennedy@Sun.COM if (strcmp(m.mnt_fstype, *fstype++) == 0) { 380*9017SJohn.Wren.Kennedy@Sun.COM skipit++; 381*9017SJohn.Wren.Kennedy@Sun.COM break; 382*9017SJohn.Wren.Kennedy@Sun.COM } 383*9017SJohn.Wren.Kennedy@Sun.COM 384*9017SJohn.Wren.Kennedy@Sun.COM if (skipit == 1) 3850Sstevel@tonic-gate continue; 3860Sstevel@tonic-gate 3870Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 3880Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 3891623Stw21770 if ((mnp = metaname(&sp, mnt_special, 3901623Stw21770 LOGICAL_DEVICE, ep)) == NULL) { 3910Sstevel@tonic-gate mdclrerror(ep); 3920Sstevel@tonic-gate continue; 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate if (strcmp(dnp->cname, mnp->drivenamep->cname) == 0) { 3950Sstevel@tonic-gate rval = mduseerror(ep, MDE_IS_MOUNTED, NODEV64, 3960Sstevel@tonic-gate mountp, dnp->cname); 3970Sstevel@tonic-gate } 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate /* return success */ 4010Sstevel@tonic-gate return (rval); 4020Sstevel@tonic-gate } 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate /* 4050Sstevel@tonic-gate * Check to see if the specified name is already in use or overlaps 4060Sstevel@tonic-gate * with a device already in use. Checks are made to determine whether 4070Sstevel@tonic-gate * the device is mounted, is a swap device, or a dump device. In each 4080Sstevel@tonic-gate * case if the device is not in use then an overlap check is done to ensure 4090Sstevel@tonic-gate * that the specified slice does not overlap. 4100Sstevel@tonic-gate */ 4110Sstevel@tonic-gate int 4120Sstevel@tonic-gate meta_check_inuse( 4130Sstevel@tonic-gate mdsetname_t *sp, 4140Sstevel@tonic-gate mdname_t *np, 4150Sstevel@tonic-gate mdinuseopts_t inuse_flags, 4160Sstevel@tonic-gate md_error_t *ep 4170Sstevel@tonic-gate ) 4180Sstevel@tonic-gate { 4190Sstevel@tonic-gate int rval = 0; 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate if ((inuse_flags & MDCHK_MOUNTED) && 4220Sstevel@tonic-gate (rval = meta_check_mounted(sp, np, ep)) != 0) 4230Sstevel@tonic-gate return (rval); 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate if ((inuse_flags & MDCHK_SWAP) && 4260Sstevel@tonic-gate (rval = meta_check_swapped(sp, np, ep)) != 0) 4270Sstevel@tonic-gate return (rval); 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate if ((inuse_flags & MDCHK_DUMP) && 4300Sstevel@tonic-gate (rval = meta_check_dump(sp, np, ep)) != 0) 4310Sstevel@tonic-gate return (rval); 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate return (rval); 4340Sstevel@tonic-gate } 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate int 4370Sstevel@tonic-gate meta_check_driveinset(mdsetname_t *sp, mddrivename_t *dn, md_error_t *ep) 4380Sstevel@tonic-gate { 4390Sstevel@tonic-gate set_t setno; 4400Sstevel@tonic-gate set_t max_sets; 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) == 0) 4430Sstevel@tonic-gate return (-1); 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate for (setno = 1; setno < max_sets; setno++) { 4460Sstevel@tonic-gate mdsetname_t *sp1; 4470Sstevel@tonic-gate int is_it; 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate if (setno == sp->setno) 4500Sstevel@tonic-gate continue; 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate if ((sp1 = metasetnosetname(setno, ep)) == NULL) { 4530Sstevel@tonic-gate if (mdismddberror(ep, MDE_DB_NODB)) { 4540Sstevel@tonic-gate mdclrerror(ep); 4550Sstevel@tonic-gate return (0); 4560Sstevel@tonic-gate } 4570Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) { 4580Sstevel@tonic-gate mdclrerror(ep); 4590Sstevel@tonic-gate continue; 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate return (-1); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate metaflushsetname(sp1); 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate if ((is_it = meta_is_drive_in_thisset(sp1, dn, FALSE, ep)) 4670Sstevel@tonic-gate == -1) 4680Sstevel@tonic-gate return (-1); 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate if (is_it) 4710Sstevel@tonic-gate return (mddserror(ep, MDE_DS_DRIVEINSET, sp->setno, 4720Sstevel@tonic-gate sp1->setname, dn->cname, sp->setname)); 4730Sstevel@tonic-gate } 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate return (0); 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate /* 4790Sstevel@tonic-gate * Add a device/device id tuple to the devname cache 4800Sstevel@tonic-gate */ 4810Sstevel@tonic-gate static void 4820Sstevel@tonic-gate add_to_devname_list( 4830Sstevel@tonic-gate char *device_name, /* fully qualified dev name */ 4840Sstevel@tonic-gate ddi_devid_t devid /* device id */ 4850Sstevel@tonic-gate ) 4860Sstevel@tonic-gate { 4870Sstevel@tonic-gate dev_list_t *dnlp; 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate dnlp = Zalloc(sizeof (*dnlp)); 4900Sstevel@tonic-gate dnlp->dev_name = Strdup(device_name); 4910Sstevel@tonic-gate dnlp->devid = devid; 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate /* link the node into the devname list */ 4940Sstevel@tonic-gate dnlp->dev_nxt = devnamelist; 4950Sstevel@tonic-gate devnamelist = dnlp; 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate /* 4990Sstevel@tonic-gate * check for same drive 500127Shshaw * 501127Shshaw * Differentiate between matching on name/dev_t and devid. In the latter 502127Shshaw * case it is correct to fail but misleading to give the same error msg as 503127Shshaw * for an overlapping slice. 504127Shshaw * 5050Sstevel@tonic-gate */ 5060Sstevel@tonic-gate int 5070Sstevel@tonic-gate meta_check_samedrive( 5080Sstevel@tonic-gate mdname_t *np1, /* first comp */ 5090Sstevel@tonic-gate mdname_t *np2, /* second comp */ 5100Sstevel@tonic-gate md_error_t *ep 5110Sstevel@tonic-gate ) 5120Sstevel@tonic-gate { 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate mdcinfo_t *cinfop1, *cinfop2; 5150Sstevel@tonic-gate mdnmtype_t type1 = np1->drivenamep->type; 5160Sstevel@tonic-gate mdnmtype_t type2 = np2->drivenamep->type; 5170Sstevel@tonic-gate int l = 0; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate char *name1 = NULL; 5200Sstevel@tonic-gate char *name2 = NULL; 5210Sstevel@tonic-gate 522127Shshaw int retval = CANT_TELL; 5230Sstevel@tonic-gate int fd1 = -1; 5240Sstevel@tonic-gate int fd2 = -1; 5250Sstevel@tonic-gate int rc1 = -2, rc2 = -2; 5260Sstevel@tonic-gate uint_t strl1 = 0, strl2 = 0; 5270Sstevel@tonic-gate int devid1_found = 0; 5280Sstevel@tonic-gate int devid2_found = 0; 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate ddi_devid_t devid1 = NULL; 5310Sstevel@tonic-gate ddi_devid_t devid2 = NULL; 5320Sstevel@tonic-gate dev_list_t *dnlp = NULL; 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate assert(type1 != MDT_FAST_META && type1 != MDT_FAST_COMP); 5350Sstevel@tonic-gate assert(type2 != MDT_FAST_META && type2 != MDT_FAST_COMP); 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate /* 5380Sstevel@tonic-gate * The process of determining if 2 names are the same drive is 5390Sstevel@tonic-gate * as follows: 5400Sstevel@tonic-gate * 5410Sstevel@tonic-gate * Case 1 - The filenames are identical 5420Sstevel@tonic-gate * 5431623Stw21770 * Case 2 - Both devices have a devid 5440Sstevel@tonic-gate * get and compare the devids for the devices. If both 5450Sstevel@tonic-gate * devices have a devid then the compare will is all 5460Sstevel@tonic-gate * that is needed we are done. 5470Sstevel@tonic-gate * 5481623Stw21770 * Case 3 - One or more devices does not have a devid 5490Sstevel@tonic-gate * start by doing a simple compare of the name, if they 5500Sstevel@tonic-gate * are the same just return. 5510Sstevel@tonic-gate * 5520Sstevel@tonic-gate * If the names differ then keep going and see if the 5530Sstevel@tonic-gate * may be the same underlying devic. First check to 5540Sstevel@tonic-gate * see if the sd name is the same (old code). 5550Sstevel@tonic-gate * 5560Sstevel@tonic-gate * Then check the major and minor numbers to see if 5570Sstevel@tonic-gate * they are the same. If they are then return (old code). 5580Sstevel@tonic-gate * 5590Sstevel@tonic-gate * Next compare the raw name and the component name and 5600Sstevel@tonic-gate * if they are the same then return. 5610Sstevel@tonic-gate * 5620Sstevel@tonic-gate * All else has failed so use the component name (cname) 5630Sstevel@tonic-gate * component number and unit number. If they all are 5640Sstevel@tonic-gate * equal then call them the same drive. 5650Sstevel@tonic-gate * 5660Sstevel@tonic-gate */ 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate if ((np1 == NULL) || (np2 == NULL)) 569127Shshaw return (NOT_SAMEDRIVE); 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate /* if the name structs are the same then the drives must be */ 5720Sstevel@tonic-gate if (np1 == np2) 573127Shshaw return (IDENTICAL_NAME_DEVT); 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate name1 = np1->bname; 5760Sstevel@tonic-gate name2 = np2->bname; 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate if ((name1 == NULL) || ((strl1 = strlen(name1)) == 0) || 5790Sstevel@tonic-gate (name2 == NULL) || ((strl2 = strlen(name2)) == 0)) 580127Shshaw return (NOT_SAMEDRIVE); 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate if ((strl1 == strl2) && (strcmp(name1, name2) == 0)) { 5830Sstevel@tonic-gate /* names are identical */ 584127Shshaw return (IDENTICAL_NAME_DEVT); 5850Sstevel@tonic-gate } 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate if (is_metaname(name1) || is_metaname(name2)) 588127Shshaw return (NOT_SAMEDRIVE); 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate /* 5910Sstevel@tonic-gate * Check to see if the devicename is in the static list. If so, 5920Sstevel@tonic-gate * use its devid. Otherwise do the expensive operations 5930Sstevel@tonic-gate * of opening the device, getting the devid, and closing the 5940Sstevel@tonic-gate * device. Add the result into the static list. 5950Sstevel@tonic-gate * 5960Sstevel@tonic-gate * The case where this list will be useful is when there are soft 5970Sstevel@tonic-gate * partitions on multiple drives and a new soft partition is being 5980Sstevel@tonic-gate * created. In that situation the underlying physical device name 5990Sstevel@tonic-gate * for the new soft partition would be compared against each of the 6000Sstevel@tonic-gate * existing soft partititions. Without this static list that would 6010Sstevel@tonic-gate * involve 2 opens, closes, and devid gets for each existing soft 6020Sstevel@tonic-gate * partition 6030Sstevel@tonic-gate */ 604*9017SJohn.Wren.Kennedy@Sun.COM for (dnlp = devnamelist; (dnlp != NULL) && 605*9017SJohn.Wren.Kennedy@Sun.COM !(devid1_found && devid2_found); dnlp = dnlp->dev_nxt) { 6060Sstevel@tonic-gate if (!devid1_found && (strcmp(dnlp->dev_name, name1) == 0)) { 6070Sstevel@tonic-gate devid1_found = 1; 6080Sstevel@tonic-gate devid1 = dnlp->devid; 6090Sstevel@tonic-gate if (devid1 == NULL) 6100Sstevel@tonic-gate rc1 = 1; 6110Sstevel@tonic-gate else 6120Sstevel@tonic-gate rc1 = 0; 6130Sstevel@tonic-gate continue; 6140Sstevel@tonic-gate } 6150Sstevel@tonic-gate if (!devid2_found && (strcmp(dnlp->dev_name, name2) == 0)) { 6160Sstevel@tonic-gate devid2_found = 1; 6170Sstevel@tonic-gate devid2 = dnlp->devid; 6180Sstevel@tonic-gate if (devid2 == NULL) 6190Sstevel@tonic-gate rc2 = 1; 6200Sstevel@tonic-gate else 6210Sstevel@tonic-gate rc2 = 0; 6220Sstevel@tonic-gate continue; 6230Sstevel@tonic-gate } 6240Sstevel@tonic-gate } 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate /* 6270Sstevel@tonic-gate * Start by checking if the device has a device id, and if they 6280Sstevel@tonic-gate * are equal. If they are there is no question there is a match. 6290Sstevel@tonic-gate * 6300Sstevel@tonic-gate * The process here is open each disk, get the devid for each 6310Sstevel@tonic-gate * disk. If they both have a devid compare them and return 6320Sstevel@tonic-gate * the results. 6330Sstevel@tonic-gate */ 6340Sstevel@tonic-gate if (!devid1_found) { 6350Sstevel@tonic-gate if ((fd1 = open(name1, O_RDONLY | O_NDELAY)) < 0) { 636127Shshaw return (NOT_SAMEDRIVE); 6370Sstevel@tonic-gate } 6380Sstevel@tonic-gate rc1 = devid_get(fd1, &devid1); 6390Sstevel@tonic-gate (void) close(fd1); 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate /* add the name and devid to the cache */ 6420Sstevel@tonic-gate add_to_devname_list(name1, devid1); 6430Sstevel@tonic-gate } 6440Sstevel@tonic-gate 6450Sstevel@tonic-gate if (!devid2_found) { 6460Sstevel@tonic-gate if ((fd2 = open(name2, O_RDONLY | O_NDELAY)) < 0) { 647127Shshaw return (NOT_SAMEDRIVE); 6480Sstevel@tonic-gate } 6490Sstevel@tonic-gate rc2 = devid_get(fd2, &devid2); 6500Sstevel@tonic-gate (void) close(fd2); 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate /* add the name and devid to the cache */ 6530Sstevel@tonic-gate add_to_devname_list(name2, devid2); 6540Sstevel@tonic-gate } 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate if ((rc1 == 0) && (rc2 == 0)) { 6580Sstevel@tonic-gate if (devid_compare(devid1, devid2) == 0) 659127Shshaw retval = IDENTICAL_DEVIDS; /* same devid */ 6600Sstevel@tonic-gate else 661127Shshaw retval = NOT_SAMEDRIVE; /* different drives */ 6620Sstevel@tonic-gate 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate 6650Sstevel@tonic-gate if (retval >= 0) { 6660Sstevel@tonic-gate return (retval); 6670Sstevel@tonic-gate } 6680Sstevel@tonic-gate 6690Sstevel@tonic-gate /* 6700Sstevel@tonic-gate * At this point in time one of the two drives did not have a 6710Sstevel@tonic-gate * device ID. Do not make the assumption that is one drive 6720Sstevel@tonic-gate * did have a device id and the other did not that they are not 6730Sstevel@tonic-gate * the same. One drive could be covered by a device and still 6740Sstevel@tonic-gate * be the same drive. This is a general flaw in the system at 6750Sstevel@tonic-gate * this time. 6760Sstevel@tonic-gate */ 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate /* 6790Sstevel@tonic-gate * The optimization can not happen if we are given an old style name 6800Sstevel@tonic-gate * in the form /dev/XXNN[a-h], since the name caches differently and 6810Sstevel@tonic-gate * allows overlaps to happen. 6820Sstevel@tonic-gate */ 6830Sstevel@tonic-gate if (! ((sscanf(np1->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 6840Sstevel@tonic-gate l == strlen(np1->bname)) || 6850Sstevel@tonic-gate (sscanf(np2->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 6860Sstevel@tonic-gate l == strlen(np2->bname))) && 6870Sstevel@tonic-gate ((type1 == MDT_COMP) || (type1 == MDT_META)) && 6880Sstevel@tonic-gate ((type2 == MDT_COMP) || (type2 == MDT_META))) 689127Shshaw if (np1->drivenamep == np2->drivenamep) 690127Shshaw return (IDENTICAL_NAME_DEVT); 691127Shshaw else 692127Shshaw return (NOT_SAMEDRIVE); 6930Sstevel@tonic-gate 6940Sstevel@tonic-gate /* check for same drive */ 6950Sstevel@tonic-gate if (meta_getmajor(np1->dev) != meta_getmajor(np2->dev)) 696127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate if (((cinfop1 = metagetcinfo(np1, ep)) == NULL) || 6990Sstevel@tonic-gate ((cinfop2 = metagetcinfo(np2, ep)) == NULL)) { 7000Sstevel@tonic-gate if ((strcmp(np1->drivenamep->cname, 7010Sstevel@tonic-gate np2->drivenamep->cname) != 0) && 7020Sstevel@tonic-gate (strcmp(np1->drivenamep->rname, 7030Sstevel@tonic-gate np2->drivenamep->rname) != 0)) { 7040Sstevel@tonic-gate mdclrerror(ep); 705127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 7060Sstevel@tonic-gate } else { 707127Shshaw return (CANT_TELL); /* can't tell */ 7080Sstevel@tonic-gate } 7090Sstevel@tonic-gate } else if ((strncmp(cinfop1->cname, cinfop2->cname, 7100Sstevel@tonic-gate sizeof (cinfop1->cname)) != 0) || 7110Sstevel@tonic-gate (cinfop1->cnum != cinfop2->cnum) || 7120Sstevel@tonic-gate (cinfop1->unit != cinfop2->unit)) { 713127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate /* same drive */ 717127Shshaw return (IDENTICAL_NAME_DEVT); 7180Sstevel@tonic-gate } 7190Sstevel@tonic-gate 7200Sstevel@tonic-gate /* 7210Sstevel@tonic-gate * check for overlap 7220Sstevel@tonic-gate */ 7230Sstevel@tonic-gate int 7240Sstevel@tonic-gate meta_check_overlap( 7250Sstevel@tonic-gate char *uname, /* user supplied name for errors */ 7260Sstevel@tonic-gate mdname_t *np1, /* first comp */ 7270Sstevel@tonic-gate diskaddr_t slblk1, /* first comp - start logical block */ 7280Sstevel@tonic-gate diskaddr_t nblks1, /* first comp - # of blocks */ 7290Sstevel@tonic-gate mdname_t *np2, /* second comp */ 7300Sstevel@tonic-gate diskaddr_t slblk2, /* second comp - start logical block */ 7310Sstevel@tonic-gate diskaddr_t nblks2, /* second comp - # of blocks */ 7320Sstevel@tonic-gate md_error_t *ep 7330Sstevel@tonic-gate ) 7340Sstevel@tonic-gate { 7350Sstevel@tonic-gate diskaddr_t sblk1, sblk2; 7360Sstevel@tonic-gate mdvtoc_t *vtocp1, *vtocp2; 7370Sstevel@tonic-gate uint_t partno1, partno2; 7380Sstevel@tonic-gate mdpart_t *partp1, *partp2; 739127Shshaw int ret; 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate /* verify args */ 7420Sstevel@tonic-gate if (slblk1 == MD_DISKADDR_ERROR) { 7430Sstevel@tonic-gate assert(0); 7440Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np1->cname)); 7450Sstevel@tonic-gate } 7460Sstevel@tonic-gate if (slblk2 == MD_DISKADDR_ERROR) { 7470Sstevel@tonic-gate assert(0); 7480Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np2->cname)); 7490Sstevel@tonic-gate } 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate /* check for same drive */ 752127Shshaw if ((ret = meta_check_samedrive(np1, np2, ep)) == 0) { 7530Sstevel@tonic-gate return (0); /* not same drive */ 754127Shshaw } else if (ret < 0) { 7550Sstevel@tonic-gate return (-1); /* can't tell */ 7560Sstevel@tonic-gate } 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate /* check for overlap */ 7590Sstevel@tonic-gate if (((vtocp1 = metagetvtoc(np1, FALSE, &partno1, ep)) == NULL) || 7600Sstevel@tonic-gate ((vtocp2 = metagetvtoc(np2, FALSE, &partno2, ep)) == NULL)) { 7610Sstevel@tonic-gate return (-1); /* can't tell */ 7620Sstevel@tonic-gate } 7630Sstevel@tonic-gate partp1 = &vtocp1->parts[partno1]; 7640Sstevel@tonic-gate partp2 = &vtocp2->parts[partno2]; 7650Sstevel@tonic-gate sblk1 = partp1->start + slblk1; 7660Sstevel@tonic-gate if (nblks1 == -1) 7670Sstevel@tonic-gate nblks1 = partp1->size - slblk1; 7680Sstevel@tonic-gate sblk2 = partp2->start + slblk2; 7690Sstevel@tonic-gate if (nblks2 == -1) 7700Sstevel@tonic-gate nblks2 = partp2->size - slblk2; 7710Sstevel@tonic-gate if (((sblk1 >= sblk2) && (sblk1 < (sblk2 + nblks2))) || 7720Sstevel@tonic-gate ((sblk2 >= sblk1) && (sblk2 < (sblk1 + nblks1)))) { 7730Sstevel@tonic-gate if (np1->dev == np2->dev) { /* slice in use */ 7740Sstevel@tonic-gate return (mduseerror(ep, MDE_ALREADY, np1->dev, 7750Sstevel@tonic-gate uname, np1->cname)); 7760Sstevel@tonic-gate } 777127Shshaw if (ret == IDENTICAL_NAME_DEVT) 778*9017SJohn.Wren.Kennedy@Sun.COM return (mduseerror(ep, /* slice overlaps */ 779*9017SJohn.Wren.Kennedy@Sun.COM MDE_OVERLAP, np1->dev, uname, np1->cname)); 780127Shshaw else 781*9017SJohn.Wren.Kennedy@Sun.COM return (mduseerror(ep, /* same devid */ 782*9017SJohn.Wren.Kennedy@Sun.COM MDE_SAME_DEVID, np1->dev, uname, np2->cname)); 7830Sstevel@tonic-gate } 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate /* return success */ 7860Sstevel@tonic-gate return (0); /* no overlap */ 7870Sstevel@tonic-gate } 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate /* 7900Sstevel@tonic-gate * check to see if a device is in a metadevice 7910Sstevel@tonic-gate */ 7920Sstevel@tonic-gate int 7930Sstevel@tonic-gate meta_check_inmeta( 7940Sstevel@tonic-gate mdsetname_t *sp, 7950Sstevel@tonic-gate mdname_t *np, 7960Sstevel@tonic-gate mdchkopts_t options, 7970Sstevel@tonic-gate diskaddr_t slblk, 7980Sstevel@tonic-gate diskaddr_t nblks, 7990Sstevel@tonic-gate md_error_t *ep 8000Sstevel@tonic-gate ) 8010Sstevel@tonic-gate { 8020Sstevel@tonic-gate uint_t partno; 8030Sstevel@tonic-gate 8040Sstevel@tonic-gate /* see if replica slice is ok, only applies to disks in sets */ 8050Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_REPSLICE) && 8060Sstevel@tonic-gate ! metaislocalset(sp)) { 8070Sstevel@tonic-gate uint_t rep_slice; 8080Sstevel@tonic-gate 8090Sstevel@tonic-gate if (metagetvtoc(np, FALSE, &partno, ep) == NULL) 8100Sstevel@tonic-gate return (-1); 8110Sstevel@tonic-gate if (meta_replicaslice(np->drivenamep, &rep_slice, ep) 8120Sstevel@tonic-gate != 0) 8130Sstevel@tonic-gate return (-1); 8140Sstevel@tonic-gate if (partno == rep_slice) 8150Sstevel@tonic-gate return (mddeverror(ep, MDE_REPCOMP_INVAL, np->dev, 8160Sstevel@tonic-gate np->cname)); 8170Sstevel@tonic-gate } 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate /* check for databases */ 8200Sstevel@tonic-gate if (meta_check_inreplica(sp, np, slblk, nblks, ep) != 0) { 8210Sstevel@tonic-gate if (mdisuseerror(ep, MDE_ALREADY)) { 8220Sstevel@tonic-gate if (options & MDCHK_ALLOW_MDDB) { 8230Sstevel@tonic-gate mdclrerror(ep); 8240Sstevel@tonic-gate } else { 8250Sstevel@tonic-gate return (mddeverror(ep, MDE_HAS_MDDB, 8260Sstevel@tonic-gate np->dev, np->cname)); 8270Sstevel@tonic-gate } 8280Sstevel@tonic-gate } else { 8290Sstevel@tonic-gate return (-1); 8300Sstevel@tonic-gate } 8310Sstevel@tonic-gate } 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate /* check metadevices */ 8340Sstevel@tonic-gate if (meta_check_instripe(sp, np, slblk, nblks, ep) != 0) 8350Sstevel@tonic-gate return (-1); 8360Sstevel@tonic-gate if (meta_check_inmirror(sp, np, slblk, nblks, ep) != 0) 8370Sstevel@tonic-gate return (-1); 8380Sstevel@tonic-gate if (meta_check_intrans(sp, np, options, slblk, nblks, ep) != 0) 8390Sstevel@tonic-gate return (-1); 8400Sstevel@tonic-gate if (meta_check_insp(sp, np, slblk, nblks, ep) != 0) 8410Sstevel@tonic-gate return (-1); 8420Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_HS)) { 8430Sstevel@tonic-gate if (meta_check_inhsp(sp, np, slblk, nblks, ep) != 0) 8440Sstevel@tonic-gate return (-1); 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate if (meta_check_inraid(sp, np, slblk, nblks, ep) != 0) 8470Sstevel@tonic-gate return (-1); 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate /* return success */ 8500Sstevel@tonic-gate return (0); 8510Sstevel@tonic-gate } 8520Sstevel@tonic-gate 8530Sstevel@tonic-gate /* 8540Sstevel@tonic-gate * check to see if a device is in its set 8550Sstevel@tonic-gate */ 8560Sstevel@tonic-gate int 8570Sstevel@tonic-gate meta_check_inset( 8580Sstevel@tonic-gate mdsetname_t *sp, 8590Sstevel@tonic-gate mdname_t *np, 8600Sstevel@tonic-gate md_error_t *ep 8610Sstevel@tonic-gate ) 8620Sstevel@tonic-gate { 8630Sstevel@tonic-gate mdsetname_t *npsp; 8640Sstevel@tonic-gate int bypass_daemon = FALSE; 8650Sstevel@tonic-gate 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate /* check devices set */ 8680Sstevel@tonic-gate if (metaislocalset(sp)) 8690Sstevel@tonic-gate bypass_daemon = TRUE; 8700Sstevel@tonic-gate if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) { 8710Sstevel@tonic-gate if ((! metaismeta(np)) && 8720Sstevel@tonic-gate (metaislocalset(sp)) && 8730Sstevel@tonic-gate (mdismddberror(ep, MDE_DB_NODB))) { 8740Sstevel@tonic-gate mdclrerror(ep); 8750Sstevel@tonic-gate npsp = sp; 8760Sstevel@tonic-gate } else { 8770Sstevel@tonic-gate return (-1); 8780Sstevel@tonic-gate } 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate 8810Sstevel@tonic-gate /* check set */ 8820Sstevel@tonic-gate if (metaissameset(sp, npsp)) 8830Sstevel@tonic-gate return (0); 8840Sstevel@tonic-gate 8850Sstevel@tonic-gate /* return appropriate error */ 8860Sstevel@tonic-gate if (metaislocalset(sp)) 8870Sstevel@tonic-gate return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname)); 8880Sstevel@tonic-gate else 8890Sstevel@tonic-gate return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname)); 8900Sstevel@tonic-gate } 8910Sstevel@tonic-gate 8920Sstevel@tonic-gate /* 8930Sstevel@tonic-gate * check to see if current user is root 8940Sstevel@tonic-gate */ 8950Sstevel@tonic-gate int 8960Sstevel@tonic-gate meta_check_root(md_error_t *ep) 8970Sstevel@tonic-gate { 8980Sstevel@tonic-gate if (geteuid() != 0) { 8990Sstevel@tonic-gate (void) mderror(ep, MDE_NOPERM, ""); 9000Sstevel@tonic-gate return (-1); 9010Sstevel@tonic-gate } 9020Sstevel@tonic-gate return (0); 9030Sstevel@tonic-gate } 904