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