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 /* Causes mddbs to be loaded in kernel */ 2890 if (setup_db_bydd(local_sp, mydd, 0, ep) == -1) { 2891 /* If ep isn't set for some reason, set it */ 2892 if (! mdisok(ep)) { 2893 (void) mdmddberror(ep, MDE_DB_NOTNOW, 2894 (minor_t)NODEV64, sp->setno, 0, NULL); 2895 } 2896 return; 2897 } 2898 2899 if (flags & MNSET_IS_STALE) 2900 stale_bool = TRUE; 2901 else 2902 stale_bool = FALSE; 2903 2904 /* 2905 * Snarf the set. No failure has occurred if STALE or 2906 * ACCOK error was set. Otherwise, fail the call setting 2907 * a generic error if no error was already set. 2908 * 2909 * STALE means that set has < 50% mddbs. 2910 * ACCOK means that the mediator provided an extra vote. 2911 */ 2912 if (snarf_set(local_sp, stale_bool, ep) != 0) { 2913 if (!(mdismddberror(ep, MDE_DB_STALE)) && 2914 !(mdismddberror(ep, MDE_DB_ACCOK))) { 2915 return; 2916 } else if (mdisok(ep)) { 2917 /* If snarf failed, but no error set - set it */ 2918 (void) mdmddberror(ep, MDE_DB_NOTNOW, 2919 (minor_t)NODEV64, sp->setno, 0, NULL); 2920 return; 2921 } 2922 } 2923 2924 /* 2925 * If node is joining during reconfig cycle, then 2926 * set mddb_parse to be in blocked state so that 2927 * mddb reparse messages are not generated until 2928 * the commd has been resumed later in the reconfig 2929 * cycle. 2930 */ 2931 if (flags & MNSET_IN_RECONFIG) { 2932 (void) memset(&mbp, 0, sizeof (mbp)); 2933 if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) { 2934 (void) memset(&mbp, 0, sizeof (mbp)); 2935 mbp.c_setno = local_sp->setno; 2936 mbp.c_blk_flags = MDDB_BLOCK_PARSE; 2937 if (metaioctl(MD_MN_MDDB_BLOCK, &mbp, 2938 &mbp.c_mde, NULL)) { 2939 mdstealerror(&xep, &mbp.c_mde); 2940 mde_perror(ep, gettext( 2941 "Could not block set %s"), 2942 sp->setname); 2943 return; 2944 } 2945 } 2946 /* 2947 * If s_ownset fails and snarf_set succeeded, 2948 * then can steal the ownset failure information 2949 * and store it into ep. If snarf_set failed, 2950 * don't overwrite critical ep information even 2951 * if s_ownset failed. 2952 */ 2953 if (!mdisok(&xep)) { 2954 /* 2955 * If snarf_set succeeded or snarf_set failed 2956 * with MDE_DB_ACCOK (which is set if the 2957 * mediator provided the extra vote) then 2958 * steal the xep failure information and put 2959 * into ep. 2960 */ 2961 if (mdisok(ep) || 2962 mdismddberror(ep, MDE_DB_ACCOK)) { 2963 mdstealerror(ep, &xep); 2964 } 2965 } 2966 } 2967 } 2968 } 2969 2970 /* 2971 * Have this node join the set. 2972 * This is called when a node has been 2973 * added to a MN diskset that has drives. 2974 * Also, called when a node is an alive 2975 * member of a MN diskset and the first 2976 * drive has been added. 2977 */ 2978 bool_t 2979 mdrpc_joinset_common( 2980 mdrpc_sp_flags_args *args, 2981 mdrpc_generic_res *res, 2982 struct svc_req *rqstp /* RPC stuff */ 2983 ) 2984 { 2985 md_error_t *ep = &res->status; 2986 int err; 2987 int op_mode = W_OK; 2988 2989 /* setup, check permissions */ 2990 (void) memset(res, 0, sizeof (*res)); 2991 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2992 return (FALSE); 2993 else if (err != 0) 2994 return (TRUE); 2995 2996 /* 2997 * During reconfig, joinset can happen without 2998 * locking first. Turn off reconfig flag before calling 2999 * joinset. 3000 */ 3001 if (!(args->flags & MNSET_IN_RECONFIG)) { 3002 if (check_set_lock(op_mode, args->cl_sk, ep)) 3003 return (TRUE); 3004 } 3005 3006 /* doit */ 3007 joinset(args->sp, args->flags, ep); 3008 3009 err = svc_fini(ep); 3010 3011 return (TRUE); 3012 } 3013 3014 bool_t 3015 mdrpc_joinset_2_svc( 3016 mdrpc_sp_flags_2_args *args, 3017 mdrpc_generic_res *res, 3018 struct svc_req *rqstp /* RPC stuff */ 3019 ) 3020 { 3021 switch (args->rev) { 3022 case MD_METAD_ARGS_REV_1: 3023 return (mdrpc_joinset_common( 3024 &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp)); 3025 default: 3026 return (FALSE); 3027 } 3028 } 3029 3030 static void 3031 withdrawset( 3032 mdsetname_t *sp, 3033 md_error_t *ep 3034 ) 3035 { 3036 mdsetname_t *my_sp; 3037 3038 if ((my_sp = metasetname(sp->setname, ep)) == NULL) 3039 return; 3040 3041 (void) halt_set(my_sp, ep); 3042 } 3043 3044 /* 3045 * Have this node withdraw from set. 3046 * In response to a failure that occurred 3047 * on the client after a joinset. 3048 */ 3049 bool_t 3050 mdrpc_withdrawset_common( 3051 mdrpc_sp_args *args, 3052 mdrpc_generic_res *res, 3053 struct svc_req *rqstp /* RPC stuff */ 3054 ) 3055 { 3056 md_error_t *ep = &res->status; 3057 int err; 3058 int op_mode = W_OK; 3059 3060 /* setup, check permissions */ 3061 (void) memset(res, 0, sizeof (*res)); 3062 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3063 return (FALSE); 3064 else if (err != 0) 3065 return (TRUE); 3066 3067 if (check_set_lock(op_mode, args->cl_sk, ep)) 3068 return (TRUE); 3069 3070 /* doit */ 3071 withdrawset(args->sp, ep); 3072 3073 err = svc_fini(ep); 3074 3075 return (TRUE); 3076 } 3077 3078 bool_t 3079 mdrpc_withdrawset_2_svc( 3080 mdrpc_sp_2_args *args, 3081 mdrpc_generic_res *res, 3082 struct svc_req *rqstp /* RPC stuff */ 3083 ) 3084 { 3085 switch (args->rev) { 3086 case MD_METAD_ARGS_REV_1: 3087 return (mdrpc_withdrawset_common( 3088 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3089 default: 3090 return (FALSE); 3091 } 3092 } 3093 3094 static mhd_mhiargs_t * 3095 gtimeout(mdsetname_t *sp, md_error_t *ep) 3096 { 3097 md_set_record *sr; 3098 mhd_mhiargs_t *mhiargs; 3099 3100 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3101 return (NULL); 3102 3103 mhiargs = Zalloc(sizeof (*mhiargs)); 3104 *mhiargs = sr->sr_mhiargs; 3105 3106 free_sr(sr); 3107 return (mhiargs); 3108 } 3109 3110 /* 3111 * Get the MH timeout values for this set. 3112 */ 3113 bool_t 3114 mdrpc_gtimeout_common( 3115 mdrpc_sp_args *args, 3116 mdrpc_gtimeout_res *res, 3117 struct svc_req *rqstp /* RPC stuff */ 3118 ) 3119 { 3120 md_error_t *ep = &res->status; 3121 int err; 3122 int op_mode = R_OK; 3123 3124 /* setup, check permissions */ 3125 (void) memset(res, 0, sizeof (*res)); 3126 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3127 return (FALSE); 3128 else if (err != 0) 3129 return (TRUE); 3130 3131 if (check_set_lock(op_mode, NULL, ep)) 3132 return (TRUE); 3133 3134 /* doit */ 3135 res->mhiargsp = gtimeout(args->sp, ep); 3136 3137 err = svc_fini(ep); 3138 3139 return (TRUE); 3140 } 3141 3142 bool_t 3143 mdrpc_gtimeout_1_svc( 3144 mdrpc_sp_args *args, 3145 mdrpc_gtimeout_res *res, 3146 struct svc_req *rqstp /* RPC stuff */ 3147 ) 3148 { 3149 return (mdrpc_gtimeout_common(args, res, rqstp)); 3150 } 3151 3152 bool_t 3153 mdrpc_gtimeout_2_svc( 3154 mdrpc_sp_2_args *args, 3155 mdrpc_gtimeout_res *res, 3156 struct svc_req *rqstp /* RPC stuff */ 3157 ) 3158 { 3159 switch (args->rev) { 3160 case MD_METAD_ARGS_REV_1: 3161 return (mdrpc_gtimeout_common( 3162 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3163 default: 3164 return (FALSE); 3165 } 3166 } 3167 3168 /* 3169 * return the official host name for the callee 3170 */ 3171 /*ARGSUSED*/ 3172 bool_t 3173 mdrpc_hostname_common( 3174 mdrpc_null_args *args, 3175 mdrpc_hostname_res *res, 3176 struct svc_req *rqstp /* RPC stuff */ 3177 ) 3178 { 3179 md_error_t *ep = &res->status; 3180 int err; 3181 int op_mode = R_OK; 3182 3183 /* setup, check permissions */ 3184 (void) memset(res, 0, sizeof (*res)); 3185 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3186 return (FALSE); 3187 else if (err != 0) 3188 return (TRUE); 3189 3190 if (check_set_lock(op_mode, NULL, ep)) 3191 return (TRUE); 3192 3193 /* doit */ 3194 res->hostname = Strdup(mynode()); 3195 3196 err = svc_fini(ep); 3197 3198 return (TRUE); 3199 } 3200 3201 bool_t 3202 mdrpc_hostname_1_svc( 3203 mdrpc_null_args *args, 3204 mdrpc_hostname_res *res, 3205 struct svc_req *rqstp /* RPC stuff */ 3206 ) 3207 { 3208 return (mdrpc_hostname_common(args, res, rqstp)); 3209 } 3210 3211 bool_t 3212 mdrpc_hostname_2_svc( 3213 mdrpc_null_args *args, 3214 mdrpc_hostname_res *res, 3215 struct svc_req *rqstp /* RPC stuff */ 3216 ) 3217 { 3218 return (mdrpc_hostname_common(args, res, rqstp)); 3219 } 3220 3221 /* 3222 * return a response 3223 */ 3224 /*ARGSUSED*/ 3225 bool_t 3226 mdrpc_nullproc_common( 3227 void *args, 3228 md_error_t *ep, 3229 struct svc_req *rqstp /* RPC stuff */ 3230 ) 3231 { 3232 *ep = mdnullerror; 3233 /* do nothing */ 3234 return (TRUE); 3235 } 3236 3237 bool_t 3238 mdrpc_nullproc_1_svc( 3239 void *args, 3240 md_error_t *ep, 3241 struct svc_req *rqstp /* RPC stuff */ 3242 ) 3243 { 3244 return (mdrpc_nullproc_common(args, ep, rqstp)); 3245 } 3246 3247 bool_t 3248 mdrpc_nullproc_2_svc( 3249 void *args, 3250 md_error_t *ep, 3251 struct svc_req *rqstp /* RPC stuff */ 3252 ) 3253 { 3254 return (mdrpc_nullproc_common(args, ep, rqstp)); 3255 } 3256 3257 /* 3258 * determine if the caller owns the set. 3259 */ 3260 bool_t 3261 mdrpc_ownset_common( 3262 mdrpc_sp_args *args, 3263 mdrpc_bool_res *res, 3264 struct svc_req *rqstp /* RPC stuff */ 3265 ) 3266 { 3267 md_error_t *ep = &res->status; 3268 int err; 3269 int op_mode = R_OK; 3270 3271 /* setup, check permissions */ 3272 (void) memset(res, 0, sizeof (*res)); 3273 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3274 return (FALSE); 3275 else if (err != 0) 3276 return (TRUE); 3277 3278 if (check_set_lock(op_mode, NULL, ep)) 3279 return (TRUE); 3280 3281 /* doit */ 3282 if (s_ownset(args->sp->setno, ep)) 3283 res->value = TRUE; 3284 else 3285 res->value = FALSE; 3286 3287 err = svc_fini(ep); 3288 3289 return (TRUE); 3290 } 3291 3292 bool_t 3293 mdrpc_ownset_1_svc( 3294 mdrpc_sp_args *args, 3295 mdrpc_bool_res *res, 3296 struct svc_req *rqstp /* RPC stuff */ 3297 ) 3298 { 3299 return (mdrpc_ownset_common(args, res, rqstp)); 3300 } 3301 3302 bool_t 3303 mdrpc_ownset_2_svc( 3304 mdrpc_sp_2_args *args, 3305 mdrpc_bool_res *res, 3306 struct svc_req *rqstp /* RPC stuff */ 3307 ) 3308 { 3309 switch (args->rev) { 3310 case MD_METAD_ARGS_REV_1: 3311 return (mdrpc_ownset_common( 3312 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3313 default: 3314 return (FALSE); 3315 } 3316 } 3317 3318 static int 3319 setnameok(char *setname, md_error_t *ep) 3320 { 3321 int rval = 0; 3322 struct stat statb; 3323 md_set_record *sr = NULL; 3324 char *setlink = NULL; 3325 3326 setlink = Strdup("/dev/md/"); 3327 setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1); 3328 (void) strcat(setlink, setname); 3329 3330 if (lstat(setlink, &statb) == -1) { 3331 /* 3332 * If lstat() fails with ENOENT, setname is OK, if it 3333 * fails for other than that, we fail the RPC 3334 */ 3335 if (errno == ENOENT) { 3336 rval = 1; 3337 goto out; 3338 } 3339 3340 (void) mdsyserror(ep, errno, setlink); 3341 goto out; 3342 } 3343 3344 /* 3345 * If the lstat() succeeded, then we see what type of object 3346 * we are dealing with, if it is a symlink, we do some further 3347 * checking, if it is not a symlink, then we return an 3348 * indication that the set name is NOT acceptable. 3349 */ 3350 if (! S_ISLNK(statb.st_mode)) 3351 goto out; 3352 3353 /* 3354 * We look up the setname to see if there is a set 3355 * with that name, if there is, then we return 3356 * an indication that the set name is NOT acceptable. 3357 */ 3358 if ((sr = getsetbyname(setname, ep)) != NULL) 3359 goto out; 3360 3361 if (! mdiserror(ep, MDE_NO_SET)) 3362 goto out; 3363 3364 mdclrerror(ep); 3365 3366 rval = 1; 3367 out: 3368 if (sr != NULL) 3369 free_sr(sr); 3370 Free(setlink); 3371 return (rval); 3372 } 3373 3374 /* 3375 * Make sure the name of the set is OK. 3376 */ 3377 bool_t 3378 mdrpc_setnameok_common( 3379 mdrpc_sp_args *args, /* device name */ 3380 mdrpc_bool_res *res, 3381 struct svc_req *rqstp /* RPC stuff */ 3382 ) 3383 { 3384 md_error_t *ep = &res->status; 3385 int err; 3386 int op_mode = R_OK; 3387 3388 /* setup, check permissions */ 3389 (void) memset(res, 0, sizeof (*res)); 3390 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3391 return (FALSE); 3392 else if (err != 0) 3393 return (TRUE); 3394 3395 if (check_set_lock(op_mode, NULL, ep)) 3396 return (TRUE); 3397 3398 /* doit */ 3399 res->value = setnameok(args->sp->setname, ep); 3400 3401 err = svc_fini(ep); 3402 3403 return (TRUE); 3404 } 3405 3406 bool_t 3407 mdrpc_setnameok_1_svc( 3408 mdrpc_sp_args *args, /* device name */ 3409 mdrpc_bool_res *res, 3410 struct svc_req *rqstp /* RPC stuff */ 3411 ) 3412 { 3413 return (mdrpc_setnameok_common(args, res, rqstp)); 3414 } 3415 3416 bool_t 3417 mdrpc_setnameok_2_svc( 3418 mdrpc_sp_2_args *args, /* device name */ 3419 mdrpc_bool_res *res, 3420 struct svc_req *rqstp /* RPC stuff */ 3421 ) 3422 { 3423 switch (args->rev) { 3424 case MD_METAD_ARGS_REV_1: 3425 return (mdrpc_setnameok_common( 3426 &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3427 default: 3428 return (FALSE); 3429 } 3430 } 3431 3432 /* 3433 * determine if the setnumber we want to share is in use. 3434 */ 3435 bool_t 3436 mdrpc_setnumbusy_common( 3437 mdrpc_setno_args *args, 3438 mdrpc_bool_res *res, 3439 struct svc_req *rqstp /* RPC stuff */ 3440 ) 3441 { 3442 md_error_t *ep = &res->status; 3443 md_set_record *sr = NULL; 3444 int err; 3445 int op_mode = R_OK; 3446 3447 /* setup, check permissions */ 3448 (void) memset(res, 0, sizeof (*res)); 3449 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3450 return (FALSE); 3451 else if (err != 0) 3452 return (TRUE); 3453 3454 if (check_set_lock(op_mode, NULL, ep)) 3455 return (TRUE); 3456 3457 /* doit */ 3458 if ((sr = getsetbynum(args->setno, ep)) != NULL) { 3459 res->value = TRUE; 3460 free_sr(sr); 3461 return (TRUE); 3462 } 3463 res->value = FALSE; 3464 if (mdiserror(ep, MDE_NO_SET)) 3465 mdclrerror(ep); 3466 3467 err = svc_fini(ep); 3468 3469 return (TRUE); 3470 } 3471 3472 bool_t 3473 mdrpc_setnumbusy_1_svc( 3474 mdrpc_setno_args *args, 3475 mdrpc_bool_res *res, 3476 struct svc_req *rqstp /* RPC stuff */ 3477 ) 3478 { 3479 return (mdrpc_setnumbusy_common(args, res, rqstp)); 3480 } 3481 3482 bool_t 3483 mdrpc_setnumbusy_2_svc( 3484 mdrpc_setno_2_args *args, 3485 mdrpc_bool_res *res, 3486 struct svc_req *rqstp /* RPC stuff */ 3487 ) 3488 { 3489 switch (args->rev) { 3490 case MD_METAD_ARGS_REV_1: 3491 return (mdrpc_setnumbusy_common( 3492 &args->mdrpc_setno_2_args_u.rev1, res, rqstp)); 3493 default: 3494 return (FALSE); 3495 } 3496 } 3497 3498 static void 3499 stimeout( 3500 mdsetname_t *sp, 3501 mhd_mhiargs_t *mhiargsp, 3502 int version, /* RPC version of calling routine */ 3503 md_error_t *ep 3504 ) 3505 { 3506 mddb_userreq_t req; 3507 md_set_record *sr; 3508 3509 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3510 return; 3511 3512 sr->sr_mhiargs = *mhiargsp; 3513 3514 (void) memset(&req, '\0', sizeof (req)); 3515 3516 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 3517 /* Do MN operation if rpc version supports it and if a MN set */ 3518 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 3519 req.ur_size = sizeof (struct md_mnset_record); 3520 } else { 3521 req.ur_size = sizeof (*sr); 3522 } 3523 req.ur_data = (uintptr_t)sr; 3524 3525 /* 3526 * Cluster nodename support 3527 * Convert nodename -> nodeid 3528 * Don't do this for MN disksets since we've already stored 3529 * both the nodeid and name. 3530 */ 3531 if ((version == METAD_VERSION) || 3532 ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3533 sdssc_cm_sr_nm2nid(sr); 3534 3535 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 3536 (void) mdstealerror(ep, &req.ur_mde); 3537 return; 3538 } 3539 3540 (void) memset(&req, '\0', sizeof (req)); 3541 METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid) 3542 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) 3543 (void) mdstealerror(ep, &req.ur_mde); 3544 3545 /* 3546 * Cluster nodename support 3547 * Convert nodeid -> nodename 3548 * Don't do this for MN disksets since we've already stored 3549 * both the nodeid and name. 3550 */ 3551 if ((version == METAD_VERSION) || 3552 ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3553 sdssc_cm_sr_nid2nm(sr); 3554 3555 free_sr(sr); 3556 } 3557 3558 /* 3559 * Set MH ioctl timeout values. 3560 */ 3561 bool_t 3562 mdrpc_stimeout_common( 3563 mdrpc_stimeout_args *args, 3564 mdrpc_generic_res *res, 3565 struct svc_req *rqstp, /* RPC stuff */ 3566 int version /* RPC version */ 3567 ) 3568 { 3569 md_error_t *ep = &res->status; 3570 int err; 3571 int op_mode = W_OK; 3572 3573 /* setup, check permissions */ 3574 (void) memset(res, 0, sizeof (*res)); 3575 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3576 return (FALSE); 3577 else if (err != 0) 3578 return (TRUE); 3579 3580 if (check_set_lock(op_mode, NULL, ep)) 3581 return (TRUE); 3582 3583 /* doit */ 3584 stimeout(args->sp, args->mhiargsp, version, ep); 3585 3586 err = svc_fini(ep); 3587 3588 return (TRUE); 3589 } 3590 3591 bool_t 3592 mdrpc_stimeout_1_svc( 3593 mdrpc_stimeout_args *args, 3594 mdrpc_generic_res *res, 3595 struct svc_req *rqstp /* RPC stuff */ 3596 ) 3597 { 3598 /* Pass RPC version (METAD_VERSION) to common routine */ 3599 return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION)); 3600 } 3601 3602 bool_t 3603 mdrpc_stimeout_2_svc( 3604 mdrpc_stimeout_2_args *args, 3605 mdrpc_generic_res *res, 3606 struct svc_req *rqstp /* RPC stuff */ 3607 ) 3608 { 3609 switch (args->rev) { 3610 case MD_METAD_ARGS_REV_1: 3611 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 3612 return (mdrpc_stimeout_common( 3613 &args->mdrpc_stimeout_2_args_u.rev1, res, 3614 rqstp, METAD_VERSION_DEVID)); 3615 default: 3616 return (FALSE); 3617 } 3618 } 3619 3620 static void 3621 upd_dr_dbinfo( 3622 mdsetname_t *sp, 3623 md_drive_desc *dd, 3624 md_error_t *ep 3625 ) 3626 { 3627 mdsetname_t *local_sp; 3628 md_set_record *sr; 3629 md_drive_record *dr; 3630 md_drive_desc *p; 3631 mddrivename_t *dn, *dn1; 3632 ddi_devid_t devid_remote = NULL; 3633 ddi_devid_t devid_local = NULL; 3634 int devid_same = -1; 3635 side_t sideno; 3636 int using_devid = 0; 3637 3638 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3639 return; 3640 3641 metaflushsetname(local_sp); 3642 3643 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3644 return; 3645 3646 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3647 return; 3648 3649 if (dd->dd_dnp == NULL) 3650 return; 3651 3652 /* 3653 * The system is either all devid or all 3654 * non-devid so we determine this by looking 3655 * at the first item in the list. 3656 * 3657 * For did disks, the dd_dnp->devid is a valid pointer which 3658 * points to a '' string of devid. We need to check this 3659 * before set the using_devid. 3660 */ 3661 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3662 (!(MD_MNSET_REC(sr)))) 3663 using_devid = 1; 3664 3665 for (p = dd; p != NULL; p = p->dd_next) { 3666 dn = p->dd_dnp; 3667 devid_remote = NULL; 3668 3669 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3670 using_devid) { 3671 /* 3672 * We have a devid so use it. 3673 */ 3674 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3675 } 3676 3677 /* check to make sure using_devid agrees with reality... */ 3678 if ((using_devid == 1) && (devid_remote == NULL)) { 3679 /* something went really wrong. Can't process */ 3680 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3681 mynode(), dn->cname, sp->setname); 3682 return; 3683 } 3684 3685 for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3686 devid_same = -1; 3687 3688 dn1 = metadrivename_withdrkey(local_sp, sideno, 3689 dr->dr_key, MD_BASICNAME_OK, ep); 3690 3691 if (dn1 == NULL) { 3692 if (devid_remote) 3693 devid_free(devid_remote); 3694 goto out; 3695 } 3696 3697 if (dn1->devid != NULL && using_devid) { 3698 if (devid_str_decode(dn1->devid, &devid_local, 3699 NULL) == 0) { 3700 devid_same = devid_compare(devid_remote, 3701 devid_local); 3702 devid_free(devid_local); 3703 } 3704 } 3705 3706 if (using_devid && devid_same == 0) 3707 break; 3708 3709 if (!using_devid && 3710 strcmp(dn->cname, dn1->cname) == 0) 3711 break; 3712 } 3713 3714 if (dr) { 3715 /* Adjust the fields in the copy */ 3716 dr->dr_dbcnt = p->dd_dbcnt; 3717 dr->dr_dbsize = p->dd_dbsize; 3718 } 3719 if (devid_remote) 3720 devid_free(devid_remote); 3721 } 3722 3723 3724 out: 3725 commitset(sr, FALSE, ep); 3726 free_sr(sr); 3727 } 3728 3729 /* 3730 * update the database count and size field of drive records. 3731 */ 3732 bool_t 3733 mdrpc_upd_dr_dbinfo_common( 3734 mdrpc_drives_2_args_r1 *args, 3735 mdrpc_generic_res *res, 3736 struct svc_req *rqstp /* RPC stuff */ 3737 ) 3738 { 3739 md_error_t *ep = &res->status; 3740 int err; 3741 int op_mode = W_OK; 3742 3743 /* setup, check permissions */ 3744 (void) memset(res, 0, sizeof (*res)); 3745 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3746 return (FALSE); 3747 else if (err != 0) 3748 return (TRUE); 3749 3750 if (check_set_lock(op_mode, args->cl_sk, ep)) 3751 return (TRUE); 3752 3753 /* doit */ 3754 upd_dr_dbinfo(args->sp, args->drivedescs, ep); 3755 3756 err = svc_fini(ep); 3757 3758 return (TRUE); 3759 } 3760 3761 /* 3762 * version 1 of the remote procedure. This procedure is called if the 3763 * client is running in version 1. We first convert version 1 arguments 3764 * into version 2 arguments and then call the common remote procedure. 3765 */ 3766 bool_t 3767 mdrpc_upd_dr_dbinfo_1_svc( 3768 mdrpc_drives_args *args, 3769 mdrpc_generic_res *res, 3770 struct svc_req *rqstp /* RPC stuff */ 3771 ) 3772 { 3773 bool_t retval; 3774 mdrpc_drives_2_args_r1 v2_args; 3775 3776 /* allocate memory */ 3777 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3778 3779 /* build args */ 3780 v2_args.cl_sk = args->cl_sk; 3781 v2_args.sp = args->sp; 3782 /* convert v1 args to v2 (revision 1) args */ 3783 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3784 v2_args.timestamp = args->timestamp; 3785 v2_args.genid = args->genid; 3786 3787 retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp); 3788 3789 free_newdrvdesc(v2_args.drivedescs); 3790 3791 return (retval); 3792 } 3793 3794 bool_t 3795 mdrpc_upd_dr_dbinfo_2_svc( 3796 mdrpc_drives_2_args *args, 3797 mdrpc_generic_res *res, 3798 struct svc_req *rqstp /* RPC stuff */ 3799 ) 3800 { 3801 switch (args->rev) { 3802 case MD_METAD_ARGS_REV_1: 3803 return (mdrpc_upd_dr_dbinfo_common( 3804 &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 3805 default: 3806 return (FALSE); 3807 } 3808 } 3809 3810 static void 3811 upd_dr_flags( 3812 mdsetname_t *sp, 3813 md_drive_desc *dd, 3814 uint_t new_flags, 3815 md_error_t *ep 3816 ) 3817 { 3818 mdsetname_t *local_sp; 3819 md_set_record *sr; 3820 md_drive_record *dr; 3821 md_drive_desc *p; 3822 mddrivename_t *dn, *dn1; 3823 ddi_devid_t devid_remote = NULL; 3824 ddi_devid_t devid_local = NULL; 3825 int devid_same = -1; 3826 side_t sideno; 3827 int using_devid = 0; 3828 3829 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3830 return; 3831 3832 metaflushsetname(local_sp); 3833 3834 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3835 return; 3836 3837 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3838 return; 3839 3840 if (dd->dd_dnp == NULL) 3841 return; 3842 3843 /* 3844 * The system is either all devid or all 3845 * non-devid so we determine this by looking 3846 * at the first item in the list. 3847 * 3848 * For did disks, the dd_dnp->devid is a valid pointer which 3849 * points to a '' string of devid. We need to check this 3850 * before set the using_devid. 3851 */ 3852 if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3853 (!(MD_MNSET_REC(sr)))) 3854 using_devid = 1; 3855 3856 for (p = dd; p != NULL; p = p->dd_next) { 3857 dn = p->dd_dnp; 3858 devid_remote = NULL; 3859 3860 if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3861 using_devid) { 3862 /* 3863 * We have a devid so use it. 3864 */ 3865 (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3866 } 3867 3868 /* check to make sure using_devid agrees with reality... */ 3869 if ((using_devid == 1) && (devid_remote == NULL)) { 3870 /* something went really wrong. Can't process */ 3871 (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3872 mynode(), dn->cname, sp->setname); 3873 return; 3874 } 3875 3876 for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3877 devid_same = -1; 3878 3879 dn1 = metadrivename_withdrkey(local_sp, sideno, 3880 dr->dr_key, MD_BASICNAME_OK, ep); 3881 3882 if (dn1 == NULL) { 3883 if (devid_remote) 3884 devid_free(devid_remote); 3885 goto out; 3886 } 3887 3888 if (dn1->devid != NULL && using_devid) { 3889 if (devid_str_decode(dn1->devid, 3890 &devid_local, NULL) == 0) { 3891 devid_same = devid_compare(devid_remote, 3892 devid_local); 3893 devid_free(devid_local); 3894 } 3895 } 3896 3897 if (using_devid && devid_same == 0) 3898 break; 3899 3900 if (!using_devid && 3901 strcmp(dn->cname, dn1->cname) == 0) 3902 break; 3903 } 3904 3905 if (dr) 3906 dr->dr_flags = new_flags; 3907 if (devid_remote) 3908 devid_free(devid_remote); 3909 } 3910 out: 3911 commitset(sr, TRUE, ep); 3912 free_sr(sr); 3913 } 3914 3915 /* 3916 * update the database count and size field of drive records. 3917 */ 3918 bool_t 3919 mdrpc_upd_dr_flags_common( 3920 mdrpc_upd_dr_flags_2_args_r1 *args, 3921 mdrpc_generic_res *res, 3922 struct svc_req *rqstp /* RPC stuff */ 3923 ) 3924 { 3925 md_error_t *ep = &res->status; 3926 int err; 3927 int op_mode = W_OK; 3928 3929 /* setup, check permissions */ 3930 (void) memset(res, 0, sizeof (*res)); 3931 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3932 return (FALSE); 3933 else if (err != 0) 3934 return (TRUE); 3935 3936 if (check_set_lock(op_mode, args->cl_sk, ep)) 3937 return (TRUE); 3938 3939 /* doit */ 3940 upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep); 3941 3942 err = svc_fini(ep); 3943 3944 return (TRUE); 3945 } 3946 3947 /* 3948 * version 1 of the remote procedure. This procedure is called if the 3949 * client is running in version 1. We first convert version 1 arguments 3950 * into version 2 arguments and then call the common remote procedure. 3951 */ 3952 bool_t 3953 mdrpc_upd_dr_flags_1_svc( 3954 mdrpc_upd_dr_flags_args *args, 3955 mdrpc_generic_res *res, 3956 struct svc_req *rqstp /* RPC stuff */ 3957 ) 3958 { 3959 bool_t retval; 3960 mdrpc_upd_dr_flags_2_args_r1 v2_args; 3961 3962 /* allocate memory */ 3963 alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3964 3965 /* build args */ 3966 v2_args.cl_sk = args->cl_sk; 3967 v2_args.sp = args->sp; 3968 /* convert v1 args to v2 (revision 1) args */ 3969 meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3970 v2_args.new_flags = args->new_flags; 3971 3972 retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp); 3973 3974 free_newdrvdesc(v2_args.drivedescs); 3975 3976 return (retval); 3977 } 3978 3979 bool_t 3980 mdrpc_upd_dr_flags_2_svc( 3981 mdrpc_upd_dr_flags_2_args *args, 3982 mdrpc_generic_res *res, 3983 struct svc_req *rqstp /* RPC stuff */ 3984 ) 3985 { 3986 switch (args->rev) { 3987 case MD_METAD_ARGS_REV_1: 3988 return (mdrpc_upd_dr_flags_common( 3989 &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 3990 default: 3991 return (FALSE); 3992 } 3993 } 3994 3995 static void 3996 upd_sr_flags( 3997 mdsetname_t *sp, 3998 uint_t new_flags, 3999 md_error_t *ep 4000 ) 4001 { 4002 md_set_record *sr; 4003 4004 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4005 return; 4006 4007 sr->sr_flags = new_flags; 4008 commitset(sr, TRUE, ep); 4009 free_sr(sr); 4010 } 4011 4012 /* 4013 * update the set record flags 4014 */ 4015 bool_t 4016 mdrpc_upd_sr_flags_common( 4017 mdrpc_upd_sr_flags_args *args, 4018 mdrpc_generic_res *res, 4019 struct svc_req *rqstp /* RPC stuff */ 4020 ) 4021 { 4022 md_error_t *ep = &res->status; 4023 int err; 4024 int op_mode = W_OK; 4025 4026 /* setup, check permissions */ 4027 (void) memset(res, 0, sizeof (*res)); 4028 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4029 return (FALSE); 4030 else if (err != 0) 4031 return (TRUE); 4032 4033 if (check_set_lock(op_mode, args->cl_sk, ep)) 4034 return (TRUE); 4035 4036 /* doit */ 4037 upd_sr_flags(args->sp, args->new_flags, ep); 4038 4039 err = svc_fini(ep); 4040 4041 return (TRUE); 4042 } 4043 4044 bool_t 4045 mdrpc_upd_sr_flags_1_svc( 4046 mdrpc_upd_sr_flags_args *args, 4047 mdrpc_generic_res *res, 4048 struct svc_req *rqstp /* RPC stuff */ 4049 ) 4050 { 4051 return (mdrpc_upd_sr_flags_common(args, res, rqstp)); 4052 } 4053 4054 bool_t 4055 mdrpc_upd_sr_flags_2_svc( 4056 mdrpc_upd_sr_flags_2_args *args, 4057 mdrpc_generic_res *res, 4058 struct svc_req *rqstp /* RPC stuff */ 4059 ) 4060 { 4061 switch (args->rev) { 4062 case MD_METAD_ARGS_REV_1: 4063 return (mdrpc_upd_sr_flags_common( 4064 &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp)); 4065 default: 4066 return (FALSE); 4067 } 4068 } 4069 4070 /* 4071 * upd_nr_flags updates the node records stored in this node's local mddb 4072 * given a node desciptor list and an action. upd_nr_flags then commits 4073 * the node records to the local mddb. 4074 * 4075 * nd - A linked list of node descriptors that describes the node records 4076 * in this diskset on which the action applies. 4077 * flag_action: action to be taken on node records that match the nd list. 4078 * flag_action can be: 4079 * MD_NR_JOIN: set OWN flag in node records 4080 * MD_NR_WITHDRAW: reset OWN flag in node records 4081 * MD_NR_OK: reset ADD flags and set OK flag in node records 4082 * MD_NR_SET: set node record flags based on flags stored in nd 4083 * 4084 * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting 4085 * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW 4086 * (remove last disk from set) or OK (after addition of host to set). 4087 * 4088 * The SET flag_action is typically used when nodelist contains all nodes 4089 * in the diskset, but specific nodes have had flag changes. An example of 4090 * this would be the join/withdraw of a specific node to/from the set. 4091 * 4092 * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag. This 4093 * flag is used by the client to recover in case of failure and should not 4094 * be set in the node record flags. 4095 */ 4096 static void 4097 upd_nr_flags( 4098 mdsetname_t *sp, 4099 md_mnnode_desc *nd, 4100 uint_t flag_action, 4101 md_error_t *ep 4102 ) 4103 { 4104 mdsetname_t *local_sp; 4105 md_set_record *sr; 4106 md_mnset_record *mnsr; 4107 md_mnnode_desc *ndp; 4108 md_mnnode_record *nrp; 4109 4110 if ((local_sp = metasetname(sp->setname, ep)) == NULL) 4111 return; 4112 4113 metaflushsetname(local_sp); 4114 4115 if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4116 return; 4117 4118 if (!(MD_MNSET_REC(sr))) { 4119 return; 4120 } 4121 mnsr = (struct md_mnset_record *)sr; 4122 4123 switch (flag_action) { 4124 case MD_NR_JOIN: 4125 case MD_NR_WITHDRAW: 4126 case MD_NR_SET: 4127 case MD_NR_OK: 4128 case MD_NR_DEL: 4129 break; 4130 default: 4131 return; 4132 } 4133 4134 for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) { 4135 /* Find matching node record for given node descriptor */ 4136 for (nrp = mnsr->sr_nodechain; nrp != NULL; 4137 nrp = nrp->nr_next) { 4138 if (ndp->nd_nodeid == nrp->nr_nodeid) { 4139 switch (flag_action) { 4140 case MD_NR_JOIN: 4141 nrp->nr_flags |= MD_MN_NODE_OWN; 4142 break; 4143 case MD_NR_WITHDRAW: 4144 nrp->nr_flags &= ~MD_MN_NODE_OWN; 4145 break; 4146 case MD_NR_OK: 4147 nrp->nr_flags &= 4148 ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL); 4149 nrp->nr_flags |= MD_MN_NODE_OK; 4150 break; 4151 case MD_NR_DEL: 4152 nrp->nr_flags &= 4153 ~(MD_MN_NODE_OK | MD_MN_NODE_ADD); 4154 nrp->nr_flags |= MD_MN_NODE_DEL; 4155 break; 4156 case MD_NR_SET: 4157 /* Do not set RB_JOIN flag */ 4158 nrp->nr_flags = 4159 ndp->nd_flags & ~MD_MN_NODE_RB_JOIN; 4160 break; 4161 } 4162 break; 4163 } 4164 } 4165 } 4166 out: 4167 /* Don't increment set genid for node record flag update */ 4168 commitset(sr, FALSE, ep); 4169 free_sr(sr); 4170 } 4171 4172 /* 4173 * init/fini wrapper around upd_nr_flags 4174 */ 4175 bool_t 4176 mdrpc_upd_nr_flags_common( 4177 mdrpc_upd_nr_flags_args *args, 4178 mdrpc_generic_res *res, 4179 struct svc_req *rqstp /* RPC stuff */ 4180 ) 4181 { 4182 md_error_t *ep = &res->status; 4183 int err; 4184 int op_mode = W_OK; 4185 4186 /* setup, check permissions */ 4187 (void) memset(res, 0, sizeof (*res)); 4188 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4189 return (FALSE); 4190 else if (err != 0) 4191 return (TRUE); 4192 4193 /* 4194 * During reconfig, node record flags can be updated without 4195 * locking first. 4196 */ 4197 if (!(args->flags & MNSET_IN_RECONFIG)) { 4198 if (check_set_lock(op_mode, args->cl_sk, ep)) 4199 return (TRUE); 4200 } 4201 4202 /* doit */ 4203 upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep); 4204 4205 err = svc_fini(ep); 4206 4207 return (TRUE); 4208 } 4209 4210 /* 4211 * update the node records using given flag action. 4212 */ 4213 bool_t 4214 mdrpc_upd_nr_flags_2_svc( 4215 mdrpc_upd_nr_flags_2_args *args, 4216 mdrpc_generic_res *res, 4217 struct svc_req *rqstp /* RPC stuff */ 4218 ) 4219 { 4220 switch (args->rev) { 4221 case MD_METAD_ARGS_REV_1: 4222 return (mdrpc_upd_nr_flags_common( 4223 &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp)); 4224 default: 4225 return (FALSE); 4226 } 4227 } 4228 4229 void 4230 free_sk(md_setkey_t *skp) 4231 { 4232 Free(skp->sk_setname); 4233 Free(skp->sk_host); 4234 Free(skp); 4235 } 4236 4237 void 4238 del_sk(set_t setno) 4239 { 4240 md_setkey_t *skp; 4241 md_setkey_t *tskp; 4242 4243 for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) { 4244 if (setno == skp->sk_setno) { 4245 if (skp == my_svc_sk) 4246 my_svc_sk = skp->sk_next; 4247 else 4248 tskp->sk_next = skp->sk_next; 4249 4250 Free(skp->sk_setname); 4251 Free(skp->sk_host); 4252 Free(skp); 4253 break; 4254 } 4255 } 4256 } 4257 4258 md_setkey_t * 4259 dupsk(md_setkey_t *skp) 4260 { 4261 md_setkey_t *tskp; 4262 4263 tskp = Zalloc(sizeof (md_setkey_t)); 4264 4265 *tskp = *skp; 4266 tskp->sk_host = Strdup(skp->sk_host); 4267 tskp->sk_setname = Strdup(skp->sk_setname); 4268 4269 return (tskp); 4270 } 4271 4272 md_setkey_t * 4273 svc_get_setkey(set_t setno) 4274 { 4275 md_setkey_t *skp; 4276 4277 for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next) 4278 if (setno == skp->sk_setno) 4279 return (dupsk(skp)); 4280 return (NULL); 4281 } 4282 4283 void 4284 svc_set_setkey(md_setkey_t *svc_sk) 4285 { 4286 md_setkey_t *skp; 4287 4288 if (my_svc_sk == NULL) { 4289 my_svc_sk = dupsk(svc_sk); 4290 return; 4291 } 4292 4293 for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next) 4294 assert(svc_sk->sk_setno != skp->sk_setno); 4295 4296 skp->sk_next = dupsk(svc_sk); 4297 } 4298 4299 /* 4300 * Unlock the set 4301 * 4302 * To unlock the set, the user must have the correct key, once this is verified 4303 * the set is unlocked and the cached information for the set is flushed. 4304 */ 4305 bool_t 4306 mdrpc_unlock_set_common( 4307 mdrpc_null_args *args, 4308 mdrpc_setlock_res *res, 4309 struct svc_req *rqstp /* RPC stuff */ 4310 ) 4311 { 4312 md_error_t *ep = &res->status; 4313 int err; 4314 int op_mode = W_OK; 4315 md_setkey_t *svc_skp; 4316 md_set_desc *sd; 4317 mdsetname_t *sp; 4318 int multi_node = 0; 4319 md_error_t xep = mdnullerror; 4320 4321 /* setup, check permissions */ 4322 (void) memset(res, 0, sizeof (*res)); 4323 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4324 return (FALSE); 4325 else if (err != 0) 4326 return (TRUE); 4327 4328 /* 4329 * Is diskset a MN diskset? 4330 * Don't set error from this check since unlock set can be 4331 * called after a set has been deleted. 4332 */ 4333 if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) && 4334 ((sd = metaget_setdesc(sp, &xep)) != NULL)) { 4335 if ((MD_MNSET_DESC(sd))) { 4336 multi_node = 1; 4337 } 4338 } 4339 4340 /* Get the set key, if any */ 4341 svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4342 4343 /* The set is locked */ 4344 if (svc_skp != NULL) { 4345 4346 /* Make sure the opener has the right key. */ 4347 if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec || 4348 args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) { 4349 (void) mddserror(ep, MDE_DS_ULKSBADKEY, 4350 svc_skp->sk_setno, mynode(), svc_skp->sk_host, 4351 svc_skp->sk_setname); 4352 free_sk(svc_skp); 4353 return (TRUE); 4354 } 4355 4356 /* Unlock the set */ 4357 del_sk(args->cl_sk->sk_setno); 4358 4359 /* Cleanup */ 4360 free_sk(svc_skp); 4361 4362 goto out; 4363 } 4364 4365 4366 /* 4367 * It is possible on a MN diskset to attempt to unlock a set that 4368 * is unlocked. This could occur when the metaset or metadb command 4369 * is failing due to another metaset or metadb command running. 4370 * So, print no warning for MN disksets. 4371 */ 4372 if (multi_node == 0) { 4373 md_eprintf("Warning: set unlocked when unlock_set called!\n"); 4374 } 4375 4376 out: 4377 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4378 4379 /* Flush the set cache */ 4380 sr_cache_flush_setno(args->cl_sk->sk_setno); 4381 4382 return (TRUE); 4383 } 4384 4385 bool_t 4386 mdrpc_unlock_set_1_svc( 4387 mdrpc_null_args *args, 4388 mdrpc_setlock_res *res, 4389 struct svc_req *rqstp /* RPC stuff */ 4390 ) 4391 { 4392 return (mdrpc_unlock_set_common(args, res, rqstp)); 4393 } 4394 4395 bool_t 4396 mdrpc_unlock_set_2_svc( 4397 mdrpc_null_args *args, 4398 mdrpc_setlock_res *res, 4399 struct svc_req *rqstp /* RPC stuff */ 4400 ) 4401 { 4402 return (mdrpc_unlock_set_common(args, res, rqstp)); 4403 } 4404 4405 /* 4406 * Lock the set 4407 * 4408 * If the user does not hand us a key, then we generate a new key and lock the 4409 * set using this new key that was generated, if the user hands us a key then 4410 * we use the key to lock the set. 4411 */ 4412 bool_t 4413 mdrpc_lock_set_common( 4414 mdrpc_null_args *args, 4415 mdrpc_setlock_res *res, 4416 struct svc_req *rqstp /* RPC stuff */ 4417 ) 4418 { 4419 md_error_t *ep = &res->status; 4420 int err; 4421 md_error_t xep = mdnullerror; 4422 int op_mode = W_OK; 4423 md_setkey_t *svc_skp; 4424 md_setkey_t new_sk; 4425 md_set_desc *sd; 4426 mdsetname_t *sp; 4427 4428 /* setup, check permissions */ 4429 (void) memset(res, 0, sizeof (*res)); 4430 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4431 return (FALSE); 4432 else if (err != 0) 4433 return (TRUE); 4434 4435 svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4436 4437 /* The set is unlocked */ 4438 if (svc_skp == NULL) { 4439 /* If we have been given a key, use it. */ 4440 if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) { 4441 svc_set_setkey(args->cl_sk); 4442 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4443 goto out; 4444 } 4445 4446 /* We need to lock it, with a new key */ 4447 new_sk = *args->cl_sk; 4448 if (meta_gettimeofday(&new_sk.sk_key) == -1) { 4449 (void) mdsyserror(ep, errno, "meta_gettimeofday()"); 4450 mde_perror(&xep, ""); 4451 md_exit(NULL, 1); 4452 } 4453 svc_set_setkey(&new_sk); 4454 4455 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4456 goto out; 4457 } 4458 4459 /* 4460 * If a MN diskset, the lock_set routine is used as a locking 4461 * mechanism to keep multiple metaset and/or metadb commads 4462 * from interfering with each other. If two metaset/metadb 4463 * commands are issued at the same time - one will complete 4464 * and the other command will fail with MDE_DS_NOTNOW_CMD. 4465 */ 4466 if (((sp = metasetnosetname(args->cl_sk->sk_setno, ep)) != NULL) && 4467 ((sd = metaget_setdesc(sp, ep)) != NULL) && 4468 (MD_MNSET_DESC(sd))) { 4469 (void) mddserror(ep, MDE_DS_NOTNOW_CMD, 4470 svc_skp->sk_setno, mynode(), 4471 svc_skp->sk_host, svc_skp->sk_setname); 4472 goto out; 4473 } 4474 4475 md_eprintf("Warning: set locked when lock_set called!\n"); 4476 4477 md_eprintf("Lock info:\n"); 4478 4479 md_eprintf("\tLock(svc):\n"); 4480 md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname); 4481 md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno); 4482 md_eprintf("\t\tHost: %s\n", svc_skp->sk_host); 4483 md_eprintf("\t\tKey: %d/%d %s", 4484 svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec, 4485 ctime((const time_t *)&svc_skp->sk_key.tv_sec)); 4486 4487 md_eprintf("\tLock(cl):\n"); 4488 md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname); 4489 md_eprintf("\t\tSetno: %d\n", args->cl_sk->sk_setno); 4490 md_eprintf("\t\tHost: %s\n", args->cl_sk->sk_host); 4491 md_eprintf("\t\tKey: %d/%d %s", 4492 args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec, 4493 ctime((const time_t *)&args->cl_sk->sk_key.tv_sec)); 4494 4495 /* The set is locked, do we have the key? */ 4496 if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec && 4497 args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) { 4498 res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4499 goto out; 4500 } 4501 4502 /* 4503 * The set is locked and we do not have the key, so we set up an error. 4504 */ 4505 (void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(), 4506 svc_skp->sk_host, args->cl_sk->sk_setname); 4507 4508 out: 4509 if (svc_skp != NULL) 4510 free_sk(svc_skp); 4511 4512 /* Flush the set cache */ 4513 sr_cache_flush_setno(args->cl_sk->sk_setno); 4514 4515 return (TRUE); 4516 } 4517 4518 bool_t 4519 mdrpc_lock_set_1_svc( 4520 mdrpc_null_args *args, 4521 mdrpc_setlock_res *res, 4522 struct svc_req *rqstp /* RPC stuff */ 4523 ) 4524 { 4525 return (mdrpc_lock_set_common(args, res, rqstp)); 4526 } 4527 4528 bool_t 4529 mdrpc_lock_set_2_svc( 4530 mdrpc_null_args *args, 4531 mdrpc_setlock_res *res, 4532 struct svc_req *rqstp /* RPC stuff */ 4533 ) 4534 { 4535 return (mdrpc_lock_set_common(args, res, rqstp)); 4536 } 4537 4538 static void 4539 updmeds( 4540 char *setname, 4541 md_h_arr_t *medp, 4542 int version, /* RPC version of calling routine */ 4543 md_error_t *ep 4544 ) 4545 { 4546 mddb_userreq_t req; 4547 md_set_record *sr; 4548 mddb_med_parm_t mp; 4549 4550 if ((sr = getsetbyname(setname, ep)) == NULL) 4551 return; 4552 4553 sr->sr_med = *medp; /* structure assignment */ 4554 4555 (void) memset(&req, '\0', sizeof (req)); 4556 4557 METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 4558 /* Do MN operation if rpc version supports it and if a MN set */ 4559 if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 4560 req.ur_size = sizeof (struct md_mnset_record); 4561 } else { 4562 req.ur_size = sizeof (*sr); 4563 } 4564 req.ur_data = (uintptr_t)sr; 4565 if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 4566 (void) mdstealerror(ep, &req.ur_mde); 4567 free_sr(sr); 4568 return; 4569 } 4570 4571 commitset(sr, TRUE, ep); 4572 4573 /* 4574 * If a MN disket, send the mediator list to the kernel. 4575 */ 4576 if (MD_MNSET_REC(sr)) { 4577 (void) memset(&mp, '\0', sizeof (mddb_med_parm_t)); 4578 mp.med_setno = sr->sr_setno; 4579 if (meta_h2hi(medp, &mp.med, ep)) { 4580 free_sr(sr); 4581 return; 4582 } 4583 4584 /* Resolve the IP addresses for the host list */ 4585 if (meta_med_hnm2ip(&mp.med, ep)) { 4586 free_sr(sr); 4587 return; 4588 } 4589 4590 /* If node not yet joined to set, failure is ok. */ 4591 if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) { 4592 if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) { 4593 (void) mdstealerror(ep, &mp.med_mde); 4594 } 4595 } 4596 } 4597 free_sr(sr); 4598 } 4599 4600 /* 4601 * Update the mediator data in the set record 4602 */ 4603 bool_t 4604 mdrpc_updmeds_common( 4605 mdrpc_updmeds_args *args, 4606 mdrpc_generic_res *res, 4607 struct svc_req *rqstp, /* RPC stuff */ 4608 int version /* RPC version */ 4609 ) 4610 { 4611 md_error_t *ep = &res->status; 4612 int err; 4613 int op_mode = W_OK; 4614 4615 /* setup, check permissions */ 4616 (void) memset(res, 0, sizeof (*res)); 4617 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4618 return (FALSE); 4619 else if (err != 0) 4620 return (TRUE); 4621 4622 if (check_set_lock(op_mode, args->cl_sk, ep)) 4623 return (TRUE); 4624 4625 /* doit */ 4626 updmeds(args->sp->setname, &args->meds, version, ep); 4627 4628 err = svc_fini(ep); 4629 4630 return (TRUE); 4631 } 4632 4633 bool_t 4634 mdrpc_updmeds_1_svc( 4635 mdrpc_updmeds_args *args, 4636 mdrpc_generic_res *res, 4637 struct svc_req *rqstp /* RPC stuff */ 4638 ) 4639 { 4640 /* Pass RPC version (METAD_VERSION) to common routine */ 4641 return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION)); 4642 } 4643 4644 bool_t 4645 mdrpc_updmeds_2_svc( 4646 mdrpc_updmeds_2_args *args, 4647 mdrpc_generic_res *res, 4648 struct svc_req *rqstp /* RPC stuff */ 4649 ) 4650 { 4651 switch (args->rev) { 4652 case MD_METAD_ARGS_REV_1: 4653 /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 4654 return (mdrpc_updmeds_common( 4655 &args->mdrpc_updmeds_2_args_u.rev1, res, 4656 rqstp, METAD_VERSION_DEVID)); 4657 default: 4658 return (FALSE); 4659 } 4660 } 4661 4662 /* 4663 * Call routines to suspend, reinit and resume mdcommd. 4664 * Called during metaset and metadb command. 4665 * NOT called during reconfig cycle. 4666 */ 4667 bool_t 4668 mdrpc_mdcommdctl_2_svc( 4669 mdrpc_mdcommdctl_2_args *args, 4670 mdrpc_generic_res *res, 4671 struct svc_req *rqstp /* RPC stuff */ 4672 ) 4673 { 4674 mdrpc_mdcommdctl_args *args_cc; 4675 md_error_t *ep = &res->status; 4676 int err; 4677 int op_mode = R_OK; 4678 int suspend_ret; 4679 4680 switch (args->rev) { 4681 case MD_METAD_ARGS_REV_1: 4682 /* setup, check permissions */ 4683 (void) memset(res, 0, sizeof (*res)); 4684 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4685 return (FALSE); 4686 else if (err != 0) 4687 return (TRUE); 4688 4689 args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1); 4690 switch (args_cc->flag_action) { 4691 case COMMDCTL_SUSPEND: 4692 suspend_ret = mdmn_suspend(args_cc->setno, 4693 args_cc->class); 4694 if (suspend_ret != 0) { 4695 (void) mddserror(ep, suspend_ret, 4696 args_cc->setno, mynode(), 4697 NULL, mynode()); 4698 } 4699 break; 4700 case COMMDCTL_RESUME: 4701 if (mdmn_resume(args_cc->setno, 4702 args_cc->class, args_cc->flags)) { 4703 (void) mddserror(ep, 4704 MDE_DS_COMMDCTL_RESUME_FAIL, 4705 args_cc->setno, mynode(), 4706 NULL, mynode()); 4707 } 4708 break; 4709 case COMMDCTL_REINIT: 4710 if (mdmn_reinit_set(args_cc->setno)) { 4711 (void) mddserror(ep, 4712 MDE_DS_COMMDCTL_REINIT_FAIL, 4713 args_cc->setno, mynode(), 4714 NULL, mynode()); 4715 } 4716 break; 4717 } 4718 err = svc_fini(ep); 4719 return (TRUE); 4720 4721 default: 4722 return (FALSE); 4723 } 4724 } 4725 4726 /* 4727 * Return TRUE if set is stale. 4728 */ 4729 bool_t 4730 mdrpc_mn_is_stale_2_svc( 4731 mdrpc_setno_2_args *args, 4732 mdrpc_bool_res *res, 4733 struct svc_req *rqstp /* RPC stuff */ 4734 ) 4735 { 4736 md_error_t *ep = &res->status; 4737 mddb_config_t c; 4738 int err; 4739 int op_mode = R_OK; 4740 4741 (void) memset(&c, 0, sizeof (c)); 4742 switch (args->rev) { 4743 case MD_METAD_ARGS_REV_1: 4744 c.c_id = 0; 4745 c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno; 4746 4747 /* setup, check permissions */ 4748 (void) memset(res, 0, sizeof (*res)); 4749 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4750 return (FALSE); 4751 else if (err != 0) 4752 return (TRUE); 4753 4754 if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) { 4755 mdstealerror(ep, &c.c_mde); 4756 return (TRUE); 4757 } 4758 4759 if (c.c_flags & MDDB_C_STALE) { 4760 res->value = TRUE; 4761 } else { 4762 res->value = FALSE; 4763 } 4764 4765 err = svc_fini(ep); 4766 return (TRUE); 4767 4768 default: 4769 return (FALSE); 4770 } 4771 } 4772 4773 /* 4774 * Clear out all clnt_locks held by all MN disksets. 4775 * This is only used during a reconfig cycle. 4776 */ 4777 /* ARGSUSED */ 4778 int 4779 mdrpc_clr_mnsetlock_2_svc( 4780 mdrpc_null_args *args, 4781 mdrpc_generic_res *res, 4782 struct svc_req *rqstp /* RPC stuff */ 4783 ) 4784 { 4785 set_t max_sets, setno; 4786 md_error_t *ep = &res->status; 4787 int err; 4788 int op_mode = W_OK; 4789 mdsetname_t *sp; 4790 4791 /* setup, check permissions */ 4792 (void) memset(res, 0, sizeof (*res)); 4793 4794 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4795 return (FALSE); 4796 else if (err != 0) 4797 return (TRUE); 4798 4799 /* 4800 * Walk through all possible disksets. 4801 * For each MN set, delete all keys associated with that set. 4802 */ 4803 if ((max_sets = get_max_sets(ep)) == 0) { 4804 return (TRUE); 4805 } 4806 4807 /* start walking through all possible disksets */ 4808 for (setno = 1; setno < max_sets; setno++) { 4809 if ((sp = metasetnosetname(setno, ep)) == NULL) { 4810 if (mdiserror(ep, MDE_NO_SET)) { 4811 /* No set for this setno - continue */ 4812 mdclrerror(ep); 4813 continue; 4814 } else { 4815 mde_perror(ep, gettext( 4816 "Unable to get set %s information"), 4817 sp->setname); 4818 mdclrerror(ep); 4819 continue; 4820 } 4821 } 4822 4823 /* only check multi-node disksets */ 4824 if (!meta_is_mn_set(sp, ep)) { 4825 mdclrerror(ep); 4826 continue; 4827 } 4828 4829 /* Delete keys associated with rpc.metad clnt_lock */ 4830 del_sk(setno); 4831 } 4832 4833 *ep = mdnullerror; 4834 4835 err = svc_fini(ep); 4836 4837 return (TRUE); 4838 } 4839 4840 /* 4841 * Get drive desc on this host for given setno. 4842 * This is only used during a reconfig cycle. 4843 * Returns a drive desc structure for the given mdsetname 4844 * from this host. 4845 * 4846 * Returned drive desc structure is partially filled in with 4847 * the drive name but is not filled in with any other strings 4848 * in the drivename structure. 4849 */ 4850 bool_t 4851 mdrpc_getdrivedesc_2_svc( 4852 mdrpc_sp_2_args *args, 4853 mdrpc_getdrivedesc_res *res, 4854 struct svc_req *rqstp /* RPC stuff */ 4855 ) 4856 { 4857 md_drive_desc *dd; 4858 md_error_t *ep = &res->status; 4859 int err; 4860 int op_mode = R_OK; 4861 mdsetname_t *my_sp; 4862 mdrpc_sp_args *args_r1; 4863 4864 switch (args->rev) { 4865 case MD_METAD_ARGS_REV_1: 4866 /* setup, check permissions */ 4867 (void) memset(res, 0, sizeof (*res)); 4868 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4869 return (FALSE); 4870 else if (err != 0) 4871 return (TRUE); 4872 4873 /* doit */ 4874 args_r1 = &args->mdrpc_sp_2_args_u.rev1; 4875 if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL) 4876 return (TRUE); 4877 4878 dd = metaget_drivedesc(my_sp, 4879 (MD_BASICNAME_OK | PRINT_FAST), ep); 4880 4881 res->dd = dd_list_dup(dd); 4882 4883 err = svc_fini(ep); 4884 4885 return (TRUE); 4886 default: 4887 return (FALSE); 4888 } 4889 } 4890 4891 /* 4892 * Update drive records given list from master during reconfig. 4893 * Make this node's list match the master's list which may include 4894 * deleting a drive record that is known by this node and not known 4895 * by the master node. 4896 * 4897 * Sync up the set/node/drive record genids to match the genid 4898 * passed in the dd structure (all genids in this structure 4899 * are the same). 4900 */ 4901 bool_t 4902 mdrpc_upd_dr_reconfig_common( 4903 mdrpc_upd_dr_flags_2_args_r1 *args, 4904 mdrpc_generic_res *res, 4905 struct svc_req *rqstp /* RPC stuff */ 4906 ) 4907 { 4908 md_error_t *ep = &res->status; 4909 int err; 4910 mdsetname_t *local_sp; 4911 md_set_record *sr; 4912 md_mnset_record *mnsr; 4913 md_drive_record *dr, *dr_placeholder = NULL; 4914 md_drive_desc *dd; 4915 mddrivename_t *dn, *dn1; 4916 side_t sideno; 4917 md_mnnode_record *nrp; 4918 int op_mode = W_OK; 4919 int change = 0; 4920 4921 /* setup, check permissions */ 4922 (void) memset(res, 0, sizeof (*res)); 4923 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4924 return (FALSE); 4925 else if (err != 0) 4926 return (TRUE); 4927 4928 if ((local_sp = metasetname(args->sp->setname, ep)) == NULL) 4929 return (TRUE); 4930 4931 metaflushsetname(local_sp); 4932 4933 if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 4934 return (TRUE); 4935 4936 if ((sr = getsetbyname(args->sp->setname, ep)) == NULL) 4937 return (TRUE); 4938 4939 if (!(MD_MNSET_REC(sr))) { 4940 free_sr(sr); 4941 return (TRUE); 4942 } 4943 4944 mnsr = (md_mnset_record *)sr; 4945 /* Setup genid on set and node records */ 4946 if (args->drivedescs) { 4947 if (mnsr->sr_genid != args->drivedescs->dd_genid) { 4948 change = 1; 4949 mnsr->sr_genid = args->drivedescs->dd_genid; 4950 } 4951 nrp = mnsr->sr_nodechain; 4952 while (nrp) { 4953 if (nrp->nr_genid != args->drivedescs->dd_genid) { 4954 change = 1; 4955 nrp->nr_genid = args->drivedescs->dd_genid; 4956 } 4957 nrp = nrp->nr_next; 4958 } 4959 } 4960 for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) { 4961 dn1 = metadrivename_withdrkey(local_sp, sideno, 4962 dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep); 4963 if (dn1 == NULL) 4964 goto out; 4965 for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) { 4966 dn = dd->dd_dnp; 4967 /* Found this node's drive rec to match dd */ 4968 if (strcmp(dn->cname, dn1->cname) == 0) 4969 break; 4970 } 4971 4972 /* 4973 * If drive found in master's list, make slave match master. 4974 * If drive not found in master's list, remove drive. 4975 */ 4976 if (dd) { 4977 if ((dr->dr_flags != dd->dd_flags) || 4978 (dr->dr_genid != dd->dd_genid)) { 4979 change = 1; 4980 dr->dr_flags = dd->dd_flags; 4981 dr->dr_genid = dd->dd_genid; 4982 } 4983 } else { 4984 /* 4985 * Delete entry from linked list. Need to use 4986 * dr_placeholder so that dr->dr_next points to 4987 * the next drive record in the list. 4988 */ 4989 if (dr_placeholder == NULL) { 4990 dr_placeholder = 4991 Zalloc(sizeof (md_drive_record)); 4992 } 4993 dr_placeholder->dr_next = dr->dr_next; 4994 dr_placeholder->dr_key = dr->dr_key; 4995 sr_del_drv(sr, dr->dr_selfid); 4996 (void) del_sideno_sidenm(dr_placeholder->dr_key, 4997 sideno, ep); 4998 change = 1; 4999 dr = dr_placeholder; 5000 } 5001 } 5002 out: 5003 /* If incore records are correct, don't need to write to disk */ 5004 if (change) { 5005 /* Don't increment the genid in commitset */ 5006 commitset(sr, FALSE, ep); 5007 } 5008 free_sr(sr); 5009 5010 err = svc_fini(ep); 5011 5012 if (dr_placeholder != NULL) 5013 Free(dr_placeholder); 5014 5015 return (TRUE); 5016 } 5017 5018 /* 5019 * Version 2 routine to update this node's drive records based on 5020 * list passed in from master node. 5021 */ 5022 bool_t 5023 mdrpc_upd_dr_reconfig_2_svc( 5024 mdrpc_upd_dr_flags_2_args *args, 5025 mdrpc_generic_res *res, 5026 struct svc_req *rqstp /* RPC stuff */ 5027 ) 5028 { 5029 switch (args->rev) { 5030 case MD_METAD_ARGS_REV_1: 5031 return (mdrpc_upd_dr_reconfig_common( 5032 &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 5033 default: 5034 return (FALSE); 5035 } 5036 } 5037 5038 /* 5039 * reset mirror owner for mirrors owned by deleted 5040 * or withdrawn host(s). Hosts being deleted or 5041 * withdrawn are designated by nodeid since host is 5042 * already deleted or withdrawn from set and may not 5043 * be able to translate between a nodename and a nodeid. 5044 * If an error occurs, ep will be set to that error information. 5045 */ 5046 static void 5047 reset_mirror_owner( 5048 char *setname, 5049 int node_c, 5050 int *node_id, /* Array of node ids */ 5051 md_error_t *ep 5052 ) 5053 { 5054 mdsetname_t *local_sp; 5055 int i; 5056 mdnamelist_t *devnlp = NULL; 5057 mdnamelist_t *p; 5058 mdname_t *devnp = NULL; 5059 md_set_mmown_params_t ownpar_p; 5060 md_set_mmown_params_t *ownpar = &ownpar_p; 5061 char *miscname; 5062 5063 if ((local_sp = metasetname(setname, ep)) == NULL) 5064 return; 5065 5066 /* get a list of all the mirrors for current set */ 5067 if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0) 5068 return; 5069 5070 /* for each mirror */ 5071 for (p = devnlp; (p != NULL); p = p->next) { 5072 devnp = p->namep; 5073 5074 /* 5075 * we can only do these for mirrors so make sure we 5076 * really have a mirror device and not a softpartition 5077 * imitating one. meta_get_mirror_names seems to think 5078 * softparts on top of a mirror are mirrors! 5079 */ 5080 if ((miscname = metagetmiscname(devnp, ep)) == NULL) 5081 goto out; 5082 if (strcmp(miscname, MD_MIRROR) != 0) 5083 continue; 5084 5085 (void) memset(ownpar, 0, sizeof (*ownpar)); 5086 ownpar->d.mnum = meta_getminor(devnp->dev); 5087 MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno); 5088 5089 /* get the current owner id */ 5090 if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep, 5091 "MD_MN_GET_MM_OWNER") != 0) { 5092 mde_perror(ep, gettext( 5093 "Unable to get mirror owner for %s/d%u"), 5094 local_sp->setname, 5095 (unsigned)MD_MIN2UNIT(ownpar->d.mnum)); 5096 goto out; 5097 } 5098 5099 if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) { 5100 mdclrerror(ep); 5101 continue; 5102 } 5103 /* 5104 * reset owner only if the current owner is 5105 * in the list of nodes being deleted. 5106 */ 5107 for (i = 0; i < node_c; i++) { 5108 if (ownpar->d.owner == node_id[i]) { 5109 if (meta_mn_change_owner(&ownpar, 5110 local_sp->setno, ownpar->d.mnum, 5111 MD_MN_MIRROR_UNOWNED, 5112 MD_MN_MM_ALLOW_CHANGE) == -1) { 5113 mde_perror(ep, gettext( 5114 "Unable to reset mirror owner for" 5115 " %s/d%u"), local_sp->setname, 5116 (unsigned)MD_MIN2UNIT( 5117 ownpar->d.mnum)); 5118 goto out; 5119 } 5120 break; 5121 } 5122 } 5123 } 5124 5125 out: 5126 /* cleanup */ 5127 metafreenamelist(devnlp); 5128 } 5129 5130 /* 5131 * Wrapper routine for reset_mirror_owner. 5132 * Called when hosts are deleted or withdrawn 5133 * in order to reset any mirror owners that are needed. 5134 */ 5135 bool_t 5136 mdrpc_reset_mirror_owner_common( 5137 mdrpc_nodeid_args *args, 5138 mdrpc_generic_res *res, 5139 struct svc_req *rqstp /* RPC stuff */ 5140 ) 5141 { 5142 md_error_t *ep = &res->status; 5143 int err; 5144 int op_mode = W_OK; 5145 5146 /* setup, check permissions */ 5147 (void) memset(res, 0, sizeof (*res)); 5148 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5149 return (FALSE); 5150 else if (err != 0) 5151 return (TRUE); 5152 5153 if (check_set_lock(op_mode, args->cl_sk, ep)) 5154 return (TRUE); 5155 5156 /* doit */ 5157 reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len, 5158 args->nodeid.nodeid_val, ep); 5159 5160 err = svc_fini(ep); 5161 5162 return (TRUE); 5163 } 5164 5165 /* 5166 * RPC service routine to reset the mirror owner for mirrors owned 5167 * by the given hosts. Typically, the list of given hosts is a list 5168 * of nodes being deleted or withdrawn from a diskset. 5169 * The given hosts are designated by nodeid since host may 5170 * already be deleted or withdrawn from set and may not 5171 * be able to translate between a nodename and a nodeid. 5172 */ 5173 bool_t 5174 mdrpc_reset_mirror_owner_2_svc( 5175 mdrpc_nodeid_2_args *args, 5176 mdrpc_generic_res *res, 5177 struct svc_req *rqstp /* RPC stuff */ 5178 ) 5179 { 5180 switch (args->rev) { 5181 case MD_METAD_ARGS_REV_1: 5182 return (mdrpc_reset_mirror_owner_common( 5183 &args->mdrpc_nodeid_2_args_u.rev1, res, 5184 rqstp)); 5185 default: 5186 return (FALSE); 5187 } 5188 } 5189 5190 /* 5191 * Call routines to suspend and resume I/O for the given diskset(s). 5192 * Called during reconfig cycle. 5193 * Diskset of 0 represents all MN disksets. 5194 */ 5195 bool_t 5196 mdrpc_mn_susp_res_io_2_svc( 5197 mdrpc_mn_susp_res_io_2_args *args, 5198 mdrpc_generic_res *res, 5199 struct svc_req *rqstp /* RPC stuff */ 5200 ) 5201 { 5202 mdrpc_mn_susp_res_io_args *args_sr; 5203 md_error_t *ep = &res->status; 5204 int err; 5205 int op_mode = R_OK; 5206 5207 switch (args->rev) { 5208 case MD_METAD_ARGS_REV_1: 5209 /* setup, check permissions */ 5210 (void) memset(res, 0, sizeof (*res)); 5211 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5212 return (FALSE); 5213 else if (err != 0) 5214 return (TRUE); 5215 5216 args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1); 5217 switch (args_sr->susp_res_cmd) { 5218 case MN_SUSP_IO: 5219 (void) (metaioctl(MD_MN_SUSPEND_SET, 5220 &args_sr->susp_res_setno, ep, NULL)); 5221 break; 5222 case MN_RES_IO: 5223 (void) (metaioctl(MD_MN_RESUME_SET, 5224 &args_sr->susp_res_setno, ep, NULL)); 5225 break; 5226 } 5227 err = svc_fini(ep); 5228 return (TRUE); 5229 5230 default: 5231 return (FALSE); 5232 } 5233 } 5234 5235 /* 5236 * Resnarf a set after it has been imported 5237 */ 5238 bool_t 5239 mdrpc_resnarf_set_2_svc( 5240 mdrpc_setno_2_args *args, 5241 mdrpc_generic_res *res, 5242 struct svc_req *rqstp /* RPC stuff */ 5243 ) 5244 { 5245 mdrpc_setno_args *setno_args; 5246 md_error_t *ep = &res->status; 5247 int err; 5248 int op_mode = R_OK; 5249 5250 switch (args->rev) { 5251 case MD_METAD_ARGS_REV_1: 5252 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5253 break; 5254 default: 5255 return (FALSE); 5256 } 5257 5258 (void) memset(res, 0, sizeof (*res)); 5259 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5260 return (FALSE); 5261 else if (err != 0) 5262 return (TRUE); 5263 5264 /* do it */ 5265 if (resnarf_set(setno_args->setno, ep) < 0) 5266 return (FALSE); 5267 5268 err = svc_fini(ep); 5269 return (TRUE); 5270 } 5271 5272 /* 5273 * Creates a resync thread. 5274 * Always returns true. 5275 */ 5276 bool_t 5277 mdrpc_mn_mirror_resync_all_2_svc( 5278 mdrpc_setno_2_args *args, 5279 mdrpc_generic_res *res, 5280 struct svc_req *rqstp /* RPC stuff */ 5281 ) 5282 { 5283 md_error_t *ep = &res->status; 5284 mdrpc_setno_args *setno_args; 5285 int err; 5286 int op_mode = R_OK; 5287 5288 switch (args->rev) { 5289 case MD_METAD_ARGS_REV_1: 5290 /* setup, check permissions */ 5291 (void) memset(res, 0, sizeof (*res)); 5292 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5293 return (FALSE); 5294 else if (err != 0) 5295 return (TRUE); 5296 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5297 5298 /* 5299 * Need to invoke a metasync on a node newly added to a set. 5300 */ 5301 meta_mn_mirror_resync_all(&(setno_args->setno)); 5302 5303 err = svc_fini(ep); 5304 return (TRUE); 5305 5306 default: 5307 return (FALSE); 5308 } 5309 } 5310 5311 /* 5312 * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(), 5313 * which forks a daemon process to perform this action. 5314 * Always returns true. 5315 */ 5316 bool_t 5317 mdrpc_mn_sp_update_abr_2_svc( 5318 mdrpc_setno_2_args *args, 5319 mdrpc_generic_res *res, 5320 struct svc_req *rqstp /* RPC stuff */ 5321 ) 5322 { 5323 md_error_t *ep = &res->status; 5324 mdrpc_setno_args *setno_args; 5325 int err; 5326 int op_mode = R_OK; 5327 5328 switch (args->rev) { 5329 case MD_METAD_ARGS_REV_1: 5330 /* setup, check permissions */ 5331 (void) memset(res, 0, sizeof (*res)); 5332 if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5333 return (FALSE); 5334 else if (err != 0) 5335 return (TRUE); 5336 setno_args = &args->mdrpc_setno_2_args_u.rev1; 5337 5338 meta_mn_sp_update_abr(&(setno_args->setno)); 5339 5340 err = svc_fini(ep); 5341 return (TRUE); 5342 5343 default: 5344 return (FALSE); 5345 } 5346 } 5347