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