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