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