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 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*127Shshaw * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate /* 300Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that 310Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 320Sstevel@tonic-gate */ 330Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 340Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate /* 380Sstevel@tonic-gate * check componets 390Sstevel@tonic-gate */ 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include <meta.h> 420Sstevel@tonic-gate #include "meta_lib_prv.h" 430Sstevel@tonic-gate 440Sstevel@tonic-gate #include <sys/mnttab.h> 450Sstevel@tonic-gate #include <sys/swap.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate #include "meta_lib_prv.h" 480Sstevel@tonic-gate #include <devid.h> 490Sstevel@tonic-gate #include <sys/dumpadm.h> 500Sstevel@tonic-gate 51*127Shshaw /* possible returns from meta_check_samedrive */ 52*127Shshaw #define CANT_TELL -1 53*127Shshaw #define NOT_SAMEDRIVE 0 54*127Shshaw #define IDENTICAL_NAME_DEVT 1 55*127Shshaw #define IDENTICAL_DEVIDS 2 56*127Shshaw 570Sstevel@tonic-gate /* 580Sstevel@tonic-gate * static list(s) 590Sstevel@tonic-gate */ 600Sstevel@tonic-gate typedef struct dev_list { 610Sstevel@tonic-gate char *dev_name; 620Sstevel@tonic-gate ddi_devid_t devid; 630Sstevel@tonic-gate struct dev_list *dev_nxt; 640Sstevel@tonic-gate } dev_list_t; 650Sstevel@tonic-gate 660Sstevel@tonic-gate static dev_list_t *devnamelist = NULL; 670Sstevel@tonic-gate 680Sstevel@tonic-gate /* 690Sstevel@tonic-gate * free swap info 700Sstevel@tonic-gate */ 710Sstevel@tonic-gate static void 720Sstevel@tonic-gate free_swapinfo( 730Sstevel@tonic-gate struct swaptable *swtp 740Sstevel@tonic-gate ) 750Sstevel@tonic-gate { 760Sstevel@tonic-gate int i; 770Sstevel@tonic-gate 780Sstevel@tonic-gate if (swtp == NULL) 790Sstevel@tonic-gate return; 800Sstevel@tonic-gate 810Sstevel@tonic-gate for (i = 0; (i < swtp->swt_n); ++i) { 820Sstevel@tonic-gate if (swtp->swt_ent[i].ste_path != NULL) 830Sstevel@tonic-gate Free(swtp->swt_ent[i].ste_path); 840Sstevel@tonic-gate } 850Sstevel@tonic-gate 860Sstevel@tonic-gate Free(swtp); 870Sstevel@tonic-gate } 880Sstevel@tonic-gate 890Sstevel@tonic-gate /* 900Sstevel@tonic-gate * get swap info 910Sstevel@tonic-gate */ 920Sstevel@tonic-gate static int 930Sstevel@tonic-gate get_swapinfo( 940Sstevel@tonic-gate struct swaptable **swtpp, 950Sstevel@tonic-gate int *nswap, 960Sstevel@tonic-gate md_error_t *ep 970Sstevel@tonic-gate ) 980Sstevel@tonic-gate { 990Sstevel@tonic-gate int i; 1000Sstevel@tonic-gate size_t swtsize; 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate *swtpp = NULL; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* get number of entries */ 1050Sstevel@tonic-gate if ((*nswap = swapctl(SC_GETNSWP, NULL)) < 0) { 1060Sstevel@tonic-gate return (mdsyserror(ep, errno, "swapctl(SC_GETNSWP)")); 1070Sstevel@tonic-gate } 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate /* allocate structure */ 1100Sstevel@tonic-gate swtsize = sizeof ((*swtpp)->swt_n) + 1110Sstevel@tonic-gate ((*nswap) * sizeof ((*swtpp)->swt_ent[0])); 1120Sstevel@tonic-gate *swtpp = (struct swaptable *)Zalloc(swtsize); 1130Sstevel@tonic-gate (*swtpp)->swt_n = *nswap; 1140Sstevel@tonic-gate for (i = 0; (i < (*nswap)); ++i) 1150Sstevel@tonic-gate (*swtpp)->swt_ent[i].ste_path = Zalloc(MAXPATHLEN); 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* get info */ 1180Sstevel@tonic-gate if (((*nswap) = swapctl(SC_LIST, (*swtpp))) < 0) { 1190Sstevel@tonic-gate (void) mdsyserror(ep, errno, "swapctl(SC_LIST)"); 1200Sstevel@tonic-gate free_swapinfo(*swtpp); 1210Sstevel@tonic-gate return (-1); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate /* return success */ 1250Sstevel@tonic-gate return (0); 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate /* 1290Sstevel@tonic-gate * check whether device is swapped on 1300Sstevel@tonic-gate */ 1310Sstevel@tonic-gate static int 1320Sstevel@tonic-gate meta_check_swapped( 1330Sstevel@tonic-gate mdsetname_t *sp, 1340Sstevel@tonic-gate mdname_t *np, 1350Sstevel@tonic-gate md_error_t *ep 1360Sstevel@tonic-gate ) 1370Sstevel@tonic-gate { 1380Sstevel@tonic-gate struct swaptable *swtp; 1390Sstevel@tonic-gate int nswap; 1400Sstevel@tonic-gate int i; 1410Sstevel@tonic-gate int rval = 0; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate /* should have a set */ 1440Sstevel@tonic-gate assert(sp != NULL); 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* get swap info */ 1470Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 1480Sstevel@tonic-gate return (-1); 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate /* look for match */ 1510Sstevel@tonic-gate for (i = 0; ((i < nswap) && (rval == 0)); ++i) { 1520Sstevel@tonic-gate mdname_t *snp; 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 1550Sstevel@tonic-gate ep)) == NULL) { 1560Sstevel@tonic-gate mdclrerror(ep); 1570Sstevel@tonic-gate continue; 1580Sstevel@tonic-gate } 1590Sstevel@tonic-gate if (np->dev == snp->dev) { 1600Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, 1610Sstevel@tonic-gate np->dev, np->cname); 1620Sstevel@tonic-gate } else { /* not swap - does it overlap */ 1630Sstevel@tonic-gate rval = meta_check_overlap(snp->cname, np, 0, -1, 1640Sstevel@tonic-gate snp, 0, -1, ep); 1650Sstevel@tonic-gate if (rval != 0) { 1660Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_SWAP, 1670Sstevel@tonic-gate np->cname, NULL, snp->cname); 1680Sstevel@tonic-gate } 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate free_swapinfo(swtp); 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate /* return success */ 1740Sstevel@tonic-gate return (rval); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate /* 1780Sstevel@tonic-gate * Is a driver currently swapped on? 1790Sstevel@tonic-gate */ 1800Sstevel@tonic-gate int 1810Sstevel@tonic-gate meta_check_driveswapped( 1820Sstevel@tonic-gate mdsetname_t *sp, 1830Sstevel@tonic-gate mddrivename_t *dnp, 1840Sstevel@tonic-gate md_error_t *ep 1850Sstevel@tonic-gate ) 1860Sstevel@tonic-gate { 1870Sstevel@tonic-gate struct swaptable *swtp; 1880Sstevel@tonic-gate int nswap; 1890Sstevel@tonic-gate int i; 1900Sstevel@tonic-gate int rval = 0; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate /* should have a set */ 1930Sstevel@tonic-gate assert(sp != NULL); 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate /* get swap info */ 1960Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 1970Sstevel@tonic-gate return (-1); 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate /* look for match */ 2000Sstevel@tonic-gate for (i = 0; (i < nswap); ++i) { 2010Sstevel@tonic-gate mdname_t *snp; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 2040Sstevel@tonic-gate ep)) == NULL) { 2050Sstevel@tonic-gate mdclrerror(ep); 2060Sstevel@tonic-gate continue; 2070Sstevel@tonic-gate } 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) { 2100Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64, 2110Sstevel@tonic-gate dnp->cname); 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate free_swapinfo(swtp); 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate /* return success */ 2170Sstevel@tonic-gate return (rval); 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate /* 2210Sstevel@tonic-gate * check whether device is a dump device 2220Sstevel@tonic-gate */ 2230Sstevel@tonic-gate static int 2240Sstevel@tonic-gate meta_check_dump( 2250Sstevel@tonic-gate mdsetname_t *sp, 2260Sstevel@tonic-gate mdname_t *np, 2270Sstevel@tonic-gate md_error_t *ep 2280Sstevel@tonic-gate ) 2290Sstevel@tonic-gate { 2300Sstevel@tonic-gate int rval = 0; 2310Sstevel@tonic-gate int dump_fd; 2320Sstevel@tonic-gate char device[MAXPATHLEN]; 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0) 2360Sstevel@tonic-gate return (mdsyserror(ep, errno, "/dev/dump")); 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate if (ioctl(dump_fd, DIOCGETDEV, device) != -1) { 2390Sstevel@tonic-gate mdname_t *dump_np; 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate if ((dump_np = metaname(&sp, device, ep)) == NULL) { 2420Sstevel@tonic-gate mdclrerror(ep); 2430Sstevel@tonic-gate (void) close(dump_fd); 2440Sstevel@tonic-gate return (0); 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if (np->dev == dump_np->dev) { 2480Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_DUMP, 2490Sstevel@tonic-gate np->dev, np->cname); 2500Sstevel@tonic-gate } else { /* not a dump device - but does it overlap? */ 2510Sstevel@tonic-gate rval = meta_check_overlap(dump_np->cname, np, 0, -1, 2520Sstevel@tonic-gate dump_np, 0, -1, ep); 2530Sstevel@tonic-gate if (rval != 0) { 2540Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_DUMP, 2550Sstevel@tonic-gate np->cname, NULL, dump_np->cname); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate (void) close(dump_fd); 2600Sstevel@tonic-gate return (rval); 2610Sstevel@tonic-gate } 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate /* 2640Sstevel@tonic-gate * check whether device is mounted 2650Sstevel@tonic-gate */ 2660Sstevel@tonic-gate static int 2670Sstevel@tonic-gate meta_check_mounted( 2680Sstevel@tonic-gate mdsetname_t *sp, 2690Sstevel@tonic-gate mdname_t *np, 2700Sstevel@tonic-gate md_error_t *ep 2710Sstevel@tonic-gate ) 2720Sstevel@tonic-gate { 2730Sstevel@tonic-gate FILE *mfp; 2740Sstevel@tonic-gate struct mnttab m; 2750Sstevel@tonic-gate int rval = 0; 2760Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 2770Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate /* should have a set */ 2800Sstevel@tonic-gate assert(sp != NULL); 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate /* look in mnttab */ 2830Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 2840Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 2850Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 2860Sstevel@tonic-gate mdname_t *mnp; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 2890Sstevel@tonic-gate continue; 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 2920Sstevel@tonic-gate continue; 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate if ((strcmp(m.mnt_fstype, "nfs") == 0) || 2950Sstevel@tonic-gate (strcmp(m.mnt_fstype, "autofs") == 0) || 2960Sstevel@tonic-gate (strcmp(m.mnt_fstype, "proc") == 0) || 2970Sstevel@tonic-gate (strcmp(m.mnt_fstype, "tmpfs") == 0) || 2980Sstevel@tonic-gate (strcmp(m.mnt_fstype, "cachefs") == 0) || 2990Sstevel@tonic-gate (strcmp(m.mnt_fstype, "lofs") == 0) || 3000Sstevel@tonic-gate (strcmp(m.mnt_fstype, "rfs") == 0) || 3010Sstevel@tonic-gate (strcmp(m.mnt_fstype, "fd") == 0) || 3020Sstevel@tonic-gate (strcmp(m.mnt_fstype, "mntfs") == 0) || 3030Sstevel@tonic-gate (strcmp(m.mnt_fstype, "devfs") == 0)) 3040Sstevel@tonic-gate continue; 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 3070Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate if ((mnp = metaname(&sp, mnt_special, ep)) == NULL) { 3100Sstevel@tonic-gate mdclrerror(ep); 3110Sstevel@tonic-gate continue; 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate if (np->dev == mnp->dev) { 3150Sstevel@tonic-gate rval = mduseerror(ep, MDE_IS_MOUNTED, 3160Sstevel@tonic-gate np->dev, mountp, np->cname); 3170Sstevel@tonic-gate } else { /* device isn't in mnttab - does it overlap? */ 3180Sstevel@tonic-gate rval = meta_check_overlap(mnp->cname, np, 0, -1, 3190Sstevel@tonic-gate mnp, 0, -1, ep); 3200Sstevel@tonic-gate if (rval != 0) { 3210Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED, 3220Sstevel@tonic-gate np->cname, mountp, mnp->cname); 3230Sstevel@tonic-gate } 3240Sstevel@tonic-gate } 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate /* return success */ 3280Sstevel@tonic-gate return (rval); 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate /* 3330Sstevel@tonic-gate * Is a file system currently mounted on this disk drive? 3340Sstevel@tonic-gate */ 3350Sstevel@tonic-gate int 3360Sstevel@tonic-gate meta_check_drivemounted( 3370Sstevel@tonic-gate mdsetname_t *sp, 3380Sstevel@tonic-gate mddrivename_t *dnp, 3390Sstevel@tonic-gate md_error_t *ep 3400Sstevel@tonic-gate ) 3410Sstevel@tonic-gate { 3420Sstevel@tonic-gate FILE *mfp; 3430Sstevel@tonic-gate struct mnttab m; 3440Sstevel@tonic-gate int rval = 0; 3450Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 3460Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate /* should have a set */ 3490Sstevel@tonic-gate assert(sp != NULL); 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate /* look in mnttab */ 3520Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 3530Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 3540Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 3550Sstevel@tonic-gate mdname_t *mnp; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 3580Sstevel@tonic-gate continue; 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 3610Sstevel@tonic-gate continue; 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate if ((strcmp(m.mnt_fstype, "nfs") == 0) || 3640Sstevel@tonic-gate (strcmp(m.mnt_fstype, "autofs") == 0) || 3650Sstevel@tonic-gate (strcmp(m.mnt_fstype, "proc") == 0) || 3660Sstevel@tonic-gate (strcmp(m.mnt_fstype, "tmpfs") == 0) || 3670Sstevel@tonic-gate (strcmp(m.mnt_fstype, "cachefs") == 0) || 3680Sstevel@tonic-gate (strcmp(m.mnt_fstype, "lofs") == 0) || 3690Sstevel@tonic-gate (strcmp(m.mnt_fstype, "rfs") == 0) || 3700Sstevel@tonic-gate (strcmp(m.mnt_fstype, "fd") == 0)) 3710Sstevel@tonic-gate continue; 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 3740Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 3750Sstevel@tonic-gate if ((mnp = metaname(&sp, mnt_special, 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 485*127Shshaw * 486*127Shshaw * Differentiate between matching on name/dev_t and devid. In the latter 487*127Shshaw * case it is correct to fail but misleading to give the same error msg as 488*127Shshaw * for an overlapping slice. 489*127Shshaw * 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 507*127Shshaw 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 * 5280Sstevel@tonic-gate * Case 2 - Either name is a metadevice name. If so then they 5290Sstevel@tonic-gate * are not the same drive. 5300Sstevel@tonic-gate * 5310Sstevel@tonic-gate * Case 3 - Both devices have a devid 5320Sstevel@tonic-gate * get and compare the devids for the devices. If both 5330Sstevel@tonic-gate * devices have a devid then the compare will is all 5340Sstevel@tonic-gate * that is needed we are done. 5350Sstevel@tonic-gate * 5360Sstevel@tonic-gate * Case 4 - One or more devices does not have a devid 5370Sstevel@tonic-gate * start by doing a simple compare of the name, if they 5380Sstevel@tonic-gate * are the same just return. 5390Sstevel@tonic-gate * 5400Sstevel@tonic-gate * If the names differ then keep going and see if the 5410Sstevel@tonic-gate * may be the same underlying devic. First check to 5420Sstevel@tonic-gate * see if the sd name is the same (old code). 5430Sstevel@tonic-gate * 5440Sstevel@tonic-gate * Then check the major and minor numbers to see if 5450Sstevel@tonic-gate * they are the same. If they are then return (old code). 5460Sstevel@tonic-gate * 5470Sstevel@tonic-gate * Next compare the raw name and the component name and 5480Sstevel@tonic-gate * if they are the same then return. 5490Sstevel@tonic-gate * 5500Sstevel@tonic-gate * All else has failed so use the component name (cname) 5510Sstevel@tonic-gate * component number and unit number. If they all are 5520Sstevel@tonic-gate * equal then call them the same drive. 5530Sstevel@tonic-gate * 5540Sstevel@tonic-gate */ 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate if ((np1 == NULL) || (np2 == NULL)) 557*127Shshaw return (NOT_SAMEDRIVE); 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate /* if the name structs are the same then the drives must be */ 5600Sstevel@tonic-gate if (np1 == np2) 561*127Shshaw return (IDENTICAL_NAME_DEVT); 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate name1 = np1->bname; 5640Sstevel@tonic-gate name2 = np2->bname; 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate if ((name1 == NULL) || ((strl1 = strlen(name1)) == 0) || 5670Sstevel@tonic-gate (name2 == NULL) || ((strl2 = strlen(name2)) == 0)) 568*127Shshaw return (NOT_SAMEDRIVE); 5690Sstevel@tonic-gate 5700Sstevel@tonic-gate if ((strl1 == strl2) && (strcmp(name1, name2) == 0)) { 5710Sstevel@tonic-gate /* names are identical */ 572*127Shshaw return (IDENTICAL_NAME_DEVT); 5730Sstevel@tonic-gate } 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate if (is_metaname(name1) || is_metaname(name2)) 576*127Shshaw return (NOT_SAMEDRIVE); 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate /* 5790Sstevel@tonic-gate * Check to see if the devicename is in the static list. If so, 5800Sstevel@tonic-gate * use its devid. Otherwise do the expensive operations 5810Sstevel@tonic-gate * of opening the device, getting the devid, and closing the 5820Sstevel@tonic-gate * device. Add the result into the static list. 5830Sstevel@tonic-gate * 5840Sstevel@tonic-gate * The case where this list will be useful is when there are soft 5850Sstevel@tonic-gate * partitions on multiple drives and a new soft partition is being 5860Sstevel@tonic-gate * created. In that situation the underlying physical device name 5870Sstevel@tonic-gate * for the new soft partition would be compared against each of the 5880Sstevel@tonic-gate * existing soft partititions. Without this static list that would 5890Sstevel@tonic-gate * involve 2 opens, closes, and devid gets for each existing soft 5900Sstevel@tonic-gate * partition 5910Sstevel@tonic-gate */ 5920Sstevel@tonic-gate for (dnlp = devnamelist; 5930Sstevel@tonic-gate (dnlp != NULL) && !(devid1_found && devid2_found); 5940Sstevel@tonic-gate dnlp = dnlp->dev_nxt) { 5950Sstevel@tonic-gate if (!devid1_found && (strcmp(dnlp->dev_name, name1) == 0)) { 5960Sstevel@tonic-gate devid1_found = 1; 5970Sstevel@tonic-gate devid1 = dnlp->devid; 5980Sstevel@tonic-gate if (devid1 == NULL) 5990Sstevel@tonic-gate rc1 = 1; 6000Sstevel@tonic-gate else 6010Sstevel@tonic-gate rc1 = 0; 6020Sstevel@tonic-gate continue; 6030Sstevel@tonic-gate } 6040Sstevel@tonic-gate if (!devid2_found && (strcmp(dnlp->dev_name, name2) == 0)) { 6050Sstevel@tonic-gate devid2_found = 1; 6060Sstevel@tonic-gate devid2 = dnlp->devid; 6070Sstevel@tonic-gate if (devid2 == NULL) 6080Sstevel@tonic-gate rc2 = 1; 6090Sstevel@tonic-gate else 6100Sstevel@tonic-gate rc2 = 0; 6110Sstevel@tonic-gate continue; 6120Sstevel@tonic-gate } 6130Sstevel@tonic-gate } 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate /* 6160Sstevel@tonic-gate * Start by checking if the device has a device id, and if they 6170Sstevel@tonic-gate * are equal. If they are there is no question there is a match. 6180Sstevel@tonic-gate * 6190Sstevel@tonic-gate * The process here is open each disk, get the devid for each 6200Sstevel@tonic-gate * disk. If they both have a devid compare them and return 6210Sstevel@tonic-gate * the results. 6220Sstevel@tonic-gate */ 6230Sstevel@tonic-gate if (!devid1_found) { 6240Sstevel@tonic-gate if ((fd1 = open(name1, O_RDONLY | O_NDELAY)) < 0) { 625*127Shshaw return (NOT_SAMEDRIVE); 6260Sstevel@tonic-gate } 6270Sstevel@tonic-gate rc1 = devid_get(fd1, &devid1); 6280Sstevel@tonic-gate (void) close(fd1); 6290Sstevel@tonic-gate 6300Sstevel@tonic-gate /* add the name and devid to the cache */ 6310Sstevel@tonic-gate add_to_devname_list(name1, devid1); 6320Sstevel@tonic-gate } 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate if (!devid2_found) { 6350Sstevel@tonic-gate if ((fd2 = open(name2, O_RDONLY | O_NDELAY)) < 0) { 636*127Shshaw return (NOT_SAMEDRIVE); 6370Sstevel@tonic-gate } 6380Sstevel@tonic-gate rc2 = devid_get(fd2, &devid2); 6390Sstevel@tonic-gate (void) close(fd2); 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate /* add the name and devid to the cache */ 6420Sstevel@tonic-gate add_to_devname_list(name2, devid2); 6430Sstevel@tonic-gate } 6440Sstevel@tonic-gate 6450Sstevel@tonic-gate 6460Sstevel@tonic-gate if ((rc1 == 0) && (rc2 == 0)) { 6470Sstevel@tonic-gate if (devid_compare(devid1, devid2) == 0) 648*127Shshaw retval = IDENTICAL_DEVIDS; /* same devid */ 6490Sstevel@tonic-gate else 650*127Shshaw retval = NOT_SAMEDRIVE; /* different drives */ 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate } 6530Sstevel@tonic-gate 6540Sstevel@tonic-gate if (retval >= 0) { 6550Sstevel@tonic-gate return (retval); 6560Sstevel@tonic-gate } 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate /* 6590Sstevel@tonic-gate * At this point in time one of the two drives did not have a 6600Sstevel@tonic-gate * device ID. Do not make the assumption that is one drive 6610Sstevel@tonic-gate * did have a device id and the other did not that they are not 6620Sstevel@tonic-gate * the same. One drive could be covered by a device and still 6630Sstevel@tonic-gate * be the same drive. This is a general flaw in the system at 6640Sstevel@tonic-gate * this time. 6650Sstevel@tonic-gate */ 6660Sstevel@tonic-gate 6670Sstevel@tonic-gate /* 6680Sstevel@tonic-gate * The optimization can not happen if we are given an old style name 6690Sstevel@tonic-gate * in the form /dev/XXNN[a-h], since the name caches differently and 6700Sstevel@tonic-gate * allows overlaps to happen. 6710Sstevel@tonic-gate */ 6720Sstevel@tonic-gate if (! ((sscanf(np1->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 6730Sstevel@tonic-gate l == strlen(np1->bname)) || 6740Sstevel@tonic-gate (sscanf(np2->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 6750Sstevel@tonic-gate l == strlen(np2->bname))) && 6760Sstevel@tonic-gate ((type1 == MDT_COMP) || (type1 == MDT_META)) && 6770Sstevel@tonic-gate ((type2 == MDT_COMP) || (type2 == MDT_META))) 678*127Shshaw if (np1->drivenamep == np2->drivenamep) 679*127Shshaw return (IDENTICAL_NAME_DEVT); 680*127Shshaw else 681*127Shshaw return (NOT_SAMEDRIVE); 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate /* check for same drive */ 6840Sstevel@tonic-gate if (meta_getmajor(np1->dev) != meta_getmajor(np2->dev)) 685*127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate if (((cinfop1 = metagetcinfo(np1, ep)) == NULL) || 6880Sstevel@tonic-gate ((cinfop2 = metagetcinfo(np2, ep)) == NULL)) { 6890Sstevel@tonic-gate if ((strcmp(np1->drivenamep->cname, 6900Sstevel@tonic-gate np2->drivenamep->cname) != 0) && 6910Sstevel@tonic-gate (strcmp(np1->drivenamep->rname, 6920Sstevel@tonic-gate np2->drivenamep->rname) != 0)) { 6930Sstevel@tonic-gate mdclrerror(ep); 694*127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 6950Sstevel@tonic-gate } else { 696*127Shshaw return (CANT_TELL); /* can't tell */ 6970Sstevel@tonic-gate } 6980Sstevel@tonic-gate } else if ((strncmp(cinfop1->cname, cinfop2->cname, 6990Sstevel@tonic-gate sizeof (cinfop1->cname)) != 0) || 7000Sstevel@tonic-gate (cinfop1->cnum != cinfop2->cnum) || 7010Sstevel@tonic-gate (cinfop1->unit != cinfop2->unit)) { 702*127Shshaw return (NOT_SAMEDRIVE); /* not same drive */ 7030Sstevel@tonic-gate } 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate /* same drive */ 706*127Shshaw return (IDENTICAL_NAME_DEVT); 7070Sstevel@tonic-gate } 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate /* 7100Sstevel@tonic-gate * check for overlap 7110Sstevel@tonic-gate */ 7120Sstevel@tonic-gate int 7130Sstevel@tonic-gate meta_check_overlap( 7140Sstevel@tonic-gate char *uname, /* user supplied name for errors */ 7150Sstevel@tonic-gate mdname_t *np1, /* first comp */ 7160Sstevel@tonic-gate diskaddr_t slblk1, /* first comp - start logical block */ 7170Sstevel@tonic-gate diskaddr_t nblks1, /* first comp - # of blocks */ 7180Sstevel@tonic-gate mdname_t *np2, /* second comp */ 7190Sstevel@tonic-gate diskaddr_t slblk2, /* second comp - start logical block */ 7200Sstevel@tonic-gate diskaddr_t nblks2, /* second comp - # of blocks */ 7210Sstevel@tonic-gate md_error_t *ep 7220Sstevel@tonic-gate ) 7230Sstevel@tonic-gate { 7240Sstevel@tonic-gate diskaddr_t sblk1, sblk2; 7250Sstevel@tonic-gate mdvtoc_t *vtocp1, *vtocp2; 7260Sstevel@tonic-gate uint_t partno1, partno2; 7270Sstevel@tonic-gate mdpart_t *partp1, *partp2; 728*127Shshaw int ret; 7290Sstevel@tonic-gate 7300Sstevel@tonic-gate /* verify args */ 7310Sstevel@tonic-gate if (slblk1 == MD_DISKADDR_ERROR) { 7320Sstevel@tonic-gate assert(0); 7330Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np1->cname)); 7340Sstevel@tonic-gate } 7350Sstevel@tonic-gate if (slblk2 == MD_DISKADDR_ERROR) { 7360Sstevel@tonic-gate assert(0); 7370Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np2->cname)); 7380Sstevel@tonic-gate } 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate /* check for same drive */ 741*127Shshaw if ((ret = meta_check_samedrive(np1, np2, ep)) == 0) { 7420Sstevel@tonic-gate return (0); /* not same drive */ 743*127Shshaw } else if (ret < 0) { 7440Sstevel@tonic-gate return (-1); /* can't tell */ 7450Sstevel@tonic-gate } 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate /* check for overlap */ 7480Sstevel@tonic-gate if (((vtocp1 = metagetvtoc(np1, FALSE, &partno1, ep)) == NULL) || 7490Sstevel@tonic-gate ((vtocp2 = metagetvtoc(np2, FALSE, &partno2, ep)) == NULL)) { 7500Sstevel@tonic-gate return (-1); /* can't tell */ 7510Sstevel@tonic-gate } 7520Sstevel@tonic-gate partp1 = &vtocp1->parts[partno1]; 7530Sstevel@tonic-gate partp2 = &vtocp2->parts[partno2]; 7540Sstevel@tonic-gate sblk1 = partp1->start + slblk1; 7550Sstevel@tonic-gate if (nblks1 == -1) 7560Sstevel@tonic-gate nblks1 = partp1->size - slblk1; 7570Sstevel@tonic-gate sblk2 = partp2->start + slblk2; 7580Sstevel@tonic-gate if (nblks2 == -1) 7590Sstevel@tonic-gate nblks2 = partp2->size - slblk2; 7600Sstevel@tonic-gate if (((sblk1 >= sblk2) && (sblk1 < (sblk2 + nblks2))) || 7610Sstevel@tonic-gate ((sblk2 >= sblk1) && (sblk2 < (sblk1 + nblks1)))) { 7620Sstevel@tonic-gate if (np1->dev == np2->dev) { /* slice in use */ 7630Sstevel@tonic-gate return (mduseerror(ep, MDE_ALREADY, np1->dev, 7640Sstevel@tonic-gate uname, np1->cname)); 7650Sstevel@tonic-gate } 766*127Shshaw if (ret == IDENTICAL_NAME_DEVT) 767*127Shshaw return (mduseerror(ep, /* slice overlaps */ 768*127Shshaw MDE_OVERLAP, np1->dev, uname, np1->cname)); 769*127Shshaw else 770*127Shshaw return (mduseerror(ep, /* same devid */ 771*127Shshaw MDE_SAME_DEVID, np1->dev, uname, np2->cname)); 7720Sstevel@tonic-gate } 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate /* return success */ 7750Sstevel@tonic-gate return (0); /* no overlap */ 7760Sstevel@tonic-gate } 7770Sstevel@tonic-gate 7780Sstevel@tonic-gate /* 7790Sstevel@tonic-gate * check to see if a device is in a metadevice 7800Sstevel@tonic-gate */ 7810Sstevel@tonic-gate int 7820Sstevel@tonic-gate meta_check_inmeta( 7830Sstevel@tonic-gate mdsetname_t *sp, 7840Sstevel@tonic-gate mdname_t *np, 7850Sstevel@tonic-gate mdchkopts_t options, 7860Sstevel@tonic-gate diskaddr_t slblk, 7870Sstevel@tonic-gate diskaddr_t nblks, 7880Sstevel@tonic-gate md_error_t *ep 7890Sstevel@tonic-gate ) 7900Sstevel@tonic-gate { 7910Sstevel@tonic-gate uint_t partno; 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate /* see if replica slice is ok, only applies to disks in sets */ 7940Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_REPSLICE) && 7950Sstevel@tonic-gate ! metaislocalset(sp)) { 7960Sstevel@tonic-gate uint_t rep_slice; 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate if (metagetvtoc(np, FALSE, &partno, ep) == NULL) 7990Sstevel@tonic-gate return (-1); 8000Sstevel@tonic-gate if (meta_replicaslice(np->drivenamep, &rep_slice, ep) 8010Sstevel@tonic-gate != 0) 8020Sstevel@tonic-gate return (-1); 8030Sstevel@tonic-gate if (partno == rep_slice) 8040Sstevel@tonic-gate return (mddeverror(ep, MDE_REPCOMP_INVAL, np->dev, 8050Sstevel@tonic-gate np->cname)); 8060Sstevel@tonic-gate } 8070Sstevel@tonic-gate 8080Sstevel@tonic-gate /* check for databases */ 8090Sstevel@tonic-gate if (meta_check_inreplica(sp, np, slblk, nblks, ep) != 0) { 8100Sstevel@tonic-gate if (mdisuseerror(ep, MDE_ALREADY)) { 8110Sstevel@tonic-gate if (options & MDCHK_ALLOW_MDDB) { 8120Sstevel@tonic-gate mdclrerror(ep); 8130Sstevel@tonic-gate } else { 8140Sstevel@tonic-gate return (mddeverror(ep, MDE_HAS_MDDB, 8150Sstevel@tonic-gate np->dev, np->cname)); 8160Sstevel@tonic-gate } 8170Sstevel@tonic-gate } else { 8180Sstevel@tonic-gate return (-1); 8190Sstevel@tonic-gate } 8200Sstevel@tonic-gate } 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate /* check metadevices */ 8230Sstevel@tonic-gate if (meta_check_instripe(sp, np, slblk, nblks, ep) != 0) 8240Sstevel@tonic-gate return (-1); 8250Sstevel@tonic-gate if (meta_check_inmirror(sp, np, slblk, nblks, ep) != 0) 8260Sstevel@tonic-gate return (-1); 8270Sstevel@tonic-gate if (meta_check_intrans(sp, np, options, slblk, nblks, ep) != 0) 8280Sstevel@tonic-gate return (-1); 8290Sstevel@tonic-gate if (meta_check_insp(sp, np, slblk, nblks, ep) != 0) 8300Sstevel@tonic-gate return (-1); 8310Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_HS)) { 8320Sstevel@tonic-gate if (meta_check_inhsp(sp, np, slblk, nblks, ep) != 0) 8330Sstevel@tonic-gate return (-1); 8340Sstevel@tonic-gate } 8350Sstevel@tonic-gate if (meta_check_inraid(sp, np, slblk, nblks, ep) != 0) 8360Sstevel@tonic-gate return (-1); 8370Sstevel@tonic-gate 8380Sstevel@tonic-gate /* return success */ 8390Sstevel@tonic-gate return (0); 8400Sstevel@tonic-gate } 8410Sstevel@tonic-gate 8420Sstevel@tonic-gate /* 8430Sstevel@tonic-gate * check to see if a device is in its set 8440Sstevel@tonic-gate */ 8450Sstevel@tonic-gate int 8460Sstevel@tonic-gate meta_check_inset( 8470Sstevel@tonic-gate mdsetname_t *sp, 8480Sstevel@tonic-gate mdname_t *np, 8490Sstevel@tonic-gate md_error_t *ep 8500Sstevel@tonic-gate ) 8510Sstevel@tonic-gate { 8520Sstevel@tonic-gate mdsetname_t *npsp; 8530Sstevel@tonic-gate int bypass_daemon = FALSE; 8540Sstevel@tonic-gate 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate /* check devices set */ 8570Sstevel@tonic-gate if (metaislocalset(sp)) 8580Sstevel@tonic-gate bypass_daemon = TRUE; 8590Sstevel@tonic-gate if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) { 8600Sstevel@tonic-gate if ((! metaismeta(np)) && 8610Sstevel@tonic-gate (metaislocalset(sp)) && 8620Sstevel@tonic-gate (mdismddberror(ep, MDE_DB_NODB))) { 8630Sstevel@tonic-gate mdclrerror(ep); 8640Sstevel@tonic-gate npsp = sp; 8650Sstevel@tonic-gate } else { 8660Sstevel@tonic-gate return (-1); 8670Sstevel@tonic-gate } 8680Sstevel@tonic-gate } 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate /* check set */ 8710Sstevel@tonic-gate if (metaissameset(sp, npsp)) 8720Sstevel@tonic-gate return (0); 8730Sstevel@tonic-gate 8740Sstevel@tonic-gate /* return appropriate error */ 8750Sstevel@tonic-gate if (metaislocalset(sp)) 8760Sstevel@tonic-gate return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname)); 8770Sstevel@tonic-gate else 8780Sstevel@tonic-gate return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname)); 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate 8810Sstevel@tonic-gate /* 8820Sstevel@tonic-gate * check to see if current user is root 8830Sstevel@tonic-gate */ 8840Sstevel@tonic-gate int 8850Sstevel@tonic-gate meta_check_root(md_error_t *ep) 8860Sstevel@tonic-gate { 8870Sstevel@tonic-gate if (geteuid() != 0) { 8880Sstevel@tonic-gate (void) mderror(ep, MDE_NOPERM, ""); 8890Sstevel@tonic-gate return (-1); 8900Sstevel@tonic-gate } 8910Sstevel@tonic-gate return (0); 8920Sstevel@tonic-gate } 893