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 #include "metad_local.h" 29 #include <metad.h> 30 #include <sys/lvm/md_mddb.h> 31 #include <sdssc.h> 32 #include <sys/lvm/md_mirror.h> 33 #include <syslog.h> 34 35 #include <sys/sysevent/eventdefs.h> 36 #include <sys/sysevent/svm.h> 37 #include <thread.h> 38 39 #define MDDOORS "/usr/lib/lvm/mddoors" 40 41 /* 42 * rpc.metad daemon 43 * 44 * The rpc.metad deamon supports two versions of the svm rpc calls - version 1 45 * and version 2. The over-the-wire structures sent as part of these rpc calls 46 * are also versioned - version 1 and version 2 exist. It must be noted that 47 * the version 2 structures have sub-versions or revisions as well. The 48 * revisions in the version 2 structures allow for flexiblility in changing 49 * over the wire structures without creating a new version of the svm rpc 50 * calls. No changes may be made to the version 1 routines or structures used 51 * by these routines. 52 * 53 * If, for example, the version 2 mdrpc_devinfo_args over the wire structure 54 * (mdrpc_devinfo_2_args*) is changed then the structure change must be 55 * accompanied by the following: 56 * 57 * Header file changes: 58 * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where 59 * X is the revision number. 60 * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the 61 * structure. 62 * . Add a switch statement in mdrpc_devinfo_2_args. 63 * 64 * rpc.metad changes: 65 * . Check for the structure revision in the appropriate mdrpc_devinfo_svc 66 * routine (mdrpc_devinfo_2_svc). 67 * 68 * libmeta changes: 69 * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments 70 * being passed as part of this call (namely mdrpc_devinfo_Y_args) must have 71 * the revision field and associated structure populated correctly. 72 */ 73 74 static md_setkey_t *my_svc_sk = NULL; 75 76 /* 77 * Add namespace entry to local mddb for using given sideno, key 78 * and names. 79 */ 80 static int 81 add_sideno_sidenm( 82 mdsidenames_t *sidenms, 83 mdkey_t local_key, 84 side_t sideno, 85 md_set_desc *sd, /* Only used with Version 2 */ 86 md_error_t *ep 87 ) 88 { 89 mdsidenames_t *sn; 90 mdsetname_t *local_sp; 91 char *nm; 92 93 if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 94 return (-1); 95 96 for (sn = sidenms; sn != NULL; sn = sn->next) 97 if (sn->sideno == sideno) 98 break; 99 100 assert(sn != NULL); 101 102 103 /* 104 * SKEW will be used on the traditional diskset despite of the 105 * rpc version. SKEW is not used on the multinode diskset 106 */ 107 if (MD_MNSET_DESC(sd)) { 108 nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep); 109 } else { 110 nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep); 111 } 112 113 if (nm == NULL) { 114 if (! mdisok(ep)) { 115 if (! mdissyserror(ep, ENOENT)) 116 return (-1); 117 mdclrerror(ep); 118 } 119 120 /* 121 * Ignore returned key from add_name, only care about errs 122 * 123 * SKEW is used for a regular diskset since sideno could 124 * have a value of 0 in that diskset type. add_name is 125 * writing to the local mddb and a sideno of 0 in the 126 * local mddb is reserved for non-diskset names. 127 * SKEW is added to the sideno in the local mddb so that 128 * the sideno for the diskset will never be 0. 129 * 130 * In a MNdiskset, the sideno will never be 0 (by design). 131 * So, no SKEW is needed when writing to the local mddb. 132 */ 133 if (MD_MNSET_DESC(sd)) { 134 if (add_name(local_sp, sideno, local_key, 135 sn->dname, sn->mnum, sn->cname, ep) == -1) 136 return (-1); 137 } else { 138 if (add_name(local_sp, sideno+SKEW, local_key, 139 sn->dname, sn->mnum, sn->cname, ep) == -1) 140 return (-1); 141 } 142 } else 143 Free(nm); 144 145 return (0); 146 } 147 148 /* 149 * Delete sidename entry from local set using key and sideno. 150 */ 151 static int 152 del_sideno_sidenm( 153 mdkey_t sidekey, 154 side_t sideno, 155 md_error_t *ep 156 ) 157 { 158 mdsetname_t *local_sp; 159 160 if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 161 return (-1); 162 163 if (del_name(local_sp, sideno, sidekey, ep) == -1) 164 mdclrerror(ep); /* ignore errs */ 165 166 return (0); 167 } 168 169 170 /* 171 * Add namespace entries to local mddb for drives in drive list in 172 * set descriptor. 173 * 174 * If a MNset and if this host is being added to the set (this host 175 * is in the node_v list), add a namespace entry for the name of 176 * each drive using this host's sideno. 177 * 178 * If not a MNset, add namespace entries for all the new hosts being 179 * added to this set (list in node_v). 180 */ 181 static void 182 add_drv_sidenms( 183 char *hostname, 184 mdsetname_t *sp, 185 md_set_desc *sd, 186 int node_c, 187 char **node_v, 188 md_error_t *ep 189 ) 190 { 191 mdsetname_t *my_sp; 192 md_drive_desc *dd, *my_dd, *p, *q; 193 mddrivename_t *dn, *my_dn; 194 int i; 195 side_t sideno = 0, mysideno = 0; 196 ddi_devid_t devid_remote = NULL; 197 ddi_devid_t devid_local = NULL; 198 int devid_same = -1; 199 int using_devid = 0; 200 md_mnnode_desc *nd; 201 202 assert(sd->sd_drvs != NULL); 203 dd = sd->sd_drvs; 204 205 if (dd->dd_dnp == NULL) 206 return; 207 208 if ((my_sp = metasetname(sp->setname, ep)) == NULL) 209 return; 210 metaflushsetname(my_sp); 211 212 /* If a MN diskset */ 213 if (MD_MNSET_DESC(sd)) { 214 /* Find sideno associated with RPC client. */ 215 nd = sd->sd_nodelist; 216 while (nd) { 217 218 if (strcmp(nd->nd_nodename, hostname) == 0) { 219 sideno = nd->nd_nodeid; 220 } 221 222 /* While looping, find my side num as well */ 223 if (strcmp(nd->nd_nodename, mynode()) == 0) { 224 mysideno = nd->nd_nodeid; 225 } 226 227 if ((sideno) && (mysideno)) { 228 break; 229 } 230 nd = nd->nd_next; 231 } 232 233 if (!sideno) { 234 (void) mddserror(ep, MDE_DS_HOSTNOSIDE, 235 sp->setno, hostname, NULL, sp->setname); 236 return; 237 } 238 } else { 239 /* 240 * if not a MN diskset 241 * do action for traditional diskset. 242 * despite of the rpc version 243 */ 244 for (sideno = 0; sideno < MD_MAXSIDES; sideno++) { 245 /* Skip empty slots */ 246 if (sd->sd_nodes[sideno][0] == '\0') 247 continue; 248 249 if (strcmp(hostname, sd->sd_nodes[sideno]) == 0) 250 break; 251 } 252 253 if (sideno == MD_MAXSIDES) { 254 (void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno, 255 hostname, NULL, sp->setname); 256 return; 257 } 258 } 259 if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK, 260 ep)) == NULL) { 261 if (! mdisok(ep)) 262 return; 263 /* we are supposed to have drives!!!! */ 264 assert(0); 265 } 266 267 /* 268 * The system is either all devid or all 269 * non-devid so we look at the first item 270 * in the list to determine if we're using devids or not. 271 * We also check to make sure it's not a multi-node diskset. 272 * If it is, we don't use devid's. 273 * 274 * For did disks, the dd_dnp->devid is a valid pointer which 275 * points to a '' string of devid. We need to check this 276 * before set the using_devid. 277 */ 278 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 279 (!(MD_MNSET_DESC(sd)))) 280 using_devid = 1; 281 282 /* 283 * We have to match-up the dd that were passed 284 * across the wire to the dd we have in this daemon. 285 * That way we can pick up the new sidenames that were 286 * passed to us and match them up with the local namespace key. 287 * Only we have the key, this cannot be passed in. 288 */ 289 for (p = dd; p != NULL; p = p->dd_next) { 290 dn = p->dd_dnp; 291 devid_remote = NULL; 292 293 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 294 using_devid) { 295 /* 296 * We have a devid so use it 297 */ 298 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 299 } 300 301 /* check to make sure using_devid agrees with reality... */ 302 if ((using_devid == 1) && (devid_remote == NULL)) { 303 /* something went really wrong. Can't process */ 304 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 305 hostname, dn->cname, sp->setname); 306 return; 307 } 308 309 for (q = my_dd; q != NULL; q = q->dd_next) { 310 my_dn = q->dd_dnp; 311 devid_same = -1; 312 313 if (my_dn->devid != NULL && using_devid) { 314 if (devid_str_decode(my_dn->devid, 315 &devid_local, NULL) == 0) { 316 devid_same = devid_compare(devid_remote, 317 devid_local); 318 devid_free(devid_local); 319 } 320 } 321 322 if (using_devid && devid_same == 0) { 323 break; 324 } 325 326 if (!using_devid && 327 strcmp(my_dn->cname, dn->cname) == 0) 328 break; 329 } 330 331 if (devid_remote) { 332 devid_free(devid_remote); 333 } 334 assert(q != NULL); 335 assert(my_dn->side_names_key != MD_KEYWILD); 336 337 if (MD_MNSET_DESC(sd)) { 338 /* 339 * Add the side names to the local db 340 * for this node only. 341 */ 342 if (add_sideno_sidenm(dn->side_names, 343 my_dn->side_names_key, mysideno, sd, ep)) 344 return; 345 /* 346 * Sidenames for this drive were added 347 * to this host during the routine adddrvs. 348 * The sidenames that were added are the 349 * names associated with this drive on 350 * each of the hosts that were previously 351 * in the set. 352 * When the sidename for this drive on 353 * this host is added, the sidename 354 * from the host executing the command 355 * (not this host) is sent to this host. 356 * This host finds the originating host's 357 * sidename and can then determine this 358 * host's sidename. 359 * The sidenames from the other hosts serve 360 * only as temporary sidenames until this 361 * host's sidename can be added. 362 * In order to conserve space in the 363 * local mddb, the code now deletes the 364 * temporary sidenames added during adddrvs. 365 * When finished, only the sidename for this 366 * node should be left. 367 * Ignore any errors during this process since 368 * a failure to delete the extraneous 369 * sidenames shouldn't cause this routine 370 * to fail (in case that sidename didn't exist). 371 */ 372 nd = sd->sd_nodelist; 373 while (nd) { 374 if (nd->nd_nodeid != mysideno) { 375 if (del_sideno_sidenm( 376 dn->side_names_key, 377 nd->nd_nodeid, ep) == -1) 378 mdclrerror(ep); 379 } 380 nd = nd->nd_next; 381 } 382 } else { 383 for (i = 0; i < MD_MAXSIDES; i++) { 384 /* Skip empty slots */ 385 if (sd->sd_nodes[i][0] == '\0') 386 continue; 387 388 /* Skip nodes not being added */ 389 if (! strinlst(sd->sd_nodes[i], 390 node_c, node_v)) 391 continue; 392 393 /* Add the per side names to local db */ 394 if (add_sideno_sidenm(dn->side_names, 395 my_dn->side_names_key, i, sd, ep)) 396 return; 397 } 398 } 399 } 400 } 401 402 /* ARGSUSED */ 403 bool_t 404 mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res, 405 struct svc_req *rqstp) 406 { 407 md_error_t *ep = &res->status; 408 int err, 409 op_mode = W_OK; 410 411 memset(res, 0, sizeof (*res)); 412 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 413 return (FALSE); 414 else if (err != 0) 415 return (TRUE); 416 417 metaflushnames(1); 418 419 err = svc_fini(ep); 420 421 return (TRUE); 422 } 423 424 bool_t 425 mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res, 426 struct svc_req *rqstp) 427 { 428 return (mdrpc_flush_internal_common(args, res, rqstp)); 429 } 430 431 bool_t 432 mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res, 433 struct svc_req *rqstp) 434 { 435 return (mdrpc_flush_internal_common(args, res, rqstp)); 436 } 437 438 /* 439 * add 1 or more namespace entries per drive record. 440 * (into the local namespace) 441 */ 442 bool_t 443 mdrpc_add_drv_sidenms_common( 444 mdrpc_drv_sidenm_2_args_r1 *args, 445 mdrpc_generic_res *res, 446 struct svc_req *rqstp /* RPC stuff */ 447 ) 448 { 449 md_error_t *ep = &res->status; 450 int err; 451 int op_mode = W_OK; 452 453 /* setup, check permissions */ 454 (void) memset(res, 0, sizeof (*res)); 455 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 456 return (FALSE); 457 else if (err != 0) 458 return (TRUE); 459 460 if (check_set_lock(op_mode, args->cl_sk, ep)) 461 return (TRUE); 462 463 /* doit */ 464 add_drv_sidenms(args->hostname, args->sp, args->sd, 465 args->node_v.node_v_len, args->node_v.node_v_val, ep); 466 467 err = svc_fini(ep); 468 469 return (TRUE); 470 } 471 472 /* 473 * version 1 of the remote procedure. This procedure is called if the 474 * client is running in version 1. We first convert version 1 arguments 475 * into version 2 arguments and then call the common remote procedure. 476 */ 477 bool_t 478 mdrpc_add_drv_sidenms_1_svc( 479 mdrpc_drv_sidenm_args *args, 480 mdrpc_generic_res *res, 481 struct svc_req *rqstp /* RPC stuff */ 482 ) 483 { 484 bool_t retval; 485 mdrpc_drv_sidenm_2_args_r1 v2_args; 486 int i, j; 487 488 /* allocate memory */ 489 v2_args.sd = Zalloc(sizeof (md_set_desc)); 490 alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs); 491 492 /* build args */ 493 v2_args.hostname = args->hostname; 494 v2_args.cl_sk = args->cl_sk; 495 v2_args.sp = args->sp; 496 /* set descriptor */ 497 v2_args.sd->sd_ctime = args->sd->sd_ctime; 498 v2_args.sd->sd_genid = args->sd->sd_genid; 499 v2_args.sd->sd_setno = args->sd->sd_setno; 500 v2_args.sd->sd_flags = args->sd->sd_flags; 501 for (i = 0; i < MD_MAXSIDES; i++) { 502 v2_args.sd->sd_isown[i] = args->sd->sd_isown[i]; 503 504 for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++) 505 v2_args.sd->sd_nodes[i][j] = 506 args->sd->sd_nodes[i][j]; 507 } 508 v2_args.sd->sd_med = args->sd->sd_med; 509 /* convert v1 args to v2 (revision 1) args */ 510 meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs); 511 v2_args.node_v.node_v_len = args->node_v.node_v_len; 512 v2_args.node_v.node_v_val = args->node_v.node_v_val; 513 514 retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp); 515 516 free(v2_args.sd); 517 free_newdrvdesc(v2_args.sd->sd_drvs); 518 519 return (retval); 520 } 521 522 bool_t 523 mdrpc_add_drv_sidenms_2_svc( 524 mdrpc_drv_sidenm_2_args *args, 525 mdrpc_generic_res *res, 526 struct svc_req *rqstp /* RPC stuff */ 527 ) 528 { 529 switch (args->rev) { 530 case MD_METAD_ARGS_REV_1: 531 return (mdrpc_add_drv_sidenms_common( 532 &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp)); 533 default: 534 return (FALSE); 535 } 536 } 537 538 static int 539 add_sidenamelist( 540 mddrivename_t *dn, 541 side_t thisside, 542 md_set_record *sr, /* used by RPC version 2 */ 543 md_error_t *ep 544 ) 545 { 546 mdsidenames_t *sn; 547 mdkey_t key; 548 int err; 549 mdsetname_t *local_sp; 550 md_mnset_record *mnsr; 551 md_mnnode_record *nr; 552 uint_t nodeid = 0; 553 554 if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 555 return (-1); 556 557 key = MD_KEYWILD; 558 559 /* 560 * If a multi-node diskset, find nodeid associated with this node. 561 */ 562 if (MD_MNSET_REC(sr)) { 563 mnsr = (struct md_mnset_record *)sr; 564 nr = mnsr->sr_nodechain; 565 while (nr) { 566 if (strcmp(nr->nr_nodename, mynode()) == 0) { 567 break; 568 } 569 nr = nr->nr_next; 570 } 571 /* 572 * If node is found, then a new drive is being added to 573 * a MN set of which this node is a member. 574 * If node is not found, then this host is being added to 575 * a MN set that has drives associated with it. 576 */ 577 if (nr) 578 nodeid = nr->nr_nodeid; 579 } 580 for (sn = dn->side_names; sn != NULL; sn = sn->next) { 581 if (MD_MNSET_REC(sr)) { 582 /* 583 * In multi-node disksets, only add side information 584 * to the local mddb about this node. 585 * If the sideno for this node is found, then 586 * a new drive is being added to a MN set of 587 * which this node is a member. 588 * If the sideno for this node is not found, then 589 * this host is being added to a MNset that 590 * has drives associated with it. In this case, 591 * need to add the sidename associated with the 592 * rpc client, but since we don't know which node 593 * is the client, then add temp entries for all sides. 594 * Later, the sidename for this node will be set 595 * via add_drv_sidenms and then the temp 596 * sidenames can be removed. 597 */ 598 if (nodeid == sn->sideno) { 599 if ((err = add_name(local_sp, sn->sideno, key, 600 sn->dname, sn->mnum, sn->cname, ep)) == -1) 601 return (-1); 602 key = (mdkey_t)err; 603 break; 604 } 605 } else { 606 /* 607 * When a sidename is added into the namespace the local 608 * side information for the name is added first of all. 609 * When the first sidename is created this causes the 610 * devid of the disk to be recorded in the namespace, if 611 * the non-local side information is added first then 612 * there is the possibility of getting the wrong devid 613 * because there is no guarantee that the dev_t (mnum in 614 * this instance) is the same across all the nodes in 615 * the set. So the only way to make sure that the 616 * correct dev_t is used is to force the adding in of 617 * the local sidename record first of all. This same 618 * issue affects add_key_name(). 619 */ 620 if (sn->sideno != thisside) 621 continue; 622 if ((err = add_name(local_sp, sn->sideno+SKEW, key, 623 sn->dname, sn->mnum, sn->cname, ep)) == -1) 624 return (-1); 625 key = (mdkey_t)err; 626 break; 627 } 628 } 629 630 /* 631 * Now the other sides for non-MN set 632 */ 633 if (!MD_MNSET_REC(sr)) { 634 for (sn = dn->side_names; sn != NULL; sn = sn->next) { 635 if (sn->sideno == thisside) 636 continue; 637 if ((err = add_name(local_sp, sn->sideno+SKEW, key, 638 sn->dname, sn->mnum, sn->cname, ep)) == -1) 639 return (-1); 640 key = (mdkey_t)err; 641 } 642 } 643 644 /* Temporarily add all sides. */ 645 if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) { 646 for (sn = dn->side_names; sn != NULL; sn = sn->next) { 647 sn = dn->side_names; 648 if (sn) { 649 if ((err = add_name(local_sp, sn->sideno, key, 650 sn->dname, sn->mnum, sn->cname, ep)) == -1) 651 return (-1); 652 key = (mdkey_t)err; 653 } 654 } 655 } 656 657 dn->side_names_key = key; 658 return (0); 659 } 660 661 static void 662 adddrvs( 663 char *setname, 664 md_drive_desc *dd, 665 md_timeval32_t timestamp, 666 ulong_t genid, 667 md_error_t *ep 668 ) 669 { 670 mddb_userreq_t req; 671 md_drive_record *dr; 672 md_set_record *sr; 673 md_drive_desc *p; 674 mddrivename_t *dn; 675 mdname_t *np; 676 md_dev64_t dev; 677 md_error_t xep = mdnullerror; 678 int i; 679 680 if ((sr = getsetbyname(setname, ep)) == NULL) 681 return; 682 683 if (MD_MNSET_REC(sr)) 684 i = 0; 685 else { 686 /* get thisside */ 687 for (i = 0; i < MD_MAXSIDES; i++) { 688 if (sr->sr_nodes[i][0] == '\0') 689 continue; 690 if (strcmp(mynode(), sr->sr_nodes[i]) == 0) 691 break; 692 } 693 694 if (i == MD_MAXSIDES) { 695 /* so find the first free slot! */ 696 for (i = 0; i < MD_MAXSIDES; i++) { 697 if (sr->sr_nodes[i][0] == '\0') 698 break; 699 } 700 } 701 } 702 703 for (p = dd; p != NULL; p = p->dd_next) { 704 uint_t rep_slice; 705 706 dn = p->dd_dnp; 707 708 /* Add the per side names to the local db */ 709 if (add_sidenamelist(dn, (side_t)i, sr, ep)) { 710 free_sr(sr); 711 return; 712 } 713 714 /* Create the drive record */ 715 (void) memset(&req, 0, sizeof (req)); 716 METAD_SETUP_DR(MD_DB_CREATE, 0); 717 req.ur_size = sizeof (*dr); 718 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 719 (void) mdstealerror(ep, &req.ur_mde); 720 free_sr(sr); 721 return; 722 } 723 724 /* Fill in the drive record values */ 725 dr = Zalloc(sizeof (*dr)); 726 dr->dr_selfid = req.ur_recid; 727 dr->dr_dbcnt = p->dd_dbcnt; 728 dr->dr_dbsize = p->dd_dbsize; 729 dr->dr_key = dn->side_names_key; 730 731 dr->dr_ctime = timestamp; 732 dr->dr_genid = genid; 733 dr->dr_revision = MD_DRIVE_RECORD_REVISION; 734 dr->dr_flags = MD_DR_ADD; 735 736 /* Link the drive records and fill in in-core data */ 737 dr_cache_add(sr, dr); 738 739 dev = NODEV64; 740 if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) && 741 ((np = metaslicename(dn, rep_slice, &xep)) != NULL)) 742 dev = np->dev; 743 else 744 mdclrerror(&xep); 745 746 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE, 747 MD_LOCAL_SET, dev); 748 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE, 749 sr->sr_setno, dev); 750 } 751 752 /* Commit all the records atomically */ 753 commitset(sr, TRUE, ep); 754 free_sr(sr); 755 } 756 757 /* 758 * add 1 or more drive records to a set. 759 */ 760 bool_t 761 mdrpc_adddrvs_common( 762 mdrpc_drives_2_args_r1 *args, 763 mdrpc_generic_res *res, 764 struct svc_req *rqstp /* RPC stuff */ 765 ) 766 { 767 md_error_t *ep = &res->status; 768 int err; 769 int op_mode = W_OK; 770 771 /* setup, check permissions */ 772 (void) memset(res, 0, sizeof (*res)); 773 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 774 return (FALSE); 775 else if (err != 0) 776 return (TRUE); 777 778 if (check_set_lock(op_mode, args->cl_sk, ep)) 779 return (TRUE); 780 781 /* doit */ 782 adddrvs(args->sp->setname, args->drivedescs, args->timestamp, 783 args->genid, ep); 784 785 err = svc_fini(ep); 786 787 return (TRUE); 788 } 789 790 /* 791 * version 1 of the remote procedure. This procedure is called if the 792 * client is running in version 1. We first convert version 1 arguments 793 * into version 2 arguments and then call the common remote procedure. 794 */ 795 bool_t 796 mdrpc_adddrvs_1_svc( 797 mdrpc_drives_args *args, 798 mdrpc_generic_res *res, 799 struct svc_req *rqstp /* RPC stuff */ 800 ) 801 { 802 bool_t retval; 803 mdrpc_drives_2_args_r1 v2_args; 804 805 /* allocate memory */ 806 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 807 808 /* build args */ 809 v2_args.cl_sk = args->cl_sk; 810 v2_args.sp = args->sp; 811 /* convert v1 args to v2 (revision 1) args */ 812 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 813 v2_args.timestamp = args->timestamp; 814 v2_args.genid = args->genid; 815 816 retval = mdrpc_adddrvs_common(&v2_args, res, rqstp); 817 818 free_newdrvdesc(v2_args.drivedescs); 819 820 return (retval); 821 } 822 823 bool_t 824 mdrpc_adddrvs_2_svc( 825 mdrpc_drives_2_args *args, 826 mdrpc_generic_res *res, 827 struct svc_req *rqstp /* RPC stuff */ 828 ) 829 { 830 switch (args->rev) { 831 case MD_METAD_ARGS_REV_1: 832 return (mdrpc_adddrvs_common( 833 &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 834 default: 835 return (FALSE); 836 } 837 } 838 839 static void 840 addhosts( 841 char *setname, 842 int node_c, 843 char **node_v, 844 int version, /* RPC version of calling routine */ 845 md_error_t *ep 846 ) 847 { 848 mddb_userreq_t req; 849 md_set_record *sr; 850 int i, j; 851 md_mnset_record *mnsr; 852 md_mnnode_record *nr; 853 mddb_set_node_params_t snp; 854 int nodecnt; 855 mndiskset_membershiplist_t *nl, *nl2; 856 857 if ((sr = getsetbyname(setname, ep)) == NULL) 858 return; 859 860 /* Do MN operation if rpc version supports it and if a MN set */ 861 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 862 mnsr = (md_mnset_record *)sr; 863 /* 864 * Verify nodes are in membership list on THIS node. 865 * Initiating node has verified that nodes are in membership 866 * list on the initiating node. 867 * Get membershiplist from API routine. If there's 868 * an error, fail to add hosts and pass back error. 869 */ 870 if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) { 871 free_sr(sr); 872 return; 873 } 874 /* Verify that all nodes are in member list */ 875 for (i = 0; i < node_c; i++) { 876 /* 877 * If node in list isn't a member of the membership, 878 * just return error. 879 */ 880 if (meta_is_member(node_v[i], NULL, nl) == 0) { 881 meta_free_nodelist(nl); 882 (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST, 883 sr->sr_setno, node_v[i], NULL, setname); 884 free_sr(sr); 885 return; 886 } 887 } 888 } 889 890 for (i = 0; i < node_c; i++) { 891 /* Do MN operation if rpc version supports it and if a MN set */ 892 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 893 mnsr = (md_mnset_record *)sr; 894 /* Create the node record */ 895 (void) memset(&req, 0, sizeof (req)); 896 METAD_SETUP_NR(MD_DB_CREATE, 0); 897 req.ur_size = sizeof (*nr); 898 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) 899 != 0) { 900 (void) mdstealerror(ep, &req.ur_mde); 901 meta_free_nodelist(nl); 902 free_sr(sr); 903 return; 904 } 905 906 nr = Zalloc(sizeof (*nr)); 907 nr->nr_revision = MD_MNNODE_RECORD_REVISION; 908 nr->nr_selfid = req.ur_recid; 909 nr->nr_ctime = sr->sr_ctime; 910 nr->nr_genid = sr->sr_genid; 911 nr->nr_flags = MD_MN_NODE_ADD; 912 nl2 = nl; 913 while (nl2) { 914 if (strcmp(nl2->msl_node_name, node_v[i]) 915 == 0) { 916 nr->nr_nodeid = nl2->msl_node_id; 917 break; 918 } 919 nl2 = nl2->next; 920 } 921 922 (void) strcpy(nr->nr_nodename, node_v[i]); 923 924 /* 925 * When a node is added to a MN diskset, set the 926 * nodeid of this node in the md_set structure 927 * in the kernel. 928 */ 929 if (strcmp(nr->nr_nodename, mynode()) == 0) { 930 (void) memset(&snp, 0, sizeof (snp)); 931 snp.sn_nodeid = nr->nr_nodeid; 932 snp.sn_setno = mnsr->sr_setno; 933 if (metaioctl(MD_MN_SET_NODEID, &snp, 934 &snp.sn_mde, NULL) != 0) { 935 (void) mdstealerror(ep, &snp.sn_mde); 936 meta_free_nodelist(nl); 937 free_sr(sr); 938 return; 939 } 940 } 941 942 /* Link the node records and fill in in-core data */ 943 mnnr_cache_add(mnsr, nr); 944 945 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, 946 mnsr->sr_setno, nr->nr_nodeid); 947 } else { 948 for (j = 0; j < MD_MAXSIDES; j++) { 949 if (sr->sr_nodes[j][0] != '\0') 950 continue; 951 (void) strcpy(sr->sr_nodes[j], node_v[i]); 952 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, 953 SVM_TAG_HOST, sr->sr_setno, j); 954 break; 955 } 956 } 957 } 958 /* Do MN operation if rpc version supports it and if a MN set */ 959 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 960 meta_free_nodelist(nl); 961 } 962 963 (void) memset(&req, '\0', sizeof (req)); 964 965 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 966 967 /* Do MN operation if rpc version supports it and if a MN set */ 968 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 969 req.ur_size = sizeof (*mnsr); 970 } else { 971 req.ur_size = sizeof (*sr); 972 } 973 req.ur_data = (uintptr_t)sr; 974 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 975 (void) mdstealerror(ep, &req.ur_mde); 976 free_sr(sr); 977 return; 978 } 979 980 commitset(sr, TRUE, ep); 981 982 free_sr(sr); 983 } 984 985 /* 986 * add 1 or more hosts to a set. 987 */ 988 bool_t 989 mdrpc_addhosts_common( 990 mdrpc_host_args *args, 991 mdrpc_generic_res *res, 992 struct svc_req *rqstp, /* RPC stuff */ 993 int version /* RPC version */ 994 ) 995 { 996 md_error_t *ep = &res->status; 997 int err; 998 int op_mode = W_OK; 999 1000 /* setup, check permissions */ 1001 (void) memset(res, 0, sizeof (*res)); 1002 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1003 return (FALSE); 1004 else if (err != 0) 1005 return (TRUE); 1006 1007 if (check_set_lock(op_mode, args->cl_sk, ep)) 1008 return (TRUE); 1009 1010 /* doit */ 1011 addhosts(args->sp->setname, args->hosts.hosts_len, 1012 args->hosts.hosts_val, version, ep); 1013 1014 err = svc_fini(ep); 1015 1016 return (TRUE); 1017 } 1018 1019 bool_t 1020 mdrpc_addhosts_1_svc( 1021 mdrpc_host_args *args, 1022 mdrpc_generic_res *res, 1023 struct svc_req *rqstp /* RPC stuff */ 1024 ) 1025 { 1026 /* Pass RPC version (METAD_VERSION) to common routine */ 1027 return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION)); 1028 } 1029 1030 bool_t 1031 mdrpc_addhosts_2_svc( 1032 mdrpc_host_2_args *args, 1033 mdrpc_generic_res *res, 1034 struct svc_req *rqstp /* RPC stuff */ 1035 ) 1036 { 1037 switch (args->rev) { 1038 case MD_METAD_ARGS_REV_1: 1039 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 1040 return (mdrpc_addhosts_common( 1041 &args->mdrpc_host_2_args_u.rev1, res, 1042 rqstp, METAD_VERSION_DEVID)); 1043 default: 1044 return (FALSE); 1045 } 1046 } 1047 1048 static void 1049 createset( 1050 mdsetname_t *sp, 1051 md_node_nm_arr_t nodes, 1052 md_timeval32_t timestamp, 1053 ulong_t genid, 1054 md_error_t *ep 1055 ) 1056 { 1057 mddb_userreq_t req; 1058 md_set_record *sr; 1059 int i; 1060 1061 (void) memset(&req, 0, sizeof (req)); 1062 METAD_SETUP_SR(MD_DB_CREATE, 0); 1063 req.ur_size = sizeof (*sr); 1064 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1065 (void) mdstealerror(ep, &req.ur_mde); 1066 return; 1067 } 1068 1069 sr = Zalloc(sizeof (*sr)); 1070 1071 sr->sr_selfid = req.ur_recid; 1072 sr->sr_setno = sp->setno; 1073 (void) strcpy(sr->sr_setname, sp->setname); 1074 1075 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno, 1076 NODEV64); 1077 1078 (void) meta_smf_enable(META_SMF_DISKSET, NULL); 1079 1080 for (i = 0; i < MD_MAXSIDES; i++) { 1081 (void) strcpy(sr->sr_nodes[i], nodes[i]); 1082 /* Skip empty slots */ 1083 if (sr->sr_nodes[i][0] == '\0') 1084 continue; 1085 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno, 1086 i); 1087 } 1088 1089 sr->sr_ctime = timestamp; 1090 sr->sr_genid = genid; 1091 sr->sr_revision = MD_SET_RECORD_REVISION; 1092 sr->sr_flags |= MD_SR_ADD; 1093 1094 sr->sr_mhiargs = defmhiargs; 1095 1096 sr_cache_add(sr); 1097 1098 commitset(sr, TRUE, ep); 1099 } 1100 1101 static void 1102 mncreateset( 1103 mdsetname_t *sp, 1104 md_mnnode_desc *nodelist, 1105 md_timeval32_t timestamp, 1106 ulong_t genid, 1107 md_node_nm_t master_nodenm, 1108 int master_nodeid, 1109 md_error_t *ep 1110 ) 1111 { 1112 mddb_userreq_t req; 1113 md_mnset_record *mnsr; 1114 md_mnnode_record *nr; 1115 md_mnnode_desc *nd; 1116 mddb_set_node_params_t snp; 1117 int nodecnt; 1118 mndiskset_membershiplist_t *nl; 1119 1120 /* 1121 * Validate that nodes in set being created are in the 1122 * membership list on THIS node. 1123 * Initiating node has verified that nodes are in membership 1124 * list on the initiating node. 1125 * Get membershiplist from API routine. If there's 1126 * an error, fail to add set and pass back error. 1127 */ 1128 if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) { 1129 return; 1130 } 1131 /* Verify that all nodes are in member list */ 1132 nd = nodelist; 1133 while (nd) { 1134 /* 1135 * If node in list isn't a member of the membership, 1136 * just return error. 1137 */ 1138 if (meta_is_member(nd->nd_nodename, 0, nl) == 0) { 1139 meta_free_nodelist(nl); 1140 (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST, 1141 sp->setno, nd->nd_nodename, NULL, sp->setname); 1142 return; 1143 } 1144 nd = nd->nd_next; 1145 } 1146 meta_free_nodelist(nl); 1147 1148 (void) memset(&req, 0, sizeof (req)); 1149 METAD_SETUP_SR(MD_DB_CREATE, 0); 1150 req.ur_size = sizeof (*mnsr); 1151 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1152 (void) mdstealerror(ep, &req.ur_mde); 1153 return; 1154 } 1155 1156 mnsr = Zalloc(sizeof (*mnsr)); 1157 mnsr->sr_selfid = req.ur_recid; 1158 mnsr->sr_setno = sp->setno; 1159 (void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME); 1160 1161 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno, 1162 NODEV64); 1163 1164 (void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL); 1165 1166 nd = nodelist; 1167 while (nd) { 1168 /* Create the node record */ 1169 (void) memset(&req, 0, sizeof (req)); 1170 METAD_SETUP_NR(MD_DB_CREATE, 0); 1171 req.ur_size = sizeof (*nr); 1172 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1173 /* Frees mnsr and any alloc'd node records */ 1174 free_sr((struct md_set_record *)mnsr); 1175 (void) mdstealerror(ep, &req.ur_mde); 1176 return; 1177 } 1178 1179 nr = Zalloc(sizeof (*nr)); 1180 nr->nr_revision = MD_MNNODE_RECORD_REVISION; 1181 nr->nr_selfid = req.ur_recid; 1182 nr->nr_ctime = timestamp; 1183 nr->nr_genid = genid; 1184 nr->nr_nodeid = nd->nd_nodeid; 1185 nr->nr_flags = nd->nd_flags; 1186 (void) strlcpy(nr->nr_nodename, nd->nd_nodename, 1187 MD_MAX_NODENAME); 1188 1189 /* Link the node records and fill in in-core data */ 1190 mnnr_cache_add(mnsr, nr); 1191 1192 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno, 1193 nr->nr_nodeid); 1194 1195 nd = nd->nd_next; 1196 } 1197 1198 /* 1199 * For backward compatibility, fill in mynode name 1200 * as the only name in the sr_nodes array. This 1201 * allows the pre-MNdiskset code to see that there 1202 * is a node in this diskset. This will keep the 1203 * pre-MNdiskset code from removing this set. 1204 */ 1205 (void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME); 1206 1207 mnsr->sr_ctime = timestamp; 1208 mnsr->sr_genid = genid; 1209 mnsr->sr_revision = MD_SET_RECORD_REVISION; 1210 mnsr->sr_flags |= MD_SR_ADD; 1211 1212 mnsr->sr_flags |= MD_SR_MN; 1213 strcpy(mnsr->sr_master_nodenm, master_nodenm); 1214 mnsr->sr_master_nodeid = master_nodeid; 1215 1216 mnsr->sr_mhiargs = defmhiargs; 1217 1218 sr_cache_add((struct md_set_record *)mnsr); 1219 1220 commitset((struct md_set_record *)mnsr, TRUE, ep); 1221 1222 /* 1223 * When a set is created for the first time, the nodelist 1224 * will contain this node. 1225 * When a node is just being added to a set, the nodelist 1226 * will not contain this node. This node is added to the 1227 * set structure with a later call to addhosts. 1228 * 1229 * So, if the nodelist contains an entry for this node 1230 * then set the nodeid of this node in the md_set kernel 1231 * data structure. 1232 */ 1233 nd = nodelist; 1234 while (nd) { 1235 if (strcmp(nd->nd_nodename, mynode()) == 0) { 1236 break; 1237 } 1238 nd = nd->nd_next; 1239 } 1240 if (nd) { 1241 (void) memset(&snp, 0, sizeof (snp)); 1242 snp.sn_nodeid = nd->nd_nodeid; 1243 snp.sn_setno = sp->setno; 1244 if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) { 1245 (void) mdstealerror(ep, &snp.sn_mde); 1246 return; 1247 } 1248 } 1249 } 1250 1251 /* 1252 * create a set on a host 1253 */ 1254 bool_t 1255 mdrpc_createset_common( 1256 mdrpc_createset_args *args, 1257 mdrpc_generic_res *res, 1258 struct svc_req *rqstp /* RPC stuff */ 1259 ) 1260 { 1261 md_error_t *ep = &res->status; 1262 char stringbuf1[MAXPATHLEN]; 1263 char stringbuf2[MAXPATHLEN]; 1264 int err; 1265 int op_mode = W_OK; 1266 1267 /* setup, check permissions */ 1268 (void) memset(res, 0, sizeof (*res)); 1269 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1270 return (FALSE); 1271 else if (err != 0) 1272 return (TRUE); 1273 1274 if (check_set_lock(op_mode, args->cl_sk, ep)) 1275 return (TRUE); 1276 1277 /* create the arguments for the symlink() and unlink() calls */ 1278 (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s", 1279 args->sp->setname); 1280 (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d", 1281 args->sp->setno); 1282 1283 /* 1284 * Since we already verified that the setname was OK, make sure to 1285 * cleanup before proceeding. 1286 */ 1287 if (unlink(stringbuf2) == -1) { 1288 if (errno != ENOENT) { 1289 (void) mdsyserror(ep, errno, stringbuf2); 1290 return (TRUE); 1291 } 1292 } 1293 1294 /* create the set */ 1295 createset(args->sp, args->nodes, args->timestamp, args->genid, ep); 1296 1297 if (! mdisok(ep)) 1298 return (TRUE); 1299 1300 /* create the symlink */ 1301 if (symlink(stringbuf1, stringbuf2) == -1) 1302 (void) mdsyserror(ep, errno, stringbuf2); 1303 1304 err = svc_fini(ep); 1305 1306 return (TRUE); 1307 } 1308 1309 bool_t 1310 mdrpc_createset_1_svc( 1311 mdrpc_createset_args *args, 1312 mdrpc_generic_res *res, 1313 struct svc_req *rqstp /* RPC stuff */ 1314 ) 1315 { 1316 return (mdrpc_createset_common(args, res, rqstp)); 1317 } 1318 1319 bool_t 1320 mdrpc_createset_2_svc( 1321 mdrpc_createset_2_args *args, 1322 mdrpc_generic_res *res, 1323 struct svc_req *rqstp /* RPC stuff */ 1324 ) 1325 { 1326 switch (args->rev) { 1327 case MD_METAD_ARGS_REV_1: 1328 return (mdrpc_createset_common( 1329 &args->mdrpc_createset_2_args_u.rev1, res, rqstp)); 1330 default: 1331 return (FALSE); 1332 } 1333 } 1334 1335 bool_t 1336 mdrpc_mncreateset_common( 1337 mdrpc_mncreateset_args *args, 1338 mdrpc_generic_res *res, 1339 struct svc_req *rqstp /* RPC stuff */ 1340 ) 1341 { 1342 md_error_t *ep = &res->status; 1343 char stringbuf1[MAXPATHLEN]; 1344 char stringbuf2[MAXPATHLEN]; 1345 int err; 1346 int op_mode = W_OK; 1347 1348 /* setup, check permissions */ 1349 (void) memset(res, 0, sizeof (*res)); 1350 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1351 return (FALSE); 1352 else if (err != 0) 1353 return (TRUE); 1354 1355 if (check_set_lock(op_mode, args->cl_sk, ep)) 1356 return (TRUE); 1357 1358 /* create the arguments for the symlink() and unlink() calls */ 1359 (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s", 1360 args->sp->setname); 1361 (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d", 1362 args->sp->setno); 1363 1364 /* 1365 * Since we already verified that the setname was OK, make sure to 1366 * cleanup before proceeding. 1367 */ 1368 if (unlink(stringbuf2) == -1) { 1369 if (errno != ENOENT) { 1370 (void) mdsyserror(ep, errno, stringbuf2); 1371 return (TRUE); 1372 } 1373 } 1374 1375 /* create the set */ 1376 mncreateset(args->sp, args->nodelist, args->timestamp, args->genid, 1377 args->master_nodenm, args->master_nodeid, ep); 1378 1379 if (! mdisok(ep)) { 1380 return (TRUE); 1381 } 1382 1383 /* create the symlink */ 1384 if (symlink(stringbuf1, stringbuf2) == -1) 1385 (void) mdsyserror(ep, errno, stringbuf2); 1386 1387 err = svc_fini(ep); 1388 1389 return (TRUE); 1390 } 1391 1392 bool_t 1393 mdrpc_mncreateset_2_svc( 1394 mdrpc_mncreateset_2_args *args, 1395 mdrpc_generic_res *res, 1396 struct svc_req *rqstp /* RPC stuff */ 1397 ) 1398 { 1399 switch (args->rev) { 1400 case MD_METAD_ARGS_REV_1: 1401 return (mdrpc_mncreateset_common( 1402 &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp)); 1403 default: 1404 return (FALSE); 1405 } 1406 } 1407 1408 static void 1409 del_drv_sidenms( 1410 mdsetname_t *sp, 1411 int version, /* RPC version of calling routine */ 1412 md_error_t *ep 1413 ) 1414 { 1415 md_set_record *sr; 1416 md_drive_desc *dd, *p; 1417 mddrivename_t *dn; 1418 mdsetname_t *local_sp; 1419 int i; 1420 int rb_mode = 0; 1421 1422 if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 1423 return; 1424 1425 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 1426 return; 1427 1428 /* Do MN operation if rpc version supports it and if a MN set */ 1429 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1430 /* 1431 * In the multi-node diskset, there are no diskset 1432 * entries in the local set for other nodes, so there's 1433 * nothing to do. 1434 */ 1435 free_sr(sr); 1436 return; 1437 } 1438 1439 if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST), 1440 ep)) == NULL) { 1441 if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) { 1442 metaflushsetname(sp); 1443 if (! mdisok(ep)) { 1444 free_sr(sr); 1445 return; 1446 } 1447 /* we are supposed to have drives!!!! */ 1448 assert(0); 1449 } 1450 rb_mode = 1; 1451 mdclrerror(ep); 1452 for (i = 0; i < MD_MAXSIDES; i++) { 1453 /* Skip empty sides of the diskset */ 1454 if (sr->sr_nodes[i][0] == '\0') 1455 continue; 1456 dd = metaget_drivedesc_sideno(sp, i, 1457 (MD_BASICNAME_OK | PRINT_FAST), ep); 1458 /* Got dd, get out of loop */ 1459 if (dd != NULL) 1460 break; 1461 1462 /* some error occurred, get out of loop */ 1463 if (! mdisok(ep)) 1464 break; 1465 } 1466 /* 1467 * At this point, we have one of three possibilities: 1468 * 1) dd != NULL (we have found drives using an alternate 1469 * side.) 1470 * 2) dd == NULL (no drives) && mdisok(ep) : assert(0) 1471 * 3) dd == NULL (no drives) && ! mdisok(ep) : return 1472 * error information to caller. 1473 */ 1474 if (dd == NULL) { 1475 metaflushsetname(sp); 1476 if (! mdisok(ep)) { 1477 free_sr(sr); 1478 return; 1479 } 1480 /* we are supposed to have drives!!!! */ 1481 assert(0); 1482 } 1483 } 1484 1485 /* 1486 * Let's run through each drive descriptor, and delete the 1487 * sidename for all sides that are not in the sr_nodes array. 1488 * We will ignore errors, cause the empty side may not 1489 * have had any names to begin with. 1490 */ 1491 for (p = dd; p != NULL; p = p->dd_next) { 1492 dn = p->dd_dnp; 1493 1494 for (i = 0; i < MD_MAXSIDES; i++) { 1495 /* Skip existing sides of the diskset */ 1496 if (!rb_mode && sr->sr_nodes[i][0] != '\0') 1497 continue; 1498 /* An empty side, delete the sidename */ 1499 if (del_name(local_sp, i+SKEW, 1500 dn->side_names_key, ep)) { 1501 if (!mdissyserror(ep, ENOENT)) { 1502 free_sr(sr); 1503 return; 1504 } 1505 mdclrerror(ep); 1506 } 1507 } 1508 } 1509 free_sr(sr); 1510 metaflushsetname(sp); 1511 } 1512 1513 /* 1514 * delete 1 or more sidenames per drive desc, from the local namespace 1515 */ 1516 bool_t 1517 mdrpc_del_drv_sidenms_common( 1518 mdrpc_sp_args *args, 1519 mdrpc_generic_res *res, 1520 struct svc_req *rqstp, /* RPC stuff */ 1521 int version /* RPC version */ 1522 ) 1523 { 1524 md_error_t *ep = &res->status; 1525 int err; 1526 int op_mode = W_OK; 1527 1528 /* setup, check permissions */ 1529 (void) memset(res, 0, sizeof (*res)); 1530 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1531 return (FALSE); 1532 else if (err != 0) 1533 return (TRUE); 1534 1535 if (check_set_lock(op_mode, args->cl_sk, ep)) 1536 return (TRUE); 1537 1538 /* doit */ 1539 del_drv_sidenms(args->sp, version, ep); 1540 1541 err = svc_fini(ep); 1542 1543 return (TRUE); 1544 } 1545 1546 bool_t 1547 mdrpc_del_drv_sidenms_1_svc( 1548 mdrpc_sp_args *args, 1549 mdrpc_generic_res *res, 1550 struct svc_req *rqstp /* RPC stuff */ 1551 ) 1552 { 1553 /* Pass RPC version (METAD_VERSION) to common routine */ 1554 return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION)); 1555 } 1556 1557 bool_t 1558 mdrpc_del_drv_sidenms_2_svc( 1559 mdrpc_sp_2_args *args, 1560 mdrpc_generic_res *res, 1561 struct svc_req *rqstp /* RPC stuff */ 1562 ) 1563 { 1564 switch (args->rev) { 1565 case MD_METAD_ARGS_REV_1: 1566 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 1567 return (mdrpc_del_drv_sidenms_common( 1568 &args->mdrpc_sp_2_args_u.rev1, res, 1569 rqstp, METAD_VERSION_DEVID)); 1570 default: 1571 return (FALSE); 1572 } 1573 } 1574 1575 static int 1576 del_sidenamelist( 1577 md_set_record *sr, 1578 mddrivename_t *dn, 1579 md_error_t *ep 1580 ) 1581 { 1582 mdsidenames_t *sn; 1583 mdsetname_t *local_sp; 1584 md_mnset_record *mnsr; 1585 md_mnnode_record *nr; 1586 1587 if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 1588 return (-1); 1589 1590 for (sn = dn->side_names; sn != NULL; sn = sn->next) 1591 if (MD_MNSET_REC(sr)) { 1592 mnsr = (struct md_mnset_record *)sr; 1593 /* 1594 * Only delete side name entries for this node 1595 * on a multi-node diskset. 1596 */ 1597 nr = mnsr->sr_nodechain; 1598 while (nr) { 1599 if (nr->nr_nodeid == sn->sideno) { 1600 if (del_name(local_sp, sn->sideno, 1601 dn->side_names_key, ep) == -1) 1602 mdclrerror(ep); /* ignore err */ 1603 break; 1604 } 1605 nr = nr->nr_next; 1606 } 1607 } else { 1608 if (del_name(local_sp, sn->sideno+SKEW, 1609 dn->side_names_key, ep) == -1) 1610 mdclrerror(ep); /* ignore errors */ 1611 } 1612 1613 dn->side_names_key = MD_KEYBAD; 1614 return (0); 1615 } 1616 1617 static void 1618 deldrvs( 1619 char *setname, 1620 md_drive_desc *dd, 1621 md_error_t *ep 1622 ) 1623 { 1624 mdsetname_t *sp; 1625 md_set_record *sr; 1626 md_drive_record *dr; 1627 mddb_userreq_t req; 1628 md_drive_desc *p; 1629 mddrivename_t *dn, *dn1; 1630 side_t sideno; 1631 int i; 1632 int rb_mode = 0; 1633 mdname_t *np; 1634 md_dev64_t dev; 1635 md_error_t xep = mdnullerror; 1636 ddi_devid_t devid_remote = NULL; 1637 ddi_devid_t devid_local = NULL; 1638 int devid_same = -1; 1639 int using_devid = 0; 1640 md_mnnode_record *nr; 1641 md_mnset_record *mnsr; 1642 1643 if ((sp = metasetname(setname, ep)) == NULL) 1644 return; 1645 1646 metaflushsetname(sp); 1647 1648 if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) { 1649 if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) 1650 return; 1651 mdclrerror(ep); 1652 /* 1653 * The set record is incomplete, so we need to make note 1654 * here so that we can do some special handling later. 1655 */ 1656 rb_mode = 1; 1657 } 1658 1659 if ((sr = getsetbyname(setname, ep)) == NULL) 1660 return; 1661 1662 if (dd->dd_dnp == NULL) 1663 return; 1664 1665 /* 1666 * The system is either all devid or all 1667 * non-devid so we determine this by looking 1668 * at the first item in the list. 1669 * 1670 * For did disks, the dd_dnp->devid is a valid pointer which 1671 * points to a '' string of devid. We need to check this 1672 * before set the using_devid. 1673 */ 1674 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 1675 (!(MD_MNSET_REC(sr)))) 1676 using_devid = 1; 1677 1678 for (p = dd; p != NULL; p = p->dd_next) { 1679 dn = p->dd_dnp; 1680 devid_remote = NULL; 1681 1682 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 1683 using_devid) { 1684 /* 1685 * We have a devid so use it 1686 */ 1687 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 1688 } 1689 1690 /* check to make sure using_devid agrees with reality... */ 1691 if ((using_devid == 1) && (devid_remote == NULL)) { 1692 /* something went really wrong. Can't process */ 1693 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 1694 mynode(), dn->cname, sp->setname); 1695 return; 1696 } 1697 1698 for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 1699 devid_same = -1; 1700 1701 if (! rb_mode) { 1702 dn1 = metadrivename_withdrkey(sp, sideno, 1703 dr->dr_key, MD_BASICNAME_OK, ep); 1704 if (dn1 == NULL) { 1705 free_sr(sr); 1706 if (devid_remote) 1707 devid_free(devid_remote); 1708 return; 1709 } 1710 } else { 1711 /* 1712 * Handle special case here where sidenames 1713 * from other hosts for this drive may be 1714 * in the local mddb, but there is no 1715 * sidename entry for this host for this drive. 1716 * This could have happened if the node 1717 * panic'd between the 2 operations when 1718 * adding this node to the set. 1719 * So, delete all sidename entries for this 1720 * drive. 1721 */ 1722 if (MD_MNSET_REC(sr)) { 1723 mnsr = (struct md_mnset_record *)sr; 1724 nr = mnsr->sr_nodechain; 1725 while (nr) { 1726 /* We delete all dr sides */ 1727 dn1 = metadrivename_withdrkey( 1728 sp, nr->nr_nodeid, 1729 dr->dr_key, 1730 MD_BASICNAME_OK, ep); 1731 1732 /* if we do, get out of loop */ 1733 if (dn1 != NULL) 1734 break; 1735 1736 /* save error for later */ 1737 (void) mdstealerror(&xep, ep); 1738 1739 mdclrerror(ep); 1740 1741 nr = nr->nr_next; 1742 } 1743 } else { 1744 /* 1745 * Handle special case here 1746 * for traditional diskset 1747 */ 1748 for (i = 0; i < MD_MAXSIDES; i++) { 1749 /* We delete all dr sides */ 1750 dn1 = metadrivename_withdrkey( 1751 sp, i, dr->dr_key, 1752 MD_BASICNAME_OK, ep); 1753 1754 /* if we do, get out of loop */ 1755 if (dn1 != NULL) 1756 break; 1757 1758 /* save error for later */ 1759 (void) mdstealerror(&xep, ep); 1760 1761 mdclrerror(ep); 1762 } 1763 } 1764 1765 if (dn1 == NULL) { 1766 (void) mdstealerror(ep, &xep); 1767 free_sr(sr); 1768 if (devid_remote) 1769 devid_free(devid_remote); 1770 return; 1771 } 1772 1773 if (!using_devid) 1774 mdclrerror(ep); 1775 } 1776 1777 if (dn1->devid != NULL && using_devid) { 1778 if (devid_str_decode(dn1->devid, &devid_local, 1779 NULL) == 0) { 1780 devid_same = devid_compare(devid_remote, 1781 devid_local); 1782 devid_free(devid_local); 1783 } 1784 } 1785 1786 /* 1787 * Has the required disk been found - either the devids 1788 * match if devid are being used or the actual name of 1789 * the disk matches. 1790 */ 1791 if ((using_devid && devid_same == 0) || 1792 (!using_devid && 1793 strcmp(dn->cname, dn1->cname) == 0)) { 1794 uint_t rep_slice; 1795 1796 dev = NODEV64; 1797 np = NULL; 1798 if (meta_replicaslice(dn1, 1799 &rep_slice, &xep) == 0) { 1800 np = metaslicename(dn1, 1801 rep_slice, &xep); 1802 } 1803 1804 if (np != NULL) 1805 dev = np->dev; 1806 else 1807 mdclrerror(&xep); 1808 break; 1809 } 1810 } 1811 1812 if (dr) { 1813 (void) memset(&req, 0, sizeof (req)); 1814 METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid) 1815 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) 1816 != 0) { 1817 (void) mdstealerror(ep, &req.ur_mde); 1818 if (devid_remote) 1819 devid_free(devid_remote); 1820 free_sr(sr); 1821 return; 1822 } 1823 1824 dr_cache_del(sr, dr->dr_selfid); 1825 1826 if (del_sidenamelist(sr, dn1, ep) == -1) { 1827 goto out; 1828 } 1829 1830 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE, 1831 sr->sr_setno, dev); 1832 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE, 1833 MD_LOCAL_SET, dev); 1834 1835 continue; 1836 } 1837 1838 if (devid_remote) 1839 devid_free(devid_remote); 1840 } 1841 1842 out: 1843 commitset(sr, TRUE, ep); 1844 1845 free_sr(sr); 1846 } 1847 1848 /* 1849 * delete 1 or more drive records from a host. 1850 */ 1851 bool_t 1852 mdrpc_deldrvs_common( 1853 mdrpc_drives_2_args_r1 *args, 1854 mdrpc_generic_res *res, 1855 struct svc_req *rqstp /* RPC stuff */ 1856 ) 1857 { 1858 md_error_t *ep = &res->status; 1859 int err; 1860 int op_mode = W_OK; 1861 1862 /* setup, check permissions */ 1863 (void) memset(res, 0, sizeof (*res)); 1864 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1865 return (FALSE); 1866 else if (err != 0) 1867 return (TRUE); 1868 1869 if (check_set_lock(op_mode, args->cl_sk, ep)) 1870 return (TRUE); 1871 1872 /* doit */ 1873 deldrvs(args->sp->setname, args->drivedescs, ep); 1874 1875 err = svc_fini(ep); 1876 1877 return (TRUE); 1878 } 1879 1880 /* 1881 * version 1 of the remote procedure. This procedure is called if the 1882 * client is running in version 1. We first convert version 1 arguments 1883 * into version 2 arguments and then call the common remote procedure. 1884 */ 1885 bool_t 1886 mdrpc_deldrvs_1_svc( 1887 mdrpc_drives_args *args, 1888 mdrpc_generic_res *res, 1889 struct svc_req *rqstp /* RPC stuff */ 1890 ) 1891 { 1892 bool_t retval; 1893 mdrpc_drives_2_args_r1 v2_args; 1894 1895 /* allocate memory */ 1896 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 1897 1898 /* build args */ 1899 v2_args.cl_sk = args->cl_sk; 1900 v2_args.sp = args->sp; 1901 /* convert v1 args to v2 (revision 1) args */ 1902 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 1903 v2_args.timestamp = args->timestamp; 1904 v2_args.genid = args->genid; 1905 1906 retval = mdrpc_deldrvs_common(&v2_args, res, rqstp); 1907 1908 free_newdrvdesc(v2_args.drivedescs); 1909 1910 return (retval); 1911 } 1912 1913 bool_t 1914 mdrpc_deldrvs_2_svc( 1915 mdrpc_drives_2_args *args, 1916 mdrpc_generic_res *res, 1917 struct svc_req *rqstp /* RPC stuff */ 1918 ) 1919 { 1920 switch (args->rev) { 1921 case MD_METAD_ARGS_REV_1: 1922 return (mdrpc_deldrvs_common( 1923 &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 1924 default: 1925 return (FALSE); 1926 } 1927 } 1928 1929 static void 1930 delhosts( 1931 char *setname, 1932 int node_c, 1933 char **node_v, 1934 int version, /* RPC version of calling routine */ 1935 md_error_t *ep 1936 ) 1937 { 1938 mddb_userreq_t req; 1939 md_set_record *sr; 1940 int i, j; 1941 md_mnset_record *mnsr; 1942 md_mnnode_record *nr; 1943 1944 if ((sr = getsetbyname(setname, ep)) == NULL) 1945 return; 1946 1947 for (i = 0; i < node_c; i++) { 1948 /* Do MN operation if rpc version supports it and if a MN set */ 1949 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1950 mnsr = (struct md_mnset_record *)sr; 1951 nr = mnsr->sr_nodechain; 1952 while (nr) { 1953 if (strcmp(nr->nr_nodename, node_v[i]) == 0) { 1954 SE_NOTIFY(EC_SVM_CONFIG, 1955 ESC_SVM_REMOVE, SVM_TAG_HOST, 1956 sr->sr_setno, nr->nr_nodeid); 1957 (void) memset(&req, '\0', sizeof (req)); 1958 METAD_SETUP_NR(MD_DB_DELETE, 1959 nr->nr_selfid); 1960 if (metaioctl(MD_DB_USERREQ, &req, 1961 &req.ur_mde, NULL) != 0) { 1962 (void) mdstealerror(ep, 1963 &req.ur_mde); 1964 free_sr(sr); 1965 return; 1966 } 1967 mnnr_cache_del(mnsr, nr->nr_selfid); 1968 break; 1969 } 1970 nr = nr->nr_next; 1971 } 1972 } else { 1973 for (j = 0; j < MD_MAXSIDES; j++) { 1974 if (sr->sr_nodes[j][0] == '\0') 1975 continue; 1976 if (strcmp(sr->sr_nodes[j], node_v[i]) != 0) 1977 continue; 1978 (void) memset(sr->sr_nodes[j], '\0', 1979 sizeof (sr->sr_nodes[j])); 1980 SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, 1981 SVM_TAG_HOST, sr->sr_setno, j); 1982 break; 1983 } 1984 } 1985 } 1986 1987 (void) memset(&req, '\0', sizeof (req)); 1988 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 1989 /* Do MN operation if rpc version supports it and if a MN set */ 1990 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1991 req.ur_size = sizeof (*mnsr); 1992 } else { 1993 req.ur_size = sizeof (*sr); 1994 } 1995 req.ur_data = (uintptr_t)sr; 1996 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1997 (void) mdstealerror(ep, &req.ur_mde); 1998 free_sr(sr); 1999 return; 2000 } 2001 2002 commitset(sr, TRUE, ep); 2003 free_sr(sr); 2004 } 2005 2006 /* 2007 * delete 1 or more a hosts from a set. 2008 */ 2009 bool_t 2010 mdrpc_delhosts_common( 2011 mdrpc_host_args *args, 2012 mdrpc_generic_res *res, 2013 struct svc_req *rqstp, /* RPC stuff */ 2014 int version /* RPC version */ 2015 ) 2016 { 2017 md_error_t *ep = &res->status; 2018 int err; 2019 int op_mode = W_OK; 2020 2021 /* setup, check permissions */ 2022 (void) memset(res, 0, sizeof (*res)); 2023 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2024 return (FALSE); 2025 else if (err != 0) 2026 return (TRUE); 2027 2028 if (check_set_lock(op_mode, args->cl_sk, ep)) 2029 return (TRUE); 2030 2031 /* doit */ 2032 delhosts(args->sp->setname, args->hosts.hosts_len, 2033 args->hosts.hosts_val, version, ep); 2034 2035 err = svc_fini(ep); 2036 2037 return (TRUE); 2038 } 2039 2040 bool_t 2041 mdrpc_delhosts_1_svc( 2042 mdrpc_host_args *args, 2043 mdrpc_generic_res *res, 2044 struct svc_req *rqstp /* RPC stuff */ 2045 ) 2046 { 2047 /* Pass RPC version (METAD_VERSION) to common routine */ 2048 return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION)); 2049 } 2050 2051 bool_t 2052 mdrpc_delhosts_2_svc( 2053 mdrpc_host_2_args *args, 2054 mdrpc_generic_res *res, 2055 struct svc_req *rqstp /* RPC stuff */ 2056 ) 2057 { 2058 switch (args->rev) { 2059 case MD_METAD_ARGS_REV_1: 2060 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 2061 return (mdrpc_delhosts_common( 2062 &args->mdrpc_host_2_args_u.rev1, res, 2063 rqstp, METAD_VERSION_DEVID)); 2064 default: 2065 return (FALSE); 2066 } 2067 } 2068 2069 /* 2070 * delete a set. 2071 */ 2072 bool_t 2073 mdrpc_delset_common( 2074 mdrpc_sp_args *args, 2075 mdrpc_generic_res *res, 2076 struct svc_req *rqstp /* RPC stuff */ 2077 ) 2078 { 2079 md_error_t *ep = &res->status; 2080 int err; 2081 int op_mode = W_OK; 2082 2083 /* setup, check permissions */ 2084 (void) memset(res, 0, sizeof (*res)); 2085 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2086 return (FALSE); 2087 else if (err != 0) 2088 return (TRUE); 2089 2090 if (check_set_lock(op_mode, args->cl_sk, ep)) 2091 return (TRUE); 2092 2093 /* doit */ 2094 s_delset(args->sp->setname, ep); 2095 2096 err = svc_fini(ep); 2097 2098 return (TRUE); 2099 } 2100 2101 bool_t 2102 mdrpc_delset_1_svc( 2103 mdrpc_sp_args *args, 2104 mdrpc_generic_res *res, 2105 struct svc_req *rqstp /* RPC stuff */ 2106 ) 2107 { 2108 return (mdrpc_delset_common(args, res, rqstp)); 2109 } 2110 2111 bool_t 2112 mdrpc_delset_2_svc( 2113 mdrpc_sp_2_args *args, 2114 mdrpc_generic_res *res, 2115 struct svc_req *rqstp /* RPC stuff */ 2116 ) 2117 { 2118 switch (args->rev) { 2119 case MD_METAD_ARGS_REV_1: 2120 return (mdrpc_delset_common( 2121 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 2122 default: 2123 return (FALSE); 2124 } 2125 } 2126 2127 /* 2128 * return device info 2129 */ 2130 static void 2131 devinfo( 2132 mdsetname_t *sp, 2133 mddrivename_t *dp, 2134 mdrpc_devinfo_2_res *res, 2135 md_error_t *ep 2136 ) 2137 { 2138 mdname_t *np, *real_np; 2139 2140 if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL) 2141 return; 2142 2143 if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL) 2144 return; 2145 2146 res->dev = real_np->dev; 2147 (void) getdevstamp(dp, (long *)&res->vtime, ep); 2148 res->enc_devid = meta_get_devid(np->rname); 2149 } 2150 2151 bool_t 2152 mdrpc_devinfo_common( 2153 mdrpc_devinfo_2_args_r1 *args, 2154 mdrpc_devinfo_2_res *res, 2155 struct svc_req *rqstp /* RPC stuff */ 2156 ) 2157 { 2158 int slice; 2159 mdname_t *np; 2160 mddrivename_t *dnp = args->drivenamep; 2161 md_error_t *ep = &res->status; 2162 int err; 2163 int op_mode = R_OK; 2164 2165 /* setup, check permissions */ 2166 (void) memset(res, 0, sizeof (*res)); 2167 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2168 return (FALSE); 2169 else if (err != 0) 2170 return (TRUE); 2171 2172 if (check_set_lock(op_mode, NULL, ep)) 2173 return (TRUE); 2174 2175 /* 2176 * fix all the drivenamep's in the mdname_t's to 2177 * point to the right place. 2178 */ 2179 for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2180 if ((np = metaslicename(dnp, slice, ep)) == NULL) 2181 return (TRUE); 2182 np->drivenamep = dnp; 2183 } 2184 2185 /* doit */ 2186 devinfo(args->sp, dnp, res, ep); 2187 2188 err = svc_fini(ep); 2189 2190 return (TRUE); 2191 } 2192 2193 /* 2194 * version 1 of the remote procedure. This procedure is called if the 2195 * client is running in version 1. We first convert version 1 arguments 2196 * into version 2 arguments and then call the common remote procedure. 2197 */ 2198 bool_t 2199 mdrpc_devinfo_1_svc( 2200 mdrpc_devinfo_args *args, 2201 mdrpc_devinfo_res *res, 2202 struct svc_req *rqstp /* RPC stuff */ 2203 ) 2204 { 2205 bool_t retval; 2206 mdrpc_devinfo_2_args_r1 v2_args; 2207 mdrpc_devinfo_2_res v2_res; 2208 2209 /* allocate memory */ 2210 v2_args.drivenamep = Zalloc(sizeof (mddrivename_t)); 2211 v2_args.drivenamep->parts.parts_val = 2212 Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len); 2213 2214 /* convert v1 args to v2 (revision 1) args */ 2215 meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep); 2216 retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp); 2217 2218 /* 2219 * Fill in the result appropriately. 2220 * Since dev_t's for version 2 are 64-bit, 2221 * we need to convert them to 32-bit for version 1. 2222 */ 2223 res->dev = meta_cmpldev(v2_res.dev); 2224 res->vtime = v2_res.vtime; 2225 res->status = v2_res.status; 2226 2227 free(v2_args.drivenamep); 2228 free(v2_args.drivenamep->parts.parts_val); 2229 2230 return (retval); 2231 } 2232 2233 bool_t 2234 mdrpc_devinfo_2_svc( 2235 mdrpc_devinfo_2_args *args, 2236 mdrpc_devinfo_2_res *res, 2237 struct svc_req *rqstp /* RPC stuff */ 2238 ) 2239 { 2240 switch (args->rev) { 2241 case MD_METAD_ARGS_REV_1: 2242 return (mdrpc_devinfo_common( 2243 &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp)); 2244 default: 2245 return (FALSE); 2246 } 2247 } 2248 2249 /* 2250 * return device id 2251 */ 2252 static void 2253 mdrpc_get_devid( 2254 mdsetname_t *sp, 2255 mddrivename_t *dp, 2256 mdrpc_devid_res *res, 2257 md_error_t *ep 2258 ) 2259 { 2260 mdname_t *np; 2261 2262 if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL) 2263 return; 2264 2265 if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL) 2266 return; 2267 2268 res->enc_devid = meta_get_devid(np->rname); 2269 } 2270 2271 bool_t 2272 mdrpc_devid_2_svc( 2273 mdrpc_devid_2_args *args, 2274 mdrpc_devid_res *res, 2275 struct svc_req *rqstp /* RPC stuff */ 2276 ) 2277 { 2278 int slice; 2279 mdname_t *np; 2280 mddrivename_t *dnp; 2281 md_error_t *ep = &res->status; 2282 int err; 2283 int op_mode = R_OK; 2284 2285 switch (args->rev) { 2286 case MD_METAD_ARGS_REV_1: 2287 dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep; 2288 break; 2289 default: 2290 return (FALSE); 2291 } 2292 2293 /* setup, check permissions */ 2294 (void) memset(res, 0, sizeof (*res)); 2295 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2296 return (FALSE); 2297 else if (err != 0) 2298 return (TRUE); 2299 2300 if (check_set_lock(op_mode, NULL, ep)) 2301 return (TRUE); 2302 2303 /* 2304 * fix all the drivenamep's in the mdname_t's to 2305 * point to the right place. 2306 */ 2307 for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2308 if ((np = metaslicename(dnp, slice, ep)) == NULL) 2309 return (TRUE); 2310 np->drivenamep = dnp; 2311 } 2312 2313 /* doit */ 2314 mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep); 2315 2316 err = svc_fini(ep); 2317 2318 return (TRUE); 2319 } 2320 2321 /* 2322 * This routine should not be called for a multi-node diskset. 2323 * 2324 * The devid support is disabled for MN diskset so this routine 2325 * will not be called if the set is MN diskset. The check has 2326 * been done early in meta_getnextside_devinfo. However this 2327 * routine will be called when the devid support for MN set is 2328 * enabled and check is removed. 2329 */ 2330 bool_t 2331 mdrpc_devinfo_by_devid_2_svc( 2332 mdrpc_devidstr_args *args, 2333 mdrpc_devinfo_2_res *res, 2334 struct svc_req *rqstp /* RPC stuff */ 2335 ) 2336 { 2337 2338 char *devidstr = args->enc_devid; 2339 md_error_t *ep = &res->status; 2340 ddi_devid_t devid; 2341 char *minor_name = NULL; 2342 int ret = 0; 2343 int err; 2344 devid_nmlist_t *disklist = NULL; 2345 int op_mode = R_OK; 2346 mdname_t *np; 2347 mdsetname_t *sp = args->sp; 2348 2349 /* setup, check permissions */ 2350 (void) memset(res, 0, sizeof (*res)); 2351 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2352 return (FALSE); 2353 else if (err != 0) 2354 return (TRUE); 2355 2356 if (check_set_lock(op_mode, NULL, ep)) 2357 return (TRUE); 2358 2359 if (devid_str_decode(devidstr, &devid, &minor_name) != 0) 2360 return (TRUE); 2361 2362 /* 2363 * if we do not have a minor name then look for a character device. 2364 * This is because the caller (checkdrive_onnode) expects a character 2365 * device to be returned. The other client of this interface is 2366 * meta_getnextside_devinfo and this supplies a minor name. 2367 */ 2368 if (minor_name == NULL) { 2369 ret = meta_deviceid_to_nmlist("/dev", devid, 2370 DEVID_MINOR_NAME_ALL_CHR, &disklist); 2371 } else { 2372 ret = meta_deviceid_to_nmlist("/dev", devid, minor_name, 2373 &disklist); 2374 devid_str_free(minor_name); 2375 } 2376 2377 devid_free(devid); 2378 if (ret != 0) { 2379 res->dev = NODEV64; 2380 devid_free_nmlist(disklist); 2381 return (TRUE); 2382 } 2383 2384 np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep); 2385 if (np != NULL) { 2386 mdcinfo_t *cinfo; 2387 if ((cinfo = metagetcinfo(np, ep)) != NULL) { 2388 res->drivername = Strdup(cinfo->dname); 2389 } 2390 } 2391 2392 res->dev = meta_expldev(disklist[0].dev); 2393 res->devname = strdup(disklist[0].devname); 2394 2395 devid_free_nmlist(disklist); 2396 2397 err = svc_fini(ep); 2398 2399 return (TRUE); 2400 } 2401 2402 /* 2403 * This routine should not be called for a multi-node diskset. 2404 * 2405 * The devid support is disabled for MN diskset so this routine 2406 * will not be called if the set is MN diskset. The check has 2407 * been done early in meta_getnextside_devinfo. However this 2408 * routine will be called when the devid support for MN set is 2409 * enabled and check is removed. 2410 * 2411 * This function will return the device info attempting to use 2412 * both the passed in devid and device name. This is to deal 2413 * with systems that use multi-path disks but not running mpxio. 2414 * In this situation meta_deviceid_to_nmlist will return multiple 2415 * devices. The orig_devname is used to disambiguate. 2416 * 2417 */ 2418 bool_t 2419 mdrpc_devinfo_by_devid_name_2_svc( 2420 mdrpc_devid_name_2_args *args, 2421 mdrpc_devinfo_2_res *res, 2422 struct svc_req *rqstp /* RPC stuff */ 2423 ) 2424 { 2425 2426 char *devidstr; 2427 char *orig_devname; 2428 md_error_t *ep = &res->status; 2429 ddi_devid_t devid; 2430 char *minor_name = NULL; 2431 int ret = 0; 2432 int err; 2433 int i; 2434 devid_nmlist_t *disklist = NULL; 2435 int op_mode = R_OK; 2436 mdname_t *np; 2437 mdsetname_t *sp; 2438 2439 switch (args->rev) { 2440 case MD_METAD_ARGS_REV_1: 2441 sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp; 2442 devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid; 2443 orig_devname = 2444 (&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname; 2445 break; 2446 default: 2447 return (FALSE); 2448 } 2449 2450 /* setup, check permissions */ 2451 (void) memset(res, 0, sizeof (*res)); 2452 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2453 return (FALSE); 2454 else if (err != 0) 2455 return (TRUE); 2456 2457 if (check_set_lock(op_mode, NULL, ep)) 2458 return (TRUE); 2459 2460 if (devid_str_decode(devidstr, &devid, &minor_name) != 0) 2461 return (TRUE); 2462 2463 /* 2464 * if we do not have a minor name then look for a character device. 2465 * This is because the caller (checkdrive_onnode) expects a character 2466 * device to be returned. The other client of this interface is 2467 * meta_getnextside_devinfo and this supplies a minor name. 2468 */ 2469 if (minor_name == NULL) { 2470 ret = meta_deviceid_to_nmlist("/dev", devid, 2471 DEVID_MINOR_NAME_ALL_CHR, &disklist); 2472 } else { 2473 ret = meta_deviceid_to_nmlist("/dev", devid, minor_name, 2474 &disklist); 2475 devid_str_free(minor_name); 2476 } 2477 2478 devid_free(devid); 2479 if (ret != 0) { 2480 res->dev = NODEV64; 2481 devid_free_nmlist(disklist); 2482 return (TRUE); 2483 } 2484 2485 /* attempt to match to the device name on the originating node */ 2486 for (i = 0; disklist[i].dev != NODEV; i++) { 2487 if (strncmp(orig_devname, disklist[i].devname, 2488 strlen(disklist[i].devname)) == 0) 2489 break; 2490 } 2491 2492 /* if it's not found then use the first disk in the list */ 2493 if (disklist[i].dev == NODEV) 2494 i = 0; 2495 2496 np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep); 2497 if (np != NULL) { 2498 mdcinfo_t *cinfo; 2499 if ((cinfo = metagetcinfo(np, ep)) != NULL) { 2500 res->drivername = Strdup(cinfo->dname); 2501 } 2502 } 2503 2504 res->dev = meta_expldev(disklist[i].dev); 2505 res->devname = strdup(disklist[i].devname); 2506 2507 devid_free_nmlist(disklist); 2508 2509 err = svc_fini(ep); 2510 2511 return (TRUE); 2512 } 2513 2514 static void 2515 drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep) 2516 { 2517 if (meta_check_drivemounted(sp, dnp, ep)) 2518 return; 2519 2520 if (meta_check_driveswapped(sp, dnp, ep)) 2521 return; 2522 2523 if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp, 2524 TRUE, ep)) 2525 return; 2526 2527 (void) meta_check_driveinset(sp, dnp, ep); 2528 } 2529 2530 /* 2531 * determine if a device is in use. 2532 */ 2533 bool_t 2534 mdrpc_drvused_common( 2535 mdrpc_drvused_2_args_r1 *args, 2536 mdrpc_generic_res *res, 2537 struct svc_req *rqstp /* RPC stuff */ 2538 ) 2539 { 2540 md_error_t *ep = &res->status; 2541 int slice; 2542 mdname_t *np; 2543 mddrivename_t *dnp = args->drivenamep; 2544 int err; 2545 int op_mode = R_OK; 2546 2547 /* setup, check permissions */ 2548 (void) memset(res, 0, sizeof (*res)); 2549 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2550 return (FALSE); 2551 else if (err != 0) 2552 return (TRUE); 2553 2554 if (check_set_lock(op_mode, NULL, ep)) 2555 return (TRUE); 2556 2557 if (dnp == NULL) { 2558 /* no drive pointer specified */ 2559 return (TRUE); 2560 } 2561 /* 2562 * fix all the drivenamep's in the mdname_t's to 2563 * point to the right place. 2564 */ 2565 for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2566 if ((np = metaslicename(dnp, slice, ep)) == NULL) 2567 return (TRUE); 2568 np->drivenamep = dnp; 2569 } 2570 2571 /* doit */ 2572 drvused(args->sp, dnp, ep); 2573 2574 err = svc_fini(ep); 2575 2576 return (TRUE); 2577 } 2578 2579 /* 2580 * version 1 of the remote procedure. This procedure is called if the 2581 * client is running in version 1. We first convert version 1 arguments 2582 * into version 2 arguments and then call the common remote procedure. 2583 */ 2584 bool_t 2585 mdrpc_drvused_1_svc( 2586 mdrpc_drvused_args *args, 2587 mdrpc_generic_res *res, 2588 struct svc_req *rqstp /* RPC stuff */ 2589 ) 2590 { 2591 bool_t retval; 2592 mdrpc_drvused_2_args_r1 v2_args; 2593 2594 /* allocate memory */ 2595 v2_args.drivenamep = Zalloc(sizeof (mddrivename_t)); 2596 v2_args.drivenamep->parts.parts_val = 2597 Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len); 2598 2599 /* build args */ 2600 v2_args.sp = args->sp; 2601 v2_args.cl_sk = args->cl_sk; 2602 2603 /* convert v1 args to v2 (revision 1) args */ 2604 meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep); 2605 retval = mdrpc_drvused_common(&v2_args, res, rqstp); 2606 2607 free(v2_args.drivenamep); 2608 free(v2_args.drivenamep->parts.parts_val); 2609 2610 return (retval); 2611 } 2612 2613 bool_t 2614 mdrpc_drvused_2_svc( 2615 mdrpc_drvused_2_args *args, 2616 mdrpc_generic_res *res, 2617 struct svc_req *rqstp /* RPC stuff */ 2618 ) 2619 { 2620 switch (args->rev) { 2621 case MD_METAD_ARGS_REV_1: 2622 return (mdrpc_drvused_common( 2623 &args->mdrpc_drvused_2_args_u.rev1, res, rqstp)); 2624 default: 2625 return (FALSE); 2626 } 2627 } 2628 2629 /* 2630 * return a set records selected by name or number. 2631 */ 2632 bool_t 2633 mdrpc_getset_common( 2634 mdrpc_getset_args *args, 2635 mdrpc_getset_res *res, 2636 struct svc_req *rqstp /* RPC stuff */ 2637 ) 2638 { 2639 md_error_t *ep = &res->status; 2640 int err; 2641 int op_mode = R_OK; 2642 2643 /* setup, check permissions */ 2644 (void) memset(res, 0, sizeof (*res)); 2645 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2646 return (FALSE); 2647 else if (err != 0) 2648 return (TRUE); 2649 2650 /* Don't have a setno, so we don't check the lock */ 2651 if (check_set_lock(op_mode, NULL, ep)) 2652 return (TRUE); 2653 2654 /* doit */ 2655 if (args->setname && *args->setname) 2656 res->sr = setdup(getsetbyname(args->setname, ep)); 2657 else if (args->setno > 0) 2658 res->sr = setdup(getsetbynum(args->setno, ep)); 2659 else 2660 res->sr = NULL; 2661 2662 err = svc_fini(ep); 2663 2664 return (TRUE); 2665 } 2666 2667 bool_t 2668 mdrpc_getset_1_svc( 2669 mdrpc_getset_args *args, 2670 mdrpc_getset_res *res, 2671 struct svc_req *rqstp /* RPC stuff */ 2672 ) 2673 { 2674 return (mdrpc_getset_common(args, res, rqstp)); 2675 } 2676 2677 bool_t 2678 mdrpc_getset_2_svc( 2679 mdrpc_getset_2_args *args, 2680 mdrpc_getset_res *res, 2681 struct svc_req *rqstp /* RPC stuff */ 2682 ) 2683 { 2684 switch (args->rev) { 2685 case MD_METAD_ARGS_REV_1: 2686 return (mdrpc_getset_common( 2687 &args->mdrpc_getset_2_args_u.rev1, res, rqstp)); 2688 default: 2689 return (FALSE); 2690 } 2691 } 2692 2693 /* 2694 * return a MN set record selected by name or number. 2695 */ 2696 bool_t 2697 mdrpc_mngetset_common( 2698 mdrpc_getset_args *args, 2699 mdrpc_mngetset_res *res, 2700 struct svc_req *rqstp /* RPC stuff */ 2701 ) 2702 { 2703 md_error_t *ep = &res->status; 2704 int err; 2705 int op_mode = R_OK; 2706 md_set_record *sr = NULL; 2707 md_mnset_record *mnsr = NULL; 2708 2709 /* setup, check permissions */ 2710 (void) memset(res, 0, sizeof (*res)); 2711 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2712 return (FALSE); 2713 else if (err != 0) 2714 return (TRUE); 2715 2716 /* Don't have a setno, so we don't check the lock */ 2717 if (check_set_lock(op_mode, NULL, ep)) 2718 return (TRUE); 2719 2720 /* doit */ 2721 res->mnsr = NULL; 2722 if (args->setname && *args->setname) 2723 sr = getsetbyname(args->setname, ep); 2724 else if (args->setno > 0) 2725 sr = getsetbynum(args->setno, ep); 2726 2727 if ((sr) && (MD_MNSET_REC(sr))) { 2728 mnsr = (struct md_mnset_record *)sr; 2729 res->mnsr = mnsetdup(mnsr); 2730 } 2731 2732 err = svc_fini(ep); 2733 2734 return (TRUE); 2735 } 2736 2737 bool_t 2738 mdrpc_mngetset_2_svc( 2739 mdrpc_getset_2_args *args, 2740 mdrpc_mngetset_res *res, 2741 struct svc_req *rqstp /* RPC stuff */ 2742 ) 2743 { 2744 switch (args->rev) { 2745 case MD_METAD_ARGS_REV_1: 2746 return (mdrpc_mngetset_common( 2747 &args->mdrpc_getset_2_args_u.rev1, res, rqstp)); 2748 default: 2749 return (FALSE); 2750 } 2751 } 2752 2753 static void 2754 upd_setmaster( 2755 mdsetname_t *sp, 2756 md_node_nm_t master_nodenm, 2757 int master_nodeid, 2758 md_error_t *ep 2759 ) 2760 { 2761 mdsetname_t *local_sp; 2762 md_set_record *sr; 2763 md_mnset_record *mnsr; 2764 mddb_setmaster_config_t sm; 2765 2766 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 2767 return; 2768 2769 metaflushsetname(local_sp); 2770 2771 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 2772 return; 2773 2774 if (MD_MNSET_REC(sr)) { 2775 mnsr = (struct md_mnset_record *)sr; 2776 strlcpy(mnsr->sr_master_nodenm, master_nodenm, 2777 MD_MAX_NODENAME); 2778 mnsr->sr_master_nodeid = master_nodeid; 2779 if (master_nodeid != 0) { 2780 (void) memset(&sm, 0, sizeof (sm)); 2781 sm.c_setno = sp->setno; 2782 /* Use magic to help protect ioctl against attack. */ 2783 sm.c_magic = MDDB_SETMASTER_MAGIC; 2784 if (strcmp(master_nodenm, mynode()) == 0) { 2785 sm.c_current_host_master = 1; 2786 } else { 2787 sm.c_current_host_master = 0; 2788 } 2789 (void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL); 2790 mdclrerror(&sm.c_mde); 2791 } 2792 } 2793 2794 out: 2795 commitset(sr, FALSE, ep); 2796 free_sr(sr); 2797 } 2798 2799 /* 2800 * set the master and nodeid in node record 2801 */ 2802 bool_t 2803 mdrpc_mnsetmaster_common( 2804 mdrpc_mnsetmaster_args *args, 2805 mdrpc_generic_res *res, 2806 struct svc_req *rqstp /* RPC stuff */ 2807 ) 2808 { 2809 md_error_t *ep = &res->status; 2810 int err; 2811 int op_mode = W_OK; 2812 2813 /* setup, check permissions */ 2814 (void) memset(res, 0, sizeof (*res)); 2815 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2816 return (FALSE); 2817 else if (err != 0) 2818 return (TRUE); 2819 2820 if (check_set_lock(op_mode, args->cl_sk, ep)) 2821 return (TRUE); 2822 2823 /* doit */ 2824 upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep); 2825 2826 err = svc_fini(ep); 2827 2828 return (TRUE); 2829 } 2830 2831 bool_t 2832 mdrpc_mnsetmaster_2_svc( 2833 mdrpc_mnsetmaster_2_args *args, 2834 mdrpc_generic_res *res, 2835 struct svc_req *rqstp /* RPC stuff */ 2836 ) 2837 { 2838 switch (args->rev) { 2839 case MD_METAD_ARGS_REV_1: 2840 return (mdrpc_mnsetmaster_common( 2841 &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp)); 2842 default: 2843 return (FALSE); 2844 } 2845 } 2846 2847 /* 2848 * Join this node to the diskset. 2849 * Pass stale_flag information to snarf_set so that snarf code 2850 * can choose a STALE or non-STALE state when starting the set. 2851 * If master is STALE, any joining node will join a stale set regardless 2852 * of the number of accessible mddbs. Also, if master is at 50% 2853 * accessible replicas and is in the TOOFEW state, don't mark newly 2854 * joining node as STALE; mark it TOOFEW instead. 2855 */ 2856 static void 2857 joinset( 2858 mdsetname_t *sp, 2859 int flags, 2860 md_error_t *ep 2861 ) 2862 { 2863 mdsetname_t *local_sp; 2864 md_drive_desc *mydd; 2865 bool_t stale_bool; 2866 mddb_block_parm_t mbp; 2867 md_error_t xep = mdnullerror; 2868 2869 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 2870 return; 2871 2872 /* 2873 * Start mddoors daemon here. 2874 * mddoors itself takes care there will be 2875 * only one instance running, so starting it twice won't hurt 2876 */ 2877 pclose(popen(MDDOORS, "w")); 2878 2879 /* 2880 * Get latest copy of data. If a drive was just added causing 2881 * nodes to get joined - this drive won't be in the local 2882 * name caches drive list yet. 2883 */ 2884 metaflushsetname(local_sp); 2885 2886 mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep); 2887 if (mydd) { 2888 /* 2889 * Causes mddbs to be loaded into the kernel. 2890 * Set the force flag so that replica locations can be loaded 2891 * into the kernel even if a mediator node was unavailable. 2892 * This allows a node to join an MO diskset when there are 2893 * sufficient replicas available, but a mediator node 2894 * in unavailable. 2895 */ 2896 if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) { 2897 /* If ep isn't set for some reason, set it */ 2898 if (mdisok(ep)) { 2899 (void) mdmddberror(ep, MDE_DB_NOTNOW, 2900 (minor_t)NODEV64, sp->setno, 0, NULL); 2901 } 2902 return; 2903 } 2904 2905 if (flags & MNSET_IS_STALE) 2906 stale_bool = TRUE; 2907 else 2908 stale_bool = FALSE; 2909 2910 /* 2911 * Snarf the set. No failure has occurred if STALE or 2912 * ACCOK error was set. Otherwise, fail the call setting 2913 * a generic error if no error was already set. 2914 * 2915 * STALE means that set has < 50% mddbs. 2916 * ACCOK means that the mediator provided an extra vote. 2917 */ 2918 if (snarf_set(local_sp, stale_bool, ep) != 0) { 2919 if (!(mdismddberror(ep, MDE_DB_STALE)) && 2920 !(mdismddberror(ep, MDE_DB_ACCOK))) { 2921 return; 2922 } else if (mdisok(ep)) { 2923 /* If snarf failed, but no error set - set it */ 2924 (void) mdmddberror(ep, MDE_DB_NOTNOW, 2925 (minor_t)NODEV64, sp->setno, 0, NULL); 2926 return; 2927 } 2928 } 2929 2930 /* 2931 * If node is joining during reconfig cycle, then 2932 * set mddb_parse to be in blocked state so that 2933 * mddb reparse messages are not generated until 2934 * the commd has been resumed later in the reconfig 2935 * cycle. 2936 */ 2937 if (flags & MNSET_IN_RECONFIG) { 2938 (void) memset(&mbp, 0, sizeof (mbp)); 2939 if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) { 2940 (void) memset(&mbp, 0, sizeof (mbp)); 2941 mbp.c_setno = local_sp->setno; 2942 mbp.c_blk_flags = MDDB_BLOCK_PARSE; 2943 if (metaioctl(MD_MN_MDDB_BLOCK, &mbp, 2944 &mbp.c_mde, NULL)) { 2945 mdstealerror(&xep, &mbp.c_mde); 2946 mde_perror(ep, gettext( 2947 "Could not block set %s"), 2948 sp->setname); 2949 return; 2950 } 2951 } 2952 /* 2953 * If s_ownset fails and snarf_set succeeded, 2954 * then can steal the ownset failure information 2955 * and store it into ep. If snarf_set failed, 2956 * don't overwrite critical ep information even 2957 * if s_ownset failed. 2958 */ 2959 if (!mdisok(&xep)) { 2960 /* 2961 * If snarf_set succeeded or snarf_set failed 2962 * with MDE_DB_ACCOK (which is set if the 2963 * mediator provided the extra vote) then 2964 * steal the xep failure information and put 2965 * into ep. 2966 */ 2967 if (mdisok(ep) || 2968 mdismddberror(ep, MDE_DB_ACCOK)) { 2969 mdstealerror(ep, &xep); 2970 } 2971 } 2972 } 2973 } 2974 } 2975 2976 /* 2977 * Have this node join the set. 2978 * This is called when a node has been 2979 * added to a MN diskset that has drives. 2980 * Also, called when a node is an alive 2981 * member of a MN diskset and the first 2982 * drive has been added. 2983 */ 2984 bool_t 2985 mdrpc_joinset_common( 2986 mdrpc_sp_flags_args *args, 2987 mdrpc_generic_res *res, 2988 struct svc_req *rqstp /* RPC stuff */ 2989 ) 2990 { 2991 md_error_t *ep = &res->status; 2992 int err; 2993 int op_mode = W_OK; 2994 2995 /* setup, check permissions */ 2996 (void) memset(res, 0, sizeof (*res)); 2997 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2998 return (FALSE); 2999 else if (err != 0) 3000 return (TRUE); 3001 3002 /* 3003 * During reconfig, joinset can happen without 3004 * locking first. Turn off reconfig flag before calling 3005 * joinset. 3006 */ 3007 if (!(args->flags & MNSET_IN_RECONFIG)) { 3008 if (check_set_lock(op_mode, args->cl_sk, ep)) 3009 return (TRUE); 3010 } 3011 3012 /* doit */ 3013 joinset(args->sp, args->flags, ep); 3014 3015 err = svc_fini(ep); 3016 3017 return (TRUE); 3018 } 3019 3020 bool_t 3021 mdrpc_joinset_2_svc( 3022 mdrpc_sp_flags_2_args *args, 3023 mdrpc_generic_res *res, 3024 struct svc_req *rqstp /* RPC stuff */ 3025 ) 3026 { 3027 switch (args->rev) { 3028 case MD_METAD_ARGS_REV_1: 3029 return (mdrpc_joinset_common( 3030 &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp)); 3031 default: 3032 return (FALSE); 3033 } 3034 } 3035 3036 static void 3037 withdrawset( 3038 mdsetname_t *sp, 3039 md_error_t *ep 3040 ) 3041 { 3042 mdsetname_t *my_sp; 3043 3044 if ((my_sp = metasetname(sp->setname, ep)) == NULL) 3045 return; 3046 3047 (void) halt_set(my_sp, ep); 3048 } 3049 3050 /* 3051 * Have this node withdraw from set. 3052 * In response to a failure that occurred 3053 * on the client after a joinset. 3054 */ 3055 bool_t 3056 mdrpc_withdrawset_common( 3057 mdrpc_sp_args *args, 3058 mdrpc_generic_res *res, 3059 struct svc_req *rqstp /* RPC stuff */ 3060 ) 3061 { 3062 md_error_t *ep = &res->status; 3063 int err; 3064 int op_mode = W_OK; 3065 3066 /* setup, check permissions */ 3067 (void) memset(res, 0, sizeof (*res)); 3068 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3069 return (FALSE); 3070 else if (err != 0) 3071 return (TRUE); 3072 3073 if (check_set_lock(op_mode, args->cl_sk, ep)) 3074 return (TRUE); 3075 3076 /* doit */ 3077 withdrawset(args->sp, ep); 3078 3079 err = svc_fini(ep); 3080 3081 return (TRUE); 3082 } 3083 3084 bool_t 3085 mdrpc_withdrawset_2_svc( 3086 mdrpc_sp_2_args *args, 3087 mdrpc_generic_res *res, 3088 struct svc_req *rqstp /* RPC stuff */ 3089 ) 3090 { 3091 switch (args->rev) { 3092 case MD_METAD_ARGS_REV_1: 3093 return (mdrpc_withdrawset_common( 3094 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3095 default: 3096 return (FALSE); 3097 } 3098 } 3099 3100 static mhd_mhiargs_t * 3101 gtimeout(mdsetname_t *sp, md_error_t *ep) 3102 { 3103 md_set_record *sr; 3104 mhd_mhiargs_t *mhiargs; 3105 3106 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3107 return (NULL); 3108 3109 mhiargs = Zalloc(sizeof (*mhiargs)); 3110 *mhiargs = sr->sr_mhiargs; 3111 3112 free_sr(sr); 3113 return (mhiargs); 3114 } 3115 3116 /* 3117 * Get the MH timeout values for this set. 3118 */ 3119 bool_t 3120 mdrpc_gtimeout_common( 3121 mdrpc_sp_args *args, 3122 mdrpc_gtimeout_res *res, 3123 struct svc_req *rqstp /* RPC stuff */ 3124 ) 3125 { 3126 md_error_t *ep = &res->status; 3127 int err; 3128 int op_mode = R_OK; 3129 3130 /* setup, check permissions */ 3131 (void) memset(res, 0, sizeof (*res)); 3132 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3133 return (FALSE); 3134 else if (err != 0) 3135 return (TRUE); 3136 3137 if (check_set_lock(op_mode, NULL, ep)) 3138 return (TRUE); 3139 3140 /* doit */ 3141 res->mhiargsp = gtimeout(args->sp, ep); 3142 3143 err = svc_fini(ep); 3144 3145 return (TRUE); 3146 } 3147 3148 bool_t 3149 mdrpc_gtimeout_1_svc( 3150 mdrpc_sp_args *args, 3151 mdrpc_gtimeout_res *res, 3152 struct svc_req *rqstp /* RPC stuff */ 3153 ) 3154 { 3155 return (mdrpc_gtimeout_common(args, res, rqstp)); 3156 } 3157 3158 bool_t 3159 mdrpc_gtimeout_2_svc( 3160 mdrpc_sp_2_args *args, 3161 mdrpc_gtimeout_res *res, 3162 struct svc_req *rqstp /* RPC stuff */ 3163 ) 3164 { 3165 switch (args->rev) { 3166 case MD_METAD_ARGS_REV_1: 3167 return (mdrpc_gtimeout_common( 3168 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3169 default: 3170 return (FALSE); 3171 } 3172 } 3173 3174 /* 3175 * return the official host name for the callee 3176 */ 3177 /*ARGSUSED*/ 3178 bool_t 3179 mdrpc_hostname_common( 3180 mdrpc_null_args *args, 3181 mdrpc_hostname_res *res, 3182 struct svc_req *rqstp /* RPC stuff */ 3183 ) 3184 { 3185 md_error_t *ep = &res->status; 3186 int err; 3187 int op_mode = R_OK; 3188 3189 /* setup, check permissions */ 3190 (void) memset(res, 0, sizeof (*res)); 3191 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3192 return (FALSE); 3193 else if (err != 0) 3194 return (TRUE); 3195 3196 if (check_set_lock(op_mode, NULL, ep)) 3197 return (TRUE); 3198 3199 /* doit */ 3200 res->hostname = Strdup(mynode()); 3201 3202 err = svc_fini(ep); 3203 3204 return (TRUE); 3205 } 3206 3207 bool_t 3208 mdrpc_hostname_1_svc( 3209 mdrpc_null_args *args, 3210 mdrpc_hostname_res *res, 3211 struct svc_req *rqstp /* RPC stuff */ 3212 ) 3213 { 3214 return (mdrpc_hostname_common(args, res, rqstp)); 3215 } 3216 3217 bool_t 3218 mdrpc_hostname_2_svc( 3219 mdrpc_null_args *args, 3220 mdrpc_hostname_res *res, 3221 struct svc_req *rqstp /* RPC stuff */ 3222 ) 3223 { 3224 return (mdrpc_hostname_common(args, res, rqstp)); 3225 } 3226 3227 /* 3228 * return a response 3229 */ 3230 /*ARGSUSED*/ 3231 bool_t 3232 mdrpc_nullproc_common( 3233 void *args, 3234 md_error_t *ep, 3235 struct svc_req *rqstp /* RPC stuff */ 3236 ) 3237 { 3238 *ep = mdnullerror; 3239 /* do nothing */ 3240 return (TRUE); 3241 } 3242 3243 bool_t 3244 mdrpc_nullproc_1_svc( 3245 void *args, 3246 md_error_t *ep, 3247 struct svc_req *rqstp /* RPC stuff */ 3248 ) 3249 { 3250 return (mdrpc_nullproc_common(args, ep, rqstp)); 3251 } 3252 3253 bool_t 3254 mdrpc_nullproc_2_svc( 3255 void *args, 3256 md_error_t *ep, 3257 struct svc_req *rqstp /* RPC stuff */ 3258 ) 3259 { 3260 return (mdrpc_nullproc_common(args, ep, rqstp)); 3261 } 3262 3263 /* 3264 * determine if the caller owns the set. 3265 */ 3266 bool_t 3267 mdrpc_ownset_common( 3268 mdrpc_sp_args *args, 3269 mdrpc_bool_res *res, 3270 struct svc_req *rqstp /* RPC stuff */ 3271 ) 3272 { 3273 md_error_t *ep = &res->status; 3274 int err; 3275 int op_mode = R_OK; 3276 3277 /* setup, check permissions */ 3278 (void) memset(res, 0, sizeof (*res)); 3279 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3280 return (FALSE); 3281 else if (err != 0) 3282 return (TRUE); 3283 3284 if (check_set_lock(op_mode, NULL, ep)) 3285 return (TRUE); 3286 3287 /* doit */ 3288 if (s_ownset(args->sp->setno, ep)) 3289 res->value = TRUE; 3290 else 3291 res->value = FALSE; 3292 3293 err = svc_fini(ep); 3294 3295 return (TRUE); 3296 } 3297 3298 bool_t 3299 mdrpc_ownset_1_svc( 3300 mdrpc_sp_args *args, 3301 mdrpc_bool_res *res, 3302 struct svc_req *rqstp /* RPC stuff */ 3303 ) 3304 { 3305 return (mdrpc_ownset_common(args, res, rqstp)); 3306 } 3307 3308 bool_t 3309 mdrpc_ownset_2_svc( 3310 mdrpc_sp_2_args *args, 3311 mdrpc_bool_res *res, 3312 struct svc_req *rqstp /* RPC stuff */ 3313 ) 3314 { 3315 switch (args->rev) { 3316 case MD_METAD_ARGS_REV_1: 3317 return (mdrpc_ownset_common( 3318 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3319 default: 3320 return (FALSE); 3321 } 3322 } 3323 3324 static int 3325 setnameok(char *setname, md_error_t *ep) 3326 { 3327 int rval = 0; 3328 struct stat statb; 3329 md_set_record *sr = NULL; 3330 char *setlink = NULL; 3331 3332 setlink = Strdup("/dev/md/"); 3333 setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1); 3334 (void) strcat(setlink, setname); 3335 3336 if (lstat(setlink, &statb) == -1) { 3337 /* 3338 * If lstat() fails with ENOENT, setname is OK, if it 3339 * fails for other than that, we fail the RPC 3340 */ 3341 if (errno == ENOENT) { 3342 rval = 1; 3343 goto out; 3344 } 3345 3346 (void) mdsyserror(ep, errno, setlink); 3347 goto out; 3348 } 3349 3350 /* 3351 * If the lstat() succeeded, then we see what type of object 3352 * we are dealing with, if it is a symlink, we do some further 3353 * checking, if it is not a symlink, then we return an 3354 * indication that the set name is NOT acceptable. 3355 */ 3356 if (! S_ISLNK(statb.st_mode)) 3357 goto out; 3358 3359 /* 3360 * We look up the setname to see if there is a set 3361 * with that name, if there is, then we return 3362 * an indication that the set name is NOT acceptable. 3363 */ 3364 if ((sr = getsetbyname(setname, ep)) != NULL) 3365 goto out; 3366 3367 if (! mdiserror(ep, MDE_NO_SET)) 3368 goto out; 3369 3370 mdclrerror(ep); 3371 3372 rval = 1; 3373 out: 3374 if (sr != NULL) 3375 free_sr(sr); 3376 Free(setlink); 3377 return (rval); 3378 } 3379 3380 /* 3381 * Make sure the name of the set is OK. 3382 */ 3383 bool_t 3384 mdrpc_setnameok_common( 3385 mdrpc_sp_args *args, /* device name */ 3386 mdrpc_bool_res *res, 3387 struct svc_req *rqstp /* RPC stuff */ 3388 ) 3389 { 3390 md_error_t *ep = &res->status; 3391 int err; 3392 int op_mode = R_OK; 3393 3394 /* setup, check permissions */ 3395 (void) memset(res, 0, sizeof (*res)); 3396 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3397 return (FALSE); 3398 else if (err != 0) 3399 return (TRUE); 3400 3401 if (check_set_lock(op_mode, NULL, ep)) 3402 return (TRUE); 3403 3404 /* doit */ 3405 res->value = setnameok(args->sp->setname, ep); 3406 3407 err = svc_fini(ep); 3408 3409 return (TRUE); 3410 } 3411 3412 bool_t 3413 mdrpc_setnameok_1_svc( 3414 mdrpc_sp_args *args, /* device name */ 3415 mdrpc_bool_res *res, 3416 struct svc_req *rqstp /* RPC stuff */ 3417 ) 3418 { 3419 return (mdrpc_setnameok_common(args, res, rqstp)); 3420 } 3421 3422 bool_t 3423 mdrpc_setnameok_2_svc( 3424 mdrpc_sp_2_args *args, /* device name */ 3425 mdrpc_bool_res *res, 3426 struct svc_req *rqstp /* RPC stuff */ 3427 ) 3428 { 3429 switch (args->rev) { 3430 case MD_METAD_ARGS_REV_1: 3431 return (mdrpc_setnameok_common( 3432 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3433 default: 3434 return (FALSE); 3435 } 3436 } 3437 3438 /* 3439 * determine if the setnumber we want to share is in use. 3440 */ 3441 bool_t 3442 mdrpc_setnumbusy_common( 3443 mdrpc_setno_args *args, 3444 mdrpc_bool_res *res, 3445 struct svc_req *rqstp /* RPC stuff */ 3446 ) 3447 { 3448 md_error_t *ep = &res->status; 3449 md_set_record *sr = NULL; 3450 int err; 3451 int op_mode = R_OK; 3452 3453 /* setup, check permissions */ 3454 (void) memset(res, 0, sizeof (*res)); 3455 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3456 return (FALSE); 3457 else if (err != 0) 3458 return (TRUE); 3459 3460 if (check_set_lock(op_mode, NULL, ep)) 3461 return (TRUE); 3462 3463 /* doit */ 3464 if ((sr = getsetbynum(args->setno, ep)) != NULL) { 3465 res->value = TRUE; 3466 free_sr(sr); 3467 return (TRUE); 3468 } 3469 res->value = FALSE; 3470 if (mdiserror(ep, MDE_NO_SET)) 3471 mdclrerror(ep); 3472 3473 err = svc_fini(ep); 3474 3475 return (TRUE); 3476 } 3477 3478 bool_t 3479 mdrpc_setnumbusy_1_svc( 3480 mdrpc_setno_args *args, 3481 mdrpc_bool_res *res, 3482 struct svc_req *rqstp /* RPC stuff */ 3483 ) 3484 { 3485 return (mdrpc_setnumbusy_common(args, res, rqstp)); 3486 } 3487 3488 bool_t 3489 mdrpc_setnumbusy_2_svc( 3490 mdrpc_setno_2_args *args, 3491 mdrpc_bool_res *res, 3492 struct svc_req *rqstp /* RPC stuff */ 3493 ) 3494 { 3495 switch (args->rev) { 3496 case MD_METAD_ARGS_REV_1: 3497 return (mdrpc_setnumbusy_common( 3498 &args->mdrpc_setno_2_args_u.rev1, res, rqstp)); 3499 default: 3500 return (FALSE); 3501 } 3502 } 3503 3504 static void 3505 stimeout( 3506 mdsetname_t *sp, 3507 mhd_mhiargs_t *mhiargsp, 3508 int version, /* RPC version of calling routine */ 3509 md_error_t *ep 3510 ) 3511 { 3512 mddb_userreq_t req; 3513 md_set_record *sr; 3514 3515 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3516 return; 3517 3518 sr->sr_mhiargs = *mhiargsp; 3519 3520 (void) memset(&req, '\0', sizeof (req)); 3521 3522 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 3523 /* Do MN operation if rpc version supports it and if a MN set */ 3524 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 3525 req.ur_size = sizeof (struct md_mnset_record); 3526 } else { 3527 req.ur_size = sizeof (*sr); 3528 } 3529 req.ur_data = (uintptr_t)sr; 3530 3531 /* 3532 * Cluster nodename support 3533 * Convert nodename -> nodeid 3534 * Don't do this for MN disksets since we've already stored 3535 * both the nodeid and name. 3536 */ 3537 if ((version == METAD_VERSION) || 3538 ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3539 sdssc_cm_sr_nm2nid(sr); 3540 3541 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 3542 (void) mdstealerror(ep, &req.ur_mde); 3543 return; 3544 } 3545 3546 (void) memset(&req, '\0', sizeof (req)); 3547 METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid) 3548 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) 3549 (void) mdstealerror(ep, &req.ur_mde); 3550 3551 /* 3552 * Cluster nodename support 3553 * Convert nodeid -> nodename 3554 * Don't do this for MN disksets since we've already stored 3555 * both the nodeid and name. 3556 */ 3557 if ((version == METAD_VERSION) || 3558 ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3559 sdssc_cm_sr_nid2nm(sr); 3560 3561 free_sr(sr); 3562 } 3563 3564 /* 3565 * Set MH ioctl timeout values. 3566 */ 3567 bool_t 3568 mdrpc_stimeout_common( 3569 mdrpc_stimeout_args *args, 3570 mdrpc_generic_res *res, 3571 struct svc_req *rqstp, /* RPC stuff */ 3572 int version /* RPC version */ 3573 ) 3574 { 3575 md_error_t *ep = &res->status; 3576 int err; 3577 int op_mode = W_OK; 3578 3579 /* setup, check permissions */ 3580 (void) memset(res, 0, sizeof (*res)); 3581 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3582 return (FALSE); 3583 else if (err != 0) 3584 return (TRUE); 3585 3586 if (check_set_lock(op_mode, NULL, ep)) 3587 return (TRUE); 3588 3589 /* doit */ 3590 stimeout(args->sp, args->mhiargsp, version, ep); 3591 3592 err = svc_fini(ep); 3593 3594 return (TRUE); 3595 } 3596 3597 bool_t 3598 mdrpc_stimeout_1_svc( 3599 mdrpc_stimeout_args *args, 3600 mdrpc_generic_res *res, 3601 struct svc_req *rqstp /* RPC stuff */ 3602 ) 3603 { 3604 /* Pass RPC version (METAD_VERSION) to common routine */ 3605 return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION)); 3606 } 3607 3608 bool_t 3609 mdrpc_stimeout_2_svc( 3610 mdrpc_stimeout_2_args *args, 3611 mdrpc_generic_res *res, 3612 struct svc_req *rqstp /* RPC stuff */ 3613 ) 3614 { 3615 switch (args->rev) { 3616 case MD_METAD_ARGS_REV_1: 3617 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 3618 return (mdrpc_stimeout_common( 3619 &args->mdrpc_stimeout_2_args_u.rev1, res, 3620 rqstp, METAD_VERSION_DEVID)); 3621 default: 3622 return (FALSE); 3623 } 3624 } 3625 3626 static void 3627 upd_dr_dbinfo( 3628 mdsetname_t *sp, 3629 md_drive_desc *dd, 3630 md_error_t *ep 3631 ) 3632 { 3633 mdsetname_t *local_sp; 3634 md_set_record *sr; 3635 md_drive_record *dr; 3636 md_drive_desc *p; 3637 mddrivename_t *dn, *dn1; 3638 ddi_devid_t devid_remote = NULL; 3639 ddi_devid_t devid_local = NULL; 3640 int devid_same = -1; 3641 side_t sideno; 3642 int using_devid = 0; 3643 3644 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3645 return; 3646 3647 metaflushsetname(local_sp); 3648 3649 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3650 return; 3651 3652 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3653 return; 3654 3655 if (dd->dd_dnp == NULL) 3656 return; 3657 3658 /* 3659 * The system is either all devid or all 3660 * non-devid so we determine this by looking 3661 * at the first item in the list. 3662 * 3663 * For did disks, the dd_dnp->devid is a valid pointer which 3664 * points to a '' string of devid. We need to check this 3665 * before set the using_devid. 3666 */ 3667 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3668 (!(MD_MNSET_REC(sr)))) 3669 using_devid = 1; 3670 3671 for (p = dd; p != NULL; p = p->dd_next) { 3672 dn = p->dd_dnp; 3673 devid_remote = NULL; 3674 3675 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3676 using_devid) { 3677 /* 3678 * We have a devid so use it. 3679 */ 3680 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3681 } 3682 3683 /* check to make sure using_devid agrees with reality... */ 3684 if ((using_devid == 1) && (devid_remote == NULL)) { 3685 /* something went really wrong. Can't process */ 3686 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3687 mynode(), dn->cname, sp->setname); 3688 return; 3689 } 3690 3691 for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3692 devid_same = -1; 3693 3694 dn1 = metadrivename_withdrkey(local_sp, sideno, 3695 dr->dr_key, MD_BASICNAME_OK, ep); 3696 3697 if (dn1 == NULL) { 3698 if (devid_remote) 3699 devid_free(devid_remote); 3700 goto out; 3701 } 3702 3703 if (dn1->devid != NULL && using_devid) { 3704 if (devid_str_decode(dn1->devid, &devid_local, 3705 NULL) == 0) { 3706 devid_same = devid_compare(devid_remote, 3707 devid_local); 3708 devid_free(devid_local); 3709 } 3710 } 3711 3712 if (using_devid && devid_same == 0) 3713 break; 3714 3715 if (!using_devid && 3716 strcmp(dn->cname, dn1->cname) == 0) 3717 break; 3718 } 3719 3720 if (dr) { 3721 /* Adjust the fields in the copy */ 3722 dr->dr_dbcnt = p->dd_dbcnt; 3723 dr->dr_dbsize = p->dd_dbsize; 3724 } 3725 if (devid_remote) 3726 devid_free(devid_remote); 3727 } 3728 3729 3730 out: 3731 commitset(sr, FALSE, ep); 3732 free_sr(sr); 3733 } 3734 3735 /* 3736 * update the database count and size field of drive records. 3737 */ 3738 bool_t 3739 mdrpc_upd_dr_dbinfo_common( 3740 mdrpc_drives_2_args_r1 *args, 3741 mdrpc_generic_res *res, 3742 struct svc_req *rqstp /* RPC stuff */ 3743 ) 3744 { 3745 md_error_t *ep = &res->status; 3746 int err; 3747 int op_mode = W_OK; 3748 3749 /* setup, check permissions */ 3750 (void) memset(res, 0, sizeof (*res)); 3751 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3752 return (FALSE); 3753 else if (err != 0) 3754 return (TRUE); 3755 3756 if (check_set_lock(op_mode, args->cl_sk, ep)) 3757 return (TRUE); 3758 3759 /* doit */ 3760 upd_dr_dbinfo(args->sp, args->drivedescs, ep); 3761 3762 err = svc_fini(ep); 3763 3764 return (TRUE); 3765 } 3766 3767 /* 3768 * version 1 of the remote procedure. This procedure is called if the 3769 * client is running in version 1. We first convert version 1 arguments 3770 * into version 2 arguments and then call the common remote procedure. 3771 */ 3772 bool_t 3773 mdrpc_upd_dr_dbinfo_1_svc( 3774 mdrpc_drives_args *args, 3775 mdrpc_generic_res *res, 3776 struct svc_req *rqstp /* RPC stuff */ 3777 ) 3778 { 3779 bool_t retval; 3780 mdrpc_drives_2_args_r1 v2_args; 3781 3782 /* allocate memory */ 3783 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3784 3785 /* build args */ 3786 v2_args.cl_sk = args->cl_sk; 3787 v2_args.sp = args->sp; 3788 /* convert v1 args to v2 (revision 1) args */ 3789 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3790 v2_args.timestamp = args->timestamp; 3791 v2_args.genid = args->genid; 3792 3793 retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp); 3794 3795 free_newdrvdesc(v2_args.drivedescs); 3796 3797 return (retval); 3798 } 3799 3800 bool_t 3801 mdrpc_upd_dr_dbinfo_2_svc( 3802 mdrpc_drives_2_args *args, 3803 mdrpc_generic_res *res, 3804 struct svc_req *rqstp /* RPC stuff */ 3805 ) 3806 { 3807 switch (args->rev) { 3808 case MD_METAD_ARGS_REV_1: 3809 return (mdrpc_upd_dr_dbinfo_common( 3810 &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 3811 default: 3812 return (FALSE); 3813 } 3814 } 3815 3816 static void 3817 upd_dr_flags( 3818 mdsetname_t *sp, 3819 md_drive_desc *dd, 3820 uint_t new_flags, 3821 md_error_t *ep 3822 ) 3823 { 3824 mdsetname_t *local_sp; 3825 md_set_record *sr; 3826 md_drive_record *dr; 3827 md_drive_desc *p; 3828 mddrivename_t *dn, *dn1; 3829 ddi_devid_t devid_remote = NULL; 3830 ddi_devid_t devid_local = NULL; 3831 int devid_same = -1; 3832 side_t sideno; 3833 int using_devid = 0; 3834 3835 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3836 return; 3837 3838 metaflushsetname(local_sp); 3839 3840 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3841 return; 3842 3843 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3844 return; 3845 3846 if (dd->dd_dnp == NULL) 3847 return; 3848 3849 /* 3850 * The system is either all devid or all 3851 * non-devid so we determine this by looking 3852 * at the first item in the list. 3853 * 3854 * For did disks, the dd_dnp->devid is a valid pointer which 3855 * points to a '' string of devid. We need to check this 3856 * before set the using_devid. 3857 */ 3858 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3859 (!(MD_MNSET_REC(sr)))) 3860 using_devid = 1; 3861 3862 for (p = dd; p != NULL; p = p->dd_next) { 3863 dn = p->dd_dnp; 3864 devid_remote = NULL; 3865 3866 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3867 using_devid) { 3868 /* 3869 * We have a devid so use it. 3870 */ 3871 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3872 } 3873 3874 /* check to make sure using_devid agrees with reality... */ 3875 if ((using_devid == 1) && (devid_remote == NULL)) { 3876 /* something went really wrong. Can't process */ 3877 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3878 mynode(), dn->cname, sp->setname); 3879 return; 3880 } 3881 3882 for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3883 devid_same = -1; 3884 3885 dn1 = metadrivename_withdrkey(local_sp, sideno, 3886 dr->dr_key, MD_BASICNAME_OK, ep); 3887 3888 if (dn1 == NULL) { 3889 if (devid_remote) 3890 devid_free(devid_remote); 3891 goto out; 3892 } 3893 3894 if (dn1->devid != NULL && using_devid) { 3895 if (devid_str_decode(dn1->devid, 3896 &devid_local, NULL) == 0) { 3897 devid_same = devid_compare(devid_remote, 3898 devid_local); 3899 devid_free(devid_local); 3900 } 3901 } 3902 3903 if (using_devid && devid_same == 0) 3904 break; 3905 3906 if (!using_devid && 3907 strcmp(dn->cname, dn1->cname) == 0) 3908 break; 3909 } 3910 3911 if (dr) 3912 dr->dr_flags = new_flags; 3913 if (devid_remote) 3914 devid_free(devid_remote); 3915 } 3916 out: 3917 commitset(sr, TRUE, ep); 3918 free_sr(sr); 3919 } 3920 3921 /* 3922 * update the database count and size field of drive records. 3923 */ 3924 bool_t 3925 mdrpc_upd_dr_flags_common( 3926 mdrpc_upd_dr_flags_2_args_r1 *args, 3927 mdrpc_generic_res *res, 3928 struct svc_req *rqstp /* RPC stuff */ 3929 ) 3930 { 3931 md_error_t *ep = &res->status; 3932 int err; 3933 int op_mode = W_OK; 3934 3935 /* setup, check permissions */ 3936 (void) memset(res, 0, sizeof (*res)); 3937 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3938 return (FALSE); 3939 else if (err != 0) 3940 return (TRUE); 3941 3942 if (check_set_lock(op_mode, args->cl_sk, ep)) 3943 return (TRUE); 3944 3945 /* doit */ 3946 upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep); 3947 3948 err = svc_fini(ep); 3949 3950 return (TRUE); 3951 } 3952 3953 /* 3954 * version 1 of the remote procedure. This procedure is called if the 3955 * client is running in version 1. We first convert version 1 arguments 3956 * into version 2 arguments and then call the common remote procedure. 3957 */ 3958 bool_t 3959 mdrpc_upd_dr_flags_1_svc( 3960 mdrpc_upd_dr_flags_args *args, 3961 mdrpc_generic_res *res, 3962 struct svc_req *rqstp /* RPC stuff */ 3963 ) 3964 { 3965 bool_t retval; 3966 mdrpc_upd_dr_flags_2_args_r1 v2_args; 3967 3968 /* allocate memory */ 3969 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3970 3971 /* build args */ 3972 v2_args.cl_sk = args->cl_sk; 3973 v2_args.sp = args->sp; 3974 /* convert v1 args to v2 (revision 1) args */ 3975 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3976 v2_args.new_flags = args->new_flags; 3977 3978 retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp); 3979 3980 free_newdrvdesc(v2_args.drivedescs); 3981 3982 return (retval); 3983 } 3984 3985 bool_t 3986 mdrpc_upd_dr_flags_2_svc( 3987 mdrpc_upd_dr_flags_2_args *args, 3988 mdrpc_generic_res *res, 3989 struct svc_req *rqstp /* RPC stuff */ 3990 ) 3991 { 3992 switch (args->rev) { 3993 case MD_METAD_ARGS_REV_1: 3994 return (mdrpc_upd_dr_flags_common( 3995 &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 3996 default: 3997 return (FALSE); 3998 } 3999 } 4000 4001 static void 4002 upd_sr_flags( 4003 mdsetname_t *sp, 4004 uint_t new_flags, 4005 md_error_t *ep 4006 ) 4007 { 4008 md_set_record *sr; 4009 4010 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4011 return; 4012 4013 sr->sr_flags = new_flags; 4014 commitset(sr, TRUE, ep); 4015 free_sr(sr); 4016 } 4017 4018 /* 4019 * update the set record flags 4020 */ 4021 bool_t 4022 mdrpc_upd_sr_flags_common( 4023 mdrpc_upd_sr_flags_args *args, 4024 mdrpc_generic_res *res, 4025 struct svc_req *rqstp /* RPC stuff */ 4026 ) 4027 { 4028 md_error_t *ep = &res->status; 4029 int err; 4030 int op_mode = W_OK; 4031 4032 /* setup, check permissions */ 4033 (void) memset(res, 0, sizeof (*res)); 4034 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4035 return (FALSE); 4036 else if (err != 0) 4037 return (TRUE); 4038 4039 if (check_set_lock(op_mode, args->cl_sk, ep)) 4040 return (TRUE); 4041 4042 /* doit */ 4043 upd_sr_flags(args->sp, args->new_flags, ep); 4044 4045 err = svc_fini(ep); 4046 4047 return (TRUE); 4048 } 4049 4050 bool_t 4051 mdrpc_upd_sr_flags_1_svc( 4052 mdrpc_upd_sr_flags_args *args, 4053 mdrpc_generic_res *res, 4054 struct svc_req *rqstp /* RPC stuff */ 4055 ) 4056 { 4057 return (mdrpc_upd_sr_flags_common(args, res, rqstp)); 4058 } 4059 4060 bool_t 4061 mdrpc_upd_sr_flags_2_svc( 4062 mdrpc_upd_sr_flags_2_args *args, 4063 mdrpc_generic_res *res, 4064 struct svc_req *rqstp /* RPC stuff */ 4065 ) 4066 { 4067 switch (args->rev) { 4068 case MD_METAD_ARGS_REV_1: 4069 return (mdrpc_upd_sr_flags_common( 4070 &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp)); 4071 default: 4072 return (FALSE); 4073 } 4074 } 4075 4076 /* 4077 * upd_nr_flags updates the node records stored in this node's local mddb 4078 * given a node desciptor list and an action. upd_nr_flags then commits 4079 * the node records to the local mddb. 4080 * 4081 * nd - A linked list of node descriptors that describes the node records 4082 * in this diskset on which the action applies. 4083 * flag_action: action to be taken on node records that match the nd list. 4084 * flag_action can be: 4085 * MD_NR_JOIN: set OWN flag in node records 4086 * MD_NR_WITHDRAW: reset OWN flag in node records 4087 * MD_NR_OK: reset ADD flags and set OK flag in node records 4088 * MD_NR_SET: set node record flags based on flags stored in nd 4089 * 4090 * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting 4091 * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW 4092 * (remove last disk from set) or OK (after addition of host to set). 4093 * 4094 * The SET flag_action is typically used when nodelist contains all nodes 4095 * in the diskset, but specific nodes have had flag changes. An example of 4096 * this would be the join/withdraw of a specific node to/from the set. 4097 * 4098 * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag. This 4099 * flag is used by the client to recover in case of failure and should not 4100 * be set in the node record flags. 4101 */ 4102 static void 4103 upd_nr_flags( 4104 mdsetname_t *sp, 4105 md_mnnode_desc *nd, 4106 uint_t flag_action, 4107 md_error_t *ep 4108 ) 4109 { 4110 mdsetname_t *local_sp; 4111 md_set_record *sr; 4112 md_mnset_record *mnsr; 4113 md_mnnode_desc *ndp; 4114 md_mnnode_record *nrp; 4115 4116 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 4117 return; 4118 4119 metaflushsetname(local_sp); 4120 4121 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4122 return; 4123 4124 if (!(MD_MNSET_REC(sr))) { 4125 return; 4126 } 4127 mnsr = (struct md_mnset_record *)sr; 4128 4129 switch (flag_action) { 4130 case MD_NR_JOIN: 4131 case MD_NR_WITHDRAW: 4132 case MD_NR_SET: 4133 case MD_NR_OK: 4134 case MD_NR_DEL: 4135 break; 4136 default: 4137 return; 4138 } 4139 4140 for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) { 4141 /* Find matching node record for given node descriptor */ 4142 for (nrp = mnsr->sr_nodechain; nrp != NULL; 4143 nrp = nrp->nr_next) { 4144 if (ndp->nd_nodeid == nrp->nr_nodeid) { 4145 switch (flag_action) { 4146 case MD_NR_JOIN: 4147 nrp->nr_flags |= MD_MN_NODE_OWN; 4148 break; 4149 case MD_NR_WITHDRAW: 4150 nrp->nr_flags &= ~MD_MN_NODE_OWN; 4151 break; 4152 case MD_NR_OK: 4153 nrp->nr_flags &= 4154 ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL); 4155 nrp->nr_flags |= MD_MN_NODE_OK; 4156 break; 4157 case MD_NR_DEL: 4158 nrp->nr_flags &= 4159 ~(MD_MN_NODE_OK | MD_MN_NODE_ADD); 4160 nrp->nr_flags |= MD_MN_NODE_DEL; 4161 break; 4162 case MD_NR_SET: 4163 /* Do not set RB_JOIN flag */ 4164 nrp->nr_flags = 4165 ndp->nd_flags & ~MD_MN_NODE_RB_JOIN; 4166 break; 4167 } 4168 break; 4169 } 4170 } 4171 } 4172 out: 4173 /* Don't increment set genid for node record flag update */ 4174 commitset(sr, FALSE, ep); 4175 free_sr(sr); 4176 } 4177 4178 /* 4179 * init/fini wrapper around upd_nr_flags 4180 */ 4181 bool_t 4182 mdrpc_upd_nr_flags_common( 4183 mdrpc_upd_nr_flags_args *args, 4184 mdrpc_generic_res *res, 4185 struct svc_req *rqstp /* RPC stuff */ 4186 ) 4187 { 4188 md_error_t *ep = &res->status; 4189 int err; 4190 int op_mode = W_OK; 4191 4192 /* setup, check permissions */ 4193 (void) memset(res, 0, sizeof (*res)); 4194 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4195 return (FALSE); 4196 else if (err != 0) 4197 return (TRUE); 4198 4199 /* 4200 * During reconfig, node record flags can be updated without 4201 * locking first. 4202 */ 4203 if (!(args->flags & MNSET_IN_RECONFIG)) { 4204 if (check_set_lock(op_mode, args->cl_sk, ep)) 4205 return (TRUE); 4206 } 4207 4208 /* doit */ 4209 upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep); 4210 4211 err = svc_fini(ep); 4212 4213 return (TRUE); 4214 } 4215 4216 /* 4217 * update the node records using given flag action. 4218 */ 4219 bool_t 4220 mdrpc_upd_nr_flags_2_svc( 4221 mdrpc_upd_nr_flags_2_args *args, 4222 mdrpc_generic_res *res, 4223 struct svc_req *rqstp /* RPC stuff */ 4224 ) 4225 { 4226 switch (args->rev) { 4227 case MD_METAD_ARGS_REV_1: 4228 return (mdrpc_upd_nr_flags_common( 4229 &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp)); 4230 default: 4231 return (FALSE); 4232 } 4233 } 4234 4235 void 4236 free_sk(md_setkey_t *skp) 4237 { 4238 Free(skp->sk_setname); 4239 Free(skp->sk_host); 4240 Free(skp); 4241 } 4242 4243 void 4244 del_sk(set_t setno) 4245 { 4246 md_setkey_t *skp; 4247 md_setkey_t *tskp; 4248 4249 for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) { 4250 if (setno == skp->sk_setno) { 4251 if (skp == my_svc_sk) 4252 my_svc_sk = skp->sk_next; 4253 else 4254 tskp->sk_next = skp->sk_next; 4255 4256 Free(skp->sk_setname); 4257 Free(skp->sk_host); 4258 Free(skp); 4259 break; 4260 } 4261 } 4262 } 4263 4264 md_setkey_t * 4265 dupsk(md_setkey_t *skp) 4266 { 4267 md_setkey_t *tskp; 4268 4269 tskp = Zalloc(sizeof (md_setkey_t)); 4270 4271 *tskp = *skp; 4272 tskp->sk_host = Strdup(skp->sk_host); 4273 tskp->sk_setname = Strdup(skp->sk_setname); 4274 4275 return (tskp); 4276 } 4277 4278 md_setkey_t * 4279 svc_get_setkey(set_t setno) 4280 { 4281 md_setkey_t *skp; 4282 4283 for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next) 4284 if (setno == skp->sk_setno) 4285 return (dupsk(skp)); 4286 return (NULL); 4287 } 4288 4289 void 4290 svc_set_setkey(md_setkey_t *svc_sk) 4291 { 4292 md_setkey_t *skp; 4293 4294 if (my_svc_sk == NULL) { 4295 my_svc_sk = dupsk(svc_sk); 4296 return; 4297 } 4298 4299 for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next) 4300 assert(svc_sk->sk_setno != skp->sk_setno); 4301 4302 skp->sk_next = dupsk(svc_sk); 4303 } 4304 4305 /* 4306 * Unlock the set 4307 * 4308 * To unlock the set, the user must have the correct key, once this is verified 4309 * the set is unlocked and the cached information for the set is flushed. 4310 */ 4311 bool_t 4312 mdrpc_unlock_set_common( 4313 mdrpc_null_args *args, 4314 mdrpc_setlock_res *res, 4315 struct svc_req *rqstp /* RPC stuff */ 4316 ) 4317 { 4318 md_error_t *ep = &res->status; 4319 int err; 4320 int op_mode = W_OK; 4321 md_setkey_t *svc_skp; 4322 md_set_desc *sd; 4323 mdsetname_t *sp; 4324 int multi_node = 0; 4325 md_error_t xep = mdnullerror; 4326 4327 /* setup, check permissions */ 4328 (void) memset(res, 0, sizeof (*res)); 4329 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4330 return (FALSE); 4331 else if (err != 0) 4332 return (TRUE); 4333 4334 /* 4335 * Is diskset a MN diskset? 4336 * Don't set error from this check since unlock set can be 4337 * called after a set has been deleted. 4338 */ 4339 if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) && 4340 ((sd = metaget_setdesc(sp, &xep)) != NULL)) { 4341 if ((MD_MNSET_DESC(sd))) { 4342 multi_node = 1; 4343 } 4344 } 4345 4346 /* Get the set key, if any */ 4347 svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4348 4349 /* The set is locked */ 4350 if (svc_skp != NULL) { 4351 4352 /* Make sure the opener has the right key. */ 4353 if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec || 4354 args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) { 4355 (void) mddserror(ep, MDE_DS_ULKSBADKEY, 4356 svc_skp->sk_setno, mynode(), svc_skp->sk_host, 4357 svc_skp->sk_setname); 4358 free_sk(svc_skp); 4359 return (TRUE); 4360 } 4361 4362 /* Unlock the set */ 4363 del_sk(args->cl_sk->sk_setno); 4364 4365 /* Cleanup */ 4366 free_sk(svc_skp); 4367 4368 goto out; 4369 } 4370 4371 4372 /* 4373 * It is possible on a MN diskset to attempt to unlock a set that 4374 * is unlocked. This could occur when the metaset or metadb command 4375 * is failing due to another metaset or metadb command running. 4376 * So, print no warning for MN disksets. 4377 */ 4378 if (multi_node == 0) { 4379 md_eprintf("Warning: set unlocked when unlock_set called!\n"); 4380 } 4381 4382 out: 4383 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4384 4385 /* Flush the set cache */ 4386 sr_cache_flush_setno(args->cl_sk->sk_setno); 4387 4388 return (TRUE); 4389 } 4390 4391 bool_t 4392 mdrpc_unlock_set_1_svc( 4393 mdrpc_null_args *args, 4394 mdrpc_setlock_res *res, 4395 struct svc_req *rqstp /* RPC stuff */ 4396 ) 4397 { 4398 return (mdrpc_unlock_set_common(args, res, rqstp)); 4399 } 4400 4401 bool_t 4402 mdrpc_unlock_set_2_svc( 4403 mdrpc_null_args *args, 4404 mdrpc_setlock_res *res, 4405 struct svc_req *rqstp /* RPC stuff */ 4406 ) 4407 { 4408 return (mdrpc_unlock_set_common(args, res, rqstp)); 4409 } 4410 4411 /* 4412 * Lock the set 4413 * 4414 * If the user does not hand us a key, then we generate a new key and lock the 4415 * set using this new key that was generated, if the user hands us a key then 4416 * we use the key to lock the set. 4417 */ 4418 bool_t 4419 mdrpc_lock_set_common( 4420 mdrpc_null_args *args, 4421 mdrpc_setlock_res *res, 4422 struct svc_req *rqstp /* RPC stuff */ 4423 ) 4424 { 4425 md_error_t *ep = &res->status; 4426 int err; 4427 md_error_t xep = mdnullerror; 4428 int op_mode = W_OK; 4429 md_setkey_t *svc_skp; 4430 md_setkey_t new_sk; 4431 md_set_desc *sd = NULL; 4432 mdsetname_t *sp = NULL; 4433 4434 /* setup, check permissions */ 4435 (void) memset(res, 0, sizeof (*res)); 4436 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4437 return (FALSE); 4438 else if (err != 0) 4439 return (TRUE); 4440 4441 svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4442 4443 /* The set is locked */ 4444 if (svc_skp != NULL) { 4445 4446 /* 4447 * This lock request could be for a new diskset, as 4448 * such metasetnosetname() may not return anything 4449 * useful. Only call it if there is already a key. 4450 */ 4451 if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep)) 4452 != NULL) { 4453 sd = metaget_setdesc(sp, ep); 4454 } 4455 4456 /* 4457 * meta_lock() provides local locking for non-MN 4458 * disksets. The local lock is held before we call 4459 * this RPC function. We should not receive a lock 4460 * request from the host which owns the lock. If we 4461 * do, release the lock. 4462 */ 4463 if (!((sd != NULL) && (MD_MNSET_DESC(sd))) && 4464 (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) { 4465 md_eprintf( 4466 "Warning: set locked when lock_set called!\n"); 4467 4468 md_eprintf("Held lock info:\n"); 4469 4470 md_eprintf("\tLock:\n"); 4471 md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname); 4472 md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno); 4473 md_eprintf("\t\tHost: %s\n", svc_skp->sk_host); 4474 md_eprintf("\t\tKey: %d/%d %s\n", 4475 svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec, 4476 ctime((const time_t *)&svc_skp->sk_key.tv_sec)); 4477 4478 /* Unlock set */ 4479 del_sk(svc_skp->sk_setno); 4480 free_sk(svc_skp); 4481 svc_skp = NULL; 4482 4483 md_eprintf("Released lock held by requesting host\n"); 4484 } 4485 } 4486 4487 /* The set is unlocked */ 4488 if (svc_skp == NULL) { 4489 /* If we have been given a key, use it. */ 4490 if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) { 4491 svc_set_setkey(args->cl_sk); 4492 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4493 goto out; 4494 } 4495 4496 /* We need to lock it, with a new key */ 4497 new_sk = *args->cl_sk; 4498 if (meta_gettimeofday(&new_sk.sk_key) == -1) { 4499 (void) mdsyserror(ep, errno, "meta_gettimeofday()"); 4500 mde_perror(&xep, ""); 4501 md_exit(NULL, 1); 4502 } 4503 svc_set_setkey(&new_sk); 4504 4505 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4506 goto out; 4507 } 4508 4509 /* 4510 * If a MN diskset, the lock_set routine is used as a locking 4511 * mechanism to keep multiple metaset and/or metadb commads 4512 * from interfering with each other. If two metaset/metadb 4513 * commands are issued at the same time - one will complete 4514 * and the other command will fail with MDE_DS_NOTNOW_CMD. 4515 */ 4516 if ((sd != NULL) && MD_MNSET_DESC(sd)) { 4517 (void) mddserror(ep, MDE_DS_NOTNOW_CMD, 4518 svc_skp->sk_setno, mynode(), 4519 svc_skp->sk_host, svc_skp->sk_setname); 4520 goto out; 4521 } 4522 4523 md_eprintf("Warning: set locked when lock_set called!\n"); 4524 4525 md_eprintf("Lock info:\n"); 4526 4527 md_eprintf("\tLock(svc):\n"); 4528 md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname); 4529 md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno); 4530 md_eprintf("\t\tHost: %s\n", svc_skp->sk_host); 4531 md_eprintf("\t\tKey: %d/%d %s", 4532 svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec, 4533 ctime((const time_t *)&svc_skp->sk_key.tv_sec)); 4534 4535 md_eprintf("\tLock(cl):\n"); 4536 md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname); 4537 md_eprintf("\t\tSetno: %d\n", args->cl_sk->sk_setno); 4538 md_eprintf("\t\tHost: %s\n", args->cl_sk->sk_host); 4539 md_eprintf("\t\tKey: %d/%d %s", 4540 args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec, 4541 ctime((const time_t *)&args->cl_sk->sk_key.tv_sec)); 4542 4543 /* The set is locked, do we have the key? */ 4544 if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec && 4545 args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) { 4546 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4547 goto out; 4548 } 4549 4550 /* 4551 * The set is locked and we do not have the key, so we set up an error. 4552 */ 4553 (void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(), 4554 svc_skp->sk_host, args->cl_sk->sk_setname); 4555 4556 out: 4557 if (svc_skp != NULL) 4558 free_sk(svc_skp); 4559 4560 /* Flush the set cache */ 4561 sr_cache_flush_setno(args->cl_sk->sk_setno); 4562 4563 return (TRUE); 4564 } 4565 4566 bool_t 4567 mdrpc_lock_set_1_svc( 4568 mdrpc_null_args *args, 4569 mdrpc_setlock_res *res, 4570 struct svc_req *rqstp /* RPC stuff */ 4571 ) 4572 { 4573 return (mdrpc_lock_set_common(args, res, rqstp)); 4574 } 4575 4576 bool_t 4577 mdrpc_lock_set_2_svc( 4578 mdrpc_null_args *args, 4579 mdrpc_setlock_res *res, 4580 struct svc_req *rqstp /* RPC stuff */ 4581 ) 4582 { 4583 return (mdrpc_lock_set_common(args, res, rqstp)); 4584 } 4585 4586 static void 4587 updmeds( 4588 char *setname, 4589 md_h_arr_t *medp, 4590 int version, /* RPC version of calling routine */ 4591 md_error_t *ep 4592 ) 4593 { 4594 mddb_userreq_t req; 4595 md_set_record *sr; 4596 mddb_med_parm_t mp; 4597 4598 if ((sr = getsetbyname(setname, ep)) == NULL) 4599 return; 4600 4601 sr->sr_med = *medp; /* structure assignment */ 4602 4603 (void) memset(&req, '\0', sizeof (req)); 4604 4605 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 4606 /* Do MN operation if rpc version supports it and if a MN set */ 4607 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 4608 req.ur_size = sizeof (struct md_mnset_record); 4609 } else { 4610 req.ur_size = sizeof (*sr); 4611 } 4612 req.ur_data = (uintptr_t)sr; 4613 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 4614 (void) mdstealerror(ep, &req.ur_mde); 4615 free_sr(sr); 4616 return; 4617 } 4618 4619 commitset(sr, TRUE, ep); 4620 4621 /* 4622 * If a MN disket, send the mediator list to the kernel. 4623 */ 4624 if (MD_MNSET_REC(sr)) { 4625 (void) memset(&mp, '\0', sizeof (mddb_med_parm_t)); 4626 mp.med_setno = sr->sr_setno; 4627 if (meta_h2hi(medp, &mp.med, ep)) { 4628 free_sr(sr); 4629 return; 4630 } 4631 4632 /* Resolve the IP addresses for the host list */ 4633 if (meta_med_hnm2ip(&mp.med, ep)) { 4634 free_sr(sr); 4635 return; 4636 } 4637 4638 /* If node not yet joined to set, failure is ok. */ 4639 if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) { 4640 if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) { 4641 (void) mdstealerror(ep, &mp.med_mde); 4642 } 4643 } 4644 } 4645 free_sr(sr); 4646 } 4647 4648 /* 4649 * Update the mediator data in the set record 4650 */ 4651 bool_t 4652 mdrpc_updmeds_common( 4653 mdrpc_updmeds_args *args, 4654 mdrpc_generic_res *res, 4655 struct svc_req *rqstp, /* RPC stuff */ 4656 int version /* RPC version */ 4657 ) 4658 { 4659 md_error_t *ep = &res->status; 4660 int err; 4661 int op_mode = W_OK; 4662 4663 /* setup, check permissions */ 4664 (void) memset(res, 0, sizeof (*res)); 4665 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4666 return (FALSE); 4667 else if (err != 0) 4668 return (TRUE); 4669 4670 if (check_set_lock(op_mode, args->cl_sk, ep)) 4671 return (TRUE); 4672 4673 /* doit */ 4674 updmeds(args->sp->setname, &args->meds, version, ep); 4675 4676 err = svc_fini(ep); 4677 4678 return (TRUE); 4679 } 4680 4681 bool_t 4682 mdrpc_updmeds_1_svc( 4683 mdrpc_updmeds_args *args, 4684 mdrpc_generic_res *res, 4685 struct svc_req *rqstp /* RPC stuff */ 4686 ) 4687 { 4688 /* Pass RPC version (METAD_VERSION) to common routine */ 4689 return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION)); 4690 } 4691 4692 bool_t 4693 mdrpc_updmeds_2_svc( 4694 mdrpc_updmeds_2_args *args, 4695 mdrpc_generic_res *res, 4696 struct svc_req *rqstp /* RPC stuff */ 4697 ) 4698 { 4699 switch (args->rev) { 4700 case MD_METAD_ARGS_REV_1: 4701 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 4702 return (mdrpc_updmeds_common( 4703 &args->mdrpc_updmeds_2_args_u.rev1, res, 4704 rqstp, METAD_VERSION_DEVID)); 4705 default: 4706 return (FALSE); 4707 } 4708 } 4709 4710 /* 4711 * Call routines to suspend, reinit and resume mdcommd. 4712 * Called during metaset and metadb command. 4713 * NOT called during reconfig cycle. 4714 */ 4715 bool_t 4716 mdrpc_mdcommdctl_2_svc( 4717 mdrpc_mdcommdctl_2_args *args, 4718 mdrpc_generic_res *res, 4719 struct svc_req *rqstp /* RPC stuff */ 4720 ) 4721 { 4722 mdrpc_mdcommdctl_args *args_cc; 4723 md_error_t *ep = &res->status; 4724 int err; 4725 int op_mode = R_OK; 4726 int suspend_ret; 4727 4728 switch (args->rev) { 4729 case MD_METAD_ARGS_REV_1: 4730 /* setup, check permissions */ 4731 (void) memset(res, 0, sizeof (*res)); 4732 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4733 return (FALSE); 4734 else if (err != 0) 4735 return (TRUE); 4736 4737 args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1); 4738 switch (args_cc->flag_action) { 4739 case COMMDCTL_SUSPEND: 4740 suspend_ret = mdmn_suspend(args_cc->setno, 4741 args_cc->class); 4742 if (suspend_ret != 0) { 4743 (void) mddserror(ep, suspend_ret, 4744 args_cc->setno, mynode(), 4745 NULL, mynode()); 4746 } 4747 break; 4748 case COMMDCTL_RESUME: 4749 if (mdmn_resume(args_cc->setno, 4750 args_cc->class, args_cc->flags)) { 4751 (void) mddserror(ep, 4752 MDE_DS_COMMDCTL_RESUME_FAIL, 4753 args_cc->setno, mynode(), 4754 NULL, mynode()); 4755 } 4756 break; 4757 case COMMDCTL_REINIT: 4758 if (mdmn_reinit_set(args_cc->setno)) { 4759 (void) mddserror(ep, 4760 MDE_DS_COMMDCTL_REINIT_FAIL, 4761 args_cc->setno, mynode(), 4762 NULL, mynode()); 4763 } 4764 break; 4765 } 4766 err = svc_fini(ep); 4767 return (TRUE); 4768 4769 default: 4770 return (FALSE); 4771 } 4772 } 4773 4774 /* 4775 * Return TRUE if set is stale. 4776 */ 4777 bool_t 4778 mdrpc_mn_is_stale_2_svc( 4779 mdrpc_setno_2_args *args, 4780 mdrpc_bool_res *res, 4781 struct svc_req *rqstp /* RPC stuff */ 4782 ) 4783 { 4784 md_error_t *ep = &res->status; 4785 mddb_config_t c; 4786 int err; 4787 int op_mode = R_OK; 4788 4789 (void) memset(&c, 0, sizeof (c)); 4790 switch (args->rev) { 4791 case MD_METAD_ARGS_REV_1: 4792 c.c_id = 0; 4793 c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno; 4794 4795 /* setup, check permissions */ 4796 (void) memset(res, 0, sizeof (*res)); 4797 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4798 return (FALSE); 4799 else if (err != 0) 4800 return (TRUE); 4801 4802 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) { 4803 mdstealerror(ep, &c.c_mde); 4804 return (TRUE); 4805 } 4806 4807 if (c.c_flags & MDDB_C_STALE) { 4808 res->value = TRUE; 4809 } else { 4810 res->value = FALSE; 4811 } 4812 4813 err = svc_fini(ep); 4814 return (TRUE); 4815 4816 default: 4817 return (FALSE); 4818 } 4819 } 4820 4821 /* 4822 * Clear out all clnt_locks held by all MN disksets. 4823 * This is only used during a reconfig cycle. 4824 */ 4825 /* ARGSUSED */ 4826 int 4827 mdrpc_clr_mnsetlock_2_svc( 4828 mdrpc_null_args *args, 4829 mdrpc_generic_res *res, 4830 struct svc_req *rqstp /* RPC stuff */ 4831 ) 4832 { 4833 set_t max_sets, setno; 4834 md_error_t *ep = &res->status; 4835 int err; 4836 int op_mode = W_OK; 4837 mdsetname_t *sp; 4838 4839 /* setup, check permissions */ 4840 (void) memset(res, 0, sizeof (*res)); 4841 4842 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4843 return (FALSE); 4844 else if (err != 0) 4845 return (TRUE); 4846 4847 /* 4848 * Walk through all possible disksets. 4849 * For each MN set, delete all keys associated with that set. 4850 */ 4851 if ((max_sets = get_max_sets(ep)) == 0) { 4852 return (TRUE); 4853 } 4854 4855 /* start walking through all possible disksets */ 4856 for (setno = 1; setno < max_sets; setno++) { 4857 if ((sp = metasetnosetname(setno, ep)) == NULL) { 4858 if (mdiserror(ep, MDE_NO_SET)) { 4859 /* No set for this setno - continue */ 4860 mdclrerror(ep); 4861 continue; 4862 } else { 4863 mde_perror(ep, gettext( 4864 "Unable to get set %s information"), 4865 sp->setname); 4866 mdclrerror(ep); 4867 continue; 4868 } 4869 } 4870 4871 /* only check multi-node disksets */ 4872 if (!meta_is_mn_set(sp, ep)) { 4873 mdclrerror(ep); 4874 continue; 4875 } 4876 4877 /* Delete keys associated with rpc.metad clnt_lock */ 4878 del_sk(setno); 4879 } 4880 4881 *ep = mdnullerror; 4882 4883 err = svc_fini(ep); 4884 4885 return (TRUE); 4886 } 4887 4888 /* 4889 * Get drive desc on this host for given setno. 4890 * This is only used during a reconfig cycle. 4891 * Returns a drive desc structure for the given mdsetname 4892 * from this host. 4893 * 4894 * Returned drive desc structure is partially filled in with 4895 * the drive name but is not filled in with any other strings 4896 * in the drivename structure. 4897 */ 4898 bool_t 4899 mdrpc_getdrivedesc_2_svc( 4900 mdrpc_sp_2_args *args, 4901 mdrpc_getdrivedesc_res *res, 4902 struct svc_req *rqstp /* RPC stuff */ 4903 ) 4904 { 4905 md_drive_desc *dd; 4906 md_error_t *ep = &res->status; 4907 int err; 4908 int op_mode = R_OK; 4909 mdsetname_t *my_sp; 4910 mdrpc_sp_args *args_r1; 4911 4912 switch (args->rev) { 4913 case MD_METAD_ARGS_REV_1: 4914 /* setup, check permissions */ 4915 (void) memset(res, 0, sizeof (*res)); 4916 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4917 return (FALSE); 4918 else if (err != 0) 4919 return (TRUE); 4920 4921 /* doit */ 4922 args_r1 = &args->mdrpc_sp_2_args_u.rev1; 4923 if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL) 4924 return (TRUE); 4925 4926 dd = metaget_drivedesc(my_sp, 4927 (MD_BASICNAME_OK | PRINT_FAST), ep); 4928 4929 res->dd = dd_list_dup(dd); 4930 4931 err = svc_fini(ep); 4932 4933 return (TRUE); 4934 default: 4935 return (FALSE); 4936 } 4937 } 4938 4939 /* 4940 * Update drive records given list from master during reconfig. 4941 * Make this node's list match the master's list which may include 4942 * deleting a drive record that is known by this node and not known 4943 * by the master node. 4944 * 4945 * Sync up the set/node/drive record genids to match the genid 4946 * passed in the dd structure (all genids in this structure 4947 * are the same). 4948 */ 4949 bool_t 4950 mdrpc_upd_dr_reconfig_common( 4951 mdrpc_upd_dr_flags_2_args_r1 *args, 4952 mdrpc_generic_res *res, 4953 struct svc_req *rqstp /* RPC stuff */ 4954 ) 4955 { 4956 md_error_t *ep = &res->status; 4957 int err; 4958 mdsetname_t *local_sp; 4959 md_set_record *sr; 4960 md_mnset_record *mnsr; 4961 md_drive_record *dr, *dr_placeholder = NULL; 4962 md_drive_desc *dd; 4963 mddrivename_t *dn, *dn1; 4964 side_t sideno; 4965 md_mnnode_record *nrp; 4966 int op_mode = W_OK; 4967 int change = 0; 4968 4969 /* setup, check permissions */ 4970 (void) memset(res, 0, sizeof (*res)); 4971 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4972 return (FALSE); 4973 else if (err != 0) 4974 return (TRUE); 4975 4976 if ((local_sp = metasetname(args->sp->setname, ep)) == NULL) 4977 return (TRUE); 4978 4979 metaflushsetname(local_sp); 4980 4981 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 4982 return (TRUE); 4983 4984 if ((sr = getsetbyname(args->sp->setname, ep)) == NULL) 4985 return (TRUE); 4986 4987 if (!(MD_MNSET_REC(sr))) { 4988 free_sr(sr); 4989 return (TRUE); 4990 } 4991 4992 mnsr = (md_mnset_record *)sr; 4993 /* Setup genid on set and node records */ 4994 if (args->drivedescs) { 4995 if (mnsr->sr_genid != args->drivedescs->dd_genid) { 4996 change = 1; 4997 mnsr->sr_genid = args->drivedescs->dd_genid; 4998 } 4999 nrp = mnsr->sr_nodechain; 5000 while (nrp) { 5001 if (nrp->nr_genid != args->drivedescs->dd_genid) { 5002 change = 1; 5003 nrp->nr_genid = args->drivedescs->dd_genid; 5004 } 5005 nrp = nrp->nr_next; 5006 } 5007 } 5008 for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) { 5009 dn1 = metadrivename_withdrkey(local_sp, sideno, 5010 dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep); 5011 if (dn1 == NULL) 5012 goto out; 5013 for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) { 5014 dn = dd->dd_dnp; 5015 /* Found this node's drive rec to match dd */ 5016 if (strcmp(dn->cname, dn1->cname) == 0) 5017 break; 5018 } 5019 5020 /* 5021 * If drive found in master's list, make slave match master. 5022 * If drive not found in master's list, remove drive. 5023 */ 5024 if (dd) { 5025 if ((dr->dr_flags != dd->dd_flags) || 5026 (dr->dr_genid != dd->dd_genid)) { 5027 change = 1; 5028 dr->dr_flags = dd->dd_flags; 5029 dr->dr_genid = dd->dd_genid; 5030 } 5031 } else { 5032 /* 5033 * Delete entry from linked list. Need to use 5034 * dr_placeholder so that dr->dr_next points to 5035 * the next drive record in the list. 5036 */ 5037 if (dr_placeholder == NULL) { 5038 dr_placeholder = 5039 Zalloc(sizeof (md_drive_record)); 5040 } 5041 dr_placeholder->dr_next = dr->dr_next; 5042 dr_placeholder->dr_key = dr->dr_key; 5043 sr_del_drv(sr, dr->dr_selfid); 5044 (void) del_sideno_sidenm(dr_placeholder->dr_key, 5045 sideno, ep); 5046 change = 1; 5047 dr = dr_placeholder; 5048 } 5049 } 5050 out: 5051 /* If incore records are correct, don't need to write to disk */ 5052 if (change) { 5053 /* Don't increment the genid in commitset */ 5054 commitset(sr, FALSE, ep); 5055 } 5056 free_sr(sr); 5057 5058 err = svc_fini(ep); 5059 5060 if (dr_placeholder != NULL) 5061 Free(dr_placeholder); 5062 5063 return (TRUE); 5064 } 5065 5066 /* 5067 * Version 2 routine to update this node's drive records based on 5068 * list passed in from master node. 5069 */ 5070 bool_t 5071 mdrpc_upd_dr_reconfig_2_svc( 5072 mdrpc_upd_dr_flags_2_args *args, 5073 mdrpc_generic_res *res, 5074 struct svc_req *rqstp /* RPC stuff */ 5075 ) 5076 { 5077 switch (args->rev) { 5078 case MD_METAD_ARGS_REV_1: 5079 return (mdrpc_upd_dr_reconfig_common( 5080 &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 5081 default: 5082 return (FALSE); 5083 } 5084 } 5085 5086 /* 5087 * reset mirror owner for mirrors owned by deleted 5088 * or withdrawn host(s). Hosts being deleted or 5089 * withdrawn are designated by nodeid since host is 5090 * already deleted or withdrawn from set and may not 5091 * be able to translate between a nodename and a nodeid. 5092 * If an error occurs, ep will be set to that error information. 5093 */ 5094 static void 5095 reset_mirror_owner( 5096 char *setname, 5097 int node_c, 5098 int *node_id, /* Array of node ids */ 5099 md_error_t *ep 5100 ) 5101 { 5102 mdsetname_t *local_sp; 5103 int i; 5104 mdnamelist_t *devnlp = NULL; 5105 mdnamelist_t *p; 5106 mdname_t *devnp = NULL; 5107 md_set_mmown_params_t ownpar_p; 5108 md_set_mmown_params_t *ownpar = &ownpar_p; 5109 char *miscname; 5110 5111 if ((local_sp = metasetname(setname, ep)) == NULL) 5112 return; 5113 5114 /* get a list of all the mirrors for current set */ 5115 if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0) 5116 return; 5117 5118 /* for each mirror */ 5119 for (p = devnlp; (p != NULL); p = p->next) { 5120 devnp = p->namep; 5121 5122 /* 5123 * we can only do these for mirrors so make sure we 5124 * really have a mirror device and not a softpartition 5125 * imitating one. meta_get_mirror_names seems to think 5126 * softparts on top of a mirror are mirrors! 5127 */ 5128 if ((miscname = metagetmiscname(devnp, ep)) == NULL) 5129 goto out; 5130 if (strcmp(miscname, MD_MIRROR) != 0) 5131 continue; 5132 5133 (void) memset(ownpar, 0, sizeof (*ownpar)); 5134 ownpar->d.mnum = meta_getminor(devnp->dev); 5135 MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno); 5136 5137 /* get the current owner id */ 5138 if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep, 5139 "MD_MN_GET_MM_OWNER") != 0) { 5140 mde_perror(ep, gettext( 5141 "Unable to get mirror owner for %s/%s"), 5142 local_sp->setname, 5143 get_mdname(local_sp, ownpar->d.mnum)); 5144 goto out; 5145 } 5146 5147 if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) { 5148 mdclrerror(ep); 5149 continue; 5150 } 5151 /* 5152 * reset owner only if the current owner is 5153 * in the list of nodes being deleted. 5154 */ 5155 for (i = 0; i < node_c; i++) { 5156 if (ownpar->d.owner == node_id[i]) { 5157 if (meta_mn_change_owner(&ownpar, 5158 local_sp->setno, ownpar->d.mnum, 5159 MD_MN_MIRROR_UNOWNED, 5160 MD_MN_MM_ALLOW_CHANGE) == -1) { 5161 mde_perror(ep, gettext( 5162 "Unable to reset mirror owner for" 5163 " %s/%s"), local_sp->setname, 5164 get_mdname(local_sp, 5165 ownpar->d.mnum)); 5166 goto out; 5167 } 5168 break; 5169 } 5170 } 5171 } 5172 5173 out: 5174 /* cleanup */ 5175 metafreenamelist(devnlp); 5176 } 5177 5178 /* 5179 * Wrapper routine for reset_mirror_owner. 5180 * Called when hosts are deleted or withdrawn 5181 * in order to reset any mirror owners that are needed. 5182 */ 5183 bool_t 5184 mdrpc_reset_mirror_owner_common( 5185 mdrpc_nodeid_args *args, 5186 mdrpc_generic_res *res, 5187 struct svc_req *rqstp /* RPC stuff */ 5188 ) 5189 { 5190 md_error_t *ep = &res->status; 5191 int err; 5192 int op_mode = W_OK; 5193 5194 /* setup, check permissions */ 5195 (void) memset(res, 0, sizeof (*res)); 5196 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5197 return (FALSE); 5198 else if (err != 0) 5199 return (TRUE); 5200 5201 if (check_set_lock(op_mode, args->cl_sk, ep)) 5202 return (TRUE); 5203 5204 /* doit */ 5205 reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len, 5206 args->nodeid.nodeid_val, ep); 5207 5208 err = svc_fini(ep); 5209 5210 return (TRUE); 5211 } 5212 5213 /* 5214 * RPC service routine to reset the mirror owner for mirrors owned 5215 * by the given hosts. Typically, the list of given hosts is a list 5216 * of nodes being deleted or withdrawn from a diskset. 5217 * The given hosts are designated by nodeid since host may 5218 * already be deleted or withdrawn from set and may not 5219 * be able to translate between a nodename and a nodeid. 5220 */ 5221 bool_t 5222 mdrpc_reset_mirror_owner_2_svc( 5223 mdrpc_nodeid_2_args *args, 5224 mdrpc_generic_res *res, 5225 struct svc_req *rqstp /* RPC stuff */ 5226 ) 5227 { 5228 switch (args->rev) { 5229 case MD_METAD_ARGS_REV_1: 5230 return (mdrpc_reset_mirror_owner_common( 5231 &args->mdrpc_nodeid_2_args_u.rev1, res, 5232 rqstp)); 5233 default: 5234 return (FALSE); 5235 } 5236 } 5237 5238 /* 5239 * Call routines to suspend and resume I/O for the given diskset(s). 5240 * Called during reconfig cycle. 5241 * Diskset of 0 represents all MN disksets. 5242 */ 5243 bool_t 5244 mdrpc_mn_susp_res_io_2_svc( 5245 mdrpc_mn_susp_res_io_2_args *args, 5246 mdrpc_generic_res *res, 5247 struct svc_req *rqstp /* RPC stuff */ 5248 ) 5249 { 5250 mdrpc_mn_susp_res_io_args *args_sr; 5251 md_error_t *ep = &res->status; 5252 int err; 5253 int op_mode = R_OK; 5254 5255 switch (args->rev) { 5256 case MD_METAD_ARGS_REV_1: 5257 /* setup, check permissions */ 5258 (void) memset(res, 0, sizeof (*res)); 5259 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5260 return (FALSE); 5261 else if (err != 0) 5262 return (TRUE); 5263 5264 args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1); 5265 switch (args_sr->susp_res_cmd) { 5266 case MN_SUSP_IO: 5267 (void) (metaioctl(MD_MN_SUSPEND_SET, 5268 &args_sr->susp_res_setno, ep, NULL)); 5269 break; 5270 case MN_RES_IO: 5271 (void) (metaioctl(MD_MN_RESUME_SET, 5272 &args_sr->susp_res_setno, ep, NULL)); 5273 break; 5274 } 5275 err = svc_fini(ep); 5276 return (TRUE); 5277 5278 default: 5279 return (FALSE); 5280 } 5281 } 5282 5283 /* 5284 * Resnarf a set after it has been imported 5285 */ 5286 bool_t 5287 mdrpc_resnarf_set_2_svc( 5288 mdrpc_setno_2_args *args, 5289 mdrpc_generic_res *res, 5290 struct svc_req *rqstp /* RPC stuff */ 5291 ) 5292 { 5293 mdrpc_setno_args *setno_args; 5294 md_error_t *ep = &res->status; 5295 int err; 5296 int op_mode = R_OK; 5297 5298 switch (args->rev) { 5299 case MD_METAD_ARGS_REV_1: 5300 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5301 break; 5302 default: 5303 return (FALSE); 5304 } 5305 5306 (void) memset(res, 0, sizeof (*res)); 5307 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5308 return (FALSE); 5309 else if (err != 0) 5310 return (TRUE); 5311 5312 /* do it */ 5313 if (resnarf_set(setno_args->setno, ep) < 0) 5314 return (FALSE); 5315 5316 err = svc_fini(ep); 5317 return (TRUE); 5318 } 5319 5320 /* 5321 * Creates a resync thread. 5322 * Always returns true. 5323 */ 5324 bool_t 5325 mdrpc_mn_mirror_resync_all_2_svc( 5326 mdrpc_setno_2_args *args, 5327 mdrpc_generic_res *res, 5328 struct svc_req *rqstp /* RPC stuff */ 5329 ) 5330 { 5331 md_error_t *ep = &res->status; 5332 mdrpc_setno_args *setno_args; 5333 int err; 5334 int op_mode = R_OK; 5335 5336 switch (args->rev) { 5337 case MD_METAD_ARGS_REV_1: 5338 /* setup, check permissions */ 5339 (void) memset(res, 0, sizeof (*res)); 5340 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5341 return (FALSE); 5342 else if (err != 0) 5343 return (TRUE); 5344 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5345 5346 /* 5347 * Need to invoke a metasync on a node newly added to a set. 5348 */ 5349 meta_mn_mirror_resync_all(&(setno_args->setno)); 5350 5351 err = svc_fini(ep); 5352 return (TRUE); 5353 5354 default: 5355 return (FALSE); 5356 } 5357 } 5358 5359 /* 5360 * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(), 5361 * which forks a daemon process to perform this action. 5362 * Always returns true. 5363 */ 5364 bool_t 5365 mdrpc_mn_sp_update_abr_2_svc( 5366 mdrpc_setno_2_args *args, 5367 mdrpc_generic_res *res, 5368 struct svc_req *rqstp /* RPC stuff */ 5369 ) 5370 { 5371 md_error_t *ep = &res->status; 5372 mdrpc_setno_args *setno_args; 5373 int err; 5374 int op_mode = R_OK; 5375 5376 switch (args->rev) { 5377 case MD_METAD_ARGS_REV_1: 5378 /* setup, check permissions */ 5379 (void) memset(res, 0, sizeof (*res)); 5380 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5381 return (FALSE); 5382 else if (err != 0) 5383 return (TRUE); 5384 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5385 5386 meta_mn_sp_update_abr(&(setno_args->setno)); 5387 5388 err = svc_fini(ep); 5389 return (TRUE); 5390 5391 default: 5392 return (FALSE); 5393 } 5394 } 5395