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