1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that 31*0Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 32*0Sstevel@tonic-gate */ 33*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 34*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 35*0Sstevel@tonic-gate #endif 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate /* 38*0Sstevel@tonic-gate * check componets 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #include <meta.h> 42*0Sstevel@tonic-gate #include "meta_lib_prv.h" 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate #include <sys/mnttab.h> 45*0Sstevel@tonic-gate #include <sys/swap.h> 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #include "meta_lib_prv.h" 48*0Sstevel@tonic-gate #include <devid.h> 49*0Sstevel@tonic-gate #include <sys/dumpadm.h> 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate /* 52*0Sstevel@tonic-gate * static list(s) 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate typedef struct dev_list { 55*0Sstevel@tonic-gate char *dev_name; 56*0Sstevel@tonic-gate ddi_devid_t devid; 57*0Sstevel@tonic-gate struct dev_list *dev_nxt; 58*0Sstevel@tonic-gate } dev_list_t; 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate static dev_list_t *devnamelist = NULL; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate /* 63*0Sstevel@tonic-gate * free swap info 64*0Sstevel@tonic-gate */ 65*0Sstevel@tonic-gate static void 66*0Sstevel@tonic-gate free_swapinfo( 67*0Sstevel@tonic-gate struct swaptable *swtp 68*0Sstevel@tonic-gate ) 69*0Sstevel@tonic-gate { 70*0Sstevel@tonic-gate int i; 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate if (swtp == NULL) 73*0Sstevel@tonic-gate return; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate for (i = 0; (i < swtp->swt_n); ++i) { 76*0Sstevel@tonic-gate if (swtp->swt_ent[i].ste_path != NULL) 77*0Sstevel@tonic-gate Free(swtp->swt_ent[i].ste_path); 78*0Sstevel@tonic-gate } 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate Free(swtp); 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate /* 84*0Sstevel@tonic-gate * get swap info 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate static int 87*0Sstevel@tonic-gate get_swapinfo( 88*0Sstevel@tonic-gate struct swaptable **swtpp, 89*0Sstevel@tonic-gate int *nswap, 90*0Sstevel@tonic-gate md_error_t *ep 91*0Sstevel@tonic-gate ) 92*0Sstevel@tonic-gate { 93*0Sstevel@tonic-gate int i; 94*0Sstevel@tonic-gate size_t swtsize; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate *swtpp = NULL; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate /* get number of entries */ 99*0Sstevel@tonic-gate if ((*nswap = swapctl(SC_GETNSWP, NULL)) < 0) { 100*0Sstevel@tonic-gate return (mdsyserror(ep, errno, "swapctl(SC_GETNSWP)")); 101*0Sstevel@tonic-gate } 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate /* allocate structure */ 104*0Sstevel@tonic-gate swtsize = sizeof ((*swtpp)->swt_n) + 105*0Sstevel@tonic-gate ((*nswap) * sizeof ((*swtpp)->swt_ent[0])); 106*0Sstevel@tonic-gate *swtpp = (struct swaptable *)Zalloc(swtsize); 107*0Sstevel@tonic-gate (*swtpp)->swt_n = *nswap; 108*0Sstevel@tonic-gate for (i = 0; (i < (*nswap)); ++i) 109*0Sstevel@tonic-gate (*swtpp)->swt_ent[i].ste_path = Zalloc(MAXPATHLEN); 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate /* get info */ 112*0Sstevel@tonic-gate if (((*nswap) = swapctl(SC_LIST, (*swtpp))) < 0) { 113*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, "swapctl(SC_LIST)"); 114*0Sstevel@tonic-gate free_swapinfo(*swtpp); 115*0Sstevel@tonic-gate return (-1); 116*0Sstevel@tonic-gate } 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* return success */ 119*0Sstevel@tonic-gate return (0); 120*0Sstevel@tonic-gate } 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* 123*0Sstevel@tonic-gate * check whether device is swapped on 124*0Sstevel@tonic-gate */ 125*0Sstevel@tonic-gate static int 126*0Sstevel@tonic-gate meta_check_swapped( 127*0Sstevel@tonic-gate mdsetname_t *sp, 128*0Sstevel@tonic-gate mdname_t *np, 129*0Sstevel@tonic-gate md_error_t *ep 130*0Sstevel@tonic-gate ) 131*0Sstevel@tonic-gate { 132*0Sstevel@tonic-gate struct swaptable *swtp; 133*0Sstevel@tonic-gate int nswap; 134*0Sstevel@tonic-gate int i; 135*0Sstevel@tonic-gate int rval = 0; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate /* should have a set */ 138*0Sstevel@tonic-gate assert(sp != NULL); 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* get swap info */ 141*0Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 142*0Sstevel@tonic-gate return (-1); 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate /* look for match */ 145*0Sstevel@tonic-gate for (i = 0; ((i < nswap) && (rval == 0)); ++i) { 146*0Sstevel@tonic-gate mdname_t *snp; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 149*0Sstevel@tonic-gate ep)) == NULL) { 150*0Sstevel@tonic-gate mdclrerror(ep); 151*0Sstevel@tonic-gate continue; 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate if (np->dev == snp->dev) { 154*0Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, 155*0Sstevel@tonic-gate np->dev, np->cname); 156*0Sstevel@tonic-gate } else { /* not swap - does it overlap */ 157*0Sstevel@tonic-gate rval = meta_check_overlap(snp->cname, np, 0, -1, 158*0Sstevel@tonic-gate snp, 0, -1, ep); 159*0Sstevel@tonic-gate if (rval != 0) { 160*0Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_SWAP, 161*0Sstevel@tonic-gate np->cname, NULL, snp->cname); 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate } 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate free_swapinfo(swtp); 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate /* return success */ 168*0Sstevel@tonic-gate return (rval); 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate /* 172*0Sstevel@tonic-gate * Is a driver currently swapped on? 173*0Sstevel@tonic-gate */ 174*0Sstevel@tonic-gate int 175*0Sstevel@tonic-gate meta_check_driveswapped( 176*0Sstevel@tonic-gate mdsetname_t *sp, 177*0Sstevel@tonic-gate mddrivename_t *dnp, 178*0Sstevel@tonic-gate md_error_t *ep 179*0Sstevel@tonic-gate ) 180*0Sstevel@tonic-gate { 181*0Sstevel@tonic-gate struct swaptable *swtp; 182*0Sstevel@tonic-gate int nswap; 183*0Sstevel@tonic-gate int i; 184*0Sstevel@tonic-gate int rval = 0; 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate /* should have a set */ 187*0Sstevel@tonic-gate assert(sp != NULL); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* get swap info */ 190*0Sstevel@tonic-gate if (get_swapinfo(&swtp, &nswap, ep) != 0) 191*0Sstevel@tonic-gate return (-1); 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate /* look for match */ 194*0Sstevel@tonic-gate for (i = 0; (i < nswap); ++i) { 195*0Sstevel@tonic-gate mdname_t *snp; 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path, 198*0Sstevel@tonic-gate ep)) == NULL) { 199*0Sstevel@tonic-gate mdclrerror(ep); 200*0Sstevel@tonic-gate continue; 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) { 204*0Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64, 205*0Sstevel@tonic-gate dnp->cname); 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate free_swapinfo(swtp); 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate /* return success */ 211*0Sstevel@tonic-gate return (rval); 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate /* 215*0Sstevel@tonic-gate * check whether device is a dump device 216*0Sstevel@tonic-gate */ 217*0Sstevel@tonic-gate static int 218*0Sstevel@tonic-gate meta_check_dump( 219*0Sstevel@tonic-gate mdsetname_t *sp, 220*0Sstevel@tonic-gate mdname_t *np, 221*0Sstevel@tonic-gate md_error_t *ep 222*0Sstevel@tonic-gate ) 223*0Sstevel@tonic-gate { 224*0Sstevel@tonic-gate int rval = 0; 225*0Sstevel@tonic-gate int dump_fd; 226*0Sstevel@tonic-gate char device[MAXPATHLEN]; 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0) 230*0Sstevel@tonic-gate return (mdsyserror(ep, errno, "/dev/dump")); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if (ioctl(dump_fd, DIOCGETDEV, device) != -1) { 233*0Sstevel@tonic-gate mdname_t *dump_np; 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate if ((dump_np = metaname(&sp, device, ep)) == NULL) { 236*0Sstevel@tonic-gate mdclrerror(ep); 237*0Sstevel@tonic-gate (void) close(dump_fd); 238*0Sstevel@tonic-gate return (0); 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate if (np->dev == dump_np->dev) { 242*0Sstevel@tonic-gate rval = mddeverror(ep, MDE_IS_DUMP, 243*0Sstevel@tonic-gate np->dev, np->cname); 244*0Sstevel@tonic-gate } else { /* not a dump device - but does it overlap? */ 245*0Sstevel@tonic-gate rval = meta_check_overlap(dump_np->cname, np, 0, -1, 246*0Sstevel@tonic-gate dump_np, 0, -1, ep); 247*0Sstevel@tonic-gate if (rval != 0) { 248*0Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_DUMP, 249*0Sstevel@tonic-gate np->cname, NULL, dump_np->cname); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate (void) close(dump_fd); 254*0Sstevel@tonic-gate return (rval); 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate /* 258*0Sstevel@tonic-gate * check whether device is mounted 259*0Sstevel@tonic-gate */ 260*0Sstevel@tonic-gate static int 261*0Sstevel@tonic-gate meta_check_mounted( 262*0Sstevel@tonic-gate mdsetname_t *sp, 263*0Sstevel@tonic-gate mdname_t *np, 264*0Sstevel@tonic-gate md_error_t *ep 265*0Sstevel@tonic-gate ) 266*0Sstevel@tonic-gate { 267*0Sstevel@tonic-gate FILE *mfp; 268*0Sstevel@tonic-gate struct mnttab m; 269*0Sstevel@tonic-gate int rval = 0; 270*0Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 271*0Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate /* should have a set */ 274*0Sstevel@tonic-gate assert(sp != NULL); 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate /* look in mnttab */ 277*0Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 278*0Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 279*0Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 280*0Sstevel@tonic-gate mdname_t *mnp; 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 283*0Sstevel@tonic-gate continue; 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 286*0Sstevel@tonic-gate continue; 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate if ((strcmp(m.mnt_fstype, "nfs") == 0) || 289*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "autofs") == 0) || 290*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "proc") == 0) || 291*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "tmpfs") == 0) || 292*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "cachefs") == 0) || 293*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "lofs") == 0) || 294*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "rfs") == 0) || 295*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "fd") == 0) || 296*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "mntfs") == 0) || 297*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "devfs") == 0)) 298*0Sstevel@tonic-gate continue; 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 301*0Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate if ((mnp = metaname(&sp, mnt_special, ep)) == NULL) { 304*0Sstevel@tonic-gate mdclrerror(ep); 305*0Sstevel@tonic-gate continue; 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate if (np->dev == mnp->dev) { 309*0Sstevel@tonic-gate rval = mduseerror(ep, MDE_IS_MOUNTED, 310*0Sstevel@tonic-gate np->dev, mountp, np->cname); 311*0Sstevel@tonic-gate } else { /* device isn't in mnttab - does it overlap? */ 312*0Sstevel@tonic-gate rval = meta_check_overlap(mnp->cname, np, 0, -1, 313*0Sstevel@tonic-gate mnp, 0, -1, ep); 314*0Sstevel@tonic-gate if (rval != 0) { 315*0Sstevel@tonic-gate (void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED, 316*0Sstevel@tonic-gate np->cname, mountp, mnp->cname); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate /* return success */ 322*0Sstevel@tonic-gate return (rval); 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate /* 327*0Sstevel@tonic-gate * Is a file system currently mounted on this disk drive? 328*0Sstevel@tonic-gate */ 329*0Sstevel@tonic-gate int 330*0Sstevel@tonic-gate meta_check_drivemounted( 331*0Sstevel@tonic-gate mdsetname_t *sp, 332*0Sstevel@tonic-gate mddrivename_t *dnp, 333*0Sstevel@tonic-gate md_error_t *ep 334*0Sstevel@tonic-gate ) 335*0Sstevel@tonic-gate { 336*0Sstevel@tonic-gate FILE *mfp; 337*0Sstevel@tonic-gate struct mnttab m; 338*0Sstevel@tonic-gate int rval = 0; 339*0Sstevel@tonic-gate char mountp[MNT_LINE_MAX]; 340*0Sstevel@tonic-gate char mnt_special[MNT_LINE_MAX]; 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate /* should have a set */ 343*0Sstevel@tonic-gate assert(sp != NULL); 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate /* look in mnttab */ 346*0Sstevel@tonic-gate if ((mfp = open_mnttab()) == NULL) 347*0Sstevel@tonic-gate return (mdsyserror(ep, errno, MNTTAB)); 348*0Sstevel@tonic-gate while ((getmntent(mfp, &m) == 0) && (rval == 0)) { 349*0Sstevel@tonic-gate mdname_t *mnp; 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL)) 352*0Sstevel@tonic-gate continue; 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate if (m.mnt_mountp[0] != '/') 355*0Sstevel@tonic-gate continue; 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate if ((strcmp(m.mnt_fstype, "nfs") == 0) || 358*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "autofs") == 0) || 359*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "proc") == 0) || 360*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "tmpfs") == 0) || 361*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "cachefs") == 0) || 362*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "lofs") == 0) || 363*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "rfs") == 0) || 364*0Sstevel@tonic-gate (strcmp(m.mnt_fstype, "fd") == 0)) 365*0Sstevel@tonic-gate continue; 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate (void) strcpy(mountp, m.mnt_mountp); 368*0Sstevel@tonic-gate (void) strcpy(mnt_special, m.mnt_special); 369*0Sstevel@tonic-gate if ((mnp = metaname(&sp, mnt_special, ep)) == NULL) { 370*0Sstevel@tonic-gate mdclrerror(ep); 371*0Sstevel@tonic-gate continue; 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate if (strcmp(dnp->cname, mnp->drivenamep->cname) == 0) { 374*0Sstevel@tonic-gate rval = mduseerror(ep, MDE_IS_MOUNTED, NODEV64, 375*0Sstevel@tonic-gate mountp, dnp->cname); 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate /* return success */ 380*0Sstevel@tonic-gate return (rval); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate /* 384*0Sstevel@tonic-gate * Check to see if the specified name is already in use or overlaps 385*0Sstevel@tonic-gate * with a device already in use. Checks are made to determine whether 386*0Sstevel@tonic-gate * the device is mounted, is a swap device, or a dump device. In each 387*0Sstevel@tonic-gate * case if the device is not in use then an overlap check is done to ensure 388*0Sstevel@tonic-gate * that the specified slice does not overlap. 389*0Sstevel@tonic-gate */ 390*0Sstevel@tonic-gate int 391*0Sstevel@tonic-gate meta_check_inuse( 392*0Sstevel@tonic-gate mdsetname_t *sp, 393*0Sstevel@tonic-gate mdname_t *np, 394*0Sstevel@tonic-gate mdinuseopts_t inuse_flags, 395*0Sstevel@tonic-gate md_error_t *ep 396*0Sstevel@tonic-gate ) 397*0Sstevel@tonic-gate { 398*0Sstevel@tonic-gate int rval = 0; 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate if ((inuse_flags & MDCHK_MOUNTED) && 401*0Sstevel@tonic-gate (rval = meta_check_mounted(sp, np, ep)) != 0) 402*0Sstevel@tonic-gate return (rval); 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate if ((inuse_flags & MDCHK_SWAP) && 405*0Sstevel@tonic-gate (rval = meta_check_swapped(sp, np, ep)) != 0) 406*0Sstevel@tonic-gate return (rval); 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate if ((inuse_flags & MDCHK_DUMP) && 409*0Sstevel@tonic-gate (rval = meta_check_dump(sp, np, ep)) != 0) 410*0Sstevel@tonic-gate return (rval); 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate return (rval); 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate int 416*0Sstevel@tonic-gate meta_check_driveinset(mdsetname_t *sp, mddrivename_t *dn, md_error_t *ep) 417*0Sstevel@tonic-gate { 418*0Sstevel@tonic-gate set_t setno; 419*0Sstevel@tonic-gate set_t max_sets; 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) == 0) 422*0Sstevel@tonic-gate return (-1); 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate for (setno = 1; setno < max_sets; setno++) { 425*0Sstevel@tonic-gate mdsetname_t *sp1; 426*0Sstevel@tonic-gate int is_it; 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate if (setno == sp->setno) 429*0Sstevel@tonic-gate continue; 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate if ((sp1 = metasetnosetname(setno, ep)) == NULL) { 432*0Sstevel@tonic-gate if (mdismddberror(ep, MDE_DB_NODB)) { 433*0Sstevel@tonic-gate mdclrerror(ep); 434*0Sstevel@tonic-gate return (0); 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) { 437*0Sstevel@tonic-gate mdclrerror(ep); 438*0Sstevel@tonic-gate continue; 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate return (-1); 441*0Sstevel@tonic-gate } 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate metaflushsetname(sp1); 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate if ((is_it = meta_is_drive_in_thisset(sp1, dn, FALSE, ep)) 446*0Sstevel@tonic-gate == -1) 447*0Sstevel@tonic-gate return (-1); 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate if (is_it) 450*0Sstevel@tonic-gate return (mddserror(ep, MDE_DS_DRIVEINSET, sp->setno, 451*0Sstevel@tonic-gate sp1->setname, dn->cname, sp->setname)); 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate return (0); 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate /* 458*0Sstevel@tonic-gate * Add a device/device id tuple to the devname cache 459*0Sstevel@tonic-gate */ 460*0Sstevel@tonic-gate static void 461*0Sstevel@tonic-gate add_to_devname_list( 462*0Sstevel@tonic-gate char *device_name, /* fully qualified dev name */ 463*0Sstevel@tonic-gate ddi_devid_t devid /* device id */ 464*0Sstevel@tonic-gate ) 465*0Sstevel@tonic-gate { 466*0Sstevel@tonic-gate dev_list_t *dnlp; 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate dnlp = Zalloc(sizeof (*dnlp)); 469*0Sstevel@tonic-gate dnlp->dev_name = Strdup(device_name); 470*0Sstevel@tonic-gate dnlp->devid = devid; 471*0Sstevel@tonic-gate 472*0Sstevel@tonic-gate /* link the node into the devname list */ 473*0Sstevel@tonic-gate dnlp->dev_nxt = devnamelist; 474*0Sstevel@tonic-gate devnamelist = dnlp; 475*0Sstevel@tonic-gate } 476*0Sstevel@tonic-gate 477*0Sstevel@tonic-gate /* 478*0Sstevel@tonic-gate * check for same drive 479*0Sstevel@tonic-gate */ 480*0Sstevel@tonic-gate int 481*0Sstevel@tonic-gate meta_check_samedrive( 482*0Sstevel@tonic-gate mdname_t *np1, /* first comp */ 483*0Sstevel@tonic-gate mdname_t *np2, /* second comp */ 484*0Sstevel@tonic-gate md_error_t *ep 485*0Sstevel@tonic-gate ) 486*0Sstevel@tonic-gate { 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate mdcinfo_t *cinfop1, *cinfop2; 489*0Sstevel@tonic-gate mdnmtype_t type1 = np1->drivenamep->type; 490*0Sstevel@tonic-gate mdnmtype_t type2 = np2->drivenamep->type; 491*0Sstevel@tonic-gate int l = 0; 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate char *name1 = NULL; 494*0Sstevel@tonic-gate char *name2 = NULL; 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate int retval = -1; 497*0Sstevel@tonic-gate int fd1 = -1; 498*0Sstevel@tonic-gate int fd2 = -1; 499*0Sstevel@tonic-gate int rc1 = -2, rc2 = -2; 500*0Sstevel@tonic-gate uint_t strl1 = 0, strl2 = 0; 501*0Sstevel@tonic-gate int devid1_found = 0; 502*0Sstevel@tonic-gate int devid2_found = 0; 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gate ddi_devid_t devid1 = NULL; 505*0Sstevel@tonic-gate ddi_devid_t devid2 = NULL; 506*0Sstevel@tonic-gate dev_list_t *dnlp = NULL; 507*0Sstevel@tonic-gate 508*0Sstevel@tonic-gate assert(type1 != MDT_FAST_META && type1 != MDT_FAST_COMP); 509*0Sstevel@tonic-gate assert(type2 != MDT_FAST_META && type2 != MDT_FAST_COMP); 510*0Sstevel@tonic-gate 511*0Sstevel@tonic-gate /* 512*0Sstevel@tonic-gate * The process of determining if 2 names are the same drive is 513*0Sstevel@tonic-gate * as follows: 514*0Sstevel@tonic-gate * 515*0Sstevel@tonic-gate * Case 1 - The filenames are identical 516*0Sstevel@tonic-gate * 517*0Sstevel@tonic-gate * Case 2 - Either name is a metadevice name. If so then they 518*0Sstevel@tonic-gate * are not the same drive. 519*0Sstevel@tonic-gate * 520*0Sstevel@tonic-gate * Case 3 - Both devices have a devid 521*0Sstevel@tonic-gate * get and compare the devids for the devices. If both 522*0Sstevel@tonic-gate * devices have a devid then the compare will is all 523*0Sstevel@tonic-gate * that is needed we are done. 524*0Sstevel@tonic-gate * 525*0Sstevel@tonic-gate * Case 4 - One or more devices does not have a devid 526*0Sstevel@tonic-gate * start by doing a simple compare of the name, if they 527*0Sstevel@tonic-gate * are the same just return. 528*0Sstevel@tonic-gate * 529*0Sstevel@tonic-gate * If the names differ then keep going and see if the 530*0Sstevel@tonic-gate * may be the same underlying devic. First check to 531*0Sstevel@tonic-gate * see if the sd name is the same (old code). 532*0Sstevel@tonic-gate * 533*0Sstevel@tonic-gate * Then check the major and minor numbers to see if 534*0Sstevel@tonic-gate * they are the same. If they are then return (old code). 535*0Sstevel@tonic-gate * 536*0Sstevel@tonic-gate * Next compare the raw name and the component name and 537*0Sstevel@tonic-gate * if they are the same then return. 538*0Sstevel@tonic-gate * 539*0Sstevel@tonic-gate * All else has failed so use the component name (cname) 540*0Sstevel@tonic-gate * component number and unit number. If they all are 541*0Sstevel@tonic-gate * equal then call them the same drive. 542*0Sstevel@tonic-gate * 543*0Sstevel@tonic-gate */ 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate if ((np1 == NULL) || (np2 == NULL)) 546*0Sstevel@tonic-gate return (0); 547*0Sstevel@tonic-gate 548*0Sstevel@tonic-gate /* if the name structs are the same then the drives must be */ 549*0Sstevel@tonic-gate if (np1 == np2) 550*0Sstevel@tonic-gate return (1); 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate name1 = np1->bname; 553*0Sstevel@tonic-gate name2 = np2->bname; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate if ((name1 == NULL) || ((strl1 = strlen(name1)) == 0) || 556*0Sstevel@tonic-gate (name2 == NULL) || ((strl2 = strlen(name2)) == 0)) 557*0Sstevel@tonic-gate return (0); 558*0Sstevel@tonic-gate 559*0Sstevel@tonic-gate if ((strl1 == strl2) && (strcmp(name1, name2) == 0)) { 560*0Sstevel@tonic-gate /* names are identical */ 561*0Sstevel@tonic-gate return (1); 562*0Sstevel@tonic-gate } 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate if (is_metaname(name1) || is_metaname(name2)) 565*0Sstevel@tonic-gate return (0); 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate /* 568*0Sstevel@tonic-gate * Check to see if the devicename is in the static list. If so, 569*0Sstevel@tonic-gate * use its devid. Otherwise do the expensive operations 570*0Sstevel@tonic-gate * of opening the device, getting the devid, and closing the 571*0Sstevel@tonic-gate * device. Add the result into the static list. 572*0Sstevel@tonic-gate * 573*0Sstevel@tonic-gate * The case where this list will be useful is when there are soft 574*0Sstevel@tonic-gate * partitions on multiple drives and a new soft partition is being 575*0Sstevel@tonic-gate * created. In that situation the underlying physical device name 576*0Sstevel@tonic-gate * for the new soft partition would be compared against each of the 577*0Sstevel@tonic-gate * existing soft partititions. Without this static list that would 578*0Sstevel@tonic-gate * involve 2 opens, closes, and devid gets for each existing soft 579*0Sstevel@tonic-gate * partition 580*0Sstevel@tonic-gate */ 581*0Sstevel@tonic-gate for (dnlp = devnamelist; 582*0Sstevel@tonic-gate (dnlp != NULL) && !(devid1_found && devid2_found); 583*0Sstevel@tonic-gate dnlp = dnlp->dev_nxt) { 584*0Sstevel@tonic-gate if (!devid1_found && (strcmp(dnlp->dev_name, name1) == 0)) { 585*0Sstevel@tonic-gate devid1_found = 1; 586*0Sstevel@tonic-gate devid1 = dnlp->devid; 587*0Sstevel@tonic-gate if (devid1 == NULL) 588*0Sstevel@tonic-gate rc1 = 1; 589*0Sstevel@tonic-gate else 590*0Sstevel@tonic-gate rc1 = 0; 591*0Sstevel@tonic-gate continue; 592*0Sstevel@tonic-gate } 593*0Sstevel@tonic-gate if (!devid2_found && (strcmp(dnlp->dev_name, name2) == 0)) { 594*0Sstevel@tonic-gate devid2_found = 1; 595*0Sstevel@tonic-gate devid2 = dnlp->devid; 596*0Sstevel@tonic-gate if (devid2 == NULL) 597*0Sstevel@tonic-gate rc2 = 1; 598*0Sstevel@tonic-gate else 599*0Sstevel@tonic-gate rc2 = 0; 600*0Sstevel@tonic-gate continue; 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate /* 605*0Sstevel@tonic-gate * Start by checking if the device has a device id, and if they 606*0Sstevel@tonic-gate * are equal. If they are there is no question there is a match. 607*0Sstevel@tonic-gate * 608*0Sstevel@tonic-gate * The process here is open each disk, get the devid for each 609*0Sstevel@tonic-gate * disk. If they both have a devid compare them and return 610*0Sstevel@tonic-gate * the results. 611*0Sstevel@tonic-gate */ 612*0Sstevel@tonic-gate if (!devid1_found) { 613*0Sstevel@tonic-gate if ((fd1 = open(name1, O_RDONLY | O_NDELAY)) < 0) { 614*0Sstevel@tonic-gate return (0); 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate rc1 = devid_get(fd1, &devid1); 617*0Sstevel@tonic-gate (void) close(fd1); 618*0Sstevel@tonic-gate 619*0Sstevel@tonic-gate /* add the name and devid to the cache */ 620*0Sstevel@tonic-gate add_to_devname_list(name1, devid1); 621*0Sstevel@tonic-gate } 622*0Sstevel@tonic-gate 623*0Sstevel@tonic-gate if (!devid2_found) { 624*0Sstevel@tonic-gate if ((fd2 = open(name2, O_RDONLY | O_NDELAY)) < 0) { 625*0Sstevel@tonic-gate return (0); 626*0Sstevel@tonic-gate } 627*0Sstevel@tonic-gate rc2 = devid_get(fd2, &devid2); 628*0Sstevel@tonic-gate (void) close(fd2); 629*0Sstevel@tonic-gate 630*0Sstevel@tonic-gate /* add the name and devid to the cache */ 631*0Sstevel@tonic-gate add_to_devname_list(name2, devid2); 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate if ((rc1 == 0) && (rc2 == 0)) { 636*0Sstevel@tonic-gate if (devid_compare(devid1, devid2) == 0) 637*0Sstevel@tonic-gate retval = 1; /* same drive */ 638*0Sstevel@tonic-gate else 639*0Sstevel@tonic-gate retval = 0; /* different drives */ 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate if (retval >= 0) { 644*0Sstevel@tonic-gate return (retval); 645*0Sstevel@tonic-gate } 646*0Sstevel@tonic-gate 647*0Sstevel@tonic-gate /* 648*0Sstevel@tonic-gate * At this point in time one of the two drives did not have a 649*0Sstevel@tonic-gate * device ID. Do not make the assumption that is one drive 650*0Sstevel@tonic-gate * did have a device id and the other did not that they are not 651*0Sstevel@tonic-gate * the same. One drive could be covered by a device and still 652*0Sstevel@tonic-gate * be the same drive. This is a general flaw in the system at 653*0Sstevel@tonic-gate * this time. 654*0Sstevel@tonic-gate */ 655*0Sstevel@tonic-gate 656*0Sstevel@tonic-gate /* 657*0Sstevel@tonic-gate * The optimization can not happen if we are given an old style name 658*0Sstevel@tonic-gate * in the form /dev/XXNN[a-h], since the name caches differently and 659*0Sstevel@tonic-gate * allows overlaps to happen. 660*0Sstevel@tonic-gate */ 661*0Sstevel@tonic-gate if (! ((sscanf(np1->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 662*0Sstevel@tonic-gate l == strlen(np1->bname)) || 663*0Sstevel@tonic-gate (sscanf(np2->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 && 664*0Sstevel@tonic-gate l == strlen(np2->bname))) && 665*0Sstevel@tonic-gate ((type1 == MDT_COMP) || (type1 == MDT_META)) && 666*0Sstevel@tonic-gate ((type2 == MDT_COMP) || (type2 == MDT_META))) 667*0Sstevel@tonic-gate return (np1->drivenamep == np2->drivenamep); 668*0Sstevel@tonic-gate 669*0Sstevel@tonic-gate /* check for same drive */ 670*0Sstevel@tonic-gate if (meta_getmajor(np1->dev) != meta_getmajor(np2->dev)) 671*0Sstevel@tonic-gate return (0); /* not same drive */ 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate if (((cinfop1 = metagetcinfo(np1, ep)) == NULL) || 674*0Sstevel@tonic-gate ((cinfop2 = metagetcinfo(np2, ep)) == NULL)) { 675*0Sstevel@tonic-gate if ((strcmp(np1->drivenamep->cname, 676*0Sstevel@tonic-gate np2->drivenamep->cname) != 0) && 677*0Sstevel@tonic-gate (strcmp(np1->drivenamep->rname, 678*0Sstevel@tonic-gate np2->drivenamep->rname) != 0)) { 679*0Sstevel@tonic-gate mdclrerror(ep); 680*0Sstevel@tonic-gate return (0); /* not same drive */ 681*0Sstevel@tonic-gate } else { 682*0Sstevel@tonic-gate return (-1); /* can't tell */ 683*0Sstevel@tonic-gate } 684*0Sstevel@tonic-gate } else if ((strncmp(cinfop1->cname, cinfop2->cname, 685*0Sstevel@tonic-gate sizeof (cinfop1->cname)) != 0) || 686*0Sstevel@tonic-gate (cinfop1->cnum != cinfop2->cnum) || 687*0Sstevel@tonic-gate (cinfop1->unit != cinfop2->unit)) { 688*0Sstevel@tonic-gate return (0); /* not same drive */ 689*0Sstevel@tonic-gate } 690*0Sstevel@tonic-gate 691*0Sstevel@tonic-gate /* same drive */ 692*0Sstevel@tonic-gate return (1); 693*0Sstevel@tonic-gate } 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate /* 696*0Sstevel@tonic-gate * check for overlap 697*0Sstevel@tonic-gate */ 698*0Sstevel@tonic-gate int 699*0Sstevel@tonic-gate meta_check_overlap( 700*0Sstevel@tonic-gate char *uname, /* user supplied name for errors */ 701*0Sstevel@tonic-gate mdname_t *np1, /* first comp */ 702*0Sstevel@tonic-gate diskaddr_t slblk1, /* first comp - start logical block */ 703*0Sstevel@tonic-gate diskaddr_t nblks1, /* first comp - # of blocks */ 704*0Sstevel@tonic-gate mdname_t *np2, /* second comp */ 705*0Sstevel@tonic-gate diskaddr_t slblk2, /* second comp - start logical block */ 706*0Sstevel@tonic-gate diskaddr_t nblks2, /* second comp - # of blocks */ 707*0Sstevel@tonic-gate md_error_t *ep 708*0Sstevel@tonic-gate ) 709*0Sstevel@tonic-gate { 710*0Sstevel@tonic-gate diskaddr_t sblk1, sblk2; 711*0Sstevel@tonic-gate mdvtoc_t *vtocp1, *vtocp2; 712*0Sstevel@tonic-gate uint_t partno1, partno2; 713*0Sstevel@tonic-gate mdpart_t *partp1, *partp2; 714*0Sstevel@tonic-gate int err; 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate /* verify args */ 717*0Sstevel@tonic-gate if (slblk1 == MD_DISKADDR_ERROR) { 718*0Sstevel@tonic-gate assert(0); 719*0Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np1->cname)); 720*0Sstevel@tonic-gate } 721*0Sstevel@tonic-gate if (slblk2 == MD_DISKADDR_ERROR) { 722*0Sstevel@tonic-gate assert(0); 723*0Sstevel@tonic-gate return (mdsyserror(ep, EINVAL, np2->cname)); 724*0Sstevel@tonic-gate } 725*0Sstevel@tonic-gate 726*0Sstevel@tonic-gate /* check for same drive */ 727*0Sstevel@tonic-gate if ((err = meta_check_samedrive(np1, np2, ep)) == 0) { 728*0Sstevel@tonic-gate return (0); /* not same drive */ 729*0Sstevel@tonic-gate } else if (err < 0) { 730*0Sstevel@tonic-gate return (-1); /* can't tell */ 731*0Sstevel@tonic-gate } 732*0Sstevel@tonic-gate 733*0Sstevel@tonic-gate /* check for overlap */ 734*0Sstevel@tonic-gate if (((vtocp1 = metagetvtoc(np1, FALSE, &partno1, ep)) == NULL) || 735*0Sstevel@tonic-gate ((vtocp2 = metagetvtoc(np2, FALSE, &partno2, ep)) == NULL)) { 736*0Sstevel@tonic-gate return (-1); /* can't tell */ 737*0Sstevel@tonic-gate } 738*0Sstevel@tonic-gate partp1 = &vtocp1->parts[partno1]; 739*0Sstevel@tonic-gate partp2 = &vtocp2->parts[partno2]; 740*0Sstevel@tonic-gate sblk1 = partp1->start + slblk1; 741*0Sstevel@tonic-gate if (nblks1 == -1) 742*0Sstevel@tonic-gate nblks1 = partp1->size - slblk1; 743*0Sstevel@tonic-gate sblk2 = partp2->start + slblk2; 744*0Sstevel@tonic-gate if (nblks2 == -1) 745*0Sstevel@tonic-gate nblks2 = partp2->size - slblk2; 746*0Sstevel@tonic-gate if (((sblk1 >= sblk2) && (sblk1 < (sblk2 + nblks2))) || 747*0Sstevel@tonic-gate ((sblk2 >= sblk1) && (sblk2 < (sblk1 + nblks1)))) { 748*0Sstevel@tonic-gate if (np1->dev == np2->dev) { /* slice in use */ 749*0Sstevel@tonic-gate return (mduseerror(ep, MDE_ALREADY, np1->dev, 750*0Sstevel@tonic-gate uname, np1->cname)); 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate return (mduseerror(ep, /* slice overlaps */ 753*0Sstevel@tonic-gate MDE_OVERLAP, np1->dev, uname, np1->cname)); 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate /* return success */ 757*0Sstevel@tonic-gate return (0); /* no overlap */ 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate /* 761*0Sstevel@tonic-gate * check to see if a device is in a metadevice 762*0Sstevel@tonic-gate */ 763*0Sstevel@tonic-gate int 764*0Sstevel@tonic-gate meta_check_inmeta( 765*0Sstevel@tonic-gate mdsetname_t *sp, 766*0Sstevel@tonic-gate mdname_t *np, 767*0Sstevel@tonic-gate mdchkopts_t options, 768*0Sstevel@tonic-gate diskaddr_t slblk, 769*0Sstevel@tonic-gate diskaddr_t nblks, 770*0Sstevel@tonic-gate md_error_t *ep 771*0Sstevel@tonic-gate ) 772*0Sstevel@tonic-gate { 773*0Sstevel@tonic-gate uint_t partno; 774*0Sstevel@tonic-gate 775*0Sstevel@tonic-gate /* see if replica slice is ok, only applies to disks in sets */ 776*0Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_REPSLICE) && 777*0Sstevel@tonic-gate ! metaislocalset(sp)) { 778*0Sstevel@tonic-gate uint_t rep_slice; 779*0Sstevel@tonic-gate 780*0Sstevel@tonic-gate if (metagetvtoc(np, FALSE, &partno, ep) == NULL) 781*0Sstevel@tonic-gate return (-1); 782*0Sstevel@tonic-gate if (meta_replicaslice(np->drivenamep, &rep_slice, ep) 783*0Sstevel@tonic-gate != 0) 784*0Sstevel@tonic-gate return (-1); 785*0Sstevel@tonic-gate if (partno == rep_slice) 786*0Sstevel@tonic-gate return (mddeverror(ep, MDE_REPCOMP_INVAL, np->dev, 787*0Sstevel@tonic-gate np->cname)); 788*0Sstevel@tonic-gate } 789*0Sstevel@tonic-gate 790*0Sstevel@tonic-gate /* check for databases */ 791*0Sstevel@tonic-gate if (meta_check_inreplica(sp, np, slblk, nblks, ep) != 0) { 792*0Sstevel@tonic-gate if (mdisuseerror(ep, MDE_ALREADY)) { 793*0Sstevel@tonic-gate if (options & MDCHK_ALLOW_MDDB) { 794*0Sstevel@tonic-gate mdclrerror(ep); 795*0Sstevel@tonic-gate } else { 796*0Sstevel@tonic-gate return (mddeverror(ep, MDE_HAS_MDDB, 797*0Sstevel@tonic-gate np->dev, np->cname)); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate } else { 800*0Sstevel@tonic-gate return (-1); 801*0Sstevel@tonic-gate } 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate /* check metadevices */ 805*0Sstevel@tonic-gate if (meta_check_instripe(sp, np, slblk, nblks, ep) != 0) 806*0Sstevel@tonic-gate return (-1); 807*0Sstevel@tonic-gate if (meta_check_inmirror(sp, np, slblk, nblks, ep) != 0) 808*0Sstevel@tonic-gate return (-1); 809*0Sstevel@tonic-gate if (meta_check_intrans(sp, np, options, slblk, nblks, ep) != 0) 810*0Sstevel@tonic-gate return (-1); 811*0Sstevel@tonic-gate if (meta_check_insp(sp, np, slblk, nblks, ep) != 0) 812*0Sstevel@tonic-gate return (-1); 813*0Sstevel@tonic-gate if (! (options & MDCHK_ALLOW_HS)) { 814*0Sstevel@tonic-gate if (meta_check_inhsp(sp, np, slblk, nblks, ep) != 0) 815*0Sstevel@tonic-gate return (-1); 816*0Sstevel@tonic-gate } 817*0Sstevel@tonic-gate if (meta_check_inraid(sp, np, slblk, nblks, ep) != 0) 818*0Sstevel@tonic-gate return (-1); 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate /* return success */ 821*0Sstevel@tonic-gate return (0); 822*0Sstevel@tonic-gate } 823*0Sstevel@tonic-gate 824*0Sstevel@tonic-gate /* 825*0Sstevel@tonic-gate * check to see if a device is in its set 826*0Sstevel@tonic-gate */ 827*0Sstevel@tonic-gate int 828*0Sstevel@tonic-gate meta_check_inset( 829*0Sstevel@tonic-gate mdsetname_t *sp, 830*0Sstevel@tonic-gate mdname_t *np, 831*0Sstevel@tonic-gate md_error_t *ep 832*0Sstevel@tonic-gate ) 833*0Sstevel@tonic-gate { 834*0Sstevel@tonic-gate mdsetname_t *npsp; 835*0Sstevel@tonic-gate int bypass_daemon = FALSE; 836*0Sstevel@tonic-gate 837*0Sstevel@tonic-gate 838*0Sstevel@tonic-gate /* check devices set */ 839*0Sstevel@tonic-gate if (metaislocalset(sp)) 840*0Sstevel@tonic-gate bypass_daemon = TRUE; 841*0Sstevel@tonic-gate if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) { 842*0Sstevel@tonic-gate if ((! metaismeta(np)) && 843*0Sstevel@tonic-gate (metaislocalset(sp)) && 844*0Sstevel@tonic-gate (mdismddberror(ep, MDE_DB_NODB))) { 845*0Sstevel@tonic-gate mdclrerror(ep); 846*0Sstevel@tonic-gate npsp = sp; 847*0Sstevel@tonic-gate } else { 848*0Sstevel@tonic-gate return (-1); 849*0Sstevel@tonic-gate } 850*0Sstevel@tonic-gate } 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate /* check set */ 853*0Sstevel@tonic-gate if (metaissameset(sp, npsp)) 854*0Sstevel@tonic-gate return (0); 855*0Sstevel@tonic-gate 856*0Sstevel@tonic-gate /* return appropriate error */ 857*0Sstevel@tonic-gate if (metaislocalset(sp)) 858*0Sstevel@tonic-gate return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname)); 859*0Sstevel@tonic-gate else 860*0Sstevel@tonic-gate return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname)); 861*0Sstevel@tonic-gate } 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate /* 864*0Sstevel@tonic-gate * check to see if current user is root 865*0Sstevel@tonic-gate */ 866*0Sstevel@tonic-gate int 867*0Sstevel@tonic-gate meta_check_root(md_error_t *ep) 868*0Sstevel@tonic-gate { 869*0Sstevel@tonic-gate if (geteuid() != 0) { 870*0Sstevel@tonic-gate (void) mderror(ep, MDE_NOPERM, ""); 871*0Sstevel@tonic-gate return (-1); 872*0Sstevel@tonic-gate } 873*0Sstevel@tonic-gate return (0); 874*0Sstevel@tonic-gate } 875