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