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