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 * mirror operations 38 */ 39 40 #include <meta.h> 41 #include <sys/lvm/md_mirror.h> 42 #include <sys/lvm/md_convert.h> 43 44 #include <ctype.h> 45 #include <stddef.h> 46 47 /* 48 * FUNCTION: meta_get_mirror_names() 49 * INPUT: sp - the set name to get mirrors from 50 * options - options from the command line 51 * OUTPUT: nlpp - list of all mirror names 52 * ep - return error pointer 53 * RETURNS: int - -1 if error, 0 success 54 * PURPOSE: returns a list of all mirrors in the metadb 55 * for all devices in the specified set 56 */ 57 int 58 meta_get_mirror_names( 59 mdsetname_t *sp, 60 mdnamelist_t **nlpp, 61 int options, 62 md_error_t *ep 63 ) 64 { 65 return (meta_get_names(MD_MIRROR, sp, nlpp, options, ep)); 66 } 67 68 /* 69 * free mirror unit 70 */ 71 void 72 meta_free_mirror( 73 md_mirror_t *mirrorp 74 ) 75 { 76 Free(mirrorp); 77 } 78 79 /* 80 * get mirror unit 81 */ 82 static md_mirror_t * 83 meta_get_mirror_common( 84 mdsetname_t *sp, 85 mdname_t *mirnp, 86 int fast, 87 md_error_t *ep 88 ) 89 { 90 mddrivename_t *dnp = mirnp->drivenamep; 91 char *miscname; 92 mm_unit_t *mm; 93 md_mirror_t *mirrorp; 94 uint_t smi, nsm; 95 md_resync_ioctl_t ri; 96 97 /* must have set */ 98 assert(sp != NULL); 99 100 /* short circuit */ 101 if (dnp->unitp != NULL) { 102 assert(dnp->unitp->type == MD_METAMIRROR); 103 return ((md_mirror_t *)dnp->unitp); 104 } 105 106 /* get miscname and unit */ 107 if ((miscname = metagetmiscname(mirnp, ep)) == NULL) 108 return (NULL); 109 if (strcmp(miscname, MD_MIRROR) != 0) { 110 (void) mdmderror(ep, MDE_NOT_MM, meta_getminor(mirnp->dev), 111 mirnp->cname); 112 return (NULL); 113 } 114 if ((mm = (mm_unit_t *)meta_get_mdunit(sp, mirnp, ep)) == NULL) 115 return (NULL); 116 assert(mm->c.un_type == MD_METAMIRROR); 117 118 /* allocate mirror */ 119 mirrorp = Zalloc(sizeof (*mirrorp)); 120 121 /* get common info */ 122 mirrorp->common.namep = mirnp; 123 mirrorp->common.type = mm->c.un_type; 124 mirrorp->common.state = mm->c.un_status; 125 mirrorp->common.capabilities = mm->c.un_capabilities; 126 mirrorp->common.parent = mm->c.un_parent; 127 mirrorp->common.size = mm->c.un_total_blocks; 128 mirrorp->common.user_flags = mm->c.un_user_flags; 129 mirrorp->common.revision = mm->c.un_revision; 130 131 /* get options */ 132 mirrorp->read_option = mm->un_read_option; 133 mirrorp->write_option = mm->un_write_option; 134 mirrorp->pass_num = mm->un_pass_num; 135 136 /* get submirrors */ 137 for (smi = 0, nsm = 0; (smi < NMIRROR); ++smi) { 138 mm_submirror_t *mmsp = &mm->un_sm[smi]; 139 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 140 141 /* get submirror state */ 142 mdsp->state = mmsp->sm_state; 143 if (mdsp->state == SMS_UNUSED) 144 continue; 145 ++nsm; 146 147 /* get submirror time of last state change */ 148 mdsp->timestamp = mmsp->sm_timestamp; 149 150 /* get submirror flags */ 151 mdsp->flags = mmsp->sm_flags; 152 153 /* get submirror name */ 154 mdsp->submirnamep = metakeyname(&sp, mmsp->sm_key, fast, ep); 155 if (mdsp->submirnamep == NULL) 156 goto out; 157 } 158 assert(nsm == mm->un_nsm); 159 160 /* get resync info */ 161 (void) memset(&ri, 0, sizeof (ri)); 162 ri.ri_mnum = meta_getminor(mirnp->dev); 163 MD_SETDRIVERNAME(&ri, MD_MIRROR, sp->setno); 164 if (metaioctl(MD_IOCGETSYNC, &ri, &ri.mde, mirnp->cname) != 0) { 165 (void) mdstealerror(ep, &ri.mde); 166 goto out; 167 } 168 mirrorp->percent_done = ri.ri_percent_done; 169 mirrorp->percent_dirty = ri.ri_percent_dirty; 170 171 /* cleanup, return success */ 172 Free(mm); 173 dnp->unitp = (md_common_t *)mirrorp; 174 return (mirrorp); 175 176 /* cleanup, return error */ 177 out: 178 Free(mm); 179 meta_free_mirror(mirrorp); 180 return (NULL); 181 } 182 183 /* 184 * get mirror unit 185 */ 186 md_mirror_t * 187 meta_get_mirror( 188 mdsetname_t *sp, 189 mdname_t *mirnp, 190 md_error_t *ep 191 ) 192 { 193 return (meta_get_mirror_common(sp, mirnp, 0, ep)); 194 } 195 196 /* 197 * check mirror for dev 198 */ 199 static int 200 in_mirror( 201 mdsetname_t *sp, 202 mdname_t *mirnp, 203 mdname_t *np, 204 diskaddr_t slblk, 205 diskaddr_t nblks, 206 md_error_t *ep 207 ) 208 { 209 md_mirror_t *mirrorp; 210 uint_t smi; 211 212 /* should be in the same set */ 213 assert(sp != NULL); 214 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 215 216 /* get unit */ 217 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 218 return (-1); 219 220 /* look in submirrors */ 221 for (smi = 0; (smi < NMIRROR); ++smi) { 222 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 223 mdname_t *submirnp = mdsp->submirnamep; 224 225 /* skip unused submirrors */ 226 if (submirnp == NULL) { 227 assert(mdsp->state == SMS_UNUSED); 228 continue; 229 } 230 231 /* check overlap */ 232 if (metaismeta(submirnp)) 233 continue; 234 if (meta_check_overlap(mirnp->cname, np, slblk, nblks, 235 submirnp, 0, -1, ep) != 0) 236 return (-1); 237 } 238 239 /* return success */ 240 return (0); 241 } 242 243 /* 244 * check to see if we're in a mirror 245 */ 246 int 247 meta_check_inmirror( 248 mdsetname_t *sp, 249 mdname_t *np, 250 diskaddr_t slblk, 251 diskaddr_t nblks, 252 md_error_t *ep 253 ) 254 { 255 mdnamelist_t *mirrornlp = NULL; 256 mdnamelist_t *p; 257 int rval = 0; 258 259 /* should have a set */ 260 assert(sp != NULL); 261 262 /* for each mirror */ 263 if (meta_get_mirror_names(sp, &mirrornlp, 0, ep) < 0) 264 return (-1); 265 for (p = mirrornlp; (p != NULL); p = p->next) { 266 mdname_t *mirnp = p->namep; 267 268 /* check mirror */ 269 if (in_mirror(sp, mirnp, np, slblk, nblks, ep) != 0) { 270 rval = -1; 271 break; 272 } 273 } 274 275 /* cleanup, return success */ 276 metafreenamelist(mirrornlp); 277 return (rval); 278 } 279 280 /* 281 * Check to see if the primary mirror is built on top of a 282 * root slice which is mounted. This check is primarily to 283 * account for this case - 284 * 285 * # metainit -f d1 1 1 <root slice> 286 * # metainit d0 -m d1 287 * # metainit d2 1 1 ctds 288 * # metattach d0 d2 289 * 290 * The metattach here needs to fail if the root slice is 291 * being mirrored; otherwise there is a potential for 292 * data corruption. 293 */ 294 static int 295 meta_check_primary_mirror( 296 mdsetname_t *sp, 297 mdname_t *mirnp, 298 md_error_t *ep 299 ) 300 { 301 int smi; 302 char *curroot; 303 mdname_t *rootnp; 304 md_mirror_t *mirrorp; 305 md_stripe_t *stripep; 306 md_row_t *rp; 307 md_comp_t *cp; 308 309 if ((curroot = meta_get_current_root(ep)) == NULL) 310 return (-1); 311 /* 312 * Get device name of current root metadevice. If root 313 * is net mounted as happens if we're part of the 314 * install process, rootnp will be set to NULL and we 315 * return success. 316 * 317 * Since curroot should be a complete path, we only 318 * need to check whether the device is a logical device. 319 * The metaname below returns NULL if curroot is not a logical 320 * device. 321 */ 322 if ((rootnp = metaname(&sp, curroot, LOGICAL_DEVICE, ep)) == NULL) 323 return (0); 324 /* 325 * If we're here, the curroot is a mounted on a logical device. 326 * Make sure this mirror is not on the root logical device. 327 */ 328 if (metaismeta(mirnp)) { 329 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 330 return (-1); 331 332 for (smi = 0; (smi < NMIRROR); ++smi) { 333 /* Check all submirrors */ 334 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 335 mdname_t *submirnamep = mdsp->submirnamep; 336 337 /* skip unused submirrors */ 338 if (submirnamep == NULL) { 339 assert(mdsp->state == SMS_UNUSED); 340 continue; 341 } 342 /* check if submirror is a stripe or not */ 343 if (strcmp(metagetmiscname(submirnamep, ep), MD_STRIPE) 344 != 0) 345 return (-1); 346 if ((stripep = meta_get_stripe(sp, submirnamep, ep)) 347 == NULL) 348 return (-1); 349 350 /* 351 * Examine the first component of the first row and 352 * check to see if it has a mounted root slice 353 */ 354 rp = &stripep->rows.rows_val[0]; 355 cp = &rp->comps.comps_val[0]; 356 /* 357 * we just care about the component built on 358 * top of a raw device 359 */ 360 if (!metaismeta(cp->compnamep)) { 361 /* 362 * If root device is the 1st component of 363 * the stripe, then fail. 364 */ 365 if (strcmp(rootnp->cname, cp->compnamep->cname) 366 == 0) { 367 (void) mduseerror(ep, MDE_IS_MOUNTED, 368 rootnp->dev, "/", rootnp->cname); 369 return (-1); 370 } 371 } 372 } 373 } 374 /* return success */ 375 return (0); 376 } 377 378 /* 379 * check submirror 380 */ 381 int 382 meta_check_submirror( 383 mdsetname_t *sp, 384 mdname_t *np, 385 mdname_t *mirnp, 386 int force, 387 md_error_t *ep 388 ) 389 { 390 mdchkopts_t options = 0; 391 md_common_t *mdp; 392 393 /* make sure we have a metadevice disk */ 394 if (metachkmeta(np, ep) != 0) 395 return (-1); 396 397 /* 398 * Check to see if the primary mirror consists of a root 399 * mounted device 400 */ 401 if (mirnp && (!force) && ((meta_check_primary_mirror(sp, mirnp, ep) 402 != 0))) 403 return (-1); 404 405 /* check to ensure that it is not already in use */ 406 if ((! force) && 407 (meta_check_inuse(sp, np, MDCHK_INUSE, ep) != 0)) { 408 return (-1); 409 } 410 411 /* make sure it is in the set */ 412 if (meta_check_inset(sp, np, ep) != 0) 413 return (-1); 414 415 /* make sure its not in a metadevice */ 416 if (! metaismeta(np)) { /* Non-metadevices */ 417 if (meta_check_inmeta(sp, np, options, 0, -1, ep) != 0) 418 return (-1); 419 } else { /* Metadevices only! */ 420 /* make sure it can be parented */ 421 if ((mdp = meta_get_unit(sp, np, ep)) == NULL) 422 return (-1); 423 424 if ((! (mdp->capabilities & MD_CAN_PARENT)) || 425 (! (mdp->capabilities & MD_CAN_SUB_MIRROR)) || 426 (mdp->parent != MD_NO_PARENT)) { 427 return (mdmderror(ep, MDE_INVAL_UNIT, 428 meta_getminor(np->dev), np->cname)); 429 } 430 } 431 432 /* return success */ 433 return (0); 434 } 435 436 /* 437 * convert read options 438 */ 439 char * 440 rd_opt_to_name( 441 mm_rd_opt_t opt 442 ) 443 { 444 switch (opt) { 445 case RD_LOAD_BAL: 446 return ("roundrobin"); 447 case RD_GEOMETRY: 448 return ("geometric"); 449 case RD_FIRST: 450 return ("first"); 451 default: 452 assert(0); 453 return (dgettext(TEXT_DOMAIN, "invalid")); 454 } 455 } 456 457 static char * 458 rd_opt_to_opt( 459 mm_rd_opt_t opt 460 ) 461 { 462 switch (opt) { 463 case RD_LOAD_BAL: 464 return (NULL); /* default */ 465 case RD_GEOMETRY: 466 return ("-g"); 467 case RD_FIRST: 468 return ("-r"); 469 default: 470 assert(0); 471 return (dgettext(TEXT_DOMAIN, "invalid")); 472 } 473 } 474 475 int 476 name_to_rd_opt( 477 char *uname, 478 char *name, 479 mm_rd_opt_t *optp, 480 md_error_t *ep 481 ) 482 { 483 if (strcasecmp(name, "roundrobin") == 0) { 484 *optp = RD_LOAD_BAL; 485 return (0); 486 } 487 if (strcasecmp(name, "geometric") == 0) { 488 *optp = RD_GEOMETRY; 489 return (0); 490 } 491 if (strcasecmp(name, "first") == 0) { 492 *optp = RD_FIRST; 493 return (0); 494 } 495 return (meta_cook_syntax(ep, MDE_BAD_RD_OPT, uname, 1, &name)); 496 } 497 498 /* 499 * convert write options 500 */ 501 char * 502 wr_opt_to_name( 503 mm_wr_opt_t opt 504 ) 505 { 506 switch (opt) { 507 case WR_PARALLEL: 508 return ("parallel"); 509 case WR_SERIAL: 510 return ("serial"); 511 default: 512 assert(0); 513 return (dgettext(TEXT_DOMAIN, "invalid")); 514 } 515 } 516 517 static char * 518 wr_opt_to_opt( 519 mm_wr_opt_t opt 520 ) 521 { 522 switch (opt) { 523 case WR_PARALLEL: 524 return (NULL); /* default */ 525 case WR_SERIAL: 526 return ("-S"); 527 default: 528 assert(0); 529 return (dgettext(TEXT_DOMAIN, "invalid")); 530 } 531 } 532 533 int 534 name_to_wr_opt( 535 char *uname, 536 char *name, 537 mm_wr_opt_t *optp, 538 md_error_t *ep 539 ) 540 { 541 if (strcasecmp(name, "parallel") == 0) { 542 *optp = WR_PARALLEL; 543 return (0); 544 } 545 if (strcasecmp(name, "serial") == 0) { 546 *optp = WR_SERIAL; 547 return (0); 548 } 549 return (meta_cook_syntax(ep, MDE_BAD_WR_OPT, uname, 1, &name)); 550 } 551 552 /* 553 * convert pass numbers 554 */ 555 int 556 name_to_pass_num( 557 char *uname, 558 char *name, 559 mm_pass_num_t *passp, 560 md_error_t *ep 561 ) 562 { 563 if ((sscanf(name, "%hd", passp) != 1) || 564 (*passp < 0) || (*passp > MD_PASS_MAX)) { 565 return (meta_cook_syntax(ep, MDE_BAD_PASS_NUM, 566 uname, 1, &name)); 567 } 568 return (0); 569 } 570 571 /* 572 * convert resync option 573 */ 574 575 static char * 576 resync_opt_to_name( 577 uint_t tstate 578 ) 579 { 580 if (tstate & MD_ABR_CAP) 581 return (dgettext(TEXT_DOMAIN, "application based")); 582 else 583 return (dgettext(TEXT_DOMAIN, "optimized resync")); 584 } 585 586 /* 587 * print mirror 588 */ 589 static int 590 mirror_print( 591 md_mirror_t *mirrorp, 592 char *fname, 593 FILE *fp, 594 mdprtopts_t options, 595 md_error_t *ep 596 ) 597 { 598 uint_t smi; 599 char *p; 600 int rval = -1; 601 602 603 if (options & PRINT_LARGEDEVICES) { 604 if ((mirrorp->common.revision & MD_64BIT_META_DEV) == 0) { 605 rval = 0; 606 goto out; 607 } 608 } 609 610 if (options & PRINT_FN) { 611 if ((mirrorp->common.revision & MD_FN_META_DEV) == 0) { 612 rval = 0; 613 goto out; 614 } 615 } 616 617 /* print name and -m */ 618 if (fprintf(fp, "%s -m", mirrorp->common.namep->cname) == EOF) 619 goto out; 620 621 /* print submirrors */ 622 for (smi = 0; (smi < NMIRROR); ++smi) { 623 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 624 mdname_t *submirnamep = mdsp->submirnamep; 625 626 /* skip unused submirrors */ 627 if (submirnamep == NULL) { 628 assert(mdsp->state == SMS_UNUSED); 629 continue; 630 } 631 632 /* print submirror */ 633 if (fprintf(fp, " %s", submirnamep->rname) == EOF) 634 goto out; 635 } 636 637 /* print options */ 638 if ((p = rd_opt_to_opt(mirrorp->read_option)) != NULL) { 639 if (fprintf(fp, " %s", p) == EOF) 640 goto out; 641 } 642 if ((p = wr_opt_to_opt(mirrorp->write_option)) != NULL) { 643 if (fprintf(fp, " %s", p) == EOF) 644 goto out; 645 } 646 if (fprintf(fp, " %u\n", mirrorp->pass_num) == EOF) 647 goto out; 648 649 /* success */ 650 rval = 0; 651 652 /* cleanup, return error */ 653 out: 654 if (rval != 0) 655 (void) mdsyserror(ep, errno, fname); 656 return (rval); 657 } 658 659 /* 660 * convert submirror state to name 661 */ 662 char * 663 sm_state_to_name( 664 md_submirror_t *mdsp, 665 md_status_t mirror_status, 666 md_timeval32_t *tvp, 667 uint_t tstate 668 ) 669 { 670 static char state_to_str[100]; 671 sm_state_t state = mdsp->state; 672 uint_t is_target = mdsp->flags & MD_SM_RESYNC_TARGET; 673 674 /* grab time */ 675 if (tvp != NULL) 676 *tvp = mdsp->timestamp; 677 678 /* 679 * Only return Unavailable if there is no flagged error on the 680 * submirror. If the mirror has received any writes since the submirror 681 * went into Unavailable state a resync is required. To alert the 682 * administrator to this we return a 'Needs maintenance' message. 683 */ 684 if ((tstate != 0) && (state & SMS_RUNNING)) { 685 return (dgettext(TEXT_DOMAIN, "Unavailable")); 686 } 687 688 /* all is well */ 689 if (state & SMS_RUNNING) { 690 if (!(mirror_status & MD_UN_OPT_NOT_DONE) || 691 ((mirror_status & MD_UN_OPT_NOT_DONE) && !is_target)) { 692 return (dgettext(TEXT_DOMAIN, "Okay")); 693 } 694 } 695 696 /* resyncing, needs repair */ 697 if ((state & (SMS_COMP_RESYNC | SMS_ATTACHED_RESYNC | 698 SMS_OFFLINE_RESYNC)) || 699 (mirror_status & MD_UN_OPT_NOT_DONE)) { 700 if (mirror_status & MD_UN_RESYNC_ACTIVE) { 701 return (dgettext(TEXT_DOMAIN, "Resyncing")); 702 } 703 if (mirror_status & MD_UN_RESYNC_CANCEL) { 704 return (dgettext(TEXT_DOMAIN, "Resync cancelled")); 705 } 706 return (dgettext(TEXT_DOMAIN, "Needs maintenance")); 707 } 708 709 /* needs repair */ 710 if (state & (SMS_COMP_ERRED | SMS_ATTACHED | SMS_OFFLINE)) { 711 if (mirror_status & MD_UN_RESYNC_CANCEL) { 712 return (dgettext(TEXT_DOMAIN, "Resync cancelled")); 713 } 714 return (dgettext(TEXT_DOMAIN, "Needs maintenance")); 715 } 716 717 /* unknown */ 718 assert(0); 719 (void) sprintf(state_to_str, "0x%x", state); 720 return (state_to_str); 721 } 722 723 /* 724 * convert submirror state to repair action 725 */ 726 int 727 sm_state_to_action( 728 mdsetname_t *sp, 729 md_submirror_t *mdsp, 730 md_status_t mirror_status, 731 md_mirror_t *mirrorp, 732 char **actionp, 733 md_error_t *ep 734 ) 735 { 736 static char buf[1024]; 737 mdname_t *submirnamep = mdsp->submirnamep; 738 sm_state_t state = mdsp->state; 739 char *miscname; 740 741 /* all is well */ 742 *actionp = NULL; 743 if (mirror_status & MD_UN_RESYNC_ACTIVE) 744 return (0); 745 if ((state == SMS_RUNNING) && !(mirror_status & MD_UN_OPT_NOT_DONE)) 746 return (0); 747 748 /* complete cancelled resync */ 749 if (mirror_status & MD_UN_RESYNC_CANCEL) { 750 (void) snprintf(buf, sizeof (buf), 751 dgettext(TEXT_DOMAIN, "metasync %s"), 752 mirrorp->common.namep->cname); 753 *actionp = buf; 754 return (0); 755 } 756 757 /* replace stripe component */ 758 if ((metaismeta(submirnamep)) && (state & SMS_COMP_ERRED)) { 759 if ((miscname = metagetmiscname(submirnamep, ep)) == NULL) 760 return (-1); 761 if (strcmp(miscname, MD_STRIPE) == 0) { 762 mdname_t *compnamep; 763 comp_state_t compstate; 764 765 if (meta_find_erred_comp(sp, submirnamep, 766 &compnamep, &compstate, ep) != 0) { 767 return (-1); 768 } 769 if (compstate != CS_LAST_ERRED) 770 (void) snprintf(buf, sizeof (buf), 771 "metareplace %s %s <%s>", 772 mirrorp->common.namep->cname, 773 compnamep->cname, 774 dgettext(TEXT_DOMAIN, "new device")); 775 else 776 (void) snprintf(buf, sizeof (buf), 777 dgettext(TEXT_DOMAIN, 778 "after replacing \"Maintenance\" " 779 "components:\n" 780 "\t\tmetareplace %s %s <new device>"), 781 mirrorp->common.namep->cname, 782 compnamep->cname); 783 *actionp = buf; 784 return (0); 785 } 786 } 787 788 /* resync mirror */ 789 if ((state & (SMS_ATTACHED_RESYNC | SMS_OFFLINE_RESYNC | 790 SMS_COMP_RESYNC | SMS_ATTACHED)) || 791 (mirror_status & MD_UN_OPT_NOT_DONE)) { 792 (void) snprintf(buf, sizeof (buf), "metasync %s", 793 mirrorp->common.namep->cname); 794 *actionp = buf; 795 return (0); 796 } 797 798 /* online submirror */ 799 if (state & SMS_OFFLINE) { 800 (void) snprintf(buf, sizeof (buf), "metaonline %s %s", 801 mirrorp->common.namep->cname, submirnamep->cname); 802 *actionp = buf; 803 return (0); 804 } 805 806 /* unknown action */ 807 *actionp = dgettext(TEXT_DOMAIN, "???"); 808 return (0); 809 } 810 811 /* 812 * print mirror options 813 */ 814 int 815 meta_print_mirror_options( 816 mm_rd_opt_t read_option, 817 mm_wr_opt_t write_option, 818 mm_pass_num_t pass_num, 819 uint_t tstate, 820 char *fname, 821 mdsetname_t *sp, 822 FILE *fp, 823 md_error_t *ep 824 ) 825 { 826 char *p; 827 int rval = -1; 828 829 /* print options */ 830 if (fprintf(fp, dgettext(TEXT_DOMAIN, " Pass: %u\n"), 831 pass_num) == EOF) { 832 goto out; 833 } 834 if ((p = rd_opt_to_opt(read_option)) == NULL) 835 p = dgettext(TEXT_DOMAIN, "default"); 836 if (fprintf(fp, dgettext(TEXT_DOMAIN, " Read option: %s (%s)\n"), 837 rd_opt_to_name(read_option), p) == EOF) { 838 goto out; 839 } 840 if ((p = wr_opt_to_opt(write_option)) == NULL) 841 p = dgettext(TEXT_DOMAIN, "default"); 842 if (fprintf(fp, dgettext(TEXT_DOMAIN, " Write option: %s (%s)\n"), 843 wr_opt_to_name(write_option), p) == EOF) { 844 goto out; 845 } 846 /* Display resync option for mirror, if MultiNode set */ 847 if (meta_is_mn_set(sp, ep)) { 848 if (fprintf(fp, dgettext(TEXT_DOMAIN, 849 " Resync option: %s\n"), 850 resync_opt_to_name(tstate)) == EOF) { 851 goto out; 852 } 853 } 854 855 /* success */ 856 rval = 0; 857 858 /* cleanup, return error */ 859 out: 860 if (rval != 0) 861 (void) mdsyserror(ep, errno, fname); 862 return (rval); 863 } 864 865 static char * 866 get_node_name(uint_t nid, md_error_t *ep) 867 { 868 mndiskset_membershiplist_t *nl, *p; 869 int n; 870 char *node_nm; 871 872 /* get the known membership list */ 873 if (meta_read_nodelist(&n, &nl, ep)) { 874 return (NULL); 875 } 876 877 /* find the matching node and return the name */ 878 for (p = nl; (p != NULL); p = p->next) { 879 if (nid == p->msl_node_id) { 880 /* match found */ 881 node_nm = Strdup(p->msl_node_name); 882 goto out; 883 } 884 } 885 886 /* match not found */ 887 node_nm = Strdup(dgettext(TEXT_DOMAIN, "None")); 888 889 out: 890 meta_free_nodelist(nl); 891 return (node_nm); 892 } 893 894 /* 895 * report mirror 896 */ 897 static int 898 mirror_report( 899 mdsetname_t *sp, 900 md_mirror_t *mirrorp, 901 mdnamelist_t **nlpp, 902 char *fname, 903 FILE *fp, 904 mdprtopts_t options, 905 md_error_t *ep 906 ) 907 { 908 md_status_t status = mirrorp->common.state; 909 uint_t smi; 910 char *p; 911 int rval = -1; 912 uint_t tstate = 0; 913 914 /* 915 * check for the -B option. If -B and the metadevice is 916 * a 64 bit device, get the dev for relocation information 917 * printout. If not a 64 bit device, just don't print this 918 * information out but you need to go down to the subdevice 919 * level and print there if appropriate. 920 */ 921 if (options & PRINT_LARGEDEVICES) { 922 if ((mirrorp->common.revision & MD_64BIT_META_DEV) == 0) { 923 for (smi = 0; (smi < NMIRROR); ++smi) { 924 md_submirror_t *mdsp = 925 &mirrorp->submirrors[smi]; 926 mdname_t *submirnamep = 927 mdsp->submirnamep; 928 if (submirnamep == NULL) { 929 continue; 930 } 931 if ((metaismeta(submirnamep)) && 932 (meta_print_name(sp, submirnamep, nlpp, 933 fname, fp, options | PRINT_SUBDEVS, NULL, 934 ep) != 0)) { 935 return (-1); 936 } 937 } 938 rval = 0; 939 goto out; 940 } else { 941 if (meta_getdevs(sp, mirrorp->common.namep, 942 nlpp, ep) != 0) 943 goto out; 944 } 945 } 946 947 /* 948 * check for the -D option. If -D and the name is 949 * a descriptive name, get the dev for relocation information 950 * printout. If not a descriptive name, don't print this 951 * information out but you need to go down to the subdevice 952 * level and print there if appropriate. 953 */ 954 if (options & PRINT_FN) { 955 if ((mirrorp->common.revision & MD_FN_META_DEV) == 0) { 956 for (smi = 0; (smi < NMIRROR); ++smi) { 957 md_submirror_t *mdsp = 958 &mirrorp->submirrors[smi]; 959 mdname_t *submirnamep = 960 mdsp->submirnamep; 961 if (submirnamep == NULL) { 962 continue; 963 } 964 if ((metaismeta(submirnamep)) && 965 (meta_print_name(sp, submirnamep, nlpp, 966 fname, fp, options | PRINT_SUBDEVS, NULL, 967 ep) != 0)) { 968 return (-1); 969 } 970 } 971 rval = 0; 972 goto out; 973 } else { 974 if (meta_getdevs(sp, mirrorp->common.namep, 975 nlpp, ep) != 0) 976 goto out; 977 } 978 } 979 980 /* print header */ 981 if (options & PRINT_HEADER) { 982 if (fprintf(fp, dgettext(TEXT_DOMAIN, "%s: Mirror\n"), 983 mirrorp->common.namep->cname) == EOF) { 984 goto out; 985 } 986 } 987 988 /* print submirrors, adjust status */ 989 for (smi = 0; (smi < NMIRROR); ++smi) { 990 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 991 mdname_t *submirnamep = mdsp->submirnamep; 992 char *sm_state; 993 md_timeval32_t tv; 994 char *timep; 995 996 /* skip unused submirrors */ 997 if (submirnamep == NULL) { 998 assert(mdsp->state == SMS_UNUSED); 999 continue; 1000 } 1001 1002 if (mdsp->state & SMS_OFFLINE) 1003 status &= ~MD_UN_OPT_NOT_DONE; 1004 1005 /* print submirror */ 1006 if (fprintf(fp, dgettext(TEXT_DOMAIN, " Submirror %u: %s\n"), 1007 smi, submirnamep->cname) == EOF) { 1008 goto out; 1009 } 1010 1011 /* print state */ 1012 if (metaismeta(mdsp->submirnamep)) { 1013 if (meta_get_tstate(mdsp->submirnamep->dev, &tstate, 1014 ep) != 0) 1015 return (-1); 1016 } 1017 sm_state = sm_state_to_name(mdsp, status, &tv, 1018 tstate & MD_DEV_ERRORED); 1019 if (options & PRINT_TIMES) { 1020 timep = meta_print_time(&tv); 1021 } else { 1022 timep = ""; 1023 } 1024 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1025 " State: %-12s %s\n"), 1026 sm_state, timep) == EOF) { 1027 goto out; 1028 } 1029 } 1030 1031 /* print resync status */ 1032 if (status & MD_UN_RESYNC_CANCEL) { 1033 /* Resync was cancelled but is restartable */ 1034 if (mirrorp->common.revision & MD_64BIT_META_DEV) { 1035 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1036 " Resync cancelled: %2d.%1d %% done\n"), 1037 mirrorp->percent_done/10, 1038 mirrorp->percent_done%10) == EOF) { 1039 goto out; 1040 } 1041 } else { 1042 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1043 " Resync cancelled: %d %% done\n"), 1044 mirrorp->percent_done) == EOF) { 1045 goto out; 1046 } 1047 } 1048 } else if (status & MD_UN_RESYNC_ACTIVE) { 1049 if (mirrorp->common.revision & MD_64BIT_META_DEV) { 1050 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1051 " Resync in progress: %2d.%1d %% done\n"), 1052 mirrorp->percent_done/10, 1053 mirrorp->percent_done%10) == EOF) { 1054 goto out; 1055 } 1056 } else { 1057 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1058 " Resync in progress: %d %% done\n"), 1059 mirrorp->percent_done) == EOF) { 1060 goto out; 1061 } 1062 } 1063 } 1064 1065 /* print options */ 1066 if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0) 1067 return (-1); 1068 1069 if (meta_print_mirror_options(mirrorp->read_option, 1070 mirrorp->write_option, mirrorp->pass_num, 1071 tstate, fname, sp, fp, ep) != 0) 1072 return (-1); 1073 1074 /* print mirror owner for multi-node metadevice */ 1075 if (meta_is_mn_set(sp, ep)) { 1076 md_set_mmown_params_t ownpar; 1077 mdname_t *mirnp = mirrorp->common.namep; 1078 char *node_name; 1079 1080 (void) memset(&ownpar, 0, sizeof (ownpar)); 1081 ownpar.d.mnum = meta_getminor(mirnp->dev); 1082 MD_SETDRIVERNAME(&ownpar, MD_MIRROR, sp->setno); 1083 1084 if (metaioctl(MD_MN_GET_MM_OWNER, &ownpar, ep, 1085 "MD_MN_GET_MM_OWNER") != 0) { 1086 return (-1); 1087 } 1088 1089 node_name = get_node_name(ownpar.d.owner, ep); 1090 if (node_name == NULL) 1091 return (-1); 1092 else if (fprintf(fp, dgettext(TEXT_DOMAIN, " Owner: %s\n"), 1093 node_name) == EOF) { 1094 Free(node_name); 1095 goto out; 1096 } 1097 Free(node_name); 1098 1099 } 1100 1101 /* print size */ 1102 if (fprintf(fp, dgettext(TEXT_DOMAIN, " Size: %lld blocks (%s)\n"), 1103 mirrorp->common.size, 1104 meta_number_to_string(mirrorp->common.size, DEV_BSIZE)) 1105 == EOF) { 1106 goto out; 1107 } 1108 1109 /* MD_DEBUG stuff */ 1110 if (options & PRINT_DEBUG) { 1111 mdname_t *mirnp = mirrorp->common.namep; 1112 mm_unit_t *mm; 1113 mddb_optloc_t optloc; 1114 uint_t i; 1115 1116 /* get real mirror unit */ 1117 if ((mm = (mm_unit_t *)meta_get_mdunit(sp, mirnp, ep)) 1118 == NULL) { 1119 return (-1); 1120 } 1121 assert(mm->c.un_type == MD_METAMIRROR); 1122 1123 /* print dirty regions */ 1124 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1125 " Regions which are dirty: %d%% (blksize %d num %d)\n"), 1126 mirrorp->percent_dirty, mm->un_rrd_blksize, 1127 mm->un_rrd_num) == EOF) { 1128 Free(mm); 1129 goto out; 1130 } 1131 1132 /* print optimized resync record locations */ 1133 (void) memset(&optloc, 0, sizeof (optloc)); 1134 optloc.recid = mm->un_rr_dirty_recid; 1135 if (metaioctl(MD_DB_GETOPTLOC, &optloc, ep, 1136 "MD_DB_GETOPTLOC") != 0) { 1137 Free(mm); 1138 return (-1); 1139 } 1140 for (i = 0; (i < ((sizeof optloc.li) / sizeof (optloc.li[0]))); 1141 ++i) { 1142 mddb_config_t dbconf; 1143 char *devname; 1144 1145 (void) memset(&dbconf, 0, sizeof (dbconf)); 1146 dbconf.c_id = optloc.li[i]; 1147 dbconf.c_setno = sp->setno; 1148 dbconf.c_subcmd = MDDB_CONFIG_ABS; 1149 /* Don't need device id information from this ioctl */ 1150 dbconf.c_locator.l_devid = (uint64_t)0; 1151 dbconf.c_locator.l_devid_flags = 0; 1152 if (metaioctl(MD_DB_ENDDEV, &dbconf, &dbconf.c_mde, 1153 "MD_DB_ENDDEV") != 0) { 1154 Free(mm); 1155 return (mdstealerror(ep, &dbconf.c_mde)); 1156 } 1157 if ((devname = splicename(&dbconf.c_devname)) 1158 == NULL) { 1159 devname = Strdup(dgettext(TEXT_DOMAIN, 1160 "unknown")); 1161 } 1162 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1163 " Resync record[%u]: %d (%s %d %d)\n"), i, 1164 optloc.li[i], devname, dbconf.c_locator.l_blkno, 1165 (dbconf.c_dbend - dbconf.c_locator.l_blkno + 1)) 1166 == EOF) { 1167 Free(mm); 1168 Free(devname); 1169 goto out; 1170 } 1171 Free(devname); 1172 } 1173 Free(mm); 1174 } 1175 1176 /* print submirror details */ 1177 for (smi = 0; (smi < NMIRROR); ++smi) { 1178 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 1179 mdname_t *submirnamep = mdsp->submirnamep; 1180 char *sm_state; 1181 md_timeval32_t tv; 1182 char *timep; 1183 md_stripe_t *stripep; 1184 1185 /* skip unused submirrors */ 1186 if (submirnamep == NULL) { 1187 assert(mdsp->state == SMS_UNUSED); 1188 continue; 1189 } 1190 1191 if (options & PRINT_FN) { 1192 /* get unit structure */ 1193 if ((stripep = meta_get_stripe_common(sp, submirnamep, 1194 ((options & PRINT_FAST) ? 1 : 0), ep)) == NULL) 1195 goto out; 1196 1197 if ((stripep->common.revision & MD_FN_META_DEV) 1198 == 0) 1199 continue; 1200 } 1201 1202 /* add extra line */ 1203 if (fprintf(fp, "\n") == EOF) 1204 goto out; 1205 1206 /* print submirror */ 1207 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1208 "%s: Submirror of %s\n"), 1209 submirnamep->cname, 1210 mirrorp->common.namep->cname) == EOF) { 1211 goto out; 1212 } 1213 1214 /* print state */ 1215 if (metaismeta(mdsp->submirnamep)) { 1216 if (meta_get_tstate(mdsp->submirnamep->dev, &tstate, ep) 1217 != 0) 1218 return (-1); 1219 } 1220 sm_state = sm_state_to_name(mdsp, status, &tv, NULL); 1221 if (options & PRINT_TIMES) { 1222 timep = meta_print_time(&tv); 1223 } else { 1224 timep = ""; 1225 } 1226 1227 if ((tstate & MD_DEV_ERRORED) == 0) { 1228 if (fprintf(fp, dgettext(TEXT_DOMAIN, 1229 " State: %-12s %s\n"), 1230 sm_state, timep) == EOF) { 1231 goto out; 1232 } 1233 1234 /* print what to do */ 1235 if (sm_state_to_action(sp, mdsp, status, 1236 mirrorp, &p, ep) != 0) 1237 return (-1); 1238 if ((p != NULL) && 1239 (fprintf(fp, dgettext(TEXT_DOMAIN, 1240 " Invoke: %s\n"), p) == EOF)) { 1241 goto out; 1242 } 1243 } 1244 1245 /* print underlying metadevice */ 1246 if ((metaismeta(submirnamep)) && 1247 (meta_print_name(sp, submirnamep, nlpp, fname, fp, 1248 ((options & ~PRINT_HEADER) | PRINT_SUBDEVS), 1249 NULL, ep) != 0)) { 1250 return (-1); 1251 } 1252 } 1253 1254 /* add extra line */ 1255 if (fprintf(fp, "\n") == EOF) 1256 goto out; 1257 1258 /* success */ 1259 rval = 0; 1260 1261 /* cleanup, return error */ 1262 out: 1263 if (rval != 0) 1264 (void) mdsyserror(ep, errno, fname); 1265 return (rval); 1266 } 1267 1268 /* 1269 * print/report mirror 1270 */ 1271 int 1272 meta_mirror_print( 1273 mdsetname_t *sp, 1274 mdname_t *mirnp, 1275 mdnamelist_t **nlpp, 1276 char *fname, 1277 FILE *fp, 1278 mdprtopts_t options, 1279 md_error_t *ep 1280 ) 1281 { 1282 md_mirror_t *mirrorp; 1283 uint_t smi; 1284 1285 /* should have same set */ 1286 assert(sp != NULL); 1287 assert((mirnp == NULL) || 1288 (sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)))); 1289 1290 /* print all mirrors */ 1291 if (mirnp == NULL) { 1292 mdnamelist_t *nlp = NULL; 1293 mdnamelist_t *p; 1294 int cnt; 1295 int rval = 0; 1296 1297 /* get list */ 1298 if ((cnt = meta_get_mirror_names(sp, &nlp, options, ep)) < 0) 1299 return (-1); 1300 else if (cnt == 0) 1301 return (0); 1302 1303 /* recurse */ 1304 for (p = nlp; (p != NULL); p = p->next) { 1305 mdname_t *np = p->namep; 1306 1307 if (meta_mirror_print(sp, np, nlpp, fname, fp, 1308 options, ep) != 0) 1309 rval = -1; 1310 } 1311 1312 /* cleanup, return success */ 1313 metafreenamelist(nlp); 1314 return (rval); 1315 } 1316 1317 /* get unit structure */ 1318 if ((mirrorp = meta_get_mirror_common(sp, mirnp, 1319 ((options & PRINT_FAST) ? 1 : 0), ep)) == NULL) 1320 return (-1); 1321 1322 /* check for parented */ 1323 if ((! (options & PRINT_SUBDEVS)) && 1324 (MD_HAS_PARENT(mirrorp->common.parent))) { 1325 return (0); 1326 } 1327 1328 /* print appropriate detail */ 1329 if (options & PRINT_SHORT) { 1330 /* print mirror */ 1331 if (mirror_print(mirrorp, fname, fp, options, ep) != 0) 1332 return (-1); 1333 1334 /* print underlying metadevices */ 1335 for (smi = 0; (smi < NMIRROR); ++smi) { 1336 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 1337 mdname_t *submirnamep = mdsp->submirnamep; 1338 1339 /* skip unused submirrors */ 1340 if (submirnamep == NULL) { 1341 assert(mdsp->state == SMS_UNUSED); 1342 continue; 1343 } 1344 1345 /* print submirror */ 1346 if (metaismeta(submirnamep)) { 1347 if (meta_print_name(sp, submirnamep, nlpp, 1348 fname, fp, (options | PRINT_SUBDEVS), NULL, 1349 ep) != 0) { 1350 return (-1); 1351 } 1352 } 1353 } 1354 1355 /* return success */ 1356 return (0); 1357 } else { 1358 return (mirror_report(sp, mirrorp, nlpp, fname, fp, 1359 options, ep)); 1360 } 1361 } 1362 1363 /* 1364 * online submirror 1365 */ 1366 int 1367 meta_mirror_online( 1368 mdsetname_t *sp, 1369 mdname_t *mirnp, 1370 mdname_t *submirnp, 1371 mdcmdopts_t options, 1372 md_error_t *ep 1373 ) 1374 { 1375 md_i_off_on_t mio; 1376 md_mirror_t *mirrorp; 1377 md_set_desc *sd; 1378 uint_t tstate; 1379 1380 /* should have same set */ 1381 assert(sp != NULL); 1382 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1383 1384 /* check name */ 1385 if (metachkmeta(mirnp, ep) != 0) 1386 return (-1); 1387 1388 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 1389 return (-1); 1390 1391 /* Only valid for mirror without ABR set */ 1392 if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0) 1393 return (-1); 1394 if (tstate & MD_ABR_CAP) { 1395 (void) mderror(ep, MDE_ABR_SET, NULL); 1396 return (-1); 1397 } 1398 1399 /* 1400 * In a MN set, the master always executes the online command first. 1401 * Before the master executes the IOC_ONLINE ioctl, 1402 * the master sends a message to all nodes to suspend writes to 1403 * this mirror. Then the master executes the IOC_ONLINE ioctl 1404 * which resumes writes to this mirror from the master node. 1405 * As each slave executes the online command, each slave will 1406 * call the IOC_ONLINE ioctl which will resume writes to this mirror 1407 * from that slave node. 1408 */ 1409 if (! metaislocalset(sp)) { 1410 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1411 return (-1); 1412 if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master) 1413 if (meta_mn_send_suspend_writes( 1414 meta_getminor(mirnp->dev), ep) != 0) 1415 return (-1); 1416 } 1417 1418 /* online submirror */ 1419 (void) memset(&mio, 0, sizeof (mio)); 1420 mio.mnum = meta_getminor(mirnp->dev); 1421 MD_SETDRIVERNAME(&mio, MD_MIRROR, sp->setno); 1422 mio.submirror = submirnp->dev; 1423 if (metaioctl(MD_IOCONLINE, &mio, &mio.mde, NULL) != 0) 1424 return (mdstealerror(ep, &mio.mde)); 1425 1426 /* clear cache */ 1427 meta_invalidate_name(mirnp); 1428 meta_invalidate_name(submirnp); 1429 1430 /* let em know */ 1431 if (options & MDCMD_PRINT) { 1432 (void) printf(dgettext(TEXT_DOMAIN, 1433 "%s: submirror %s is onlined\n"), 1434 mirnp->cname, submirnp->cname); 1435 (void) fflush(stdout); 1436 } 1437 1438 /* return success */ 1439 return (0); 1440 } 1441 1442 /* 1443 * offline submirror 1444 */ 1445 int 1446 meta_mirror_offline( 1447 mdsetname_t *sp, 1448 mdname_t *mirnp, 1449 mdname_t *submirnp, 1450 mdcmdopts_t options, 1451 md_error_t *ep 1452 ) 1453 { 1454 int force = ((options & MDCMD_FORCE) ? 1 : 0); 1455 md_i_off_on_t mio; 1456 md_mirror_t *mirrorp; 1457 md_set_desc *sd; 1458 uint_t tstate; 1459 1460 /* should have same set */ 1461 assert(sp != NULL); 1462 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1463 1464 /* check name */ 1465 if (metachkmeta(mirnp, ep) != 0) 1466 return (-1); 1467 1468 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 1469 return (-1); 1470 1471 /* Only valid for mirror without ABR set */ 1472 if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0) 1473 return (-1); 1474 if (tstate & MD_ABR_CAP) { 1475 (void) mderror(ep, MDE_ABR_SET, NULL); 1476 return (-1); 1477 } 1478 1479 /* 1480 * In a MN set, the master always executes the offline command first. 1481 * Before the master executes the IOC_OFFLINE ioctl, 1482 * the master sends a message to all nodes to suspend writes to 1483 * this mirror. Then the master executes the IOC_OFFLINE ioctl 1484 * which resumes writes to this mirror from the master node. 1485 * As each slave executes the offline command, each slave will 1486 * call the IOC_OFFLINE ioctl which will resume writes to this mirror 1487 * from that slave node. 1488 */ 1489 if (! metaislocalset(sp)) { 1490 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1491 return (-1); 1492 if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master) 1493 if (meta_mn_send_suspend_writes( 1494 meta_getminor(mirnp->dev), ep) != 0) 1495 return (-1); 1496 } 1497 1498 /* offline submirror */ 1499 (void) memset(&mio, 0, sizeof (mio)); 1500 mio.mnum = meta_getminor(mirnp->dev); 1501 MD_SETDRIVERNAME(&mio, MD_MIRROR, sp->setno); 1502 mio.submirror = submirnp->dev; 1503 mio.force_offline = force; 1504 if (metaioctl(MD_IOCOFFLINE, &mio, &mio.mde, NULL) != 0) 1505 return (mdstealerror(ep, &mio.mde)); 1506 1507 /* clear cache */ 1508 meta_invalidate_name(mirnp); 1509 meta_invalidate_name(submirnp); 1510 1511 /* let em know */ 1512 if (options & MDCMD_PRINT) { 1513 (void) printf(dgettext(TEXT_DOMAIN, 1514 "%s: submirror %s is offlined\n"), 1515 mirnp->cname, submirnp->cname); 1516 (void) fflush(stdout); 1517 } 1518 1519 /* return success */ 1520 return (0); 1521 } 1522 1523 /* 1524 * attach submirror to mirror 1525 * we actually never have to worry about crossing a thresh hold here. 1526 * 2 cases 1) attach and the only way the mirror can be 64 bit is if 1527 * one of the submirrors already is. 2) grow and the only way the mirror 1528 * is 64 bit is if one of the submirror's already is. 1529 */ 1530 int 1531 meta_mirror_attach( 1532 mdsetname_t *sp, 1533 mdname_t *mirnp, 1534 mdname_t *submirnp, 1535 mdcmdopts_t options, 1536 md_error_t *ep 1537 ) 1538 { 1539 md_att_struct_t att; 1540 md_set_desc *sd; 1541 1542 /* should have same set */ 1543 assert(sp != NULL); 1544 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1545 1546 /* check name */ 1547 if (metachkmeta(mirnp, ep) != 0) 1548 return (-1); 1549 1550 /* just grow */ 1551 if (submirnp == NULL) { 1552 return (meta_concat_generic(sp, mirnp, NULL, ep)); 1553 } 1554 1555 /* check submirror */ 1556 if (meta_check_submirror(sp, submirnp, mirnp, 0, ep) != 0) 1557 return (-1); 1558 1559 /* In dryrun mode (DOIT not set) we must not alter the mddb */ 1560 if (options & MDCMD_DOIT) { 1561 /* store name in namespace */ 1562 if (add_key_name(sp, submirnp, NULL, ep) != 0) 1563 return (-1); 1564 } 1565 1566 /* 1567 * In a MN set, the master always executes the attach command first. 1568 * Before the master executes the IOC_ATTACH ioctl, in non-DRYRUN mode 1569 * the master sends a message to all nodes to suspend writes to 1570 * this mirror. Then the master executes the IOC_ATTACH ioctl 1571 * which resumes writes to this mirror from the master node. 1572 * As each slave executes the attach command, each slave will 1573 * call the IOC_ATTACH ioctl which will resume writes to this mirror 1574 * from that slave node. 1575 */ 1576 if (! metaislocalset(sp)) { 1577 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1578 return (-1); 1579 if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) && 1580 sd->sd_mn_am_i_master) 1581 if (meta_mn_send_suspend_writes( 1582 meta_getminor(mirnp->dev), ep) != 0) 1583 return (-1); 1584 } 1585 1586 /* attach submirror */ 1587 (void) memset(&att, 0, sizeof (att)); 1588 att.mnum = meta_getminor(mirnp->dev); 1589 MD_SETDRIVERNAME(&att, MD_MIRROR, sp->setno); 1590 att.submirror = submirnp->dev; 1591 att.key = submirnp->key; 1592 /* if the comamnd was issued with -n option, use dryrun mode */ 1593 if ((options & MDCMD_DOIT) == 0) { 1594 att.options = MDIOCTL_DRYRUN; 1595 } 1596 if (metaioctl(MD_IOCATTACH, &att, &att.mde, NULL) != 0) { 1597 /* In dryrun mode (DOIT not set) we must not alter the mddb */ 1598 if (options & MDCMD_DOIT) { 1599 (void) del_key_name(sp, submirnp, ep); 1600 } 1601 return (mdstealerror(ep, &att.mde)); 1602 } 1603 1604 /* In dryrun mode (DOIT not set) we must not alter the mddb */ 1605 if (options & MDCMD_DOIT) { 1606 /* clear cache */ 1607 meta_invalidate_name(mirnp); 1608 meta_invalidate_name(submirnp); 1609 } 1610 1611 /* let em know */ 1612 if (options & MDCMD_PRINT) { 1613 (void) printf(dgettext(TEXT_DOMAIN, 1614 "%s: submirror %s %s\n"), mirnp->cname, submirnp->cname, 1615 (options & MDCMD_DOIT) ? "is attached" : "would attach"); 1616 (void) fflush(stdout); 1617 } 1618 1619 /* return success */ 1620 return (0); 1621 } 1622 1623 /* 1624 * detach submirror 1625 */ 1626 int 1627 meta_mirror_detach( 1628 mdsetname_t *sp, 1629 mdname_t *mirnp, 1630 mdname_t *submirnp, 1631 mdcmdopts_t options, 1632 md_error_t *ep 1633 ) 1634 { 1635 int force = ((options & MDCMD_FORCE) ? 1 : 0); 1636 md_detach_params_t detach; 1637 md_set_desc *sd; 1638 1639 /* should have same set */ 1640 assert(sp != NULL); 1641 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1642 1643 /* check name */ 1644 if (metachkmeta(mirnp, ep) != 0) 1645 return (-1); 1646 1647 /* 1648 * In a MN set, the master always executes the detach command first. 1649 * Before the master executes the IOC_DETACH ioctl, 1650 * the master sends a message to all nodes to suspend writes to 1651 * this mirror. Then the master executes the IOC_DETACH ioctl 1652 * which resumes writes to this mirror from the master node. 1653 * As each slave executes the detach command, each slave will 1654 * call the IOC_DETACH ioctl which will resume writes to this mirror 1655 * from that slave node. 1656 */ 1657 if (! metaislocalset(sp)) { 1658 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1659 return (-1); 1660 if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master) 1661 if (meta_mn_send_suspend_writes( 1662 meta_getminor(mirnp->dev), ep) != 0) 1663 return (-1); 1664 } 1665 1666 /* detach submirror */ 1667 (void) memset(&detach, 0, sizeof (detach)); 1668 detach.mnum = meta_getminor(mirnp->dev); 1669 MD_SETDRIVERNAME(&detach, MD_MIRROR, sp->setno); 1670 detach.submirror = submirnp->dev; 1671 detach.force_detach = force; 1672 if (metaioctl(MD_IOCDETACH, &detach, &detach.mde, NULL) != 0) 1673 return (mdstealerror(ep, &detach.mde)); 1674 1675 /* clear cache */ 1676 meta_invalidate_name(mirnp); 1677 meta_invalidate_name(submirnp); 1678 1679 /* let em know */ 1680 if (options & MDCMD_PRINT) { 1681 (void) printf(dgettext(TEXT_DOMAIN, 1682 "%s: submirror %s is detached\n"), 1683 mirnp->cname, submirnp->cname); 1684 (void) fflush(stdout); 1685 } 1686 1687 /* return success */ 1688 return (0); 1689 } 1690 1691 /* 1692 * get mirror parameters 1693 */ 1694 int 1695 meta_mirror_get_params( 1696 mdsetname_t *sp, 1697 mdname_t *mirnp, 1698 mm_params_t *paramsp, 1699 md_error_t *ep 1700 ) 1701 { 1702 md_mirror_t *mirrorp; 1703 1704 /* should have a set */ 1705 assert(sp != NULL); 1706 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1707 1708 /* check name */ 1709 if (metachkmeta(mirnp, ep) != 0) 1710 return (-1); 1711 1712 /* get unit */ 1713 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 1714 return (-1); 1715 1716 /* return parameters */ 1717 (void) memset(paramsp, 0, sizeof (*paramsp)); 1718 paramsp->read_option = mirrorp->read_option; 1719 paramsp->write_option = mirrorp->write_option; 1720 paramsp->pass_num = mirrorp->pass_num; 1721 return (0); 1722 } 1723 1724 /* 1725 * set mirror parameters 1726 */ 1727 int 1728 meta_mirror_set_params( 1729 mdsetname_t *sp, 1730 mdname_t *mirnp, 1731 mm_params_t *paramsp, 1732 md_error_t *ep 1733 ) 1734 { 1735 md_mirror_params_t mmp; 1736 1737 /* should have a set */ 1738 assert(sp != NULL); 1739 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1740 1741 /* check name */ 1742 if (metachkmeta(mirnp, ep) != 0) 1743 return (-1); 1744 1745 /* set parameters */ 1746 (void) memset(&mmp, 0, sizeof (mmp)); 1747 MD_SETDRIVERNAME(&mmp, MD_MIRROR, sp->setno); 1748 mmp.mnum = meta_getminor(mirnp->dev); 1749 mmp.params = *paramsp; 1750 if (metaioctl(MD_IOCCHANGE, &mmp, &mmp.mde, mirnp->cname) != 0) 1751 return (mdstealerror(ep, &mmp.mde)); 1752 1753 /* clear cache */ 1754 meta_invalidate_name(mirnp); 1755 1756 /* return success */ 1757 return (0); 1758 } 1759 1760 /* 1761 * invalidate submirror names 1762 */ 1763 static int 1764 invalidate_submirrors( 1765 mdsetname_t *sp, 1766 mdname_t *mirnp, 1767 md_error_t *ep 1768 ) 1769 { 1770 md_mirror_t *mirrorp; 1771 uint_t smi; 1772 1773 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 1774 return (-1); 1775 for (smi = 0; (smi < NMIRROR); ++smi) { 1776 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 1777 mdname_t *submirnp = mdsp->submirnamep; 1778 1779 if (submirnp == NULL) { 1780 assert(mdsp->state == SMS_UNUSED); 1781 continue; 1782 } 1783 meta_invalidate_name(submirnp); 1784 } 1785 return (0); 1786 } 1787 1788 /* 1789 * replace mirror component 1790 */ 1791 int 1792 meta_mirror_replace( 1793 mdsetname_t *sp, 1794 mdname_t *mirnp, 1795 mdname_t *oldnp, 1796 mdname_t *newnp, 1797 mdcmdopts_t options, 1798 md_error_t *ep 1799 ) 1800 { 1801 md_mirror_t *mirrorp; 1802 uint_t smi; 1803 replace_params_t params; 1804 diskaddr_t size, label, start_blk; 1805 md_dev64_t old_dev, new_dev; 1806 diskaddr_t new_start_blk, new_end_blk; 1807 int rebind; 1808 md_set_desc *sd; 1809 char *new_devidp = NULL; 1810 int ret; 1811 md_error_t xep = mdnullerror; 1812 1813 /* should have same set */ 1814 assert(sp != NULL); 1815 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 1816 1817 /* check name */ 1818 if (metachkmeta(mirnp, ep) != 0) 1819 return (-1); 1820 1821 /* save new binding incase this is a rebind where oldnp==newnp */ 1822 new_dev = newnp->dev; 1823 new_start_blk = newnp->start_blk; 1824 new_end_blk = newnp->end_blk; 1825 1826 /* invalidate, then get the mirror (fill in oldnp from metadb) */ 1827 meta_invalidate_name(mirnp); 1828 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 1829 return (-1); 1830 for (smi = 0; (smi < NMIRROR); ++smi) { 1831 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 1832 mdname_t *submirnp = mdsp->submirnamep; 1833 1834 if (submirnp == NULL) { 1835 assert(mdsp->state == SMS_UNUSED); 1836 continue; 1837 } 1838 1839 if (! metaismeta(submirnp)) 1840 continue; 1841 1842 meta_invalidate_name(submirnp); 1843 if (meta_get_unit(sp, submirnp, ep) == NULL) 1844 return (-1); 1845 } 1846 1847 /* the old device binding is now established */ 1848 if ((old_dev = oldnp->dev) == NODEV64) 1849 return (mdsyserror(ep, ENODEV, oldnp->cname)); 1850 1851 /* 1852 * check for the case where oldnp and newnp indicate the same 1853 * device, but the dev_t of the device has changed between old 1854 * and new. This is called a rebind. On entry the dev_t 1855 * represents the new device binding determined from the 1856 * filesystem (meta_getdev). After calling meta_get_unit 1857 * oldnp (and maybe newnp if this is a rebind) is updated based 1858 * to the old binding from the metadb (done by metakeyname). 1859 */ 1860 if ((strcmp(oldnp->rname, newnp->rname) == 0) && 1861 (old_dev != new_dev)) { 1862 rebind = 1; 1863 } else { 1864 rebind = 0; 1865 } 1866 if (rebind) { 1867 newnp->dev = new_dev; 1868 newnp->start_blk = new_start_blk; 1869 newnp->end_blk = new_end_blk; 1870 } 1871 1872 /* 1873 * Save a copy of the devid associated with the new disk, the reason 1874 * is that if we are rebinding then the call to meta_check_component() 1875 * will cause the devid of the disk to be overwritten with what is in 1876 * the replica namespace. The function that actually overwrites the 1877 * devid is dr2drivedesc(). 1878 */ 1879 if (newnp->drivenamep->devid != NULL) 1880 new_devidp = Strdup(newnp->drivenamep->devid); 1881 1882 /* if it's a multi-node diskset clear new_devidp */ 1883 if (!metaislocalset(sp)) { 1884 if ((sd = metaget_setdesc(sp, ep)) == NULL) 1885 return (-1); 1886 if (MD_MNSET_DESC(sd)) 1887 new_devidp = NULL; 1888 } 1889 1890 /* check it out (dup on rebind is ok) */ 1891 if (meta_check_component(sp, newnp, 0, ep) != 0) { 1892 if ((! rebind) || (! mdisuseerror(ep, MDE_ALREADY))) { 1893 Free(new_devidp); 1894 return (-1); 1895 } 1896 mdclrerror(ep); 1897 } 1898 if ((size = metagetsize(newnp, ep)) == MD_DISKADDR_ERROR) { 1899 Free(new_devidp); 1900 return (-1); 1901 } 1902 if ((label = metagetlabel(newnp, ep)) == MD_DISKADDR_ERROR) { 1903 Free(new_devidp); 1904 return (-1); 1905 } 1906 if ((start_blk = metagetstart(sp, newnp, ep)) == MD_DISKADDR_ERROR) { 1907 Free(new_devidp); 1908 return (-1); 1909 } 1910 if (start_blk >= size) { 1911 (void) mdsyserror(ep, ENOSPC, newnp->cname); 1912 Free(new_devidp); 1913 return (-1); 1914 } 1915 1916 /* 1917 * Copy back the saved devid. 1918 */ 1919 Free(newnp->drivenamep->devid); 1920 if (new_devidp != NULL) { 1921 newnp->drivenamep->devid = Strdup(new_devidp); 1922 Free(new_devidp); 1923 } 1924 1925 /* store name in namespace, allocate new key */ 1926 if (add_key_name(sp, newnp, NULL, ep) != 0) 1927 return (-1); 1928 1929 /* 1930 * In a MN set, the master always executes the replace command first. 1931 * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode 1932 * the master sends a message to all nodes to suspend writes to 1933 * this mirror. Then the master executes the IOC_REPLACE ioctl 1934 * which resumes writes to this mirror from the master node. 1935 * As each slave executes the replace command, each slave will 1936 * call the IOC_REPLACE ioctl which will resume writes to this mirror 1937 * from that slave node. 1938 */ 1939 if (! metaislocalset(sp)) { 1940 if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) && 1941 sd->sd_mn_am_i_master) 1942 if (meta_mn_send_suspend_writes( 1943 meta_getminor(mirnp->dev), ep) != 0) 1944 return (-1); 1945 } 1946 1947 if (rebind && !metaislocalset(sp)) { 1948 /* 1949 * We are 'rebind'ing a disk that is in a diskset so as well 1950 * as updating the diskset's namespace the local set needs 1951 * to be updated because it also contains a reference to 1952 * the disk in question. 1953 */ 1954 ret = meta_fixdevid(sp, DEV_UPDATE|DEV_LOCAL_SET, 1955 newnp->cname, ep); 1956 1957 if (ret != METADEVADM_SUCCESS) { 1958 (void) del_key_name(sp, newnp, &xep); 1959 return (-1); 1960 } 1961 } 1962 1963 /* replace component */ 1964 (void) memset(¶ms, 0, sizeof (params)); 1965 params.mnum = meta_getminor(mirnp->dev); 1966 MD_SETDRIVERNAME(¶ms, MD_MIRROR, sp->setno); 1967 params.cmd = REPLACE_COMP; 1968 params.old_dev = old_dev; 1969 params.new_dev = new_dev; 1970 params.start_blk = start_blk; 1971 params.has_label = ((label > 0) ? 1 : 0); 1972 params.number_blks = size; 1973 params.new_key = newnp->key; 1974 /* Is this just a dryrun ? */ 1975 if ((options & MDCMD_DOIT) == 0) { 1976 params.options |= MDIOCTL_DRYRUN; 1977 } 1978 if (metaioctl(MD_IOCREPLACE, ¶ms, ¶ms.mde, NULL) != 0) { 1979 (void) del_key_name(sp, newnp, ep); 1980 return (mdstealerror(ep, ¶ms.mde)); 1981 } 1982 1983 /* clear cache */ 1984 meta_invalidate_name(oldnp); 1985 meta_invalidate_name(newnp); 1986 if (invalidate_submirrors(sp, mirnp, ep) != 0) { 1987 meta_invalidate_name(mirnp); 1988 return (-1); 1989 } 1990 meta_invalidate_name(mirnp); 1991 1992 /* let em know */ 1993 if (options & MDCMD_PRINT) { 1994 (void) printf(dgettext(TEXT_DOMAIN, 1995 "%s: device %s is replaced with %s\n"), 1996 mirnp->cname, oldnp->cname, newnp->cname); 1997 (void) fflush(stdout); 1998 } 1999 2000 /* return success */ 2001 return (0); 2002 } 2003 2004 /* 2005 * enable mirror component 2006 */ 2007 int 2008 meta_mirror_enable( 2009 mdsetname_t *sp, 2010 mdname_t *mirnp, 2011 mdname_t *compnp, 2012 mdcmdopts_t options, 2013 md_error_t *ep 2014 ) 2015 { 2016 md_mirror_t *mirrorp; 2017 uint_t smi; 2018 replace_params_t params; 2019 diskaddr_t size, label, start_blk; 2020 md_dev64_t fs_dev; 2021 md_set_desc *sd; 2022 int ret; 2023 2024 /* should have same set */ 2025 assert(sp != NULL); 2026 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))); 2027 2028 /* check name */ 2029 if (metachkmeta(mirnp, ep) != 0) 2030 return (-1); 2031 2032 /* get the file_system dev binding */ 2033 if (meta_getdev(sp, compnp, ep) != 0) 2034 return (-1); 2035 fs_dev = compnp->dev; 2036 2037 /* get the mirror unit (fill in compnp->dev with metadb version) */ 2038 meta_invalidate_name(mirnp); 2039 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 2040 return (-1); 2041 2042 for (smi = 0; (smi < NMIRROR); ++smi) { 2043 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2044 mdname_t *submirnp = mdsp->submirnamep; 2045 2046 if (submirnp == NULL) { 2047 assert(mdsp->state == SMS_UNUSED); 2048 continue; 2049 } 2050 2051 if (! metaismeta(submirnp)) 2052 continue; 2053 2054 meta_invalidate_name(submirnp); 2055 if (meta_get_unit(sp, submirnp, ep) == NULL) 2056 return (-1); 2057 } 2058 2059 /* the metadb device binding is now established */ 2060 if (compnp->dev == NODEV64) 2061 return (mdsyserror(ep, ENODEV, compnp->cname)); 2062 2063 /* 2064 * check for the case where the dev_t has changed between the 2065 * filesystem and the metadb. This is called a rebind, and 2066 * is handled by meta_mirror_replace. 2067 */ 2068 if (fs_dev != compnp->dev) { 2069 /* establish file system binding with invalid start/end */ 2070 compnp->dev = fs_dev; 2071 compnp->start_blk = -1; 2072 compnp->end_blk = -1; 2073 return (meta_mirror_replace(sp, mirnp, 2074 compnp, compnp, options, ep)); 2075 } 2076 2077 /* setup mirror info */ 2078 (void) memset(¶ms, 0, sizeof (params)); 2079 params.mnum = meta_getminor(mirnp->dev); 2080 MD_SETDRIVERNAME(¶ms, MD_MIRROR, sp->setno); 2081 params.cmd = ENABLE_COMP; 2082 2083 /* check it out */ 2084 if (meta_check_component(sp, compnp, 0, ep) != 0) { 2085 if (! mdisuseerror(ep, MDE_ALREADY)) 2086 return (-1); 2087 mdclrerror(ep); 2088 } 2089 2090 if ((size = metagetsize(compnp, ep)) == MD_DISKADDR_ERROR) 2091 return (-1); 2092 if ((label = metagetlabel(compnp, ep)) == MD_DISKADDR_ERROR) 2093 return (-1); 2094 if ((start_blk = metagetstart(sp, compnp, ep)) == MD_DISKADDR_ERROR) 2095 return (-1); 2096 if (start_blk >= size) { 2097 (void) mdsyserror(ep, ENOSPC, compnp->cname); 2098 return (-1); 2099 } 2100 2101 /* 2102 * In a MN set, the master always executes the replace command first. 2103 * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode 2104 * the master sends a message to all nodes to suspend writes to 2105 * this mirror. Then the master executes the IOC_REPLACE ioctl 2106 * which resumes writes to this mirror from the master node. 2107 * As each slave executes the replace command, each slave will 2108 * call the IOC_REPLACE ioctl which will resume writes to this mirror 2109 * from that slave node. 2110 */ 2111 if (! metaislocalset(sp)) { 2112 if ((sd = metaget_setdesc(sp, ep)) == NULL) 2113 return (-1); 2114 if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) && 2115 sd->sd_mn_am_i_master) 2116 if (meta_mn_send_suspend_writes( 2117 meta_getminor(mirnp->dev), ep) != 0) 2118 return (-1); 2119 } 2120 2121 /* enable component */ 2122 params.old_dev = compnp->dev; 2123 params.new_dev = compnp->dev; 2124 params.start_blk = start_blk; 2125 params.has_label = ((label > 0) ? 1 : 0); 2126 params.number_blks = size; 2127 2128 /* Is this just a dryrun ? */ 2129 if ((options & MDCMD_DOIT) == 0) { 2130 params.options |= MDIOCTL_DRYRUN; 2131 } 2132 if (metaioctl(MD_IOCREPLACE, ¶ms, ¶ms.mde, NULL) != 0) 2133 return (mdstealerror(ep, ¶ms.mde)); 2134 2135 /* 2136 * Are we dealing with a non-local set? If so need to update the 2137 * local namespace so that the disk record has the correct devid. 2138 */ 2139 if (!metaislocalset(sp)) { 2140 ret = meta_fixdevid(sp, DEV_UPDATE|DEV_LOCAL_SET, compnp->cname, 2141 ep); 2142 2143 if (ret != METADEVADM_SUCCESS) { 2144 /* 2145 * Failed to update the local set. Nothing to do here 2146 * apart from report the error. The namespace is 2147 * most likely broken and some form of remedial 2148 * recovery is going to be required. 2149 */ 2150 mde_perror(ep, ""); 2151 mdclrerror(ep); 2152 } 2153 } 2154 2155 /* clear cache */ 2156 meta_invalidate_name(compnp); 2157 if (invalidate_submirrors(sp, mirnp, ep) != 0) { 2158 meta_invalidate_name(mirnp); 2159 return (-1); 2160 } 2161 meta_invalidate_name(mirnp); 2162 2163 /* let em know */ 2164 if (options & MDCMD_PRINT) { 2165 (void) printf(dgettext(TEXT_DOMAIN, 2166 "%s: device %s is enabled\n"), 2167 mirnp->cname, compnp->cname); 2168 (void) fflush(stdout); 2169 } 2170 2171 /* return success */ 2172 return (0); 2173 } 2174 2175 /* 2176 * check for dups in the mirror itself 2177 */ 2178 static int 2179 check_twice( 2180 md_mirror_t *mirrorp, 2181 uint_t smi, 2182 md_error_t *ep 2183 ) 2184 { 2185 mdname_t *mirnp = mirrorp->common.namep; 2186 mdname_t *thisnp; 2187 uint_t s; 2188 2189 thisnp = mirrorp->submirrors[smi].submirnamep; 2190 for (s = 0; (s < smi); ++s) { 2191 md_submirror_t *mdsp = &mirrorp->submirrors[s]; 2192 mdname_t *submirnp = mdsp->submirnamep; 2193 2194 if (submirnp == NULL) 2195 continue; 2196 2197 if (meta_check_overlap(mirnp->cname, thisnp, 0, -1, 2198 submirnp, 0, -1, ep) != 0) { 2199 return (-1); 2200 } 2201 } 2202 return (0); 2203 } 2204 2205 /* 2206 * check mirror 2207 */ 2208 int 2209 meta_check_mirror( 2210 mdsetname_t *sp, 2211 md_mirror_t *mirrorp, 2212 mdcmdopts_t options, 2213 md_error_t *ep 2214 ) 2215 { 2216 mdname_t *mirnp = mirrorp->common.namep; 2217 int force = ((options & MDCMD_FORCE) ? 1 : 0); 2218 int doit = ((options & MDCMD_DOIT) ? 1 : 0); 2219 uint_t nsm = 0; 2220 uint_t smi; 2221 2222 /* check submirrors */ 2223 for (smi = 0; (smi < NMIRROR); ++smi) { 2224 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2225 mdname_t *submirnp = mdsp->submirnamep; 2226 2227 if (submirnp == NULL) 2228 continue; 2229 ++nsm; 2230 } 2231 if (nsm < 1) { 2232 return (mdmderror(ep, MDE_BAD_MIRROR, 2233 meta_getminor(mirnp->dev), mirnp->cname)); 2234 } 2235 for (smi = 0; (smi < NMIRROR); ++smi) { 2236 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2237 mdname_t *submirnp = mdsp->submirnamep; 2238 diskaddr_t size; 2239 2240 /* skip unused submirrors */ 2241 if (submirnp == NULL) { 2242 if (mdsp->state != SMS_UNUSED) { 2243 return (mdmderror(ep, MDE_BAD_MIRROR, 2244 meta_getminor(mirnp->dev), mirnp->cname)); 2245 } 2246 continue; 2247 } 2248 2249 /* check submirror */ 2250 if (doit) { 2251 if (meta_check_submirror(sp, submirnp, NULL, force, 2252 ep) != 0) 2253 return (-1); 2254 if ((size = metagetsize(submirnp, ep)) == 2255 MD_DISKADDR_ERROR) { 2256 return (-1); 2257 } else if (size == 0) { 2258 return (mdsyserror(ep, ENOSPC, 2259 submirnp->cname)); 2260 } 2261 } 2262 2263 /* check this mirror too */ 2264 if (check_twice(mirrorp, smi, ep) != 0) 2265 return (-1); 2266 } 2267 2268 /* check read option */ 2269 switch (mirrorp->read_option) { 2270 case RD_LOAD_BAL: 2271 case RD_GEOMETRY: 2272 case RD_FIRST: 2273 break; 2274 default: 2275 return (mderror(ep, MDE_BAD_RD_OPT, mirnp->cname)); 2276 } 2277 2278 /* check write option */ 2279 switch (mirrorp->write_option) { 2280 case WR_PARALLEL: 2281 case WR_SERIAL: 2282 break; 2283 default: 2284 return (mderror(ep, MDE_BAD_WR_OPT, mirnp->cname)); 2285 } 2286 2287 /* check pass number */ 2288 if ((mirrorp->pass_num < 0) || (mirrorp->pass_num > MD_PASS_MAX)) 2289 return (mderror(ep, MDE_BAD_PASS_NUM, mirnp->cname)); 2290 2291 /* return success */ 2292 return (0); 2293 } 2294 2295 /* 2296 * setup mirror geometry 2297 */ 2298 static int 2299 mirror_geom( 2300 md_mirror_t *mirrorp, 2301 mm_unit_t *mm, 2302 md_error_t *ep 2303 ) 2304 { 2305 uint_t write_reinstruct = 0; 2306 uint_t read_reinstruct = 0; 2307 uint_t round_cyl = 1; 2308 mdname_t *smnp = NULL; 2309 uint_t smi; 2310 mdgeom_t *geomp; 2311 2312 /* get worst reinstructs */ 2313 for (smi = 0; (smi < NMIRROR); ++smi) { 2314 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2315 mdname_t *submirnp = mdsp->submirnamep; 2316 2317 if (submirnp == NULL) 2318 continue; 2319 2320 if ((geomp = metagetgeom(submirnp, ep)) == NULL) 2321 return (-1); 2322 if (geomp->write_reinstruct > write_reinstruct) 2323 write_reinstruct = geomp->write_reinstruct; 2324 if (geomp->read_reinstruct > read_reinstruct) 2325 read_reinstruct = geomp->read_reinstruct; 2326 2327 if (smnp == NULL) 2328 smnp = submirnp; 2329 } 2330 2331 /* setup geometry from first submirror */ 2332 assert(smnp != NULL); 2333 if ((geomp = metagetgeom(smnp, ep)) == NULL) 2334 return (-1); 2335 if (meta_setup_geom((md_unit_t *)mm, mirrorp->common.namep, geomp, 2336 write_reinstruct, read_reinstruct, round_cyl, ep) != 0) 2337 return (-1); 2338 2339 /* return success */ 2340 return (0); 2341 } 2342 2343 /* 2344 * create mirror 2345 */ 2346 int 2347 meta_create_mirror( 2348 mdsetname_t *sp, 2349 md_mirror_t *mirrorp, 2350 mdcmdopts_t options, 2351 md_error_t *ep 2352 ) 2353 { 2354 mdname_t *mirnp = mirrorp->common.namep; 2355 mm_unit_t *mm; 2356 diskaddr_t submir_size = MD_DISKADDR_ERROR; 2357 ushort_t nsm = 0; 2358 uint_t smi; 2359 mdnamelist_t *keynlp = NULL; 2360 md_set_params_t set_params; 2361 int rval = -1; 2362 md_timeval32_t creation_time; 2363 int create_flag = MD_CRO_32BIT; 2364 2365 /* validate mirror */ 2366 if (meta_check_mirror(sp, mirrorp, options, ep) != 0) 2367 return (-1); 2368 2369 2370 /* allocate mirror unit */ 2371 mm = Zalloc(sizeof (*mm)); 2372 2373 if (meta_gettimeofday(&creation_time) == -1) 2374 return (mdsyserror(ep, errno, NULL)); 2375 2376 /* do submirrors */ 2377 for (smi = 0; (smi < NMIRROR); ++smi) { 2378 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2379 mdname_t *submirnp = mdsp->submirnamep; 2380 mm_submirror_t *mmsp = &mm->un_sm[smi]; 2381 diskaddr_t size; 2382 2383 /* skip unused submirrors */ 2384 if (submirnp == NULL) { 2385 assert(mdsp->state == SMS_UNUSED); 2386 continue; 2387 } 2388 ++nsm; 2389 2390 /* get size */ 2391 if ((size = metagetsize(submirnp, ep)) == MD_DISKADDR_ERROR) 2392 goto out; 2393 assert(size > 0); 2394 2395 /* adjust for smallest submirror */ 2396 if (submir_size == MD_DISKADDR_ERROR) { 2397 submir_size = size; 2398 } else if (size < submir_size) { 2399 submir_size = size; 2400 } 2401 2402 if (options & MDCMD_DOIT) { 2403 /* store name in namespace */ 2404 if (add_key_name(sp, submirnp, &keynlp, ep) != 0) 2405 goto out; 2406 } 2407 2408 /* setup submirror */ 2409 mmsp->sm_key = submirnp->key; 2410 mmsp->sm_dev = submirnp->dev; 2411 mmsp->sm_state = SMS_RUNNING; 2412 mmsp->sm_timestamp = creation_time; 2413 } 2414 2415 /* setup unit */ 2416 mm->c.un_type = MD_METAMIRROR; 2417 MD_SID(mm) = meta_getminor(mirnp->dev); 2418 mm->c.un_actual_tb = submir_size; 2419 mm->c.un_size = offsetof(mm_unit_t, un_smic); 2420 mm->un_nsm = nsm; 2421 mm->un_read_option = mirrorp->read_option; 2422 mm->un_write_option = mirrorp->write_option; 2423 mm->un_pass_num = mirrorp->pass_num; 2424 if (mirror_geom(mirrorp, mm, ep) != 0) 2425 goto out; 2426 2427 /* fill in the size of the mirror */ 2428 if (options & MDCMD_UPDATE) { 2429 mirrorp->common.size = mm->c.un_total_blocks; 2430 } 2431 2432 /* if we're not doing anything, return success */ 2433 if (! (options & MDCMD_DOIT)) { 2434 rval = 0; /* success */ 2435 goto out; 2436 } 2437 2438 /* create mirror */ 2439 (void) memset(&set_params, 0, sizeof (set_params)); 2440 /* did the user tell us to generate a large device? */ 2441 create_flag = meta_check_devicesize(mm->c.un_total_blocks); 2442 if (create_flag == MD_CRO_64BIT) { 2443 mm->c.un_revision |= MD_64BIT_META_DEV; 2444 set_params.options = MD_CRO_64BIT; 2445 } else { 2446 mm->c.un_revision &= ~MD_64BIT_META_DEV; 2447 set_params.options = MD_CRO_32BIT; 2448 } 2449 set_params.mnum = MD_SID(mm); 2450 set_params.size = mm->c.un_size; 2451 set_params.mdp = (uintptr_t)mm; 2452 MD_SETDRIVERNAME(&set_params, MD_MIRROR, MD_MIN2SET(set_params.mnum)); 2453 if (metaioctl(MD_IOCSET, &set_params, &set_params.mde, 2454 mirnp->cname) != 0) { 2455 (void) mdstealerror(ep, &set_params.mde); 2456 goto out; 2457 } 2458 rval = 0; /* success */ 2459 2460 /* cleanup, return success */ 2461 out: 2462 Free(mm); 2463 if (rval != 0) { 2464 (void) del_key_names(sp, keynlp, NULL); 2465 } 2466 metafreenamelist(keynlp); 2467 if ((rval == 0) && (options & MDCMD_DOIT)) { 2468 if (invalidate_submirrors(sp, mirnp, ep) != 0) 2469 rval = -1; 2470 meta_invalidate_name(mirnp); 2471 } 2472 return (rval); 2473 } 2474 2475 /* 2476 * initialize mirror 2477 * NOTE: this functions is metainit(1m)'s command line parser! 2478 */ 2479 int 2480 meta_init_mirror( 2481 mdsetname_t **spp, 2482 int argc, 2483 char *argv[], 2484 mdcmdopts_t options, 2485 md_error_t *ep 2486 ) 2487 { 2488 char *uname = argv[0]; 2489 mdname_t *mirnp = NULL; 2490 int old_optind; 2491 int c; 2492 md_mirror_t *mirrorp = NULL; 2493 uint_t smi; 2494 int rval = -1; 2495 2496 /* get mirror name */ 2497 assert(argc > 0); 2498 if (argc < 1) 2499 goto syntax; 2500 if ((mirnp = metaname(spp, uname, META_DEVICE, ep)) == NULL) 2501 goto out; 2502 assert(*spp != NULL); 2503 uname = mirnp->cname; 2504 if (metachkmeta(mirnp, ep) != 0) 2505 goto out; 2506 2507 if (!(options & MDCMD_NOLOCK)) { 2508 /* grab set lock */ 2509 if (meta_lock(*spp, TRUE, ep) != 0) 2510 goto out; 2511 2512 if (meta_check_ownership(*spp, ep) != 0) 2513 goto out; 2514 } 2515 2516 /* see if it exists already */ 2517 if (metagetmiscname(mirnp, ep) != NULL) { 2518 (void) mdmderror(ep, MDE_UNIT_ALREADY_SETUP, 2519 meta_getminor(mirnp->dev), uname); 2520 goto out; 2521 } else if (! mdismderror(ep, MDE_UNIT_NOT_SETUP)) { 2522 goto out; 2523 } else { 2524 mdclrerror(ep); 2525 } 2526 --argc, ++argv; 2527 2528 /* grab -m */ 2529 if ((argc < 1) || (strcmp(argv[0], "-m") != 0)) 2530 goto syntax; 2531 --argc, ++argv; 2532 2533 if (argc == 0) 2534 goto syntax; 2535 2536 /* parse general options */ 2537 optind = 0; 2538 opterr = 0; 2539 if (getopt(argc, argv, "") != -1) 2540 goto options; 2541 2542 /* allocate mirror */ 2543 mirrorp = Zalloc(sizeof (*mirrorp)); 2544 2545 /* setup common */ 2546 mirrorp->common.namep = mirnp; 2547 mirrorp->common.type = MD_METAMIRROR; 2548 2549 /* parse submirrors */ 2550 for (smi = 0; ((argc > 0) && (argv[0][0] != '-') && 2551 (! isdigit(argv[0][0]))); ++smi) { 2552 md_submirror_t *mdsm = &mirrorp->submirrors[smi]; 2553 mdname_t *submirnamep; 2554 2555 /* check for room */ 2556 if (smi >= NMIRROR) { 2557 (void) mdmderror(ep, MDE_MIRROR_FULL, 2558 meta_getminor(mirnp->dev), uname); 2559 goto out; 2560 } 2561 2562 /* parse submirror name */ 2563 if ((submirnamep = metaname(spp, argv[0], 2564 META_DEVICE, ep)) == NULL) 2565 goto out; 2566 mdsm->submirnamep = submirnamep; 2567 --argc, ++argv; 2568 } 2569 if (smi == 0) { 2570 (void) mdmderror(ep, MDE_NSUBMIRS, meta_getminor(mirnp->dev), 2571 uname); 2572 goto out; 2573 } 2574 2575 /* dangerous n-way mirror creation */ 2576 if ((smi > 1) && (options & MDCMD_PRINT)) { 2577 md_eprintf(dgettext(TEXT_DOMAIN, 2578 "%s: WARNING: This form of metainit is not recommended.\n" 2579 "The submirrors may not have the same data.\n" 2580 "Please see ERRORS in metainit(1M) for additional information.\n"), 2581 uname); 2582 } 2583 2584 /* parse mirror options */ 2585 mirrorp->read_option = RD_LOAD_BAL; 2586 mirrorp->write_option = WR_PARALLEL; 2587 mirrorp->pass_num = MD_PASS_DEFAULT; 2588 old_optind = optind = 0; 2589 opterr = 0; 2590 while ((c = getopt(argc, argv, "grS")) != -1) { 2591 switch (c) { 2592 case 'g': 2593 if (mirrorp->read_option != RD_LOAD_BAL) { 2594 (void) mderror(ep, MDE_BAD_RD_OPT, uname); 2595 goto out; 2596 } 2597 mirrorp->read_option = RD_GEOMETRY; 2598 break; 2599 2600 case 'r': 2601 if (mirrorp->read_option != RD_LOAD_BAL) { 2602 (void) mderror(ep, MDE_BAD_RD_OPT, uname); 2603 goto out; 2604 } 2605 mirrorp->read_option = RD_FIRST; 2606 break; 2607 2608 case 'S': 2609 if (mirrorp->write_option != WR_PARALLEL) { 2610 (void) mderror(ep, MDE_BAD_WR_OPT, uname); 2611 goto out; 2612 } 2613 mirrorp->write_option = WR_SERIAL; 2614 break; 2615 2616 default: 2617 argc -= old_optind; 2618 argv += old_optind; 2619 goto options; 2620 } 2621 old_optind = optind; 2622 } 2623 argc -= optind; 2624 argv += optind; 2625 2626 /* parse pass number */ 2627 if ((argc > 0) && (isdigit(argv[0][0]))) { 2628 if (name_to_pass_num(uname, argv[0], 2629 &mirrorp->pass_num, ep) != 0) { 2630 goto out; 2631 } 2632 --argc, ++argv; 2633 } 2634 2635 /* we should be at the end */ 2636 if (argc != 0) 2637 goto syntax; 2638 2639 /* create mirror */ 2640 if (meta_create_mirror(*spp, mirrorp, options, ep) != 0) 2641 goto out; 2642 rval = 0; /* success */ 2643 2644 /* let em know */ 2645 if (options & MDCMD_PRINT) { 2646 (void) printf(dgettext(TEXT_DOMAIN, 2647 "%s: Mirror is setup\n"), 2648 uname); 2649 (void) fflush(stdout); 2650 } 2651 goto out; 2652 2653 /* syntax error */ 2654 syntax: 2655 rval = meta_cook_syntax(ep, MDE_SYNTAX, uname, argc, argv); 2656 goto out; 2657 2658 /* options error */ 2659 options: 2660 rval = meta_cook_syntax(ep, MDE_OPTION, uname, argc, argv); 2661 goto out; 2662 2663 /* cleanup, return error */ 2664 out: 2665 if (mirrorp != NULL) 2666 meta_free_mirror(mirrorp); 2667 return (rval); 2668 } 2669 2670 /* 2671 * reset mirrors 2672 */ 2673 int 2674 meta_mirror_reset( 2675 mdsetname_t *sp, 2676 mdname_t *mirnp, 2677 mdcmdopts_t options, 2678 md_error_t *ep 2679 ) 2680 { 2681 md_mirror_t *mirrorp; 2682 uint_t smi; 2683 int rval = -1; 2684 2685 /* should have same set */ 2686 assert(sp != NULL); 2687 assert((mirnp == NULL) || 2688 (sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)))); 2689 2690 /* reset all mirrors */ 2691 if (mirnp == NULL) { 2692 mdnamelist_t *mirrornlp = NULL; 2693 mdnamelist_t *p; 2694 2695 /* for each mirror */ 2696 rval = 0; 2697 if (meta_get_mirror_names(sp, &mirrornlp, 0, ep) < 0) 2698 return (-1); 2699 for (p = mirrornlp; (p != NULL); p = p->next) { 2700 /* reset mirror */ 2701 mirnp = p->namep; 2702 /* 2703 * If this is a multi-node set, we send a series 2704 * of individual metaclear commands. 2705 */ 2706 if (meta_is_mn_set(sp, ep)) { 2707 if (meta_mn_send_metaclear_command(sp, 2708 mirnp->cname, options, 0, ep) != 0) { 2709 rval = -1; 2710 break; 2711 } 2712 } else { 2713 if (meta_mirror_reset(sp, mirnp, options, 2714 ep) != 0) { 2715 rval = -1; 2716 break; 2717 } 2718 } 2719 } 2720 2721 /* cleanup return success */ 2722 metafreenamelist(mirrornlp); 2723 return (rval); 2724 } 2725 2726 /* check name */ 2727 if (metachkmeta(mirnp, ep) != 0) 2728 return (-1); 2729 2730 /* get unit structure */ 2731 if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL) 2732 return (-1); 2733 2734 /* make sure nobody owns us */ 2735 if (MD_HAS_PARENT(mirrorp->common.parent)) { 2736 return (mdmderror(ep, MDE_IN_USE, meta_getminor(mirnp->dev), 2737 mirnp->cname)); 2738 } 2739 2740 /* clear subdevices cache */ 2741 if (invalidate_submirrors(sp, mirnp, ep) != 0) 2742 return (-1); 2743 2744 /* clear metadevice */ 2745 if (meta_reset(sp, mirnp, options, ep) != 0) 2746 goto out; 2747 rval = 0; /* success */ 2748 2749 /* let em know */ 2750 if (options & MDCMD_PRINT) { 2751 (void) printf(dgettext(TEXT_DOMAIN, 2752 "%s: Mirror is cleared\n"), mirnp->cname); 2753 (void) fflush(stdout); 2754 } 2755 2756 /* clear subdevices */ 2757 if (! (options & MDCMD_RECURSE)) 2758 goto out; 2759 for (smi = 0; (smi < NMIRROR); ++smi) { 2760 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2761 mdname_t *submirnp = mdsp->submirnamep; 2762 2763 /* skip unused submirrors */ 2764 if (submirnp == NULL) { 2765 assert(mdsp->state == SMS_UNUSED); 2766 continue; 2767 } 2768 2769 /* make sure we have a metadevice */ 2770 if (! metaismeta(submirnp)) 2771 continue; 2772 2773 /* clear submirror */ 2774 if (meta_reset_by_name(sp, submirnp, options, ep) != 0) 2775 rval = -1; 2776 } 2777 2778 /* cleanup, return success */ 2779 out: 2780 meta_invalidate_name(mirnp); 2781 return (rval); 2782 } 2783 2784 /* 2785 * reports TRUE if any mirror component is in error 2786 */ 2787 int 2788 meta_mirror_anycomp_is_err(mdsetname_t *sp, mdnamelist_t *mirror_names) 2789 { 2790 mdnamelist_t *nlp; 2791 md_error_t status = mdnullerror; 2792 md_error_t *ep = &status; 2793 int any_errs = FALSE; 2794 2795 for (nlp = mirror_names; nlp; nlp = nlp->next) { 2796 md_mirror_t *mirrorp; 2797 int smi; 2798 2799 if ((mirrorp = meta_get_mirror(sp, nlp->namep, ep)) == NULL) { 2800 any_errs |= TRUE; 2801 goto out; 2802 } 2803 2804 for (smi = 0; smi < NMIRROR; ++smi) { 2805 md_submirror_t *mdsp = &mirrorp->submirrors[smi]; 2806 2807 if (mdsp->state & 2808 (SMS_COMP_ERRED|SMS_ATTACHED|SMS_OFFLINE)) { 2809 any_errs |= TRUE; 2810 goto out; 2811 } 2812 } 2813 } 2814 out: 2815 if (!mdisok(ep)) 2816 mdclrerror(ep); 2817 2818 return (any_errs); 2819 } 2820