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 2004 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 /* 30 * Just in case we're not in a build environment, make sure that 31 * TEXT_DOMAIN gets set to something. 32 */ 33 #if !defined(TEXT_DOMAIN) 34 #define TEXT_DOMAIN "SYS_TEST" 35 #endif 36 37 /* 38 * Mediator functions 39 */ 40 41 #include <meta.h> 42 #include <metamed.h> 43 #include <dlfcn.h> 44 #include <sdssc.h> 45 46 /* 47 * There are too many external factors that affect the timing of the 48 * operations, so we set the timeout to a very large value, in this 49 * case 1 day, which should handle HW timeouts, large configurations, 50 * and other potential delays. 51 */ 52 #define CL_LONG_TMO 86400L /* 1 day */ 53 #define CL_MEDIUM_TMO 3600L /* 1 hour */ 54 #define CL_SHORT_TMO 600L /* 10 minutes */ 55 #define CL_DEF_TMO 10L /* 10 seconds */ 56 57 static md_timeval32_t def_rpcb_timeout = { MD_CLNT_CREATE_TOUT, 0 }; 58 59 /* 60 * RPC handle 61 */ 62 typedef struct { 63 char *hostname; 64 CLIENT *clntp; 65 } med_handle_t; 66 67 /* 68 * Data to be sent from med_clnt_create_timed to med_create_helper via 69 * meta_client_create_retry. 70 */ 71 typedef struct { 72 rpcprog_t mcd_program; /* RPC program designation */ 73 rpcvers_t mcd_version; /* RPC version */ 74 char *mcd_nettype; /* Type of network to use for RPC */ 75 } med_create_data_t; 76 77 /* 78 * Perform the work of actually doing the clnt_create for 79 * meta_client_create_retry. 80 */ 81 static CLIENT * 82 med_create_helper(char *hostname, void *private, struct timeval *time_out) 83 { 84 med_create_data_t *cd = (med_create_data_t *)private; 85 86 return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version, 87 cd->mcd_nettype, time_out)); 88 } 89 90 static 91 CLIENT *med_clnt_create_timed( 92 char *hostname, 93 const ulong_t prog, 94 const ulong_t vers, 95 char *nettype, 96 const md_timeval32_t *tp 97 ) 98 { 99 med_create_data_t cd; /* Create data. */ 100 101 cd.mcd_program = prog; 102 cd.mcd_version = vers; 103 cd.mcd_nettype = nettype; 104 return (meta_client_create_retry(hostname, med_create_helper, 105 (void *)&cd, (time_t)tp->tv_sec, NULL)); 106 } 107 108 /* 109 * Set the timeout value for this client handle. 110 */ 111 static int 112 cl_sto_medd( 113 CLIENT *clntp, 114 char *hostname, 115 long time_out, 116 md_error_t *ep 117 ) 118 { 119 md_timeval32_t nto; 120 121 (void) memset(&nto, '\0', sizeof (nto)); 122 123 nto.tv_sec = time_out; 124 125 if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE) 126 return (mdrpcerror(ep, clntp, hostname, 127 dgettext(TEXT_DOMAIN, "metad client set timeout"))); 128 129 return (0); 130 } 131 132 /* 133 * close RPC connection 134 */ 135 static void 136 close_medd( 137 med_handle_t *hp 138 ) 139 { 140 assert(hp != NULL); 141 if (hp->hostname != NULL) { 142 Free(hp->hostname); 143 } 144 if (hp->clntp != NULL) { 145 auth_destroy(hp->clntp->cl_auth); 146 clnt_destroy(hp->clntp); 147 } 148 Free(hp); 149 } 150 151 /* 152 * open RPC connection to rpc.medd 153 */ 154 static med_handle_t * 155 open_medd( 156 char *hostname, 157 long time_out, 158 md_error_t *ep 159 ) 160 { 161 CLIENT *clntp; 162 med_handle_t *hp; 163 164 /* default to local host */ 165 if ((hostname == NULL) || (*hostname == '\0')) 166 hostname = mynode(); 167 168 /* open RPC connection */ 169 assert(hostname != NULL); 170 if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS, 171 "tcp", &def_rpcb_timeout)) == NULL) { 172 if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) 173 clnt_pcreateerror(hostname); 174 (void) mdrpccreateerror(ep, hostname, 175 "medd med_clnt_create_timed"); 176 return (NULL); 177 } else { 178 auth_destroy(clntp->cl_auth); 179 clntp->cl_auth = authsys_create_default(); 180 assert(clntp->cl_auth != NULL); 181 } 182 183 if (cl_sto_medd(clntp, hostname, time_out, ep) != 0) 184 return (NULL); 185 186 /* return connection */ 187 hp = Zalloc(sizeof (*hp)); 188 hp->hostname = Strdup(hostname); 189 hp->clntp = clntp; 190 191 return (hp); 192 } 193 194 /* 195 * steal and convert med_err_t 196 */ 197 int 198 meddstealerror( 199 md_error_t *ep, 200 med_err_t *medep 201 ) 202 { 203 char buf[BUFSIZ]; 204 char *p = buf; 205 size_t psize = BUFSIZ; 206 char *emsg; 207 int rval = -1; 208 209 /* no error */ 210 if (medep->med_errno == 0) { 211 /* assert(medep->name == NULL); */ 212 rval = 0; 213 goto out; 214 } 215 216 /* steal error */ 217 if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) { 218 (void) snprintf(p, psize, "%s: ", medep->med_node); 219 p = &buf[strlen(buf)]; 220 psize = buf + BUFSIZ - p; 221 } 222 223 if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) { 224 (void) snprintf(p, psize, "%s: ", medep->med_misc); 225 p = &buf[strlen(buf)]; 226 psize = buf + BUFSIZ - p; 227 } 228 229 if (medep->med_errno < 0) { 230 if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL) 231 (void) snprintf(p, psize, "%s", emsg); 232 else 233 (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 234 "unknown mediator errno %d\n"), medep->med_errno); 235 } else { 236 if ((emsg = strerror(medep->med_errno)) != NULL) 237 (void) snprintf(p, psize, "%s", emsg); 238 else 239 (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 240 "errno %d out of range"), medep->med_errno); 241 } 242 (void) mderror(ep, MDE_MED_ERROR, buf); 243 244 /* cleanup, return success */ 245 out: 246 if (medep->med_node != NULL) 247 Free(medep->med_node); 248 if (medep->med_misc != NULL) 249 Free(medep->med_misc); 250 (void) memset(medep, 0, sizeof (*medep)); 251 return (rval); 252 } 253 254 static med_handle_t * 255 open_medd_wrap( 256 md_h_t *mdhp, 257 long time_out, 258 md_error_t *ep 259 ) 260 { 261 med_handle_t *hp = NULL; 262 int i; 263 char *hnm; 264 265 assert(mdhp && mdhp->a_cnt > 0); 266 267 /* Loop through the hosts listed */ 268 i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1; 269 for (; i >= 0; i--) { 270 hnm = mdhp->a_nm[i]; 271 272 if ((hp = open_medd(hnm, time_out, ep)) == NULL) { 273 if (mdanyrpcerror(ep) && i != 0) { 274 mdclrerror(ep); 275 continue; 276 } 277 } 278 return (hp); 279 } 280 281 rpc_createerr.cf_stat = RPC_CANTSEND; 282 rpc_createerr.cf_error.re_status = 0; 283 (void) mdrpccreateerror(ep, mdhp->a_nm[0], 284 dgettext(TEXT_DOMAIN, "medd open wrap")); 285 286 return (NULL); 287 } 288 289 static int 290 setup_med_transtab(md_error_t *ep) 291 { 292 mddb_med_t_parm_t *tp = NULL; 293 struct stat statb; 294 int i; 295 size_t alloc_size = 0; 296 int err = 0; 297 298 299 if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL) 300 return (mdsyserror(ep, ENOMEM, "setup_med_transtab")); 301 302 if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) { 303 err = mdstealerror(ep, &tp->med_tp_mde); 304 goto out; 305 } 306 307 if (tp->med_tp_setup == 1) 308 goto out; 309 310 alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) + 311 (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents); 312 313 if ((tp = Realloc(tp, alloc_size)) == NULL) { 314 err = mdsyserror(ep, ENOMEM, "setup_med_transtab"); 315 goto out; 316 } 317 318 if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) { 319 err = mdstealerror(ep, &tp->med_tp_mde); 320 goto out; 321 } 322 323 for (i = 0; i < tp->med_tp_nents; i++) { 324 if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) { 325 md_perror("setup_med_transtab(): stat():"); 326 tp->med_tp_ents[i].med_te_dev = NODEV64; 327 } else { 328 tp->med_tp_ents[i].med_te_dev = 329 meta_expldev(statb.st_rdev); 330 } 331 } 332 333 if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0) 334 err = mdstealerror(ep, &tp->med_tp_mde); 335 336 out: 337 Free(tp); 338 return (err); 339 } 340 341 /* 342 * Externals 343 */ 344 345 /* 346 * NULLPROC - just returns a response 347 */ 348 int 349 clnt_med_null( 350 char *hostname, 351 md_error_t *ep 352 ) 353 { 354 med_handle_t *hp; 355 med_err_t res; 356 357 /* initialize */ 358 mdclrerror(ep); 359 360 /* do it */ 361 if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 362 return (-1); 363 364 if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 365 (void) mdrpcerror(ep, hp->clntp, hostname, 366 dgettext(TEXT_DOMAIN, "medd nullproc")); 367 368 close_medd(hp); 369 370 xdr_free(xdr_med_err_t, (char *)&res); 371 372 if (! mdisok(ep)) 373 return (-1); 374 375 return (0); 376 } 377 378 /* 379 * Update the mediator information on the mediator. 380 * *** This is not normally called from user code, the kernel does this! *** 381 */ 382 int 383 clnt_med_upd_data( 384 md_h_t *mdhp, 385 mdsetname_t *sp, 386 med_data_t *meddp, 387 md_error_t *ep 388 ) 389 { 390 med_handle_t *hp; 391 med_upd_data_args_t args; 392 med_err_t res; 393 md_set_desc *sd; 394 395 /* initialize */ 396 mdclrerror(ep); 397 (void) memset(&args, 0, sizeof (args)); 398 (void) memset(&res, 0, sizeof (res)); 399 400 /* build args */ 401 if ((sd = metaget_setdesc(sp, ep)) == NULL) 402 return (-1); 403 404 if (MD_MNSET_DESC(sd)) 405 /* 406 * In the MN diskset, use a generic nodename, multiowner, as 407 * the node initiating the RPC request. This allows 408 * any node to access mediator information. 409 * 410 * MN diskset reconfig cycle forces consistent 411 * view of set/node/drive/mediator information across all nodes 412 * in the MN diskset. This allows the relaxation of 413 * node name checking in rpc.metamedd for MN disksets. 414 * 415 * In the traditional diskset, only a calling node that is 416 * in the mediator record's diskset nodelist can access 417 * mediator data. 418 */ 419 args.med.med_caller = Strdup(MED_MN_CALLER); 420 else 421 args.med.med_caller = Strdup(mynode()); 422 args.med.med_setname = Strdup(sp->setname); 423 args.med.med_setno = sp->setno; 424 args.med_data = *meddp; 425 426 /* do it */ 427 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 428 return (-1); 429 430 if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 431 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 432 dgettext(TEXT_DOMAIN, "medd update data")); 433 else 434 (void) meddstealerror(ep, &res); 435 436 close_medd(hp); 437 438 xdr_free(xdr_med_upd_data_args_t, (char *)&args); 439 xdr_free(xdr_med_err_t, (char *)&res); 440 441 if (! mdisok(ep)) 442 return (-1); 443 444 return (0); 445 } 446 447 /* 448 * Get the mediator data for this client from the mediator 449 */ 450 int 451 clnt_med_get_data( 452 md_h_t *mdhp, 453 mdsetname_t *sp, 454 med_data_t *meddp, 455 md_error_t *ep 456 ) 457 { 458 med_handle_t *hp; 459 med_args_t args; 460 med_get_data_res_t res; 461 int rval = -1; 462 md_set_desc *sd; 463 464 /* initialize */ 465 mdclrerror(ep); 466 (void) memset(&args, 0, sizeof (args)); 467 (void) memset(&res, 0, sizeof (res)); 468 469 /* build args */ 470 if ((sd = metaget_setdesc(sp, ep)) == NULL) 471 return (-1); 472 473 if (MD_MNSET_DESC(sd)) 474 /* 475 * In the MN diskset, use a generic nodename, multiowner, as 476 * the node initiating the RPC request. This allows 477 * any node to access mediator information. 478 * 479 * MN diskset reconfig cycle forces consistent 480 * view of set/node/drive/mediator information across all nodes 481 * in the MN diskset. This allows the relaxation of 482 * node name checking in rpc.metamedd for MN disksets. 483 * 484 * In the traditional diskset, only a calling node that is 485 * in the mediator record's diskset nodelist can access 486 * mediator data. 487 */ 488 args.med.med_caller = Strdup(MED_MN_CALLER); 489 else 490 args.med.med_caller = Strdup(mynode()); 491 args.med.med_setname = Strdup(sp->setname); 492 args.med.med_setno = sp->setno; 493 494 /* do it */ 495 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 496 return (-1); 497 498 if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 499 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 500 dgettext(TEXT_DOMAIN, "medd get data")); 501 else 502 (void) meddstealerror(ep, &res.med_status); 503 504 close_medd(hp); 505 506 if (mdisok(ep)) { 507 /* do something with the results */ 508 (void) memmove(meddp, &res.med_data, sizeof (med_data_t)); 509 rval = 0; 510 } 511 512 xdr_free(xdr_med_args_t, (char *)&args); 513 xdr_free(xdr_med_get_data_res_t, (char *)&res); 514 515 return (rval); 516 } 517 518 /* 519 * Update the mediator record on the mediator. 520 */ 521 int 522 clnt_med_upd_rec( 523 md_h_t *mdhp, 524 mdsetname_t *sp, 525 med_rec_t *medrp, 526 md_error_t *ep 527 ) 528 { 529 med_handle_t *hp; 530 med_upd_rec_args_t args; 531 med_err_t res; 532 md_set_desc *sd; 533 534 /* initialize */ 535 mdclrerror(ep); 536 (void) memset(&args, 0, sizeof (args)); 537 (void) memset(&res, 0, sizeof (res)); 538 539 /* build args */ 540 if ((sd = metaget_setdesc(sp, ep)) == NULL) 541 return (-1); 542 543 if (MD_MNSET_DESC(sd)) 544 /* 545 * In the MN diskset, use a generic nodename, multiowner, as 546 * the node initiating the RPC request. This allows 547 * any node to access mediator information. 548 * 549 * MN diskset reconfig cycle forces consistent 550 * view of set/node/drive/mediator information across all nodes 551 * in the MN diskset. This allows the relaxation of 552 * node name checking in rpc.metamedd for MN disksets. 553 * 554 * In the traditional diskset, only a calling node that is 555 * in the mediator record's diskset nodelist can access 556 * mediator data. 557 */ 558 args.med.med_caller = Strdup(MED_MN_CALLER); 559 else 560 args.med.med_caller = Strdup(mynode()); 561 args.med.med_setname = Strdup(sp->setname); 562 args.med.med_setno = sp->setno; 563 args.med_flags = 0; 564 args.med_rec = *medrp; /* structure assignment */ 565 566 /* do it */ 567 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 568 return (-1); 569 570 if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 571 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 572 dgettext(TEXT_DOMAIN, "medd update record")); 573 else 574 (void) meddstealerror(ep, &res); 575 576 close_medd(hp); 577 578 xdr_free(xdr_med_upd_rec_args_t, (char *)&args); 579 xdr_free(xdr_med_err_t, (char *)&res); 580 581 if (! mdisok(ep)) 582 return (-1); 583 584 return (0); 585 } 586 587 /* 588 * Get the mediator record for this client from the mediator 589 */ 590 int 591 clnt_med_get_rec( 592 md_h_t *mdhp, 593 mdsetname_t *sp, 594 med_rec_t *medrp, 595 md_error_t *ep 596 ) 597 { 598 med_handle_t *hp; 599 med_args_t args; 600 med_get_rec_res_t res; 601 int rval = -1; 602 md_set_desc *sd; 603 604 /* initialize */ 605 mdclrerror(ep); 606 (void) memset(&args, 0, sizeof (args)); 607 (void) memset(&res, 0, sizeof (res)); 608 609 /* build args */ 610 if ((sd = metaget_setdesc(sp, ep)) == NULL) 611 return (-1); 612 613 if (MD_MNSET_DESC(sd)) 614 /* 615 * In the MN diskset, use a generic nodename, multiowner, as 616 * the node initiating the RPC request. This allows 617 * any node to access mediator information. 618 * 619 * MN diskset reconfig cycle forces consistent 620 * view of set/node/drive/mediator information across all nodes 621 * in the MN diskset. This allows the relaxation of 622 * node name checking in rpc.metamedd for MN disksets. 623 * 624 * In the traditional diskset, only a calling node that is 625 * in the mediator record's diskset nodelist can access 626 * mediator data. 627 */ 628 args.med.med_caller = Strdup(MED_MN_CALLER); 629 else 630 args.med.med_caller = Strdup(mynode()); 631 args.med.med_setname = Strdup(sp->setname); 632 args.med.med_setno = sp->setno; 633 634 /* do it */ 635 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 636 return (-1); 637 638 if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 639 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 640 dgettext(TEXT_DOMAIN, "medd get record")); 641 else 642 (void) meddstealerror(ep, &res.med_status); 643 644 close_medd(hp); 645 646 if (mdisok(ep)) { 647 /* do something with the results */ 648 (void) memmove(medrp, &res.med_rec, sizeof (med_rec_t)); 649 rval = 0; 650 } 651 652 xdr_free(xdr_med_args_t, (char *)&args); 653 xdr_free(xdr_med_get_rec_res_t, (char *)&res); 654 655 return (rval); 656 } 657 658 /* 659 * Get the name of the host from the mediator daemon. 660 */ 661 int 662 clnt_med_hostname( 663 char *hostname, 664 char **ret_hostname, 665 md_error_t *ep 666 ) 667 { 668 med_handle_t *hp; 669 med_hnm_res_t res; 670 int rval = -1; 671 672 /* initialize */ 673 mdclrerror(ep); 674 (void) memset(&res, 0, sizeof (res)); 675 676 /* No args */ 677 678 /* do it */ 679 if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 680 return (-1); 681 682 if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 683 (void) mdrpcerror(ep, hp->clntp, hostname, 684 dgettext(TEXT_DOMAIN, "medd hostname")); 685 else 686 (void) meddstealerror(ep, &res.med_status); 687 688 close_medd(hp); 689 690 if (mdisok(ep)) { 691 /* do something with the results */ 692 rval = 0; 693 694 if (ret_hostname != NULL) 695 *ret_hostname = Strdup(res.med_hnm); 696 } 697 698 xdr_free(xdr_med_hnm_res_t, (char *)&res); 699 700 return (rval); 701 } 702 703 int 704 meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep) 705 { 706 int i, j; 707 int max_meds; 708 709 if ((max_meds = get_max_meds(ep)) == 0) 710 return (-1); 711 712 for (i = 0; i < max_meds; i++) { 713 mp->n_lst[i].a_flg = 0; 714 /* See if this is the local host */ 715 if (mp->n_lst[i].a_cnt > 0 && 716 strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL) 717 mp->n_lst[i].a_flg |= NMIP_F_LOCAL; 718 719 for (j = 0; j < mp->n_lst[i].a_cnt; j++) { 720 struct hostent *hp; 721 char *hnm = mp->n_lst[i].a_nm[j]; 722 723 /* 724 * Cluster nodename support 725 * 726 * See if the clustering code can give us an IP addr 727 * for the stored name. If not, find it the old way 728 * which will use the public interface. 729 */ 730 if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j], 731 (struct in_addr *)&mp->n_lst[i].a_ip[j]) != 732 SDSSC_OKAY) { 733 if ((hp = gethostbyname(hnm)) == NULL) 734 return (mdsyserror(ep, EADDRNOTAVAIL, 735 hnm)); 736 737 /* We only do INET addresses */ 738 if (hp->h_addrtype != AF_INET) 739 return (mdsyserror(ep, EPFNOSUPPORT, 740 hnm)); 741 742 /* We take the first address only */ 743 if (*hp->h_addr_list) { 744 (void) memmove(&mp->n_lst[i].a_ip[j], 745 *hp->h_addr_list, 746 sizeof (struct in_addr)); 747 } else 748 return (mdsyserror(ep, EADDRNOTAVAIL, 749 hnm)); 750 } 751 752 } 753 } 754 return (0); 755 } 756 757 int 758 meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep) 759 { 760 int i, j; 761 int max_meds; 762 763 if ((max_meds = get_max_meds(ep)) == 0) 764 return (-1); 765 766 mdhip->n_cnt = mdhp->n_cnt; 767 768 for (i = 0; i < max_meds; i++) { 769 mdhip->n_lst[i].a_flg = 0; 770 mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt; 771 if (mdhp->n_lst[i].a_cnt == 0) 772 continue; 773 for (j = 0; j < mdhp->n_lst[i].a_cnt; j++) 774 (void) strcpy(mdhip->n_lst[i].a_nm[j], 775 mdhp->n_lst[i].a_nm[j]); 776 } 777 return (0); 778 } 779 780 int 781 meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep) 782 { 783 int i, j; 784 int max_meds; 785 786 if ((max_meds = get_max_meds(ep)) == 0) 787 return (-1); 788 789 mdhp->n_cnt = mdhip->n_cnt; 790 for (i = 0; i < max_meds; i++) { 791 mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt; 792 if (mdhip->n_lst[i].a_cnt == 0) 793 continue; 794 for (j = 0; j < mdhip->n_lst[i].a_cnt; j++) 795 (void) strcpy(mdhp->n_lst[i].a_nm[j], 796 mdhip->n_lst[i].a_nm[j]); 797 } 798 return (0); 799 } 800 801 int 802 setup_med_cfg( 803 mdsetname_t *sp, 804 mddb_config_t *cp, 805 int force, 806 md_error_t *ep 807 ) 808 { 809 md_set_desc *sd; 810 int i; 811 int max_meds; 812 813 if (metaislocalset(sp)) 814 return (0); 815 816 if ((sd = metaget_setdesc(sp, ep)) == NULL) 817 return (-1); 818 819 if (setup_med_transtab(ep)) 820 return (-1); 821 822 if (meta_h2hi(&sd->sd_med, &cp->c_med, ep)) 823 return (-1); 824 825 /* Make sure the ip addresses are current */ 826 if (meta_med_hnm2ip(&cp->c_med, ep)) 827 return (-1); 828 829 if (force) 830 return (0); 831 832 if ((max_meds = get_max_meds(ep)) == 0) 833 return (-1); 834 835 /* Make sure metamedd still running on host - only chk nodename */ 836 for (i = 0; i < max_meds; i++) { 837 char *hostname; 838 char *hnm; 839 840 if (sd->sd_med.n_lst[i].a_cnt == 0) 841 continue; 842 843 hnm = sd->sd_med.n_lst[i].a_nm[0]; 844 845 if (clnt_med_hostname(hnm, &hostname, ep)) 846 return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno, 847 hnm, NULL, sp->setname)); 848 Free(hostname); 849 } 850 return (0); 851 } 852