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 * Metadevice database interfaces. 38 */ 39 40 #define MDDB 41 42 #include <meta.h> 43 #include <sys/lvm/md_mddb.h> 44 #include <sys/lvm/md_crc.h> 45 #include <sys/lvm/mdio.h> 46 #include <string.h> 47 #include <strings.h> 48 #include <ctype.h> 49 50 struct svm_daemon { 51 char *svmd_name; 52 char *svmd_kill_val; 53 }; 54 55 struct svm_daemon svmd_kill_list[] = { 56 {"mdmonitord", "HUP"}, 57 {"mddoors", "KILL"}, 58 }; 59 60 #define DAEMON_COUNT (sizeof (svmd_kill_list)/ sizeof (struct svm_daemon)) 61 #define MDMONITORD "/usr/sbin/mdmonitord" 62 63 extern int procsigs(int block, sigset_t *oldsigs, md_error_t *ep); 64 65 /* 66 * meta_get_lb_inittime sends a request for the lb_inittime to the kernel 67 */ 68 md_timeval32_t 69 meta_get_lb_inittime( 70 mdsetname_t *sp, 71 md_error_t *ep 72 ) 73 { 74 mddb_config_t c; 75 76 (void) memset(&c, 0, sizeof (c)); 77 78 /* Fill in setno, setname, and sideno */ 79 c.c_setno = sp->setno; 80 81 if (metaioctl(MD_DB_LBINITTIME, &c, &c.c_mde, NULL) != 0) { 82 (void) mdstealerror(ep, &c.c_mde); 83 } 84 85 return (c.c_timestamp); 86 } 87 88 /* 89 * mkmasterblks writes out the master blocks of the mddb to the replica. 90 * 91 * In a MN diskset, this is called by the node that is adding this replica 92 * to the diskset. 93 */ 94 95 #define MDDB_VERIFY_SIZE 8192 96 97 static int 98 mkmasterblks( 99 mdsetname_t *sp, 100 mdname_t *np, 101 int fd, 102 daddr_t firstblk, 103 int dbsize, 104 md_timeval32_t inittime, 105 md_error_t *ep 106 ) 107 { 108 int consecutive; 109 md_timeval32_t tp; 110 struct mddb_mb *mb; 111 char *buffer; 112 int iosize; 113 md_set_desc *sd; 114 int mn_set = 0; 115 daddr_t startblk; 116 int cnt; 117 ddi_devid_t devid; 118 119 if (! metaislocalset(sp)) { 120 if ((sd = metaget_setdesc(sp, ep)) == NULL) 121 return (-1); 122 123 if (MD_MNSET_DESC(sd)) { 124 mn_set = 1; /* Used later */ 125 } 126 } 127 128 /* 129 * Loop to verify the entire mddb region on disk is read/writable. 130 * buffer is used to write/read in at most MDDB_VERIFY_SIZE block 131 * chunks. 132 * 133 * A side-effect of this loop is to zero out the entire mddb region 134 */ 135 if ((buffer = Zalloc(MDDB_VERIFY_SIZE * DEV_BSIZE)) == NULL) 136 return (mdsyserror(ep, ENOMEM, np->rname)); 137 138 startblk = firstblk; 139 for (cnt = dbsize; cnt > 0; cnt -= consecutive) { 140 141 if (cnt > MDDB_VERIFY_SIZE) 142 consecutive = MDDB_VERIFY_SIZE; 143 else 144 consecutive = cnt; 145 146 if (lseek(fd, (off_t)(startblk * DEV_BSIZE), SEEK_SET) < 0) { 147 Free(buffer); 148 return (mdsyserror(ep, errno, np->rname)); 149 } 150 151 iosize = DEV_BSIZE * consecutive; 152 if (write(fd, buffer, iosize) != iosize) { 153 Free(buffer); 154 return (mdsyserror(ep, errno, np->rname)); 155 } 156 157 if (lseek(fd, (off_t)(startblk * DEV_BSIZE), SEEK_SET) < 0) { 158 Free(buffer); 159 return (mdsyserror(ep, errno, np->rname)); 160 } 161 162 if (read(fd, buffer, iosize) != iosize) { 163 Free(buffer); 164 return (mdsyserror(ep, errno, np->rname)); 165 } 166 167 startblk += consecutive; 168 } 169 170 Free(buffer); 171 if ((mb = Zalloc(DEV_BSIZE)) == NULL) 172 return (mdsyserror(ep, ENOMEM, np->rname)); 173 174 if (meta_gettimeofday(&tp) == -1) { 175 Free(mb); 176 return (mdsyserror(ep, errno, np->rname)); 177 } 178 179 mb->mb_magic = MDDB_MAGIC_MB; 180 /* 181 * If a MN diskset, set master block revision for a MN set. 182 * Even though the master block structure is no different 183 * for a MN set, setting the revision field to a different 184 * number keeps any pre-MN_diskset code from accessing 185 * this diskset. It also allows for an early determination 186 * of a MN diskset when reading in from disk so that the 187 * proper size locator block and locator names structure 188 * can be read in thus saving time on diskset startup. 189 */ 190 if (mn_set) 191 mb->mb_revision = MDDB_REV_MNMB; 192 else 193 mb->mb_revision = MDDB_REV_MB; 194 mb->mb_timestamp = tp; 195 mb->mb_setno = sp->setno; 196 mb->mb_blkcnt = dbsize - 1; 197 mb->mb_blkno = firstblk; 198 mb->mb_nextblk = 0; 199 200 mb->mb_blkmap.m_firstblk = firstblk + 1; 201 mb->mb_blkmap.m_consecutive = dbsize - 1; 202 if (! metaislocalset(sp)) { 203 mb->mb_setcreatetime = inittime; 204 } 205 206 /* 207 * We try to save the disks device ID into the remaining bytes in 208 * the master block. The saved devid is used to provide a mapping 209 * between this disk's devid and the devid stored into the master 210 * block. This allows the disk image to be self-identifying 211 * if it gets copied (e.g. SNDR, True Copy, etc.). This is used 212 * when we try to import these disks on the remote copied image. 213 * If we cannot save the disks device ID onto the master block that is 214 * ok. The disk is just not self-identifying and won't be importable 215 * in the remote copy scenario. 216 */ 217 if (devid_get(fd, &devid) == 0) { 218 size_t len; 219 220 len = devid_sizeof(devid); 221 if (len <= DEV_BSIZE - sizeof (*mb)) { 222 /* there is enough space to store the devid */ 223 mb->mb_devid_magic = MDDB_MAGIC_DE; 224 mb->mb_devid_len = len; 225 (void) memcpy(mb->mb_devid, devid, len); 226 } 227 devid_free(devid); 228 } 229 230 crcgen((uchar_t *)mb, (uint_t *)&mb->mb_checksum, (uint_t)DEV_BSIZE, 231 (crc_skip_t *)NULL); 232 233 if (lseek(fd, (off_t)(firstblk * DEV_BSIZE), SEEK_SET) < 0) { 234 Free(mb); 235 return (mdsyserror(ep, errno, np->rname)); 236 } 237 238 if (write(fd, mb, DEV_BSIZE) != DEV_BSIZE) { 239 Free(mb); 240 return (mdsyserror(ep, errno, np->rname)); 241 } 242 243 if (lseek(fd, (off_t)(firstblk * DEV_BSIZE), SEEK_SET) < 0) { 244 Free(mb); 245 return (mdsyserror(ep, errno, np->rname)); 246 } 247 248 if (read(fd, mb, DEV_BSIZE) != DEV_BSIZE) { 249 Free(mb); 250 return (mdsyserror(ep, errno, np->rname)); 251 } 252 253 if (crcchk((uchar_t *)mb, (uint_t *)&mb->mb_checksum, 254 (uint_t)DEV_BSIZE, (crc_skip_t *)NULL)) { 255 Free(mb); 256 return (mdmddberror(ep, MDE_NOTVERIFIED, 257 meta_getminor(np->dev), sp->setno, 0, np->rname)); 258 } 259 260 Free(mb); 261 return (0); 262 } 263 264 void 265 meta_mkdummymaster( 266 mdsetname_t *sp, 267 int fd, 268 daddr_t firstblk 269 ) 270 { 271 md_timeval32_t tp; 272 struct mddb_mb *mb; 273 ddi_devid_t devid; 274 md_set_desc *sd; 275 md_error_t ep = mdnullerror; 276 md_timeval32_t inittime; 277 278 /* 279 * No dummy master blocks are written for a MN diskset since devids 280 * are not supported in MN disksets. 281 */ 282 if (! metaislocalset(sp)) { 283 if ((sd = metaget_setdesc(sp, &ep)) == NULL) 284 return; 285 286 if (MD_MNSET_DESC(sd)) 287 return; 288 } 289 290 if ((mb = Zalloc(DEV_BSIZE)) == NULL) 291 return; 292 293 mb->mb_magic = MDDB_MAGIC_DU; 294 mb->mb_revision = MDDB_REV_MB; 295 mb->mb_setno = sp->setno; 296 inittime = meta_get_lb_inittime(sp, &ep); 297 mb->mb_setcreatetime = inittime; 298 299 if (meta_gettimeofday(&tp) != -1) 300 mb->mb_timestamp = tp; 301 302 /* 303 * We try to save the disks device ID into the remaining bytes in 304 * the master block. This allows the disk image to be self-identifying 305 * if it gets copied (e.g. SNDR, True Copy, etc.). This is used 306 * when we try to import these disks on the remote copied image. 307 * If we cannot save the disks device ID onto the master block that is 308 * ok. The disk is just not self-identifying and won't be importable 309 * in the remote copy scenario. 310 */ 311 if (devid_get(fd, &devid) == 0) { 312 int len; 313 314 len = devid_sizeof(devid); 315 if (len <= DEV_BSIZE - sizeof (*mb)) { 316 /* there is enough space to store the devid */ 317 mb->mb_devid_magic = MDDB_MAGIC_DE; 318 mb->mb_devid_len = len; 319 (void) memcpy(mb->mb_devid, (char *)devid, len); 320 } 321 devid_free(devid); 322 } 323 324 crcgen((uchar_t *)mb, (uint_t *)&mb->mb_checksum, (uint_t)DEV_BSIZE, 325 (crc_skip_t *)NULL); 326 327 /* 328 * If any of these operations fail, we need to inform the 329 * user that the disk won't be self identifying. When support 330 * for importing remotely replicated disksets is added, we 331 * want to add the error messages here. 332 */ 333 if (lseek(fd, (off_t)(firstblk * DEV_BSIZE), SEEK_SET) < 0) 334 goto out; 335 336 if (write(fd, mb, DEV_BSIZE) != DEV_BSIZE) 337 goto out; 338 339 if (lseek(fd, (off_t)(firstblk * DEV_BSIZE), SEEK_SET) < 0) 340 goto out; 341 342 if (read(fd, mb, DEV_BSIZE) != DEV_BSIZE) 343 goto out; 344 345 if (crcchk((uchar_t *)mb, (uint_t *)&mb->mb_checksum, 346 (uint_t)DEV_BSIZE, (crc_skip_t *)NULL)) 347 goto out; 348 349 out: 350 Free(mb); 351 } 352 353 static int 354 buildconf(mdsetname_t *sp, md_error_t *ep) 355 { 356 md_replicalist_t *rlp = NULL; 357 md_replicalist_t *rl; 358 FILE *cfp = NULL; 359 FILE *mfp = NULL; 360 struct stat sbuf; 361 int rval = 0; 362 int in_miniroot = 0; 363 char line[MDDB_BOOTLIST_MAX_LEN]; 364 char *tname = NULL; 365 366 /* get list of local replicas */ 367 if (! metaislocalset(sp)) 368 return (0); 369 370 if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 371 return (-1); 372 373 /* open tempfile, copy permissions of original file */ 374 if ((cfp = fopen(META_DBCONFTMP, "w+")) == NULL) { 375 /* 376 * On the miniroot tmp files must be created in /var/tmp. 377 * If we get a EROFS error, we assume that we are in the 378 * miniroot. 379 */ 380 if (errno != EROFS) 381 goto error; 382 in_miniroot = 1; 383 errno = 0; 384 tname = tempnam("/var/tmp", "slvm_"); 385 if (tname == NULL && errno == EROFS) { 386 /* 387 * If we are booted on a read-only root because 388 * of mddb quorum problems we don't want to emit 389 * any scary error messages. 390 */ 391 errno = 0; 392 goto out; 393 } 394 395 /* open tempfile, copy permissions of original file */ 396 if ((cfp = fopen(tname, "w+")) == NULL) 397 goto error; 398 } 399 if (stat(META_DBCONF, &sbuf) == 0) { 400 if (fchmod(fileno(cfp), (sbuf.st_mode & 0666)) != 0) 401 goto error; 402 if (fchown(fileno(cfp), sbuf.st_uid, sbuf.st_gid) != 0) 403 goto error; 404 } 405 406 /* print header */ 407 if (fprintf(cfp, "#metadevice database location file ") == EOF) 408 goto error; 409 if (fprintf(cfp, "do not hand edit\n") < 0) 410 goto error; 411 if (fprintf(cfp, 412 "#driver\tminor_t\tdaddr_t\tdevice id\tchecksum\n") < 0) 413 goto error; 414 415 /* dump replicas */ 416 for (rl = rlp; (rl != NULL); rl = rl->rl_next) { 417 md_replica_t *r = rl->rl_repp; 418 int checksum = 42; 419 int i; 420 char *devidp; 421 minor_t min; 422 423 devidp = devid_str_encode(r->r_devid, r->r_minor_name); 424 /* If devid code can't encode devidp - skip entry */ 425 if (devidp == NULL) { 426 continue; 427 } 428 429 /* compute checksum */ 430 for (i = 0; ((r->r_driver_name[i] != '\0') && 431 (i < sizeof (r->r_driver_name))); i++) { 432 checksum -= r->r_driver_name[i]; 433 } 434 min = meta_getminor(r->r_namep->dev); 435 checksum -= min; 436 checksum -= r->r_blkno; 437 438 for (i = 0; i < strlen(devidp); i++) { 439 checksum -= devidp[i]; 440 } 441 /* print info */ 442 if (fprintf(cfp, "%s\t%lu\t%ld\t%s\t%d\n", 443 r->r_driver_name, min, r->r_blkno, devidp, checksum) < 0) { 444 goto error; 445 } 446 447 devid_str_free(devidp); 448 } 449 450 /* close and rename to real file */ 451 if (fflush(cfp) != 0) 452 goto error; 453 if (fsync(fileno(cfp)) != 0) 454 goto error; 455 if (fclose(cfp) != 0) { 456 cfp = NULL; 457 goto error; 458 } 459 cfp = NULL; 460 461 /* 462 * Renames don't work in the miniroot since tmpfiles are 463 * created in /var/tmp. Hence we copy the data out. 464 */ 465 466 if (! in_miniroot) { 467 if (rename(META_DBCONFTMP, META_DBCONF) != 0) 468 goto error; 469 } else { 470 if ((cfp = fopen(tname, "r")) == NULL) 471 goto error; 472 if ((mfp = fopen(META_DBCONF, "w+")) == NULL) 473 goto error; 474 while (fgets(line, MDDB_BOOTLIST_MAX_LEN, cfp) != NULL) { 475 if (fputs(line, mfp) == NULL) 476 goto error; 477 } 478 (void) fclose(cfp); 479 cfp = NULL; 480 if (fflush(mfp) != 0) 481 goto error; 482 if (fsync(fileno(mfp)) != 0) 483 goto error; 484 if (fclose(mfp) != 0) { 485 mfp = NULL; 486 goto error; 487 } 488 /* delete the tempfile */ 489 (void) unlink(tname); 490 } 491 /* success */ 492 rval = 0; 493 goto out; 494 495 /* tempfile error */ 496 error: 497 rval = (in_miniroot) ? mdsyserror(ep, errno, tname): 498 mdsyserror(ep, errno, META_DBCONFTMP); 499 500 501 /* cleanup, return success */ 502 out: 503 if (rlp != NULL) 504 metafreereplicalist(rlp); 505 if ((cfp != NULL) && (fclose(cfp) != 0) && (rval == 0)) { 506 rval = (in_miniroot) ? mdsyserror(ep, errno, tname): 507 mdsyserror(ep, errno, META_DBCONFTMP); 508 } 509 free(tname); 510 return (rval); 511 } 512 513 /* 514 * check replica for dev 515 */ 516 static int 517 in_replica( 518 mdsetname_t *sp, 519 md_replica_t *rp, 520 mdname_t *np, 521 diskaddr_t slblk, 522 diskaddr_t nblks, 523 md_error_t *ep 524 ) 525 { 526 mdname_t *repnp = rp->r_namep; 527 diskaddr_t rep_sblk = rp->r_blkno; 528 diskaddr_t rep_nblks = rp->r_nblk; 529 530 /* should be in the same set */ 531 assert(sp != NULL); 532 533 /* if error in master block, assume whole partition */ 534 if ((rep_sblk == MD_DISKADDR_ERROR) || 535 (rep_nblks == MD_DISKADDR_ERROR)) { 536 rep_sblk = 0; 537 rep_nblks = MD_DISKADDR_ERROR; 538 } 539 540 /* check overlap */ 541 if (meta_check_overlap( 542 MDB_STR, np, slblk, nblks, repnp, rep_sblk, rep_nblks, ep) != 0) { 543 return (-1); 544 } 545 546 /* return success */ 547 return (0); 548 } 549 550 /* 551 * check to see if we're in a replica 552 */ 553 int 554 meta_check_inreplica( 555 mdsetname_t *sp, 556 mdname_t *np, 557 diskaddr_t slblk, 558 diskaddr_t nblks, 559 md_error_t *ep 560 ) 561 { 562 md_replicalist_t *rlp = NULL; 563 md_replicalist_t *rl; 564 int rval = 0; 565 566 /* should have a set */ 567 assert(sp != NULL); 568 569 /* for each replica */ 570 if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) 571 return (-1); 572 for (rl = rlp; (rl != NULL); rl = rl->rl_next) { 573 md_replica_t *rp = rl->rl_repp; 574 575 /* check replica */ 576 if (in_replica(sp, rp, np, slblk, nblks, ep) != 0) { 577 rval = -1; 578 break; 579 } 580 } 581 582 /* cleanup, return success */ 583 metafreereplicalist(rlp); 584 return (rval); 585 } 586 587 /* 588 * check replica 589 */ 590 int 591 meta_check_replica( 592 mdsetname_t *sp, /* set to check against */ 593 mdname_t *np, /* component to check against */ 594 mdchkopts_t options, /* option flags */ 595 diskaddr_t slblk, /* start logical block */ 596 diskaddr_t nblks, /* number of blocks (-1,rest of them) */ 597 md_error_t *ep /* error packet */ 598 ) 599 { 600 mdchkopts_t chkoptions = MDCHK_ALLOW_REPSLICE; 601 602 /* make sure we have a disk */ 603 if (metachkcomp(np, ep) != 0) 604 return (-1); 605 606 /* check to ensure that it is not already in use */ 607 if (meta_check_inuse(sp, np, MDCHK_INUSE, ep) != 0) { 608 return (-1); 609 } 610 611 if (options & MDCHK_ALLOW_NODBS) 612 return (0); 613 614 if (options & MDCHK_DRVINSET) 615 return (0); 616 617 /* make sure it is in the set */ 618 if (meta_check_inset(sp, np, ep) != 0) 619 return (-1); 620 621 /* make sure its not in a metadevice */ 622 if (meta_check_inmeta(sp, np, chkoptions, slblk, nblks, ep) != 0) 623 return (-1); 624 625 /* return success */ 626 return (0); 627 } 628 629 static int 630 update_dbinfo_on_drives( 631 mdsetname_t *sp, 632 md_drive_desc *dd, 633 int set_locked, 634 int force, 635 md_error_t *ep 636 ) 637 { 638 md_set_desc *sd; 639 int i; 640 md_setkey_t *cl_sk; 641 int rval = 0; 642 md_mnnode_desc *nd; 643 644 if ((sd = metaget_setdesc(sp, ep)) == NULL) 645 return (-1); 646 647 if (! set_locked) { 648 if (MD_MNSET_DESC(sd)) { 649 md_error_t xep = mdnullerror; 650 sigset_t sigs; 651 /* Make sure we are blocking all signals */ 652 if (procsigs(TRUE, &sigs, &xep) < 0) 653 mdclrerror(&xep); 654 655 nd = sd->sd_nodelist; 656 while (nd) { 657 if (force && strcmp(nd->nd_nodename, 658 mynode()) != 0) { 659 nd = nd->nd_next; 660 continue; 661 } 662 663 if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) { 664 nd = nd->nd_next; 665 continue; 666 } 667 668 if (clnt_lock_set(nd->nd_nodename, sp, ep)) 669 return (-1); 670 nd = nd->nd_next; 671 } 672 } else { 673 for (i = 0; i < MD_MAXSIDES; i++) { 674 /* Skip empty slots */ 675 if (sd->sd_nodes[i][0] == '\0') 676 continue; 677 678 if (force && strcmp(sd->sd_nodes[i], 679 mynode()) != 0) 680 continue; 681 682 if (clnt_lock_set(sd->sd_nodes[i], sp, ep)) 683 return (-1); 684 } 685 } 686 } 687 688 if (MD_MNSET_DESC(sd)) { 689 nd = sd->sd_nodelist; 690 while (nd) { 691 if (force && strcmp(nd->nd_nodename, mynode()) != 0) { 692 nd = nd->nd_next; 693 continue; 694 } 695 696 if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) { 697 nd = nd->nd_next; 698 continue; 699 } 700 701 if (clnt_upd_dr_dbinfo(nd->nd_nodename, sp, dd, ep) 702 == -1) { 703 rval = -1; 704 break; 705 } 706 nd = nd->nd_next; 707 } 708 } else { 709 for (i = 0; i < MD_MAXSIDES; i++) { 710 /* Skip empty slots */ 711 if (sd->sd_nodes[i][0] == '\0') 712 continue; 713 714 if (force && strcmp(sd->sd_nodes[i], mynode()) != 0) 715 continue; 716 717 if (clnt_upd_dr_dbinfo(sd->sd_nodes[i], sp, dd, ep) 718 == -1) { 719 rval = -1; 720 break; 721 } 722 } 723 } 724 725 if (! set_locked) { 726 cl_sk = cl_get_setkey(sp->setno, sp->setname); 727 if (MD_MNSET_DESC(sd)) { 728 nd = sd->sd_nodelist; 729 while (nd) { 730 if (force && 731 strcmp(nd->nd_nodename, mynode()) != 0) { 732 nd = nd->nd_next; 733 continue; 734 } 735 736 if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) { 737 nd = nd->nd_next; 738 continue; 739 } 740 741 if (clnt_unlock_set(nd->nd_nodename, cl_sk, 742 ep)) { 743 rval = -1; 744 break; 745 } 746 nd = nd->nd_next; 747 } 748 } else { 749 for (i = 0; i < MD_MAXSIDES; i++) { 750 /* Skip empty slots */ 751 if (sd->sd_nodes[i][0] == '\0') 752 continue; 753 754 if (force && 755 strcmp(sd->sd_nodes[i], mynode()) != 0) 756 continue; 757 758 if (clnt_unlock_set(sd->sd_nodes[i], cl_sk, 759 ep)) { 760 rval = -1; 761 break; 762 } 763 } 764 765 } 766 cl_set_setkey(NULL); 767 } 768 769 return (rval); 770 } 771 772 int 773 meta_db_addsidenms( 774 mdsetname_t *sp, 775 mdname_t *np, 776 daddr_t blkno, 777 int bcast, 778 md_error_t *ep 779 ) 780 { 781 side_t sideno; 782 char *bname = NULL; 783 char *dname = NULL; 784 minor_t mnum; 785 mddb_config_t c; 786 int done; 787 int rval = 0; 788 md_set_desc *sd; 789 790 sideno = MD_SIDEWILD; 791 /*CONSTCOND*/ 792 while (1) { 793 if (bname != NULL) { 794 Free(bname); 795 bname = NULL; 796 } 797 if (dname != NULL) { 798 Free(dname); 799 dname = NULL; 800 } 801 if ((done = meta_getnextside_devinfo(sp, np->bname, 802 &sideno, &bname, &dname, &mnum, ep)) == -1) { 803 rval = -1; 804 break; 805 } 806 807 if (done == 0) 808 break; 809 810 if (! metaislocalset(sp)) { 811 if ((sd = metaget_setdesc(sp, ep)) == NULL) { 812 rval = -1; 813 break; 814 } 815 } 816 817 /* 818 * Send addsidenms to all nodes using rpc.mdcommd if 819 * sidename is being added to MN diskset. 820 * 821 * It's ok to broadcast this call to other nodes. 822 * 823 * Note: The broadcast to other nodes isn't needed during 824 * the addition of the first mddbs to the set since the 825 * other nodes haven't been joined to the set yet. All 826 * nodes in a MN diskset are (implicitly) joined to the set 827 * on the addition of the first mddb. 828 */ 829 if ((! metaislocalset(sp)) && MD_MNSET_DESC(sd) && 830 (bcast == DB_ADDSIDENMS_BCAST)) { 831 md_mn_result_t *resultp = NULL; 832 md_mn_msg_meta_db_newside_t db_ns; 833 int send_rval; 834 835 db_ns.msg_l_dev = np->dev; 836 db_ns.msg_sideno = sideno; 837 db_ns.msg_blkno = blkno; 838 (void) strncpy(db_ns.msg_dname, dname, 839 sizeof (db_ns.msg_dname)); 840 (void) splitname(np->bname, &db_ns.msg_splitname); 841 db_ns.msg_mnum = mnum; 842 843 /* Set devid to NULL until devids are supported */ 844 db_ns.msg_devid[0] = NULL; 845 846 /* 847 * If reconfig cycle has been started, this node is 848 * stuck in in the return step until this command has 849 * completed. If mdcommd is suspended, ask 850 * send_message to fail (instead of retrying) 851 * so that metaset can finish allowing the reconfig 852 * cycle to proceed. 853 */ 854 send_rval = mdmn_send_message(sp->setno, 855 MD_MN_MSG_META_DB_NEWSIDE, MD_MSGF_FAIL_ON_SUSPEND | 856 MD_MSGF_PANIC_WHEN_INCONSISTENT, (char *)&db_ns, 857 sizeof (md_mn_msg_meta_db_newside_t), 858 &resultp, ep); 859 if (send_rval != 0) { 860 rval = -1; 861 if (resultp == NULL) 862 (void) mddserror(ep, 863 MDE_DS_COMMD_SEND_FAIL, 864 sp->setno, NULL, NULL, 865 sp->setname); 866 else { 867 (void) mdstealerror(ep, 868 &(resultp->mmr_ep)); 869 if (mdisok(ep)) { 870 (void) mddserror(ep, 871 MDE_DS_COMMD_SEND_FAIL, 872 sp->setno, NULL, NULL, 873 sp->setname); 874 } 875 free_result(resultp); 876 } 877 break; 878 } 879 if (resultp) 880 free_result(resultp); 881 } else { 882 /* 883 * Let this side's device name, minor # and driver name 884 * be known to the database replica. 885 */ 886 (void) memset(&c, 0, sizeof (c)); 887 888 /* Fill in device/replica info */ 889 c.c_locator.l_dev = meta_cmpldev(np->dev); 890 c.c_locator.l_blkno = blkno; 891 (void) strncpy(c.c_locator.l_driver, dname, 892 sizeof (c.c_locator.l_driver)); 893 (void) splitname(bname, &c.c_devname); 894 c.c_locator.l_mnum = mnum; 895 896 /* Fill in setno, setname, and sideno */ 897 c.c_setno = sp->setno; 898 (void) strncpy(c.c_setname, sp->setname, 899 sizeof (c.c_setname)); 900 c.c_sideno = sideno; 901 902 /* 903 * Don't need device id information from this ioctl 904 * Kernel determines device id from dev_t, which 905 * is just what this code would do. 906 */ 907 c.c_locator.l_devid = (uint64_t)0; 908 c.c_locator.l_devid_flags = 0; 909 910 if (metaioctl(MD_DB_NEWSIDE, &c, &c.c_mde, NULL) != 0) { 911 rval = mdstealerror(ep, &c.c_mde); 912 break; 913 } 914 } 915 } 916 917 /* cleanup, return success */ 918 if (bname != NULL) { 919 Free(bname); 920 bname = NULL; 921 } 922 if (dname != NULL) { 923 Free(dname); 924 dname = NULL; 925 } 926 return (rval); 927 } 928 929 930 int 931 meta_db_delsidenm( 932 mdsetname_t *sp, 933 side_t sideno, 934 mdname_t *np, 935 daddr_t blkno, 936 md_error_t *ep 937 ) 938 { 939 mddb_config_t c; 940 md_set_desc *sd; 941 942 if (! metaislocalset(sp)) { 943 if ((sd = metaget_setdesc(sp, ep)) == NULL) 944 return (-1); 945 } 946 /* Use rpc.mdcommd to delete mddb side from all nodes */ 947 if ((! metaislocalset(sp)) && MD_MNSET_DESC(sd) && 948 (sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)) { 949 md_mn_result_t *resultp = NULL; 950 md_mn_msg_meta_db_delside_t db_ds; 951 int send_rval; 952 953 db_ds.msg_l_dev = np->dev; 954 db_ds.msg_blkno = blkno; 955 db_ds.msg_sideno = sideno; 956 957 /* Set devid to NULL until devids are supported */ 958 db_ds.msg_devid[0] = NULL; 959 960 /* 961 * If reconfig cycle has been started, this node is 962 * stuck in in the return step until this command has 963 * completed. If mdcommd is suspended, ask 964 * send_message to fail (instead of retrying) 965 * so that metaset can finish allowing the reconfig 966 * cycle to proceed. 967 */ 968 send_rval = mdmn_send_message(sp->setno, 969 MD_MN_MSG_META_DB_DELSIDE, MD_MSGF_FAIL_ON_SUSPEND | 970 MD_MSGF_PANIC_WHEN_INCONSISTENT, (char *)&db_ds, 971 sizeof (md_mn_msg_meta_db_delside_t), &resultp, ep); 972 if (send_rval != 0) { 973 if (resultp == NULL) 974 (void) mddserror(ep, 975 MDE_DS_COMMD_SEND_FAIL, 976 sp->setno, NULL, NULL, 977 sp->setname); 978 else { 979 (void) mdstealerror(ep, &(resultp->mmr_ep)); 980 if (mdisok(ep)) { 981 (void) mddserror(ep, 982 MDE_DS_COMMD_SEND_FAIL, 983 sp->setno, NULL, NULL, 984 sp->setname); 985 } 986 free_result(resultp); 987 } 988 return (-1); 989 } 990 if (resultp) 991 free_result(resultp); 992 993 } else { 994 /* 995 * Let this side's device name, minor # and driver name 996 * be known to the database replica. 997 */ 998 (void) memset(&c, 0, sizeof (c)); 999 1000 /* Fill in device/replica info */ 1001 c.c_locator.l_dev = meta_cmpldev(np->dev); 1002 c.c_locator.l_blkno = blkno; 1003 1004 /* Fill in setno, setname, and sideno */ 1005 c.c_setno = sp->setno; 1006 (void) strcpy(c.c_setname, sp->setname); 1007 c.c_sideno = sideno; 1008 1009 /* 1010 * Don't need device id information from this ioctl 1011 * Kernel determines device id from dev_t, which 1012 * is just what this code would do. 1013 */ 1014 c.c_locator.l_devid = (uint64_t)0; 1015 c.c_locator.l_devid_flags = 0; 1016 1017 if (metaioctl(MD_DB_DELSIDE, &c, &c.c_mde, NULL) != 0) 1018 return (mdstealerror(ep, &c.c_mde)); 1019 } 1020 return (0); 1021 } 1022 1023 1024 static int 1025 mdnamesareunique(mdnamelist_t *nlp, md_error_t *ep) 1026 { 1027 mdnamelist_t *dnp1, *dnp2; 1028 1029 for (dnp1 = nlp; dnp1 != NULL; dnp1 = dnp1->next) { 1030 for (dnp2 = dnp1->next; dnp2 != NULL; dnp2 = dnp2->next) { 1031 if (strcmp(dnp1->namep->cname, dnp2->namep->cname) == 0) 1032 return (mderror(ep, MDE_DUPDRIVE, 1033 dnp1->namep->cname)); 1034 } 1035 } 1036 return (0); 1037 } 1038 1039 1040 /* 1041 * Return 1 if files are different, else return 0 1042 */ 1043 static int 1044 filediff(char *tsname, char *sname) 1045 { 1046 int ret = 1, fd; 1047 size_t tsz, sz; 1048 struct stat sbuf; 1049 char *tbuf, *buf; 1050 1051 if (stat(tsname, &sbuf) != 0) 1052 return (1); 1053 tsz = sbuf.st_size; 1054 if (stat(sname, &sbuf) != 0) 1055 return (1); 1056 sz = sbuf.st_size; 1057 if (tsz != sz) 1058 return (1); 1059 1060 /* allocate memory and read both files into buffer */ 1061 tbuf = malloc(tsz); 1062 buf = malloc(sz); 1063 if (tbuf == NULL || buf == NULL) 1064 goto out; 1065 1066 fd = open(tsname, O_RDONLY); 1067 if (fd == -1) 1068 goto out; 1069 sz = read(fd, tbuf, tsz); 1070 (void) close(fd); 1071 if (sz != tsz) 1072 goto out; 1073 1074 fd = open(sname, O_RDONLY); 1075 if (fd == -1) 1076 goto out; 1077 sz = read(fd, buf, tsz); 1078 (void) close(fd); 1079 if (sz != tsz) 1080 goto out; 1081 1082 /* compare content */ 1083 ret = bcmp(tbuf, buf, tsz); 1084 out: 1085 if (tbuf) 1086 free(tbuf); 1087 if (buf) 1088 free(buf); 1089 return (ret); 1090 } 1091 1092 /* 1093 * patch md.conf file with mddb locations 1094 */ 1095 int 1096 meta_db_patch( 1097 char *sname, /* system file name */ 1098 char *cname, /* mddb.cf file name */ 1099 int patch, /* patching locally */ 1100 md_error_t *ep 1101 ) 1102 { 1103 char *tsname = NULL; 1104 char line[MDDB_BOOTLIST_MAX_LEN]; 1105 FILE *tsfp = NULL; 1106 FILE *mfp = NULL; 1107 int rval = -1; 1108 1109 /* check names */ 1110 if (sname == NULL) { 1111 if (patch) 1112 sname = "md.conf"; 1113 else 1114 sname = "/kernel/drv/md.conf"; 1115 } 1116 if (cname == NULL) 1117 cname = META_DBCONF; 1118 1119 /* 1120 * edit file 1121 */ 1122 if (meta_systemfile_copy(sname, 0, 1, 1, 0, &tsname, &tsfp, ep) != 0) { 1123 if (mdissyserror(ep, EROFS)) { 1124 /* 1125 * If we are booted on a read-only root because 1126 * of mddb quorum problems we don't want to emit 1127 * any scary error messages. 1128 */ 1129 mdclrerror(ep); 1130 rval = 0; 1131 } 1132 goto out; 1133 } 1134 1135 if (meta_systemfile_append_mddb(cname, sname, tsname, tsfp, 1, 0, 0, 1136 ep) != 0) 1137 goto out; 1138 1139 /* if file content is identical, skip rename */ 1140 if (filediff(tsname, sname) == 0) { 1141 rval = 0; 1142 goto out; 1143 } 1144 1145 if ((fflush(tsfp) != 0) || (fsync(fileno(tsfp)) != 0) || 1146 (fclose(tsfp) != 0)) { 1147 (void) mdsyserror(ep, errno, tsname); 1148 goto out; 1149 } 1150 1151 tsfp = NULL; 1152 1153 /* 1154 * rename file. If we get a Cross Device error then it 1155 * is because we are in the miniroot. 1156 */ 1157 if (rename(tsname, sname) != 0 && errno != EXDEV) { 1158 (void) mdsyserror(ep, errno, sname); 1159 goto out; 1160 } 1161 1162 if (errno == EXDEV) { 1163 if ((tsfp = fopen(tsname, "r")) == NULL) 1164 goto out; 1165 if ((mfp = fopen(sname, "w+")) == NULL) 1166 goto out; 1167 while (fgets(line, sizeof (line), tsfp) != NULL) { 1168 if (fputs(line, mfp) == NULL) 1169 goto out; 1170 } 1171 (void) fclose(tsfp); 1172 tsfp = NULL; 1173 if (fflush(mfp) != 0) 1174 goto out; 1175 if (fsync(fileno(mfp)) != 0) 1176 goto out; 1177 if (fclose(mfp) != 0) { 1178 mfp = NULL; 1179 goto out; 1180 } 1181 } 1182 1183 Free(tsname); 1184 tsname = NULL; 1185 rval = 0; 1186 1187 /* cleanup, return error */ 1188 out: 1189 if (tsfp != NULL) 1190 (void) fclose(tsfp); 1191 if (tsname != NULL) { 1192 (void) unlink(tsname); 1193 Free(tsname); 1194 } 1195 return (rval); 1196 } 1197 1198 /* 1199 * Add replicas to set. This happens as a result of: 1200 * - metadb [-s set_name] -a 1201 * - metaset -s set_name -a disk 1202 * - metaset -s set_name -d disk (causes a rebalance of mddbs) 1203 * - metaset -s set_name -b 1204 * 1205 * For a local set, this routine is run on the local set host. 1206 * 1207 * For a traditional diskset, this routine is run on the node that 1208 * is running the metaset command. 1209 * 1210 * For a multinode diskset, this routine is run by the node that is 1211 * running the metaset command. If this is the first mddb added to 1212 * the MN diskset, then no communication is made to other nodes via commd 1213 * since the other nodes will be in-sync with respect to the mddbs when 1214 * those other nodes join the set and snarf in the newly created mddb. 1215 * If this is not the first mddb added to the MN diskset, then this 1216 * attach command is sent to all of the nodes using commd. This keeps 1217 * the nodes in-sync. 1218 */ 1219 int 1220 meta_db_attach( 1221 mdsetname_t *sp, 1222 mdnamelist_t *db_nlp, 1223 mdchkopts_t options, 1224 md_timeval32_t *timeval, 1225 int dbcnt, 1226 int dbsize, 1227 char *sysfilename, 1228 md_error_t *ep 1229 ) 1230 { 1231 struct mddb_config c; 1232 mdnamelist_t *nlp; 1233 mdname_t *np; 1234 md_drive_desc *dd = NULL; 1235 md_drive_desc *p; 1236 int i; 1237 int fd; 1238 side_t sideno; 1239 daddr_t blkno; 1240 int replicacount = 0; 1241 int start_mdmonitord = 0; 1242 int rval = 0; 1243 md_error_t status = mdnullerror; 1244 md_set_desc *sd; 1245 int stale_bool = FALSE; 1246 int flags; 1247 int firstmddb = 1; 1248 md_timeval32_t inittime = {0, 0}; 1249 1250 /* 1251 * Error if we don't get some work to do. 1252 */ 1253 if (db_nlp == NULL) 1254 return (mdsyserror(ep, EINVAL, NULL)); 1255 1256 if (mdnamesareunique(db_nlp, ep) != 0) 1257 return (-1); 1258 (void) memset(&c, 0, sizeof (c)); 1259 c.c_id = 0; 1260 c.c_setno = sp->setno; 1261 1262 /* Don't need device id information from this ioctl */ 1263 c.c_locator.l_devid = (uint64_t)0; 1264 c.c_locator.l_devid_flags = 0; 1265 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) { 1266 if (metaislocalset(sp)) { 1267 if (mdismddberror(&c.c_mde, MDE_DB_INVALID)) 1268 mdclrerror(&c.c_mde); 1269 else if (! mdismddberror(&c.c_mde, MDE_DB_NODB) || 1270 (! (options & MDCHK_ALLOW_NODBS))) 1271 return (mdstealerror(ep, &c.c_mde)); 1272 } else { 1273 if (! mdismddberror(&c.c_mde, MDE_DB_NOTOWNER)) 1274 return (mdstealerror(ep, &c.c_mde)); 1275 } 1276 mdclrerror(&c.c_mde); 1277 } 1278 /* 1279 * Is current set STALE? 1280 */ 1281 if (c.c_flags & MDDB_C_STALE) { 1282 stale_bool = TRUE; 1283 } 1284 1285 assert(db_nlp != NULL); 1286 1287 /* if creating the metadbs for the first time start mdmonitord */ 1288 if (c.c_dbcnt == 0) 1289 start_mdmonitord = 1; 1290 1291 /* 1292 * check to see if we will go over the total possible number 1293 * of data bases 1294 */ 1295 nlp = db_nlp; 1296 while (nlp) { 1297 replicacount += dbcnt; 1298 nlp = nlp->next; 1299 } 1300 1301 if ((replicacount + c.c_dbcnt) > c.c_dbmax) 1302 return (mdmddberror(ep, MDE_TOOMANY_REPLICAS, NODEV32, 1303 sp->setno, c.c_dbcnt + replicacount, NULL)); 1304 1305 /* 1306 * go through and check to make sure all locations specified 1307 * are legal also pick out driver name; 1308 */ 1309 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1310 diskaddr_t devsize; 1311 1312 np = nlp->namep; 1313 1314 if (! metaislocalset(sp)) { 1315 uint_t partno; 1316 uint_t rep_partno; 1317 mddrivename_t *dnp = np->drivenamep; 1318 1319 /* 1320 * make sure that non-local database replicas 1321 * are always on the replica slice. 1322 */ 1323 if (meta_replicaslice(dnp, 1324 &rep_partno, ep) != 0) 1325 return (-1); 1326 if (metagetvtoc(np, FALSE, &partno, ep) == NULL) 1327 return (-1); 1328 if (partno != rep_partno) 1329 return (mddeverror(ep, MDE_REPCOMP_ONLY, 1330 np->dev, sp->setname)); 1331 } 1332 1333 if (meta_check_replica(sp, np, options, 0, (dbcnt * dbsize), 1334 ep)) { 1335 return (-1); 1336 } 1337 1338 if ((devsize = metagetsize(np, ep)) == -1) 1339 return (-1); 1340 1341 if (devsize < (diskaddr_t)((dbcnt * dbsize) + 16)) 1342 return (mdmddberror(ep, MDE_REPLICA_TOOSMALL, 1343 meta_getminor(np->dev), sp->setno, devsize, 1344 np->cname)); 1345 } 1346 1347 /* 1348 * If first disk in set we don't have lb_inittime yet for use as 1349 * mb_setcreatetime so don't go looking for it. WE'll come back 1350 * later and update after the locator block has been created. 1351 * If this isn't the first disk in the set, we have a locator 1352 * block and thus we have lb_inittime. Set mb_setcreatetime to 1353 * lb_inittime. 1354 */ 1355 if (! metaislocalset(sp)) { 1356 if (c.c_dbcnt != 0) { 1357 firstmddb = 0; 1358 inittime = meta_get_lb_inittime(sp, ep); 1359 } 1360 } 1361 1362 /* 1363 * go through and write all master blocks 1364 */ 1365 1366 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1367 np = nlp->namep; 1368 1369 if ((fd = open(np->rname, O_RDWR)) < 0) 1370 return (mdsyserror(ep, errno, np->rname)); 1371 1372 for (i = 0; i < dbcnt; i++) { 1373 if (mkmasterblks(sp, np, fd, (i * dbsize + 16), dbsize, 1374 inittime, ep)) { 1375 (void) close(fd); 1376 return (-1); 1377 } 1378 } 1379 (void) close(fd); 1380 } 1381 1382 if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) 1383 return (-1); 1384 1385 if (! metaislocalset(sp)) { 1386 dd = metaget_drivedesc_fromnamelist(sp, db_nlp, ep); 1387 if (! mdisok(ep)) 1388 return (-1); 1389 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1390 return (-1); 1391 1392 } 1393 1394 /* 1395 * go through and tell kernel to add them 1396 */ 1397 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1398 mdcinfo_t *cinfo; 1399 1400 np = nlp->namep; 1401 1402 if ((cinfo = metagetcinfo(np, ep)) == NULL) { 1403 rval = -1; 1404 goto out; 1405 } 1406 1407 /* 1408 * If mddb is being added to MN diskset and there already 1409 * exists a valid mddb in the set (which equates to this 1410 * node being an owner of the set) then use rpc.mdcommd 1411 * mechanism to add mddb(s) so that all nodes stay in sync. 1412 * If set is stale, don't log the message since rpc.mdcommd 1413 * can't write the message to the mddb. 1414 * 1415 * Otherwise, just add mddb to this node. 1416 */ 1417 if ((! metaislocalset(sp)) && MD_MNSET_DESC(sd) && 1418 (sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)) { 1419 md_mn_result_t *resultp = NULL; 1420 md_mn_msg_meta_db_attach_t attach; 1421 int send_rval; 1422 1423 /* 1424 * In a scenario where new replicas had been added on 1425 * the master, and then all of the old replicas failed 1426 * before the slaves had knowledge of the new replicas, 1427 * the slaves are unable to re-parse in the mddb 1428 * from the new replicas since the slaves have no 1429 * knowledge of the new replicas. The following 1430 * algorithm solves this problem: 1431 * - META_DB_ATTACH message generates submsgs 1432 * - BLOCK parse (master) 1433 * - MDDB_ATTACH new replicas 1434 * - UNBLOCK parse (master) causing parse 1435 * information to be sent from master 1436 * to slaves at a higher class than the 1437 * unblock so the parse message will 1438 * reach slaves before unblock message. 1439 */ 1440 attach.msg_l_dev = np->dev; 1441 attach.msg_cnt = dbcnt; 1442 attach.msg_dbsize = dbsize; 1443 (void) strncpy(attach.msg_dname, cinfo->dname, 1444 sizeof (attach.msg_dname)); 1445 (void) splitname(np->bname, &attach.msg_splitname); 1446 attach.msg_options = options; 1447 1448 /* Set devid to NULL until devids are supported */ 1449 attach.msg_devid[0] = NULL; 1450 1451 /* 1452 * If reconfig cycle has been started, this node is 1453 * stuck in in the return step until this command has 1454 * completed. If mdcommd is suspended, ask 1455 * send_message to fail (instead of retrying) 1456 * so that metaset can finish allowing the reconfig 1457 * cycle to proceed. 1458 */ 1459 flags = MD_MSGF_FAIL_ON_SUSPEND; 1460 if (stale_bool == TRUE) 1461 flags |= MD_MSGF_NO_LOG; 1462 send_rval = mdmn_send_message(sp->setno, 1463 MD_MN_MSG_META_DB_ATTACH, 1464 flags, (char *)&attach, 1465 sizeof (md_mn_msg_meta_db_attach_t), 1466 &resultp, ep); 1467 if (send_rval != 0) { 1468 rval = -1; 1469 if (resultp == NULL) 1470 (void) mddserror(ep, 1471 MDE_DS_COMMD_SEND_FAIL, 1472 sp->setno, NULL, NULL, 1473 sp->setname); 1474 else { 1475 (void) mdstealerror(ep, 1476 &(resultp->mmr_ep)); 1477 if (mdisok(ep)) { 1478 (void) mddserror(ep, 1479 MDE_DS_COMMD_SEND_FAIL, 1480 sp->setno, NULL, NULL, 1481 sp->setname); 1482 } 1483 free_result(resultp); 1484 } 1485 goto out; 1486 } 1487 if (resultp) 1488 free_result(resultp); 1489 } else { 1490 /* Adding mddb(s) to just this node */ 1491 for (i = 0; i < dbcnt; i++) { 1492 (void) memset(&c, 0, sizeof (c)); 1493 /* Fill in device/replica info */ 1494 c.c_locator.l_dev = meta_cmpldev(np->dev); 1495 c.c_locator.l_blkno = i * dbsize + 16; 1496 blkno = c.c_locator.l_blkno; 1497 (void) strncpy(c.c_locator.l_driver, cinfo->dname, 1498 sizeof (c.c_locator.l_driver)); 1499 (void) splitname(np->bname, &c.c_devname); 1500 c.c_locator.l_mnum = meta_getminor(np->dev); 1501 1502 /* Fill in setno, setname, and sideno */ 1503 c.c_setno = sp->setno; 1504 if (! metaislocalset(sp)) { 1505 if (MD_MNSET_DESC(sd)) { 1506 c.c_multi_node = 1; 1507 } 1508 } 1509 (void) strcpy(c.c_setname, sp->setname); 1510 c.c_sideno = sideno; 1511 1512 /* 1513 * Don't need device id information from this ioctl 1514 * Kernel determines device id from dev_t, which 1515 * is just what this code would do. 1516 */ 1517 c.c_locator.l_devid = (uint64_t)0; 1518 c.c_locator.l_devid_flags = 0; 1519 1520 if (timeval != NULL) 1521 c.c_timestamp = *timeval; 1522 1523 if (setup_med_cfg(sp, &c, (options & MDCHK_SET_FORCE), 1524 ep)) { 1525 rval = -1; 1526 goto out; 1527 } 1528 1529 if (metaioctl(MD_DB_NEWDEV, &c, &c.c_mde, NULL) != 0) { 1530 rval = mdstealerror(ep, &c.c_mde); 1531 goto out; 1532 } 1533 /* 1534 * This is either a traditional diskset OR this 1535 * is the first replica added to a MN diskset. 1536 * In either case, set broadcast to NO_BCAST so 1537 * that message won't go through rpc.mdcommd. 1538 * If this is a traditional diskset, the bcast 1539 * flag is ignored since traditional disksets 1540 * don't use the rpc.mdcommd. 1541 */ 1542 if (meta_db_addsidenms(sp, np, blkno, 1543 DB_ADDSIDENMS_NO_BCAST, ep)) 1544 goto out; 1545 } 1546 } 1547 if (! metaislocalset(sp)) { 1548 /* update the dbcnt and size in dd */ 1549 for (p = dd; p != NULL; p = p->dd_next) 1550 if (p->dd_dnp == np->drivenamep) { 1551 p->dd_dbcnt = dbcnt; 1552 p->dd_dbsize = dbsize; 1553 break; 1554 } 1555 } 1556 1557 /* 1558 * If this was the first addition of disks to the 1559 * diskset you now need to update the mb_setcreatetime 1560 * which needed lb_inittime which wasn't there until now. 1561 */ 1562 if (firstmddb) { 1563 if (meta_update_mb(sp, dd, ep) != 0) { 1564 return (-1); 1565 } 1566 } 1567 (void) close(fd); 1568 } 1569 1570 out: 1571 if (metaislocalset(sp)) { 1572 1573 /* everything looks fine. Start mdmonitord */ 1574 /* Note: popen/pclose is the MT-safe replacement for system */ 1575 if (rval == 0 && start_mdmonitord == 1) { 1576 if (pclose(popen(MDMONITORD, "w")) == -1) 1577 md_perror(MDMONITORD); 1578 1579 if (meta_smf_enable(META_SMF_CORE, &status) == -1) { 1580 mde_perror(&status, ""); 1581 mdclrerror(&status); 1582 } 1583 } 1584 1585 if (buildconf(sp, &status)) { 1586 /* Don't mask any previous errors */ 1587 if (rval == 0) 1588 rval = mdstealerror(ep, &status); 1589 return (rval); 1590 } 1591 1592 if (meta_db_patch(sysfilename, NULL, 0, &status)) { 1593 /* Don't mask any previous errors */ 1594 if (rval == 0) 1595 rval = mdstealerror(ep, &status); 1596 } 1597 } else { 1598 if (update_dbinfo_on_drives(sp, dd, 1599 (options & MDCHK_SET_LOCKED), 1600 (options & MDCHK_SET_FORCE), 1601 &status)) { 1602 /* Don't mask any previous errors */ 1603 if (rval == 0) 1604 rval = mdstealerror(ep, &status); 1605 else 1606 mdclrerror(&status); 1607 } 1608 metafreedrivedesc(&dd); 1609 } 1610 /* 1611 * For MN disksets that already had already had nodes joined 1612 * before the attach of this mddb(s), the name invalidation is 1613 * done by the commd handler routine. Otherwise, if this 1614 * is the first attach of a MN diskset mddb, the invalidation 1615 * must be done here since the first attach cannot be sent 1616 * via the commd since there are no nodes joined to the set yet. 1617 */ 1618 if ((metaislocalset(sp)) || (!MD_MNSET_DESC(sd)) || 1619 (MD_MNSET_DESC(sd) && 1620 (!(sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)))) { 1621 for (nlp = db_nlp; (nlp != NULL); nlp = nlp->next) { 1622 meta_invalidate_name(nlp->namep); 1623 } 1624 } 1625 return (rval); 1626 } 1627 1628 /* 1629 * deletelist_length 1630 * 1631 * return the number of slices that have been specified for deletion 1632 * on the metadb command line. This does not calculate the number 1633 * of replicas because there may be multiple replicas per slice. 1634 */ 1635 static int 1636 deletelist_length(mdnamelist_t *db_nlp) 1637 { 1638 1639 mdnamelist_t *nlp; 1640 int list_length = 0; 1641 1642 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1643 list_length++; 1644 } 1645 1646 return (list_length); 1647 } 1648 1649 static int 1650 in_deletelist(char *devname, mdnamelist_t *db_nlp) 1651 { 1652 1653 mdnamelist_t *nlp; 1654 mdname_t *np; 1655 int index = 0; 1656 1657 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1658 np = nlp->namep; 1659 1660 if (strcmp(devname, np->bname) == 0) 1661 return (index); 1662 index++; 1663 } 1664 1665 return (-1); 1666 } 1667 1668 /* 1669 * Delete replicas from set. This happens as a result of: 1670 * - metadb [-s set_name] -d 1671 * - metaset -s set_name -a disk (causes a rebalance of mddbs) 1672 * - metaset -s set_name -d disk 1673 * - metaset -s set_name -b 1674 * 1675 * For a local set, this routine is run on the local set host. 1676 * 1677 * For a traditional diskset, this routine is run on the node that 1678 * is running the metaset command. 1679 * 1680 * For a multinode diskset, this routine is run by the node that is 1681 * running the metaset command. This detach routine is sent to all 1682 * of the joined nodes in the diskset using commd. This keeps 1683 * the nodes in-sync. 1684 */ 1685 int 1686 meta_db_detach( 1687 mdsetname_t *sp, 1688 mdnamelist_t *db_nlp, 1689 mdforceopts_t force_option, 1690 char *sysfilename, 1691 md_error_t *ep 1692 ) 1693 { 1694 struct mddb_config c; 1695 mdnamelist_t *nlp; 1696 mdname_t *np; 1697 md_drive_desc *dd = NULL; 1698 md_drive_desc *p; 1699 int replicacount; 1700 int replica_delete_count; 1701 int nr_replica_slices; 1702 int i; 1703 int stop_svmdaemons = 0; 1704 int rval = 0; 1705 int index; 1706 int valid_replicas_nottodelete = 0; 1707 int invalid_replicas_nottodelete = 0; 1708 int invalid_replicas_todelete = 0; 1709 int errored = 0; 1710 int *tag_array; 1711 int fd = -1; 1712 md_error_t status = mdnullerror; 1713 md_set_desc *sd; 1714 int stale_bool = FALSE; 1715 int flags; 1716 1717 /* 1718 * Error if we don't get some work to do. 1719 */ 1720 if (db_nlp == NULL) 1721 return (mdsyserror(ep, EINVAL, NULL)); 1722 1723 if (mdnamesareunique(db_nlp, ep) != 0) 1724 return (-1); 1725 1726 (void) memset(&c, 0, sizeof (c)); 1727 c.c_id = 0; 1728 c.c_setno = sp->setno; 1729 1730 /* Don't need device id information from this ioctl */ 1731 c.c_locator.l_devid = (uint64_t)0; 1732 c.c_locator.l_devid_flags = 0; 1733 1734 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) 1735 return (mdstealerror(ep, &c.c_mde)); 1736 1737 /* 1738 * Is current set STALE? 1739 */ 1740 if (c.c_flags & MDDB_C_STALE) { 1741 stale_bool = TRUE; 1742 } 1743 1744 replicacount = c.c_dbcnt; 1745 1746 assert(db_nlp != NULL); 1747 1748 /* 1749 * go through and gather how many data bases are on each 1750 * device specified. 1751 */ 1752 1753 nr_replica_slices = deletelist_length(db_nlp); 1754 tag_array = (int *)calloc(nr_replica_slices, sizeof (int)); 1755 1756 replica_delete_count = 0; 1757 for (i = 0; i < replicacount; i++) { 1758 char *devname; 1759 int found = 0; 1760 1761 c.c_id = i; 1762 1763 /* Don't need device id information from this ioctl */ 1764 c.c_locator.l_devid = (uint64_t)0; 1765 c.c_locator.l_devid_flags = 0; 1766 1767 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) 1768 return (mdstealerror(ep, &c.c_mde)); 1769 1770 devname = splicename(&c.c_devname); 1771 1772 if ((index = in_deletelist(devname, db_nlp)) != -1) { 1773 found = 1; 1774 tag_array[index] = 1; 1775 replica_delete_count++; 1776 } 1777 1778 errored = c.c_locator.l_flags & (MDDB_F_EREAD | 1779 MDDB_F_EWRITE | MDDB_F_TOOSMALL | 1780 MDDB_F_EFMT | MDDB_F_EDATA | 1781 MDDB_F_EMASTER); 1782 1783 /* 1784 * There are four combinations of "errored" and "found" 1785 * and they are used to find the number of 1786 * (a) valid/invalid replicas that are not in the delete 1787 * list and are available in the system. 1788 * (b) valid/invalid replicas that are to be deleted. 1789 */ 1790 1791 if (errored && !found) /* errored and !found */ 1792 invalid_replicas_nottodelete++; 1793 else if (!found) /* !errored and !found */ 1794 valid_replicas_nottodelete++; 1795 else if (errored) /* errored and found */ 1796 invalid_replicas_todelete++; 1797 /* 1798 * else it is !errored and found. This means 1799 * valid_replicas_todelete++; But this variable will not 1800 * be used anywhere 1801 */ 1802 1803 Free(devname); 1804 } 1805 1806 index = 0; 1807 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1808 np = nlp->namep; 1809 if (tag_array[index++] != 1) { 1810 Free(tag_array); 1811 return (mddeverror(ep, MDE_NO_DB, np->dev, np->cname)); 1812 } 1813 } 1814 1815 Free(tag_array); 1816 1817 1818 /* if all replicas are deleted stop mdmonitord */ 1819 if ((replicacount - replica_delete_count) == 0) 1820 stop_svmdaemons = 1; 1821 1822 if (((replicacount - replica_delete_count) < MD_MINREPLICAS)) { 1823 if (force_option & MDFORCE_NONE) 1824 return (mderror(ep, MDE_NOTENOUGH_DB, sp->setname)); 1825 if (! metaislocalset(sp) && ! (force_option & MDFORCE_DS)) 1826 return (mderror(ep, MDE_DELDB_NOTALLOWED, sp->setname)); 1827 } 1828 1829 /* 1830 * The following algorithms are followed to check for deletion: 1831 * (a) If the delete list(db_nlp) has all invalid replicas and no valid 1832 * replicas, then deletion should be allowed. 1833 * (b) Deletion should be allowed only if valid replicas that are "not" 1834 * to be deleted is always greater than the invalid replicas that 1835 * are "not" to be deleted. 1836 * (c) If the user uses -f option, then deletion should be allowed. 1837 */ 1838 1839 if ((invalid_replicas_todelete != replica_delete_count) && 1840 (invalid_replicas_nottodelete > valid_replicas_nottodelete) && 1841 (force_option != MDFORCE_LOCAL)) 1842 return (mderror(ep, MDE_DEL_VALIDDB_NOTALLOWED, sp->setname)); 1843 1844 /* 1845 * go through and tell kernel to delete them 1846 */ 1847 1848 /* Don't need device id information from this ioctl */ 1849 c.c_locator.l_devid = (uint64_t)0; 1850 c.c_locator.l_devid_flags = 0; 1851 1852 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) 1853 return (mdstealerror(ep, &c.c_mde)); 1854 1855 if (! metaislocalset(sp)) { 1856 dd = metaget_drivedesc_fromnamelist(sp, db_nlp, ep); 1857 if (! mdisok(ep)) 1858 return (-1); 1859 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1860 return (-1); 1861 } 1862 1863 for (nlp = db_nlp; nlp != NULL; nlp = nlp->next) { 1864 np = nlp->namep; 1865 1866 /* 1867 * If mddb is being deleted from MN diskset and node is 1868 * an owner of the diskset then use rpc.mdcommd 1869 * mechanism to add mddb(s) so that all nodes stay in sync. 1870 * If set is stale, don't log the message since rpc.mdcommd 1871 * can't write the message to the mddb. 1872 * 1873 * When mddbs are first being added to set, a detach can 1874 * be called before any node has joined the diskset, so 1875 * must check to see if node is an owner of the diskset. 1876 * 1877 * Otherwise, just delete mddb from this node. 1878 */ 1879 1880 if ((! metaislocalset(sp)) && MD_MNSET_DESC(sd) && 1881 (sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)) { 1882 md_mn_result_t *resultp; 1883 md_mn_msg_meta_db_detach_t detach; 1884 int send_rval; 1885 1886 /* 1887 * The following algorithm is used to detach replicas. 1888 * - META_DB_DETACH message generates submsgs 1889 * - BLOCK parse (master) 1890 * - MDDB_DETACH replicas 1891 * - UNBLOCK parse (master) causing parse 1892 * information to be sent from master 1893 * to slaves at a higher class than the 1894 * unblock so the parse message will 1895 * reach slaves before unblock message. 1896 */ 1897 (void) splitname(np->bname, &detach.msg_splitname); 1898 1899 /* Set devid to NULL until devids are supported */ 1900 detach.msg_devid[0] = NULL; 1901 1902 /* 1903 * If reconfig cycle has been started, this node is 1904 * stuck in in the return step until this command has 1905 * completed. If mdcommd is suspended, ask 1906 * send_message to fail (instead of retrying) 1907 * so that metaset can finish allowing the reconfig 1908 * cycle to proceed. 1909 */ 1910 flags = MD_MSGF_FAIL_ON_SUSPEND; 1911 if (stale_bool == TRUE) 1912 flags |= MD_MSGF_NO_LOG; 1913 send_rval = mdmn_send_message(sp->setno, 1914 MD_MN_MSG_META_DB_DETACH, 1915 flags, (char *)&detach, 1916 sizeof (md_mn_msg_meta_db_detach_t), 1917 &resultp, ep); 1918 if (send_rval != 0) { 1919 rval = -1; 1920 if (resultp == NULL) 1921 (void) mddserror(ep, 1922 MDE_DS_COMMD_SEND_FAIL, 1923 sp->setno, NULL, NULL, 1924 sp->setname); 1925 else { 1926 (void) mdstealerror(ep, 1927 &(resultp->mmr_ep)); 1928 if (mdisok(ep)) { 1929 (void) mddserror(ep, 1930 MDE_DS_COMMD_SEND_FAIL, 1931 sp->setno, NULL, NULL, 1932 sp->setname); 1933 } 1934 free_result(resultp); 1935 } 1936 goto out; 1937 } 1938 if (resultp) 1939 free_result(resultp); 1940 } else { 1941 i = 0; 1942 while (i < c.c_dbcnt) { 1943 char *devname; 1944 1945 c.c_id = i; 1946 1947 /* Don't need devid info from this ioctl */ 1948 c.c_locator.l_devid = (uint64_t)0; 1949 c.c_locator.l_devid_flags = 0; 1950 1951 if (metaioctl(MD_DB_GETDEV, &c, 1952 &c.c_mde, NULL)) { 1953 rval = mdstealerror(ep, &c.c_mde); 1954 goto out; 1955 } 1956 1957 devname = splicename(&c.c_devname); 1958 if (strcmp(devname, np->bname) != 0) { 1959 Free(devname); 1960 i++; 1961 continue; 1962 } 1963 Free(devname); 1964 1965 /* Don't need devid info from this ioctl */ 1966 c.c_locator.l_devid = (uint64_t)0; 1967 c.c_locator.l_devid_flags = 0; 1968 1969 if (metaioctl(MD_DB_DELDEV, &c, 1970 &c.c_mde, NULL) != 0) { 1971 rval = mdstealerror(ep, &c.c_mde); 1972 goto out; 1973 } 1974 1975 /* Not incrementing "i" intentionally */ 1976 } 1977 } 1978 if (! metaislocalset(sp)) { 1979 /* update the dbcnt and size in dd */ 1980 for (p = dd; p != NULL; p = p->dd_next) { 1981 if (p->dd_dnp == np->drivenamep) { 1982 p->dd_dbcnt = 0; 1983 p->dd_dbsize = 0; 1984 break; 1985 } 1986 } 1987 1988 /* 1989 * Slam a dummy master block and make it self 1990 * identifying 1991 */ 1992 if ((fd = open(np->rname, O_RDWR)) >= 0) { 1993 meta_mkdummymaster(sp, fd, 16); 1994 (void) close(fd); 1995 } 1996 } 1997 } 1998 out: 1999 if (metaislocalset(sp)) { 2000 /* 2001 * Stop all the daemons if there are 2002 * no more replicas so that the module can be 2003 * unloaded. 2004 */ 2005 if (rval == 0 && stop_svmdaemons == 1) { 2006 char buf[MAXPATHLEN]; 2007 int i; 2008 2009 for (i = 0; i < DAEMON_COUNT; i++) { 2010 (void) snprintf(buf, MAXPATHLEN, 2011 "/usr/bin/pkill -%s -x %s", 2012 svmd_kill_list[i].svmd_kill_val, 2013 svmd_kill_list[i].svmd_name); 2014 if (pclose(popen(buf, "w")) == -1) 2015 md_perror(buf); 2016 } 2017 2018 if (meta_smf_disable(META_SMF_ALL, &status) == -1) { 2019 mde_perror(&status, ""); 2020 mdclrerror(&status); 2021 } 2022 } 2023 if (buildconf(sp, &status)) { 2024 /* Don't mask any previous errors */ 2025 if (rval == 0) 2026 rval = mdstealerror(ep, &status); 2027 else 2028 mdclrerror(&status); 2029 return (rval); 2030 } 2031 2032 if (meta_db_patch(sysfilename, NULL, 0, &status)) { 2033 /* Don't mask any previous errors */ 2034 if (rval == 0) 2035 rval = mdstealerror(ep, &status); 2036 else 2037 mdclrerror(&status); 2038 } 2039 } else { 2040 if (update_dbinfo_on_drives(sp, dd, 2041 (force_option & MDFORCE_SET_LOCKED), 2042 ((force_option & MDFORCE_LOCAL) | 2043 (force_option & MDFORCE_DS)), &status)) { 2044 /* Don't mask any previous errors */ 2045 if (rval == 0) 2046 rval = mdstealerror(ep, &status); 2047 else 2048 mdclrerror(&status); 2049 } 2050 metafreedrivedesc(&dd); 2051 } 2052 if ((metaislocalset(sp)) || (!(MD_MNSET_DESC(sd)))) { 2053 for (nlp = db_nlp; (nlp != NULL); nlp = nlp->next) { 2054 meta_invalidate_name(nlp->namep); 2055 } 2056 } 2057 return (rval); 2058 } 2059 2060 static md_replica_t * 2061 metareplicaname( 2062 mdsetname_t *sp, 2063 int flags, 2064 struct mddb_config *c, 2065 md_error_t *ep 2066 ) 2067 { 2068 md_replica_t *rp; 2069 char *devname; 2070 size_t sz; 2071 2072 /* allocate replicaname */ 2073 rp = Zalloc(sizeof (*rp)); 2074 2075 /* get device name */ 2076 devname = splicename(&c->c_devname); 2077 if (flags & PRINT_FAST) { 2078 if ((rp->r_namep = metaname_fast(&sp, devname, 2079 LOGICAL_DEVICE, ep)) == NULL) { 2080 Free(devname); 2081 Free(rp); 2082 return (NULL); 2083 } 2084 } else { 2085 if ((rp->r_namep = metaname(&sp, devname, 2086 LOGICAL_DEVICE, ep)) == NULL) { 2087 Free(devname); 2088 Free(rp); 2089 return (NULL); 2090 } 2091 } 2092 Free(devname); 2093 2094 /* make sure it's OK */ 2095 if ((! (flags & MD_BASICNAME_OK)) && 2096 (metachkcomp(rp->r_namep, ep) != 0)) { 2097 Free(rp); 2098 return (NULL); 2099 } 2100 2101 rp->r_blkno = (daddr_t)MD_DISKADDR_ERROR; 2102 rp->r_nblk = (daddr_t)MD_DISKADDR_ERROR; 2103 rp->r_flags = c->c_locator.l_flags | MDDB_F_NODEVID; 2104 if (c->c_locator.l_devid_flags & MDDB_DEVID_VALID) { 2105 sz = devid_sizeof((ddi_devid_t)(uintptr_t) 2106 (c->c_locator.l_devid)); 2107 if ((rp->r_devid = (ddi_devid_t)malloc(sz)) == 2108 (ddi_devid_t)NULL) { 2109 Free(rp); 2110 return (NULL); 2111 } 2112 (void) memcpy((void *)rp->r_devid, 2113 (void *)(uintptr_t)c->c_locator.l_devid, sz); 2114 (void) strcpy(rp->r_minor_name, c->c_locator.l_minor_name); 2115 rp->r_flags &= ~MDDB_F_NODEVID; 2116 /* Overwrite dev derived from name with dev from devid */ 2117 rp->r_namep->dev = meta_expldev(c->c_locator.l_dev); 2118 } 2119 (void) strcpy(rp->r_driver_name, c->c_locator.l_driver); 2120 2121 rp->r_blkno = c->c_locator.l_blkno; 2122 if (c->c_dbend != 0) 2123 rp->r_nblk = c->c_dbend - c->c_locator.l_blkno + 1; 2124 2125 /* return replica */ 2126 return (rp); 2127 } 2128 2129 /* 2130 * free replica list 2131 */ 2132 void 2133 metafreereplicalist( 2134 md_replicalist_t *rlp 2135 ) 2136 { 2137 md_replicalist_t *rl = NULL; 2138 2139 for (/* void */; (rlp != NULL); rlp = rl) { 2140 rl = rlp->rl_next; 2141 if (rlp->rl_repp->r_devid != (ddi_devid_t)0) { 2142 free(rlp->rl_repp->r_devid); 2143 } 2144 Free(rlp->rl_repp); 2145 Free(rlp); 2146 } 2147 } 2148 2149 /* 2150 * return list of all replicas in set 2151 */ 2152 int 2153 metareplicalist( 2154 mdsetname_t *sp, 2155 int flags, 2156 md_replicalist_t **rlpp, 2157 md_error_t *ep 2158 ) 2159 { 2160 md_replicalist_t **tail = rlpp; 2161 int count = 0; 2162 struct mddb_config c; 2163 int i; 2164 char *devid; 2165 2166 /* for each replica */ 2167 i = 0; 2168 do { 2169 md_replica_t *rp; 2170 2171 /* get next replica */ 2172 (void) memset(&c, 0, sizeof (c)); 2173 c.c_id = i; 2174 c.c_setno = sp->setno; 2175 2176 c.c_locator.l_devid_flags = MDDB_DEVID_GETSZ; 2177 if (metaioctl(MD_DB_ENDDEV, &c, &c.c_mde, NULL) != 0) { 2178 if (mdismddberror(&c.c_mde, MDE_DB_INVALID)) { 2179 mdclrerror(&c.c_mde); 2180 break; /* handle none at all */ 2181 } 2182 (void) mdstealerror(ep, &c.c_mde); 2183 goto out; 2184 } 2185 2186 if (c.c_locator.l_devid_flags & MDDB_DEVID_SZ) { 2187 if ((devid = malloc(c.c_locator.l_devid_sz)) == NULL) { 2188 (void) mdsyserror(ep, ENOMEM, META_DBCONF); 2189 goto out; 2190 } 2191 c.c_locator.l_devid = (uintptr_t)devid; 2192 /* 2193 * Turn on space and sz flags since 'sz' amount of 2194 * space has been alloc'd. 2195 */ 2196 c.c_locator.l_devid_flags = 2197 MDDB_DEVID_SPACE | MDDB_DEVID_SZ; 2198 } 2199 2200 if (metaioctl(MD_DB_ENDDEV, &c, &c.c_mde, NULL) != 0) { 2201 if (mdismddberror(&c.c_mde, MDE_DB_INVALID)) { 2202 mdclrerror(&c.c_mde); 2203 break; /* handle none at all */ 2204 } 2205 (void) mdstealerror(ep, &c.c_mde); 2206 goto out; 2207 } 2208 2209 /* 2210 * Paranoid check - shouldn't happen, but is left as 2211 * a place holder for changes that will be needed after 2212 * dynamic reconfiguration changes are added to SVM (to 2213 * support movement of disks at any point in time). 2214 */ 2215 if (c.c_locator.l_devid_flags & MDDB_DEVID_NOSPACE) { 2216 (void) fprintf(stderr, 2217 dgettext(TEXT_DOMAIN, 2218 "Error: Relocation Information " 2219 "(drvnm=%s, mnum=0x%lx) \n" 2220 "relocation information size changed - \n" 2221 "rerun command\n"), 2222 c.c_locator.l_driver, c.c_locator.l_mnum); 2223 (void) mderror(ep, MDE_DEVID_TOOBIG, NULL); 2224 goto out; 2225 } 2226 2227 if (c.c_dbcnt == 0) 2228 break; /* handle none at all */ 2229 2230 /* get info */ 2231 if ((rp = metareplicaname(sp, flags, &c, ep)) == NULL) 2232 goto out; 2233 2234 /* append to list */ 2235 *tail = Zalloc(sizeof (**tail)); 2236 (*tail)->rl_repp = rp; 2237 tail = &(*tail)->rl_next; 2238 ++count; 2239 2240 if (c.c_locator.l_devid_flags & MDDB_DEVID_SPACE) { 2241 free(devid); 2242 c.c_locator.l_devid_flags = 0; 2243 } 2244 2245 } while (++i < c.c_dbcnt); 2246 2247 if (c.c_locator.l_devid_flags & MDDB_DEVID_SPACE) { 2248 free(devid); 2249 } 2250 2251 /* return count */ 2252 return (count); 2253 2254 /* cleanup, return error */ 2255 out: 2256 if (c.c_locator.l_devid_flags & MDDB_DEVID_SPACE) { 2257 free(devid); 2258 } 2259 metafreereplicalist(*rlpp); 2260 *rlpp = NULL; 2261 return (-1); 2262 } 2263 2264 /* 2265 * meta_sync_db_locations - get list of replicas from kernel and write 2266 * out to mddb.cf and md.conf. 'Syncs up' the replica list in 2267 * the kernel with the replica list in the conf files. 2268 * 2269 */ 2270 void 2271 meta_sync_db_locations( 2272 mdsetname_t *sp, 2273 md_error_t *ep 2274 ) 2275 { 2276 char *sname = 0; /* system file name */ 2277 char *cname = 0; /* config file name */ 2278 2279 if (!metaislocalset(sp)) 2280 return; 2281 2282 /* Updates backup of configuration file (aka mddb.cf) */ 2283 if (buildconf(sp, ep) != 0) 2284 return; 2285 2286 /* Updates system configuration file (aka md.conf) */ 2287 (void) meta_db_patch(sname, cname, 0, ep); 2288 } 2289 2290 /* 2291 * setup_db_locations - parse the mddb.cf file and 2292 * tells the driver which db locations to use. 2293 */ 2294 int 2295 meta_setup_db_locations( 2296 md_error_t *ep 2297 ) 2298 { 2299 mddb_config_t c; 2300 FILE *fp; 2301 char inbuff[1024]; 2302 char *buff; 2303 uint_t i; 2304 size_t sz; 2305 int rval = 0; 2306 char *devidp; 2307 uint_t devid_size; 2308 char *minor_name = NULL; 2309 ddi_devid_t devid_decode; 2310 int checksum; 2311 2312 /* do mddb.cf file */ 2313 (void) memset(&c, '\0', sizeof (c)); 2314 if ((fp = fopen(META_DBCONF, "r")) == NULL) { 2315 if (errno != ENOENT) 2316 return (mdsyserror(ep, errno, META_DBCONF)); 2317 } 2318 while ((fp != NULL) && ((buff = fgets(inbuff, (sizeof (inbuff) - 1), 2319 fp)) != NULL)) { 2320 2321 /* ignore comments */ 2322 if (*buff == '#') 2323 continue; 2324 2325 /* parse locator */ 2326 (void) memset(&c, 0, sizeof (c)); 2327 c.c_setno = MD_LOCAL_SET; 2328 i = strcspn(buff, " \t"); 2329 if (i > sizeof (c.c_locator.l_driver)) 2330 i = sizeof (c.c_locator.l_driver); 2331 (void) strncpy(c.c_locator.l_driver, buff, i); 2332 buff += i; 2333 c.c_locator.l_dev = 2334 makedev((major_t)0, (minor_t)strtol(buff, &buff, 10)); 2335 c.c_locator.l_blkno = (daddr_t)strtol(buff, &buff, 10); 2336 c.c_locator.l_mnum = minor(c.c_locator.l_dev); 2337 2338 /* parse out devid */ 2339 while (isspace((int)(*buff))) 2340 buff += 1; 2341 i = strcspn(buff, " \t"); 2342 if ((devidp = (char *)malloc(i+1)) == NULL) 2343 return (mdsyserror(ep, ENOMEM, META_DBCONF)); 2344 2345 (void) strncpy(devidp, buff, i); 2346 devidp[i] = '\0'; 2347 if (devid_str_decode(devidp, &devid_decode, 2348 &minor_name) == -1) { 2349 free(devidp); 2350 continue; 2351 } 2352 2353 /* Conf file must have minor name associated with devid */ 2354 if (minor_name == NULL) { 2355 free(devidp); 2356 devid_free(devid_decode); 2357 continue; 2358 } 2359 2360 sz = devid_sizeof(devid_decode); 2361 /* Copy to devid size buffer that ioctl expects */ 2362 if ((c.c_locator.l_devid = (uintptr_t)malloc(sz)) == NULL) { 2363 devid_free(devid_decode); 2364 free(minor_name); 2365 free(devidp); 2366 return (mdsyserror(ep, ENOMEM, META_DBCONF)); 2367 } 2368 2369 (void) memcpy((void *)(uintptr_t)c.c_locator.l_devid, 2370 (void *)devid_decode, sz); 2371 2372 devid_free(devid_decode); 2373 2374 if (strlen(minor_name) > MDDB_MINOR_NAME_MAX) { 2375 free(minor_name); 2376 free(devidp); 2377 free((void *)(uintptr_t)c.c_locator.l_devid); 2378 return (mdsyserror(ep, ENOMEM, META_DBCONF)); 2379 } 2380 (void) strcpy(c.c_locator.l_minor_name, minor_name); 2381 free(minor_name); 2382 c.c_locator.l_devid_flags = MDDB_DEVID_VALID | 2383 MDDB_DEVID_SPACE | MDDB_DEVID_SZ; 2384 c.c_locator.l_devid_sz = sz; 2385 2386 devid_size = strlen(devidp); 2387 buff += devid_size; 2388 2389 checksum = strtol(buff, &buff, 10); 2390 for (i = 0; c.c_locator.l_driver[i] != 0; i++) 2391 checksum += c.c_locator.l_driver[i]; 2392 for (i = 0; i < devid_size; i++) { 2393 checksum += devidp[i]; 2394 } 2395 free(devidp); 2396 2397 checksum += minor(c.c_locator.l_dev); 2398 checksum += c.c_locator.l_blkno; 2399 if (checksum != 42) { 2400 /* overwritten later for more serious problems */ 2401 rval = mderror(ep, MDE_MDDB_CKSUM, META_DBCONF); 2402 free((void *)(uintptr_t)c.c_locator.l_devid); 2403 continue; 2404 } 2405 c.c_locator.l_flags = 0; 2406 2407 /* use db location */ 2408 if (metaioctl(MD_DB_USEDEV, &c, &c.c_mde, NULL) != 0) { 2409 free((void *)(uintptr_t)c.c_locator.l_devid); 2410 return (mdstealerror(ep, &c.c_mde)); 2411 } 2412 2413 /* free up devid if in use */ 2414 free((void *)(uintptr_t)c.c_locator.l_devid); 2415 c.c_locator.l_devid = (uint64_t)0; 2416 c.c_locator.l_devid_flags = 0; 2417 } 2418 if ((fp) && (fclose(fp) != 0)) 2419 return (mdsyserror(ep, errno, META_DBCONF)); 2420 2421 /* check for stale database */ 2422 (void) memset((char *)&c, 0, sizeof (struct mddb_config)); 2423 c.c_id = 0; 2424 c.c_setno = MD_LOCAL_SET; 2425 2426 /* Don't need device id information from this ioctl */ 2427 c.c_locator.l_devid = (uint64_t)0; 2428 c.c_locator.l_devid_flags = 0; 2429 2430 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) { 2431 if (! mdismddberror(&c.c_mde, MDE_DB_INVALID)) 2432 return (mdstealerror(ep, &c.c_mde)); 2433 mdclrerror(&c.c_mde); 2434 } 2435 2436 if (c.c_flags & MDDB_C_STALE) 2437 return (mdmddberror(ep, MDE_DB_STALE, NODEV32, MD_LOCAL_SET, 2438 0, NULL)); 2439 2440 /* success */ 2441 return (rval); 2442 } 2443 2444 /* 2445 * meta_db_minreplica - returns the minimum size replica currently in use. 2446 */ 2447 daddr_t 2448 meta_db_minreplica( 2449 mdsetname_t *sp, 2450 md_error_t *ep 2451 ) 2452 { 2453 md_replica_t *r; 2454 md_replicalist_t *rl, *rlp = NULL; 2455 daddr_t nblks = 0; 2456 2457 if (metareplicalist(sp, (MD_BASICNAME_OK | PRINT_FAST), &rlp, ep) < 0) 2458 return (-1); 2459 2460 if (rlp == NULL) 2461 return (-1); 2462 2463 /* find the smallest existing replica */ 2464 for (rl = rlp; rl != NULL; rl = rl->rl_next) { 2465 r = rl->rl_repp; 2466 nblks = ((nblks == 0) ? r->r_nblk : min(r->r_nblk, nblks)); 2467 } 2468 2469 metafreereplicalist(rlp); 2470 return (nblks); 2471 } 2472 2473 /* 2474 * meta_get_replica_names 2475 * returns an mdnamelist_t of replica slices 2476 */ 2477 /*ARGSUSED*/ 2478 int 2479 meta_get_replica_names( 2480 mdsetname_t *sp, 2481 mdnamelist_t **nlpp, 2482 int options, 2483 md_error_t *ep 2484 ) 2485 { 2486 md_replicalist_t *rlp = NULL; 2487 md_replicalist_t *rl; 2488 mdnamelist_t **tailpp = nlpp; 2489 int cnt = 0; 2490 2491 assert(nlpp != NULL); 2492 2493 if (!metaislocalset(sp)) 2494 goto out; 2495 2496 /* get replicas */ 2497 if (metareplicalist(sp, MD_BASICNAME_OK, &rlp, ep) < 0) { 2498 cnt = -1; 2499 goto out; 2500 } 2501 2502 /* build name list */ 2503 for (rl = rlp; (rl != NULL); rl = rl->rl_next) { 2504 /* 2505 * Add the name struct to the end of the 2506 * namelist but keep a pointer to the last 2507 * element so that we don't incur the overhead 2508 * of traversing the list each time 2509 */ 2510 tailpp = meta_namelist_append_wrapper( 2511 tailpp, rl->rl_repp->r_namep); 2512 ++cnt; 2513 } 2514 2515 /* cleanup, return count or error */ 2516 out: 2517 metafreereplicalist(rlp); 2518 return (cnt); 2519 } 2520