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