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