1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Metadevice diskset interfaces 30 */ 31 32 #include "meta_set_prv.h" 33 #include <meta.h> 34 #include <sys/lvm/md_mddb.h> 35 #include <sys/cladm.h> 36 #include <devid.h> 37 #include <sys/lvm/md_convert.h> 38 39 /* 40 * Exported Entry Points 41 */ 42 43 int 44 checkdrive_onnode( 45 mdsetname_t *sp, 46 mddrivename_t *dnp, 47 char *node, 48 md_error_t *ep) 49 { 50 time_t mystamp, otherstamp; 51 md_dev64_t otherdev; 52 mdname_t *np, *remote_np; 53 mddrivename_t *remote_dnp; 54 int release = 0; 55 md_drive_desc dd; 56 int rval = 0; 57 int ret = -1; 58 mhd_mhiargs_t mhiargs; 59 md_set_desc *sd; 60 int is_efi = 0; 61 int do_fallback = 0; 62 63 (void) memset(&mhiargs, '\0', sizeof (mhiargs)); 64 65 if ((sd = metaget_setdesc(sp, ep)) == NULL) 66 return (-1); 67 68 if (meta_is_drive_in_thisset(sp, dnp, FALSE, ep)) { 69 release = 1; 70 dd.dd_next = NULL; 71 dd.dd_dbcnt = 0; 72 dd.dd_dbsize = 0; 73 dd.dd_dnp = dnp; 74 if (clnt_gtimeout(mynode(), sp, &mhiargs, ep) != 0) 75 return (-1); 76 if (!(MD_MNSET_DESC(sd)) && !MD_ATSET_DESC(sd)) { 77 if (rel_own_bydd(sp, &dd, TRUE, ep)) 78 return (-1); 79 } 80 } 81 if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) { 82 rval = -1; 83 goto out; 84 } 85 86 /* 87 * First try and operate assuming the other side 88 * is running a SVM version that supports device id 89 * in disksets i.e. is running SVM RPC version 2. 90 * 91 * If this call fails due to the other side running 92 * a SVM version that does not support device id 93 * in disksets i.e. is running SVM RPC version 1, we 94 * fallback to the old behaviour. 95 */ 96 if ((dnp->devid != NULL) && (!(MD_MNSET_DESC(sd)))) { 97 char *rname = NULL; 98 md_dev64_t dev = NODEV64; 99 100 /* 101 * If the disk is connected to the remote node then the 102 * only thing we can be certain of is that the disk will 103 * have the same devid on that node, it may not have the 104 * same minor number nor the same ctd name. But if it 105 * does have the same ctd name then use it. In most cases 106 * there will only be a single entry returned but if the 107 * system has multi-path disks with MPXIO turned off there 108 * will be multiple entries. Attempting to choose the same 109 * name will give the user as consistent a view across the 110 * nodes as possible. 111 */ 112 ret = clnt_devinfo_by_devid(node, sp, dnp->devid, &dev, 113 np->rname, &rname, NULL, ep); 114 115 /* 116 * If the return value was ENOTSUP, we know the 117 * other side is not running a SVM version that 118 * supports device id in disksets. We fallback 119 * to the previous behaviour in that case. 120 */ 121 if (ret == ENOTSUP) { 122 do_fallback++; 123 goto fallback; 124 } else if (ret == -1) { 125 rval = -1; 126 goto out; 127 } 128 129 /* 130 * If the device does not exist on the remote node then 131 * the returned dev should indicate this (NODEV64) but 132 * we also check to make sure the returned name is not 133 * empty to make sure that the namespace does not get 134 * created with a NULL/empty entry (should not be possbile 135 * but being paranoid). 136 */ 137 if (dev == NODEV64 || rname == (char *)NULL || 138 strcmp(rname, "") == 0) { 139 rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON, sp->setno, 140 node, dnp->cname, sp->setname); 141 goto out; 142 } 143 144 /* 145 * The rname returned from the remote node maybe different 146 * to the rname on this node, therefore we need to build up 147 * a dnp for this new rname. 148 */ 149 if (strcmp(np->rname, rname) != 0) { 150 /* different rname */ 151 remote_np = metaname_fast(&sp, rname, 152 LOGICAL_DEVICE, ep); 153 if (remote_np != NULL) { 154 remote_dnp = remote_np->drivenamep; 155 } 156 } else { 157 remote_dnp = dnp; 158 } 159 } else { 160 do_fallback++; 161 } 162 163 fallback: 164 if (do_fallback) { 165 ret = setdevstamp(dnp, &mystamp, ep); 166 /* 167 * Check if the disk in question is an EFI disk. 168 */ 169 if (ret == ENOTSUP) 170 is_efi++; 171 else if (ret == -1) 172 return (-1); 173 174 if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) { 175 rval = -1; 176 goto out; 177 } 178 179 if (is_efi) { 180 /* 181 * For EFI disks, we compare the device 182 * id for the disks in question. 183 */ 184 ddi_devid_t thisdevid, otherdevid; 185 char *encoded_otherdevid = NULL; 186 char *encoded_thisdevid = NULL; 187 188 if (clnt_devinfo(node, sp, dnp, &otherdev, NULL, ep) 189 == -1) { 190 rval = -1; 191 goto out; 192 } 193 if (np->dev != otherdev) { 194 rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON, 195 sp->setno, node, dnp->cname, sp->setname); 196 goto out; 197 } 198 199 if (clnt_devid(node, sp, dnp, &encoded_otherdevid, 200 ep) == -1) { 201 rval = -1; 202 goto out; 203 } 204 if (encoded_otherdevid == NULL) { 205 rval = -1; 206 goto out; 207 } 208 if (devid_str_decode(encoded_otherdevid, &otherdevid, 209 NULL) == 0) { 210 /* 211 * If we are here, it means that dnp->devid 212 * is NULL. This will typically happen if 213 * we are dealing with SunCluster DID devices. 214 * 215 * We want to explicitly get the device id 216 * for such a disk 217 */ 218 encoded_thisdevid = meta_get_devid(dnp->rname); 219 ret = devid_str_decode(encoded_thisdevid, 220 &thisdevid, NULL); 221 if (ret == 0) { 222 ret = devid_compare(thisdevid, 223 otherdevid); 224 devid_free(thisdevid); 225 } 226 devid_free(otherdevid); 227 if (encoded_thisdevid) 228 Free(encoded_thisdevid); 229 } 230 231 Free(encoded_otherdevid); 232 if (ret != 0) { 233 rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON, 234 sp->setno, node, dnp->cname, sp->setname); 235 goto out; 236 } 237 } else { 238 /* 239 * For VTOC disks, we compare the dev_t and 240 * timestamp for the disks in question. 241 */ 242 if (clnt_devinfo(node, sp, dnp, &otherdev, 243 &otherstamp, ep) == -1) { 244 rval = -1; 245 goto out; 246 } 247 if ((mystamp != otherstamp) || (np->dev != otherdev)) { 248 rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON, 249 sp->setno, node, dnp->cname, sp->setname); 250 goto out; 251 } 252 } 253 remote_dnp = dnp; 254 } 255 256 if (clnt_drvused(node, sp, remote_dnp, ep) == -1) 257 rval = -1; 258 259 out: 260 if (release) 261 if (!(MD_MNSET_DESC(sd)) && !MD_ATSET_DESC(sd)) { 262 if (tk_own_bydd(sp, &dd, &mhiargs, TRUE, ep)) 263 rval = -1; 264 } 265 266 return (rval); 267 } 268 269 side_t 270 getnodeside(char *node, md_set_desc *sd) 271 { 272 side_t sideno; 273 int nid; 274 md_mnnode_desc *nd; 275 276 if (MD_MNSET_DESC(sd)) { 277 nd = sd->sd_nodelist; 278 while (nd) { 279 if (strcmp(nd->nd_nodename, node) == 0) { 280 return (nd->nd_nodeid); 281 } 282 nd = nd->nd_next; 283 } 284 return (MD_SIDEWILD); 285 } 286 287 288 /* If regular diskset */ 289 for (sideno = 0; sideno < MD_MAXSIDES; sideno++) { 290 if (sd->sd_nodes[sideno] == NULL || 291 sd->sd_nodes[sideno][0] == '\0') 292 continue; 293 294 if (strcmp(sd->sd_nodes[sideno], node) == 0) { 295 return (sideno); 296 } 297 } 298 299 /* 300 * If the first loop fails we may be in a situation where this host 301 * is configured as part of a cluster yet not running in the cluster 302 * mode. If so, the names stored in sd->sd_nodes[] are going to be 303 * nodeid's instead of hostnames. See if we can find a match that way. 304 */ 305 if (_cladm(CL_CONFIG, CL_NODEID, &nid) == 0) { 306 for (sideno = 0; sideno < MD_MAXSIDES; sideno++) { 307 if (sd->sd_nodes[sideno] == NULL || 308 sd->sd_nodes[sideno][0] == '\0') 309 continue; 310 if (atoi(sd->sd_nodes[sideno]) == nid) 311 return (sideno); 312 } 313 } 314 315 return (MD_SIDEWILD); 316 } 317 318 int 319 halt_set(mdsetname_t *sp, md_error_t *ep) 320 { 321 mddb_config_t c; 322 323 (void) memset(&c, 0, sizeof (c)); 324 c.c_setno = sp->setno; 325 if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD) 326 return (-1); 327 328 if (s_ownset(sp->setno, ep) == MD_SETOWNER_YES) { 329 /* Don't need device id information from this ioctl */ 330 c.c_locator.l_devid = (uint64_t)0; 331 c.c_locator.l_devid_flags = 0; 332 /* Kill any resyncs that are running on mirrors in this set */ 333 meta_mirror_resync_kill(sp); 334 if (metaioctl(MD_RELEASE_SET, &c, &c.c_mde, NULL) != 0) 335 return (mdstealerror(ep, &c.c_mde)); 336 } 337 338 return (0); 339 } 340 341 md_drive_desc * 342 metadrivedesc_append( 343 md_drive_desc **dd, 344 mddrivename_t *dnp, 345 int dbcnt, 346 int dbsize, 347 md_timeval32_t timestamp, 348 ulong_t genid, 349 uint_t flags 350 ) 351 { 352 md_drive_desc *p; 353 354 /* run to end of list */ 355 for (/* void */; (*dd != NULL); dd = &(*dd)->dd_next) 356 /* void */; 357 358 /* allocate new list element */ 359 p = *dd = Zalloc(sizeof (*p)); 360 361 p->dd_dnp = dnp; 362 p->dd_dbcnt = dbcnt; 363 p->dd_dbsize = dbsize; 364 p->dd_ctime = timestamp; 365 p->dd_genid = genid; 366 p->dd_flags = flags; 367 return (p); 368 } 369 370 int 371 nodehasset( 372 mdsetname_t *sp, 373 char *node, 374 uint_t match_flag, 375 md_error_t *ep 376 ) 377 { 378 md_set_desc *sd; 379 md_set_record *sr; 380 int rval = 0; 381 382 if ((sd = metaget_setdesc(sp, ep)) == NULL) 383 return (-1); 384 385 /* Don't care if set record is MN or not */ 386 if (clnt_getset(node, sp->setname, MD_SET_BAD, &sr, ep)) 387 return (-1); 388 389 if (sr == NULL) { 390 if (! mdisok(ep)) 391 return (-1); 392 return (0); 393 } 394 395 /* Looking for name only match */ 396 if ((match_flag & NHS_N_EQ) == NHS_N_EQ) { 397 rval = 1; 398 goto out; 399 } 400 401 if (sd->sd_setno != sr->sr_setno) 402 goto out; 403 404 /* Looking for name and setno match */ 405 if ((match_flag & NHS_NS_EQ) == NHS_NS_EQ) { 406 rval = 1; 407 goto out; 408 } 409 410 if (sd->sd_ctime.tv_sec != sr->sr_ctime.tv_sec || 411 sd->sd_ctime.tv_usec != sr->sr_ctime.tv_usec) 412 goto out; 413 414 /* Looking for name, setno, and timestamp match */ 415 if ((match_flag & NHS_NST_EQ) == NHS_NST_EQ) { 416 rval = 1; 417 goto out; 418 } 419 420 if (sd->sd_genid != sr->sr_genid) { 421 if (sd->sd_genid < sr->sr_genid) { 422 /* 423 * Looking for name, setno, timestamp, and genid on 424 * other host is GT than other host. 425 */ 426 if ((match_flag & NHS_NST_EQ_G_GT) == NHS_NST_EQ_G_GT) { 427 rval = 1; 428 goto out; 429 } 430 } 431 goto out; 432 } 433 434 /* Looking for name, setno, timestamp, and genid match */ 435 if ((match_flag & NHS_NSTG_EQ) == NHS_NSTG_EQ) 436 rval = 1; 437 438 out: 439 /* 440 * Set record structure was allocated from RPC routine getset 441 * so this structure is only of size md_set_record even if 442 * the MN flag is set. So, clear the flag so that the free 443 * code doesn't attempt to free a structure the size of 444 * md_mnset_record. 445 */ 446 sr->sr_flags &= ~MD_SR_MN; 447 free_sr(sr); 448 449 return (rval); 450 } 451 452 int 453 nodesuniq(mdsetname_t *sp, int cnt, char **strings, md_error_t *ep) 454 { 455 int i, j; 456 for (i = 0; i < cnt; i++) 457 for (j = i + 1; j < cnt; j++) 458 if (strcmp(strings[i], strings[j]) == 0) 459 return (mddserror(ep, MDE_DS_DUPHOST, 460 sp->setno, strings[i], NULL, sp->setname)); 461 return (0); 462 } 463 464 int 465 own_set(mdsetname_t *sp, char **owner_of_set, int forceflg, md_error_t *ep) 466 { 467 md_set_desc *sd; 468 int am_i_owner; 469 int i; 470 471 if (metaislocalset(sp)) { 472 if (owner_of_set != NULL) 473 *owner_of_set = Strdup(mynode()); 474 return (MD_SETOWNER_YES); 475 } 476 477 if ((sd = metaget_setdesc(sp, ep)) == NULL) 478 return (-1); 479 480 if (clnt_ownset(mynode(), sp, &am_i_owner, ep) == -1) 481 return (-1); 482 483 if (MD_MNSET_DESC(sd)) { 484 if (am_i_owner == TRUE) 485 return (MD_SETOWNER_YES); 486 else 487 return (MD_SETOWNER_NO); 488 } 489 490 if (forceflg == TRUE) { 491 if (am_i_owner == TRUE) { 492 if (owner_of_set != NULL) 493 *owner_of_set = Strdup(mynode()); 494 return (MD_SETOWNER_YES); 495 } 496 497 if (owner_of_set != NULL) 498 *owner_of_set = NULL; 499 return (MD_SETOWNER_NONE); 500 } 501 502 if (am_i_owner == TRUE) { 503 if (owner_of_set != NULL) 504 *owner_of_set = Strdup(mynode()); 505 return (MD_SETOWNER_YES); 506 } 507 508 509 for (i = 0; i < MD_MAXSIDES; i++) { 510 /* 511 * Skip empty slots, and my own slot. 512 */ 513 if (sd->sd_nodes[i][0] == '\0' || 514 strcmp(sd->sd_nodes[i], mynode()) == 0) 515 continue; 516 517 if (clnt_ownset(sd->sd_nodes[i], sp, &am_i_owner, ep) == -1) 518 return (-1); 519 520 if (am_i_owner == TRUE) { 521 if (owner_of_set != NULL) 522 *owner_of_set = Strdup(sd->sd_nodes[i]); 523 return (MD_SETOWNER_NO); 524 } 525 } 526 527 /* We get here, we currently have no owner. */ 528 if (owner_of_set != NULL) 529 *owner_of_set = NULL; 530 return (MD_SETOWNER_NONE); 531 } 532 533 void 534 resync_genid( 535 mdsetname_t *sp, 536 md_set_desc *sd, 537 ulong_t max_genid, 538 int node_c, 539 char **node_v 540 ) 541 { 542 int i, j; 543 ulong_t cur_genid[MD_MAXSIDES]; 544 md_set_record *sr; 545 md_error_t xep = mdnullerror; 546 md_mnnode_desc *nd; 547 md_mnset_record *mnsr; 548 549 if (node_c > 0 && node_v && *node_v) { 550 /* 551 * Mark the set record MD_SR_OK. 552 */ 553 for (i = 0; i < node_c; i++) 554 if (clnt_upd_sr_flags(node_v[i], sp, MD_SR_OK, &xep)) 555 mdclrerror(&xep); 556 max_genid++; 557 } 558 559 if (MD_MNSET_DESC(sd)) { 560 nd = sd->sd_nodelist; 561 while (nd) { 562 if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) { 563 nd = nd->nd_next; 564 continue; 565 } 566 /* Will only return a multi-node diskset record */ 567 if (clnt_mngetset(nd->nd_nodename, sp->setname, 568 MD_SET_BAD, &mnsr, &xep) == -1) { 569 mdclrerror(&xep); 570 nd = nd->nd_next; 571 continue; 572 } 573 for (j = mnsr->sr_genid; j < max_genid; j++) { 574 if (clnt_upd_sr_flags(nd->nd_nodename, sp, 575 MD_SR_OK, &xep)) 576 mdclrerror(&xep); 577 } 578 free_sr((struct md_set_record *)mnsr); 579 nd = nd->nd_next; 580 } 581 return; 582 } 583 584 /* 585 * Get current genid for each node. 586 */ 587 for (i = 0; i < MD_MAXSIDES; i++) { 588 cur_genid[i] = 0; 589 590 /* Skip empty slots */ 591 if (sd->sd_nodes[i][0] == '\0') 592 continue; 593 594 /* Should be a non-multinode diskset */ 595 if (clnt_getset(sd->sd_nodes[i], sp->setname, 596 MD_SET_BAD, &sr, &xep) == -1) { 597 mdclrerror(&xep); 598 continue; 599 } 600 601 if (MD_MNSET_REC(sr)) { 602 /* 603 * Set record structure was allocated from RPC routine 604 * getset so this structure is only of size 605 * md_set_record even if the MN flag is set. So, 606 * clear the flag so that the free code doesn't 607 * attempt to free a structure the size of 608 * md_mnset_record. 609 */ 610 sr->sr_flags &= ~MD_SR_MN; 611 free_sr(sr); 612 continue; 613 } 614 615 cur_genid[i] = sr->sr_genid; 616 617 free_sr(sr); 618 } 619 620 /* 621 * Mark the set record MD_SR_OK 622 */ 623 for (i = 0; i < MD_MAXSIDES; i++) { 624 /* Skip empty slots */ 625 if (sd->sd_nodes[i][0] == '\0') 626 continue; 627 628 for (j = cur_genid[i]; j < max_genid; j++) 629 if (clnt_upd_sr_flags(sd->sd_nodes[i], sp, MD_SR_OK, 630 &xep)) 631 mdclrerror(&xep); 632 633 } 634 } 635 636 int 637 setup_db_bydd(mdsetname_t *sp, md_drive_desc *dd, int force, md_error_t *ep) 638 { 639 md_drive_desc *p; 640 struct mddb_config c; 641 int i; 642 md_set_desc *sd; 643 int use_devid = 1; 644 ddi_devid_t devidp, new_devidp; 645 char *minor_name = NULL; 646 size_t sz; 647 char *devid_str = NULL; 648 int need_to_free_devidp = 0; 649 650 if ((sd = metaget_setdesc(sp, ep)) == NULL) 651 return (-1); 652 (void) memset(&c, 0, sizeof (c)); 653 654 c.c_setno = sp->setno; 655 (void) strcpy(c.c_setname, sp->setname); 656 if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD) 657 return (-1); 658 659 c.c_timestamp = sd->sd_ctime; 660 661 if (setup_med_cfg(sp, &c, force, ep)) 662 return (-1); 663 664 for (p = dd; p != NULL; p = p->dd_next) { 665 mddrivename_t *dnp; 666 mdname_t *np; 667 mdcinfo_t *cinfo; 668 mdsidenames_t *sn = NULL; 669 670 if (p->dd_dbcnt == 0) 671 continue; 672 673 dnp = p->dd_dnp; 674 675 assert(dnp != NULL); 676 677 for (sn = dnp->side_names; sn != NULL; sn = sn->next) { 678 if (sn->sideno == c.c_sideno) 679 break; 680 } 681 682 /* 683 * The disk has no side name information 684 */ 685 if (sn == NULL) { 686 uint_t rep_slice; 687 688 if ((meta_replicaslice(dnp, &rep_slice, ep) != 0) || 689 ((np = metaslicename(dnp, rep_slice, ep)) 690 == NULL)) { 691 mdclrerror(ep); 692 continue; 693 } 694 695 if (np->dev == NODEV64) 696 continue; 697 698 c.c_locator.l_dev = meta_cmpldev(np->dev); 699 c.c_locator.l_mnum = meta_getminor(np->dev); 700 701 if (!MD_MNSET_DESC(sd)) { 702 /* 703 * minor_name will be NULL if dnp->devid == NULL 704 * - see metagetvtoc() 705 */ 706 if (np->minor_name != NULL) { 707 minor_name = Strdup(np->minor_name); 708 } 709 } 710 711 if ((cinfo = metagetcinfo(np, ep)) == NULL) { 712 mdclrerror(ep); 713 continue; 714 } 715 716 (void) strncpy(c.c_locator.l_driver, cinfo->dname, 717 sizeof (c.c_locator.l_driver)); 718 } else { 719 c.c_locator.l_dev = NODEV32; 720 c.c_locator.l_mnum = sn->mnum; 721 (void) strncpy(c.c_locator.l_driver, sn->dname, 722 sizeof (c.c_locator.l_driver)); 723 724 if (!MD_MNSET_DESC(sd)) { 725 if (dnp->devid != NULL) { 726 minor_name = meta_getdidminorbykey( 727 MD_LOCAL_SET, sn->sideno + SKEW, 728 dnp->side_names_key, ep); 729 } 730 } 731 } 732 733 if ((dnp->devid == NULL) || MD_MNSET_DESC(sd)) { 734 use_devid = 0; 735 } 736 737 if (use_devid) { 738 /* 739 * The devid associated with the dnp does not have 740 * a minor name and so we must add it in. 741 */ 742 size_t len = strlen(dnp->devid) + 743 strlen(minor_name) + 2; 744 devid_str = (char *)Malloc(len); 745 (void) snprintf(devid_str, len, "%s/%s", dnp->devid, 746 minor_name); 747 (void) devid_str_decode(devid_str, &devidp, NULL); 748 need_to_free_devidp = 1; 749 750 /* If need to fix LB then setup old_devid info */ 751 if (p->dd_flags & MD_DR_FIX_LB_NM_DID) { 752 sz = devid_sizeof(devidp); 753 c.c_locator.l_old_devid_sz = sz; 754 c.c_locator.l_old_devid = (uintptr_t)malloc(sz); 755 (void) memcpy((void *)(uintptr_t) 756 c.c_locator.l_old_devid, 757 devidp, sz); 758 759 new_devidp = replicated_list_lookup( 760 devid_sizeof((ddi_devid_t)devidp), 761 (void *)(uintptr_t)devidp); 762 devid_free(devidp); 763 need_to_free_devidp = 0; 764 devidp = new_devidp; 765 766 } 767 sz = devid_sizeof(devidp); 768 c.c_locator.l_devid = (uintptr_t)malloc(sz); 769 c.c_locator.l_devid_sz = sz; 770 (void) memcpy((void *)(uintptr_t) 771 c.c_locator.l_devid, 772 devidp, sz); 773 if (need_to_free_devidp) { 774 devid_free(devidp); 775 need_to_free_devidp = 0; 776 } 777 if (minor_name == NULL) { 778 /* ERROR fix up */ 779 Free(devid_str); 780 Free((void *)(uintptr_t)c.c_locator.l_devid); 781 if (c.c_locator.l_old_devid_sz) { 782 Free((void *) 783 (uintptr_t)c.c_locator.l_old_devid); 784 c.c_locator.l_old_devid_sz = 0; 785 c.c_locator.l_old_devid = 786 (uintptr_t)NULL; 787 } 788 return (-1); 789 } 790 (void) strcpy(c.c_locator.l_minor_name, 791 minor_name); 792 c.c_locator.l_devid_flags = MDDB_DEVID_VALID | 793 MDDB_DEVID_SPACE | MDDB_DEVID_SZ; 794 } else { 795 /* 796 * Don't need device id information from 797 * this ioctl 798 */ 799 c.c_locator.l_devid = (uint64_t)0; 800 c.c_locator.l_devid_flags = 0; 801 } 802 803 804 for (i = 0; i < p->dd_dbcnt; i++) { 805 c.c_locator.l_flags = 0; 806 c.c_locator.l_blkno = 16 + i * p->dd_dbsize; 807 808 if (metaioctl(MD_DB_USEDEV, &c, &c.c_mde, NULL) != 0) { 809 if (use_devid) { 810 Free(devid_str); 811 Free((void *) 812 (uintptr_t)c.c_locator.l_devid); 813 if (c.c_locator.l_old_devid_sz) { 814 Free((void *)(uintptr_t) 815 c.c_locator.l_old_devid); 816 c.c_locator.l_old_devid_sz = 0; 817 c.c_locator.l_old_devid = 818 (uintptr_t)NULL; 819 } 820 } 821 Free(minor_name); 822 return (mdstealerror(ep, &c.c_mde)); 823 } 824 } 825 if (use_devid) { 826 Free(devid_str); 827 Free((void *)(uintptr_t)c.c_locator.l_devid); 828 if (c.c_locator.l_old_devid_sz) { 829 Free((void *) 830 (uintptr_t)c.c_locator.l_old_devid); 831 c.c_locator.l_old_devid_sz = 0; 832 c.c_locator.l_old_devid = (uintptr_t)NULL; 833 } 834 } 835 Free(minor_name); 836 } 837 838 /* return success */ 839 return (0); 840 } 841 842 int 843 snarf_set(mdsetname_t *sp, bool_t stale_bool, md_error_t *ep) 844 { 845 mddb_config_t c; 846 847 (void) memset(&c, '\0', sizeof (c)); 848 849 c.c_setno = sp->setno; 850 if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD) 851 return (-1); 852 853 /* Don't need device id information from this ioctl */ 854 c.c_locator.l_devid = (uint64_t)0; 855 c.c_locator.l_devid_flags = 0; 856 if (stale_bool == TRUE) { 857 c.c_flags = MDDB_C_STALE; 858 } 859 if (metaioctl(MD_GRAB_SET, &c, &c.c_mde, NULL) != 0) 860 return (mdstealerror(ep, &c.c_mde)); 861 862 if (c.c_flags & MDDB_C_STALE) 863 return (mdmddberror(ep, MDE_DB_STALE, (minor_t)NODEV64, 864 sp->setno, 0, NULL)); 865 866 return (0); 867 } 868