10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*7044Smk117520 230Sstevel@tonic-gate /* 24*7044Smk117520 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate /* 310Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that 320Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 330Sstevel@tonic-gate */ 340Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 350Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 360Sstevel@tonic-gate #endif 370Sstevel@tonic-gate 380Sstevel@tonic-gate /* 390Sstevel@tonic-gate * Mediator functions 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <meta.h> 430Sstevel@tonic-gate #include <metamed.h> 440Sstevel@tonic-gate #include <dlfcn.h> 450Sstevel@tonic-gate #include <sdssc.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate /* 480Sstevel@tonic-gate * There are too many external factors that affect the timing of the 490Sstevel@tonic-gate * operations, so we set the timeout to a very large value, in this 500Sstevel@tonic-gate * case 1 day, which should handle HW timeouts, large configurations, 510Sstevel@tonic-gate * and other potential delays. 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate #define CL_LONG_TMO 86400L /* 1 day */ 540Sstevel@tonic-gate #define CL_MEDIUM_TMO 3600L /* 1 hour */ 550Sstevel@tonic-gate #define CL_SHORT_TMO 600L /* 10 minutes */ 560Sstevel@tonic-gate #define CL_DEF_TMO 10L /* 10 seconds */ 570Sstevel@tonic-gate 580Sstevel@tonic-gate static md_timeval32_t def_rpcb_timeout = { MD_CLNT_CREATE_TOUT, 0 }; 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* 610Sstevel@tonic-gate * RPC handle 620Sstevel@tonic-gate */ 630Sstevel@tonic-gate typedef struct { 640Sstevel@tonic-gate char *hostname; 650Sstevel@tonic-gate CLIENT *clntp; 660Sstevel@tonic-gate } med_handle_t; 670Sstevel@tonic-gate 680Sstevel@tonic-gate /* 690Sstevel@tonic-gate * Data to be sent from med_clnt_create_timed to med_create_helper via 700Sstevel@tonic-gate * meta_client_create_retry. 710Sstevel@tonic-gate */ 720Sstevel@tonic-gate typedef struct { 730Sstevel@tonic-gate rpcprog_t mcd_program; /* RPC program designation */ 740Sstevel@tonic-gate rpcvers_t mcd_version; /* RPC version */ 750Sstevel@tonic-gate char *mcd_nettype; /* Type of network to use for RPC */ 760Sstevel@tonic-gate } med_create_data_t; 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 790Sstevel@tonic-gate * Perform the work of actually doing the clnt_create for 800Sstevel@tonic-gate * meta_client_create_retry. 810Sstevel@tonic-gate */ 820Sstevel@tonic-gate static CLIENT * 830Sstevel@tonic-gate med_create_helper(char *hostname, void *private, struct timeval *time_out) 840Sstevel@tonic-gate { 850Sstevel@tonic-gate med_create_data_t *cd = (med_create_data_t *)private; 860Sstevel@tonic-gate 870Sstevel@tonic-gate return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version, 880Sstevel@tonic-gate cd->mcd_nettype, time_out)); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate static 920Sstevel@tonic-gate CLIENT *med_clnt_create_timed( 930Sstevel@tonic-gate char *hostname, 940Sstevel@tonic-gate const ulong_t prog, 950Sstevel@tonic-gate const ulong_t vers, 960Sstevel@tonic-gate char *nettype, 970Sstevel@tonic-gate const md_timeval32_t *tp 980Sstevel@tonic-gate ) 990Sstevel@tonic-gate { 1000Sstevel@tonic-gate med_create_data_t cd; /* Create data. */ 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate cd.mcd_program = prog; 1030Sstevel@tonic-gate cd.mcd_version = vers; 1040Sstevel@tonic-gate cd.mcd_nettype = nettype; 1050Sstevel@tonic-gate return (meta_client_create_retry(hostname, med_create_helper, 1060Sstevel@tonic-gate (void *)&cd, (time_t)tp->tv_sec, NULL)); 1070Sstevel@tonic-gate } 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate /* 1100Sstevel@tonic-gate * Set the timeout value for this client handle. 1110Sstevel@tonic-gate */ 1120Sstevel@tonic-gate static int 1130Sstevel@tonic-gate cl_sto_medd( 1140Sstevel@tonic-gate CLIENT *clntp, 1150Sstevel@tonic-gate char *hostname, 1160Sstevel@tonic-gate long time_out, 1170Sstevel@tonic-gate md_error_t *ep 1180Sstevel@tonic-gate ) 1190Sstevel@tonic-gate { 1200Sstevel@tonic-gate md_timeval32_t nto; 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate (void) memset(&nto, '\0', sizeof (nto)); 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate nto.tv_sec = time_out; 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE) 1270Sstevel@tonic-gate return (mdrpcerror(ep, clntp, hostname, 1280Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "metad client set timeout"))); 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate return (0); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* 1340Sstevel@tonic-gate * close RPC connection 1350Sstevel@tonic-gate */ 1360Sstevel@tonic-gate static void 1370Sstevel@tonic-gate close_medd( 1380Sstevel@tonic-gate med_handle_t *hp 1390Sstevel@tonic-gate ) 1400Sstevel@tonic-gate { 1410Sstevel@tonic-gate assert(hp != NULL); 1420Sstevel@tonic-gate if (hp->hostname != NULL) { 1430Sstevel@tonic-gate Free(hp->hostname); 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate if (hp->clntp != NULL) { 1460Sstevel@tonic-gate auth_destroy(hp->clntp->cl_auth); 1470Sstevel@tonic-gate clnt_destroy(hp->clntp); 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate Free(hp); 1500Sstevel@tonic-gate } 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate /* 1530Sstevel@tonic-gate * open RPC connection to rpc.medd 1540Sstevel@tonic-gate */ 1550Sstevel@tonic-gate static med_handle_t * 1560Sstevel@tonic-gate open_medd( 1570Sstevel@tonic-gate char *hostname, 1580Sstevel@tonic-gate long time_out, 1590Sstevel@tonic-gate md_error_t *ep 1600Sstevel@tonic-gate ) 1610Sstevel@tonic-gate { 1620Sstevel@tonic-gate CLIENT *clntp; 1630Sstevel@tonic-gate med_handle_t *hp; 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate /* default to local host */ 1660Sstevel@tonic-gate if ((hostname == NULL) || (*hostname == '\0')) 1670Sstevel@tonic-gate hostname = mynode(); 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate /* open RPC connection */ 1700Sstevel@tonic-gate assert(hostname != NULL); 1710Sstevel@tonic-gate if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS, 1720Sstevel@tonic-gate "tcp", &def_rpcb_timeout)) == NULL) { 1730Sstevel@tonic-gate if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) 1740Sstevel@tonic-gate clnt_pcreateerror(hostname); 1750Sstevel@tonic-gate (void) mdrpccreateerror(ep, hostname, 1760Sstevel@tonic-gate "medd med_clnt_create_timed"); 1770Sstevel@tonic-gate return (NULL); 1780Sstevel@tonic-gate } else { 1790Sstevel@tonic-gate auth_destroy(clntp->cl_auth); 1800Sstevel@tonic-gate clntp->cl_auth = authsys_create_default(); 1810Sstevel@tonic-gate assert(clntp->cl_auth != NULL); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate if (cl_sto_medd(clntp, hostname, time_out, ep) != 0) 1850Sstevel@tonic-gate return (NULL); 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate /* return connection */ 1880Sstevel@tonic-gate hp = Zalloc(sizeof (*hp)); 1890Sstevel@tonic-gate hp->hostname = Strdup(hostname); 1900Sstevel@tonic-gate hp->clntp = clntp; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate return (hp); 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate /* 1960Sstevel@tonic-gate * steal and convert med_err_t 1970Sstevel@tonic-gate */ 1980Sstevel@tonic-gate int 1990Sstevel@tonic-gate meddstealerror( 2000Sstevel@tonic-gate md_error_t *ep, 2010Sstevel@tonic-gate med_err_t *medep 2020Sstevel@tonic-gate ) 2030Sstevel@tonic-gate { 2040Sstevel@tonic-gate char buf[BUFSIZ]; 2050Sstevel@tonic-gate char *p = buf; 2060Sstevel@tonic-gate size_t psize = BUFSIZ; 2070Sstevel@tonic-gate char *emsg; 2080Sstevel@tonic-gate int rval = -1; 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate /* no error */ 2110Sstevel@tonic-gate if (medep->med_errno == 0) { 2120Sstevel@tonic-gate /* assert(medep->name == NULL); */ 2130Sstevel@tonic-gate rval = 0; 2140Sstevel@tonic-gate goto out; 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate /* steal error */ 2180Sstevel@tonic-gate if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) { 2190Sstevel@tonic-gate (void) snprintf(p, psize, "%s: ", medep->med_node); 2200Sstevel@tonic-gate p = &buf[strlen(buf)]; 2210Sstevel@tonic-gate psize = buf + BUFSIZ - p; 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) { 2250Sstevel@tonic-gate (void) snprintf(p, psize, "%s: ", medep->med_misc); 2260Sstevel@tonic-gate p = &buf[strlen(buf)]; 2270Sstevel@tonic-gate psize = buf + BUFSIZ - p; 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate if (medep->med_errno < 0) { 2310Sstevel@tonic-gate if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL) 2320Sstevel@tonic-gate (void) snprintf(p, psize, "%s", emsg); 2330Sstevel@tonic-gate else 2340Sstevel@tonic-gate (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 2350Sstevel@tonic-gate "unknown mediator errno %d\n"), medep->med_errno); 2360Sstevel@tonic-gate } else { 2370Sstevel@tonic-gate if ((emsg = strerror(medep->med_errno)) != NULL) 2380Sstevel@tonic-gate (void) snprintf(p, psize, "%s", emsg); 2390Sstevel@tonic-gate else 2400Sstevel@tonic-gate (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 2410Sstevel@tonic-gate "errno %d out of range"), medep->med_errno); 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate (void) mderror(ep, MDE_MED_ERROR, buf); 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate /* cleanup, return success */ 2460Sstevel@tonic-gate out: 2470Sstevel@tonic-gate if (medep->med_node != NULL) 2480Sstevel@tonic-gate Free(medep->med_node); 2490Sstevel@tonic-gate if (medep->med_misc != NULL) 2500Sstevel@tonic-gate Free(medep->med_misc); 2510Sstevel@tonic-gate (void) memset(medep, 0, sizeof (*medep)); 2520Sstevel@tonic-gate return (rval); 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate static med_handle_t * 2560Sstevel@tonic-gate open_medd_wrap( 2570Sstevel@tonic-gate md_h_t *mdhp, 2580Sstevel@tonic-gate long time_out, 2590Sstevel@tonic-gate md_error_t *ep 2600Sstevel@tonic-gate ) 2610Sstevel@tonic-gate { 2620Sstevel@tonic-gate med_handle_t *hp = NULL; 2630Sstevel@tonic-gate int i; 2640Sstevel@tonic-gate char *hnm; 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate assert(mdhp && mdhp->a_cnt > 0); 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate /* Loop through the hosts listed */ 2690Sstevel@tonic-gate i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1; 2700Sstevel@tonic-gate for (; i >= 0; i--) { 2710Sstevel@tonic-gate hnm = mdhp->a_nm[i]; 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate if ((hp = open_medd(hnm, time_out, ep)) == NULL) { 2740Sstevel@tonic-gate if (mdanyrpcerror(ep) && i != 0) { 2750Sstevel@tonic-gate mdclrerror(ep); 2760Sstevel@tonic-gate continue; 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate return (hp); 2800Sstevel@tonic-gate } 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_CANTSEND; 2830Sstevel@tonic-gate rpc_createerr.cf_error.re_status = 0; 2840Sstevel@tonic-gate (void) mdrpccreateerror(ep, mdhp->a_nm[0], 2850Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd open wrap")); 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate return (NULL); 2880Sstevel@tonic-gate } 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate static int 2910Sstevel@tonic-gate setup_med_transtab(md_error_t *ep) 2920Sstevel@tonic-gate { 2930Sstevel@tonic-gate mddb_med_t_parm_t *tp = NULL; 2940Sstevel@tonic-gate struct stat statb; 2950Sstevel@tonic-gate int i; 2960Sstevel@tonic-gate size_t alloc_size = 0; 2970Sstevel@tonic-gate int err = 0; 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL) 3010Sstevel@tonic-gate return (mdsyserror(ep, ENOMEM, "setup_med_transtab")); 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) { 3040Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3050Sstevel@tonic-gate goto out; 3060Sstevel@tonic-gate } 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate if (tp->med_tp_setup == 1) 3090Sstevel@tonic-gate goto out; 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) + 3120Sstevel@tonic-gate (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents); 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate if ((tp = Realloc(tp, alloc_size)) == NULL) { 3150Sstevel@tonic-gate err = mdsyserror(ep, ENOMEM, "setup_med_transtab"); 3160Sstevel@tonic-gate goto out; 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) { 3200Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3210Sstevel@tonic-gate goto out; 3220Sstevel@tonic-gate } 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate for (i = 0; i < tp->med_tp_nents; i++) { 3250Sstevel@tonic-gate if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) { 3260Sstevel@tonic-gate md_perror("setup_med_transtab(): stat():"); 3270Sstevel@tonic-gate tp->med_tp_ents[i].med_te_dev = NODEV64; 3280Sstevel@tonic-gate } else { 3290Sstevel@tonic-gate tp->med_tp_ents[i].med_te_dev = 3300Sstevel@tonic-gate meta_expldev(statb.st_rdev); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0) 3350Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate out: 3380Sstevel@tonic-gate Free(tp); 3390Sstevel@tonic-gate return (err); 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate /* 3430Sstevel@tonic-gate * Externals 3440Sstevel@tonic-gate */ 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate /* 3470Sstevel@tonic-gate * NULLPROC - just returns a response 3480Sstevel@tonic-gate */ 3490Sstevel@tonic-gate int 3500Sstevel@tonic-gate clnt_med_null( 3510Sstevel@tonic-gate char *hostname, 3520Sstevel@tonic-gate md_error_t *ep 3530Sstevel@tonic-gate ) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate med_handle_t *hp; 3560Sstevel@tonic-gate med_err_t res; 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate /* initialize */ 3590Sstevel@tonic-gate mdclrerror(ep); 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate /* do it */ 3620Sstevel@tonic-gate if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 3630Sstevel@tonic-gate return (-1); 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 3660Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hostname, 3670Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd nullproc")); 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate close_medd(hp); 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate if (! mdisok(ep)) 3740Sstevel@tonic-gate return (-1); 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate return (0); 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate /* 3800Sstevel@tonic-gate * Update the mediator information on the mediator. 381*7044Smk117520 * This function does the same functionality as 382*7044Smk117520 * clnt_med_upd_data() except that it takes different 383*7044Smk117520 * argument so that host which is just a mediator, can 384*7044Smk117520 * still update its mediator record. 385*7044Smk117520 */ 386*7044Smk117520 int 387*7044Smk117520 clnt_user_med_upd_data( 388*7044Smk117520 md_h_t *mdhp, 389*7044Smk117520 bool_t obandiskset, 390*7044Smk117520 char *setname, 391*7044Smk117520 uint_t setnum, 392*7044Smk117520 med_data_t *meddp, 393*7044Smk117520 md_error_t *ep 394*7044Smk117520 ) 395*7044Smk117520 { 396*7044Smk117520 med_handle_t *hp; 397*7044Smk117520 med_upd_data_args_t args; 398*7044Smk117520 med_err_t res; 399*7044Smk117520 400*7044Smk117520 /* Initialize */ 401*7044Smk117520 mdclrerror(ep); 402*7044Smk117520 (void) memset(&args, 0, sizeof (args)); 403*7044Smk117520 (void) memset(&res, 0, sizeof (res)); 404*7044Smk117520 405*7044Smk117520 /* Build args */ 406*7044Smk117520 if (obandiskset) 407*7044Smk117520 args.med.med_caller = Strdup(MED_MN_CALLER); 408*7044Smk117520 else 409*7044Smk117520 args.med.med_caller = Strdup(mynode()); 410*7044Smk117520 411*7044Smk117520 args.med.med_setname = Strdup(setname); 412*7044Smk117520 args.med.med_setno = setnum; 413*7044Smk117520 args.med_data = *meddp; 414*7044Smk117520 415*7044Smk117520 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 416*7044Smk117520 return (-1); 417*7044Smk117520 418*7044Smk117520 if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 419*7044Smk117520 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 420*7044Smk117520 dgettext(TEXT_DOMAIN, "medd get record")); 421*7044Smk117520 else 422*7044Smk117520 (void) meddstealerror(ep, &res); 423*7044Smk117520 424*7044Smk117520 close_medd(hp); 425*7044Smk117520 426*7044Smk117520 xdr_free(xdr_med_upd_data_args_t, (char *)&args); 427*7044Smk117520 xdr_free(xdr_med_err_t, (char *)&res); 428*7044Smk117520 429*7044Smk117520 if (! mdisok(ep)) 430*7044Smk117520 return (-1); 431*7044Smk117520 432*7044Smk117520 return (0); 433*7044Smk117520 } 434*7044Smk117520 435*7044Smk117520 /* 436*7044Smk117520 * Get the mediator information from the client. 437*7044Smk117520 * The code does same functinality as clnt_med_get_data() 438*7044Smk117520 * except that it takes different arguments so that 439*7044Smk117520 * host which doesn't have set information, can still 440*7044Smk117520 * get access to mediator information 441*7044Smk117520 */ 442*7044Smk117520 int 443*7044Smk117520 clnt_user_med_get_data( 444*7044Smk117520 md_h_t *mdhp, 445*7044Smk117520 bool_t obandiskset, 446*7044Smk117520 char *setname, 447*7044Smk117520 uint_t setnum, 448*7044Smk117520 med_data_t *meddp, 449*7044Smk117520 md_error_t *ep 450*7044Smk117520 ) 451*7044Smk117520 { 452*7044Smk117520 int rval = -1; 453*7044Smk117520 med_handle_t *hp; 454*7044Smk117520 med_args_t args; 455*7044Smk117520 med_get_data_res_t res; 456*7044Smk117520 457*7044Smk117520 /* Initialize */ 458*7044Smk117520 mdclrerror(ep); 459*7044Smk117520 (void) memset(&args, 0, sizeof (args)); 460*7044Smk117520 (void) memset(&res, 0, sizeof (res)); 461*7044Smk117520 462*7044Smk117520 /* Build args */ 463*7044Smk117520 if (obandiskset) 464*7044Smk117520 args.med.med_caller = Strdup(MED_MN_CALLER); 465*7044Smk117520 else 466*7044Smk117520 args.med.med_caller = Strdup(mynode()); 467*7044Smk117520 468*7044Smk117520 args.med.med_setname = Strdup(setname); 469*7044Smk117520 args.med.med_setno = setnum; 470*7044Smk117520 471*7044Smk117520 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 472*7044Smk117520 return (-1); 473*7044Smk117520 474*7044Smk117520 if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 475*7044Smk117520 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 476*7044Smk117520 dgettext(TEXT_DOMAIN, "medd get record")); 477*7044Smk117520 else 478*7044Smk117520 (void) meddstealerror(ep, &res.med_status); 479*7044Smk117520 480*7044Smk117520 close_medd(hp); 481*7044Smk117520 482*7044Smk117520 if (mdisok(ep)) { 483*7044Smk117520 /* copy the mediator data in meddp */ 484*7044Smk117520 (void) memmove(meddp, &res.med_data, sizeof (med_data_t)); 485*7044Smk117520 rval = 0; 486*7044Smk117520 } 487*7044Smk117520 488*7044Smk117520 xdr_free(xdr_med_args_t, (char *)&args); 489*7044Smk117520 xdr_free(xdr_med_get_data_res_t, (char *)&res); 490*7044Smk117520 491*7044Smk117520 return (rval); 492*7044Smk117520 } 493*7044Smk117520 494*7044Smk117520 495*7044Smk117520 /* 496*7044Smk117520 * Update the mediator information on the mediator. 4970Sstevel@tonic-gate * *** This is not normally called from user code, the kernel does this! *** 4980Sstevel@tonic-gate */ 4990Sstevel@tonic-gate int 5000Sstevel@tonic-gate clnt_med_upd_data( 5010Sstevel@tonic-gate md_h_t *mdhp, 5020Sstevel@tonic-gate mdsetname_t *sp, 5030Sstevel@tonic-gate med_data_t *meddp, 5040Sstevel@tonic-gate md_error_t *ep 5050Sstevel@tonic-gate ) 5060Sstevel@tonic-gate { 5070Sstevel@tonic-gate med_handle_t *hp; 5080Sstevel@tonic-gate med_upd_data_args_t args; 5090Sstevel@tonic-gate med_err_t res; 5100Sstevel@tonic-gate md_set_desc *sd; 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate /* initialize */ 5130Sstevel@tonic-gate mdclrerror(ep); 5140Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 5150Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate /* build args */ 5180Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 5190Sstevel@tonic-gate return (-1); 5200Sstevel@tonic-gate 5210Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 5220Sstevel@tonic-gate /* 5230Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 5240Sstevel@tonic-gate * the node initiating the RPC request. This allows 5250Sstevel@tonic-gate * any node to access mediator information. 5260Sstevel@tonic-gate * 5270Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 5280Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 5290Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 5300Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 5310Sstevel@tonic-gate * 5320Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 5330Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 5340Sstevel@tonic-gate * mediator data. 5350Sstevel@tonic-gate */ 5360Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 5370Sstevel@tonic-gate else 5380Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 5390Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 5400Sstevel@tonic-gate args.med.med_setno = sp->setno; 5410Sstevel@tonic-gate args.med_data = *meddp; 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate /* do it */ 5440Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 5450Sstevel@tonic-gate return (-1); 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 5480Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 5490Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd update data")); 5500Sstevel@tonic-gate else 5510Sstevel@tonic-gate (void) meddstealerror(ep, &res); 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate close_medd(hp); 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate xdr_free(xdr_med_upd_data_args_t, (char *)&args); 5560Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate if (! mdisok(ep)) 5590Sstevel@tonic-gate return (-1); 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate return (0); 5620Sstevel@tonic-gate } 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate /* 5650Sstevel@tonic-gate * Get the mediator data for this client from the mediator 5660Sstevel@tonic-gate */ 5670Sstevel@tonic-gate int 5680Sstevel@tonic-gate clnt_med_get_data( 5690Sstevel@tonic-gate md_h_t *mdhp, 5700Sstevel@tonic-gate mdsetname_t *sp, 5710Sstevel@tonic-gate med_data_t *meddp, 5720Sstevel@tonic-gate md_error_t *ep 5730Sstevel@tonic-gate ) 5740Sstevel@tonic-gate { 5750Sstevel@tonic-gate med_handle_t *hp; 5760Sstevel@tonic-gate med_args_t args; 5770Sstevel@tonic-gate med_get_data_res_t res; 5780Sstevel@tonic-gate int rval = -1; 5790Sstevel@tonic-gate md_set_desc *sd; 5800Sstevel@tonic-gate 5810Sstevel@tonic-gate /* initialize */ 5820Sstevel@tonic-gate mdclrerror(ep); 5830Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 5840Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate /* build args */ 5870Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 5880Sstevel@tonic-gate return (-1); 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 5910Sstevel@tonic-gate /* 5920Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 5930Sstevel@tonic-gate * the node initiating the RPC request. This allows 5940Sstevel@tonic-gate * any node to access mediator information. 5950Sstevel@tonic-gate * 5960Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 5970Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 5980Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 5990Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 6000Sstevel@tonic-gate * 6010Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 6020Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 6030Sstevel@tonic-gate * mediator data. 6040Sstevel@tonic-gate */ 6050Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 6060Sstevel@tonic-gate else 6070Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 6080Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 6090Sstevel@tonic-gate args.med.med_setno = sp->setno; 6100Sstevel@tonic-gate 6110Sstevel@tonic-gate /* do it */ 6120Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 6130Sstevel@tonic-gate return (-1); 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 6160Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 6170Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd get data")); 6180Sstevel@tonic-gate else 6190Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 6200Sstevel@tonic-gate 6210Sstevel@tonic-gate close_medd(hp); 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate if (mdisok(ep)) { 6240Sstevel@tonic-gate /* do something with the results */ 6250Sstevel@tonic-gate (void) memmove(meddp, &res.med_data, sizeof (med_data_t)); 6260Sstevel@tonic-gate rval = 0; 6270Sstevel@tonic-gate } 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate xdr_free(xdr_med_args_t, (char *)&args); 6300Sstevel@tonic-gate xdr_free(xdr_med_get_data_res_t, (char *)&res); 6310Sstevel@tonic-gate 6320Sstevel@tonic-gate return (rval); 6330Sstevel@tonic-gate } 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate /* 6360Sstevel@tonic-gate * Update the mediator record on the mediator. 6370Sstevel@tonic-gate */ 6380Sstevel@tonic-gate int 6390Sstevel@tonic-gate clnt_med_upd_rec( 6400Sstevel@tonic-gate md_h_t *mdhp, 6410Sstevel@tonic-gate mdsetname_t *sp, 6420Sstevel@tonic-gate med_rec_t *medrp, 6430Sstevel@tonic-gate md_error_t *ep 6440Sstevel@tonic-gate ) 6450Sstevel@tonic-gate { 6460Sstevel@tonic-gate med_handle_t *hp; 6470Sstevel@tonic-gate med_upd_rec_args_t args; 6480Sstevel@tonic-gate med_err_t res; 6490Sstevel@tonic-gate md_set_desc *sd; 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate /* initialize */ 6520Sstevel@tonic-gate mdclrerror(ep); 6530Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 6540Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate /* build args */ 6570Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 6580Sstevel@tonic-gate return (-1); 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 6610Sstevel@tonic-gate /* 6620Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 6630Sstevel@tonic-gate * the node initiating the RPC request. This allows 6640Sstevel@tonic-gate * any node to access mediator information. 6650Sstevel@tonic-gate * 6660Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 6670Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 6680Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 6690Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 6700Sstevel@tonic-gate * 6710Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 6720Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 6730Sstevel@tonic-gate * mediator data. 6740Sstevel@tonic-gate */ 6750Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 6760Sstevel@tonic-gate else 6770Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 6780Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 6790Sstevel@tonic-gate args.med.med_setno = sp->setno; 6800Sstevel@tonic-gate args.med_flags = 0; 6810Sstevel@tonic-gate args.med_rec = *medrp; /* structure assignment */ 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate /* do it */ 6840Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 6850Sstevel@tonic-gate return (-1); 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 6880Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 6890Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd update record")); 6900Sstevel@tonic-gate else 6910Sstevel@tonic-gate (void) meddstealerror(ep, &res); 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate close_medd(hp); 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate xdr_free(xdr_med_upd_rec_args_t, (char *)&args); 6960Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate if (! mdisok(ep)) 6990Sstevel@tonic-gate return (-1); 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate return (0); 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate /* 7050Sstevel@tonic-gate * Get the mediator record for this client from the mediator 7060Sstevel@tonic-gate */ 7070Sstevel@tonic-gate int 7080Sstevel@tonic-gate clnt_med_get_rec( 7090Sstevel@tonic-gate md_h_t *mdhp, 7100Sstevel@tonic-gate mdsetname_t *sp, 7110Sstevel@tonic-gate med_rec_t *medrp, 7120Sstevel@tonic-gate md_error_t *ep 7130Sstevel@tonic-gate ) 7140Sstevel@tonic-gate { 7150Sstevel@tonic-gate med_handle_t *hp; 7160Sstevel@tonic-gate med_args_t args; 7170Sstevel@tonic-gate med_get_rec_res_t res; 7180Sstevel@tonic-gate int rval = -1; 7190Sstevel@tonic-gate md_set_desc *sd; 7200Sstevel@tonic-gate 7210Sstevel@tonic-gate /* initialize */ 7220Sstevel@tonic-gate mdclrerror(ep); 7230Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 7240Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 7250Sstevel@tonic-gate 7260Sstevel@tonic-gate /* build args */ 7270Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 7280Sstevel@tonic-gate return (-1); 7290Sstevel@tonic-gate 7300Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 7310Sstevel@tonic-gate /* 7320Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 7330Sstevel@tonic-gate * the node initiating the RPC request. This allows 7340Sstevel@tonic-gate * any node to access mediator information. 7350Sstevel@tonic-gate * 7360Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 7370Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 7380Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 7390Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 7400Sstevel@tonic-gate * 7410Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 7420Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 7430Sstevel@tonic-gate * mediator data. 7440Sstevel@tonic-gate */ 7450Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 7460Sstevel@tonic-gate else 7470Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 7480Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 7490Sstevel@tonic-gate args.med.med_setno = sp->setno; 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate /* do it */ 7520Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 7530Sstevel@tonic-gate return (-1); 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 7560Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 7570Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd get record")); 7580Sstevel@tonic-gate else 7590Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate close_medd(hp); 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate if (mdisok(ep)) { 7640Sstevel@tonic-gate /* do something with the results */ 7650Sstevel@tonic-gate (void) memmove(medrp, &res.med_rec, sizeof (med_rec_t)); 7660Sstevel@tonic-gate rval = 0; 7670Sstevel@tonic-gate } 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate xdr_free(xdr_med_args_t, (char *)&args); 7700Sstevel@tonic-gate xdr_free(xdr_med_get_rec_res_t, (char *)&res); 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate return (rval); 7730Sstevel@tonic-gate } 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate /* 7760Sstevel@tonic-gate * Get the name of the host from the mediator daemon. 7770Sstevel@tonic-gate */ 7780Sstevel@tonic-gate int 7790Sstevel@tonic-gate clnt_med_hostname( 7800Sstevel@tonic-gate char *hostname, 7810Sstevel@tonic-gate char **ret_hostname, 7820Sstevel@tonic-gate md_error_t *ep 7830Sstevel@tonic-gate ) 7840Sstevel@tonic-gate { 7850Sstevel@tonic-gate med_handle_t *hp; 7860Sstevel@tonic-gate med_hnm_res_t res; 7870Sstevel@tonic-gate int rval = -1; 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate /* initialize */ 7900Sstevel@tonic-gate mdclrerror(ep); 7910Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate /* No args */ 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate /* do it */ 7960Sstevel@tonic-gate if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 7970Sstevel@tonic-gate return (-1); 7980Sstevel@tonic-gate 7990Sstevel@tonic-gate if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 8000Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hostname, 8010Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd hostname")); 8020Sstevel@tonic-gate else 8030Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate close_medd(hp); 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate if (mdisok(ep)) { 8080Sstevel@tonic-gate /* do something with the results */ 8090Sstevel@tonic-gate rval = 0; 8100Sstevel@tonic-gate 8110Sstevel@tonic-gate if (ret_hostname != NULL) 8120Sstevel@tonic-gate *ret_hostname = Strdup(res.med_hnm); 8130Sstevel@tonic-gate } 8140Sstevel@tonic-gate 8150Sstevel@tonic-gate xdr_free(xdr_med_hnm_res_t, (char *)&res); 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate return (rval); 8180Sstevel@tonic-gate } 8190Sstevel@tonic-gate 8200Sstevel@tonic-gate int 8210Sstevel@tonic-gate meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep) 8220Sstevel@tonic-gate { 8230Sstevel@tonic-gate int i, j; 8240Sstevel@tonic-gate int max_meds; 8250Sstevel@tonic-gate 8260Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 8270Sstevel@tonic-gate return (-1); 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 8300Sstevel@tonic-gate mp->n_lst[i].a_flg = 0; 8310Sstevel@tonic-gate /* See if this is the local host */ 8320Sstevel@tonic-gate if (mp->n_lst[i].a_cnt > 0 && 8330Sstevel@tonic-gate strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL) 8340Sstevel@tonic-gate mp->n_lst[i].a_flg |= NMIP_F_LOCAL; 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate for (j = 0; j < mp->n_lst[i].a_cnt; j++) { 8370Sstevel@tonic-gate struct hostent *hp; 8380Sstevel@tonic-gate char *hnm = mp->n_lst[i].a_nm[j]; 8390Sstevel@tonic-gate 8400Sstevel@tonic-gate /* 8410Sstevel@tonic-gate * Cluster nodename support 8420Sstevel@tonic-gate * 8430Sstevel@tonic-gate * See if the clustering code can give us an IP addr 8440Sstevel@tonic-gate * for the stored name. If not, find it the old way 8450Sstevel@tonic-gate * which will use the public interface. 8460Sstevel@tonic-gate */ 8470Sstevel@tonic-gate if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j], 8480Sstevel@tonic-gate (struct in_addr *)&mp->n_lst[i].a_ip[j]) != 8490Sstevel@tonic-gate SDSSC_OKAY) { 8500Sstevel@tonic-gate if ((hp = gethostbyname(hnm)) == NULL) 8510Sstevel@tonic-gate return (mdsyserror(ep, EADDRNOTAVAIL, 8520Sstevel@tonic-gate hnm)); 8530Sstevel@tonic-gate 8540Sstevel@tonic-gate /* We only do INET addresses */ 8550Sstevel@tonic-gate if (hp->h_addrtype != AF_INET) 8560Sstevel@tonic-gate return (mdsyserror(ep, EPFNOSUPPORT, 8570Sstevel@tonic-gate hnm)); 8580Sstevel@tonic-gate 8590Sstevel@tonic-gate /* We take the first address only */ 8600Sstevel@tonic-gate if (*hp->h_addr_list) { 8610Sstevel@tonic-gate (void) memmove(&mp->n_lst[i].a_ip[j], 8620Sstevel@tonic-gate *hp->h_addr_list, 8630Sstevel@tonic-gate sizeof (struct in_addr)); 8640Sstevel@tonic-gate } else 8650Sstevel@tonic-gate return (mdsyserror(ep, EADDRNOTAVAIL, 8660Sstevel@tonic-gate hnm)); 8670Sstevel@tonic-gate } 8680Sstevel@tonic-gate 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate } 8710Sstevel@tonic-gate return (0); 8720Sstevel@tonic-gate } 8730Sstevel@tonic-gate 8740Sstevel@tonic-gate int 8750Sstevel@tonic-gate meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep) 8760Sstevel@tonic-gate { 8770Sstevel@tonic-gate int i, j; 8780Sstevel@tonic-gate int max_meds; 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 8810Sstevel@tonic-gate return (-1); 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate mdhip->n_cnt = mdhp->n_cnt; 8840Sstevel@tonic-gate 8850Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 8860Sstevel@tonic-gate mdhip->n_lst[i].a_flg = 0; 8870Sstevel@tonic-gate mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt; 8880Sstevel@tonic-gate if (mdhp->n_lst[i].a_cnt == 0) 8890Sstevel@tonic-gate continue; 8900Sstevel@tonic-gate for (j = 0; j < mdhp->n_lst[i].a_cnt; j++) 8910Sstevel@tonic-gate (void) strcpy(mdhip->n_lst[i].a_nm[j], 8920Sstevel@tonic-gate mdhp->n_lst[i].a_nm[j]); 8930Sstevel@tonic-gate } 8940Sstevel@tonic-gate return (0); 8950Sstevel@tonic-gate } 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate int 8980Sstevel@tonic-gate meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep) 8990Sstevel@tonic-gate { 9000Sstevel@tonic-gate int i, j; 9010Sstevel@tonic-gate int max_meds; 9020Sstevel@tonic-gate 9030Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 9040Sstevel@tonic-gate return (-1); 9050Sstevel@tonic-gate 9060Sstevel@tonic-gate mdhp->n_cnt = mdhip->n_cnt; 9070Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 9080Sstevel@tonic-gate mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt; 9090Sstevel@tonic-gate if (mdhip->n_lst[i].a_cnt == 0) 9100Sstevel@tonic-gate continue; 9110Sstevel@tonic-gate for (j = 0; j < mdhip->n_lst[i].a_cnt; j++) 9120Sstevel@tonic-gate (void) strcpy(mdhp->n_lst[i].a_nm[j], 9130Sstevel@tonic-gate mdhip->n_lst[i].a_nm[j]); 9140Sstevel@tonic-gate } 9150Sstevel@tonic-gate return (0); 9160Sstevel@tonic-gate } 9170Sstevel@tonic-gate 9180Sstevel@tonic-gate int 9190Sstevel@tonic-gate setup_med_cfg( 9200Sstevel@tonic-gate mdsetname_t *sp, 9210Sstevel@tonic-gate mddb_config_t *cp, 9220Sstevel@tonic-gate int force, 9230Sstevel@tonic-gate md_error_t *ep 9240Sstevel@tonic-gate ) 9250Sstevel@tonic-gate { 9260Sstevel@tonic-gate md_set_desc *sd; 9270Sstevel@tonic-gate int i; 9280Sstevel@tonic-gate int max_meds; 9290Sstevel@tonic-gate 9300Sstevel@tonic-gate if (metaislocalset(sp)) 9310Sstevel@tonic-gate return (0); 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 9340Sstevel@tonic-gate return (-1); 9350Sstevel@tonic-gate 9360Sstevel@tonic-gate if (setup_med_transtab(ep)) 9370Sstevel@tonic-gate return (-1); 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate if (meta_h2hi(&sd->sd_med, &cp->c_med, ep)) 9400Sstevel@tonic-gate return (-1); 9410Sstevel@tonic-gate 9420Sstevel@tonic-gate /* Make sure the ip addresses are current */ 9430Sstevel@tonic-gate if (meta_med_hnm2ip(&cp->c_med, ep)) 9440Sstevel@tonic-gate return (-1); 9450Sstevel@tonic-gate 9460Sstevel@tonic-gate if (force) 9470Sstevel@tonic-gate return (0); 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 9500Sstevel@tonic-gate return (-1); 9510Sstevel@tonic-gate 9520Sstevel@tonic-gate /* Make sure metamedd still running on host - only chk nodename */ 9530Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 9540Sstevel@tonic-gate char *hostname; 9550Sstevel@tonic-gate char *hnm; 9560Sstevel@tonic-gate 9570Sstevel@tonic-gate if (sd->sd_med.n_lst[i].a_cnt == 0) 9580Sstevel@tonic-gate continue; 9590Sstevel@tonic-gate 9600Sstevel@tonic-gate hnm = sd->sd_med.n_lst[i].a_nm[0]; 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate if (clnt_med_hostname(hnm, &hostname, ep)) 9630Sstevel@tonic-gate return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno, 9640Sstevel@tonic-gate hnm, NULL, sp->setname)); 9650Sstevel@tonic-gate Free(hostname); 9660Sstevel@tonic-gate } 9670Sstevel@tonic-gate return (0); 9680Sstevel@tonic-gate } 969*7044Smk117520 970*7044Smk117520 /* 971*7044Smk117520 * This is a general routine to get mediator information from 972*7044Smk117520 * file /etc/lvm/meddb. Commands medstat and metainit use this 973*7044Smk117520 * routine to get mediator information from all mediator hosts or update 974*7044Smk117520 * its mediator record respectively. 975*7044Smk117520 */ 976*7044Smk117520 int 977*7044Smk117520 meta_mediator_info_from_file(char *sname, int verbose, md_error_t *ep) 978*7044Smk117520 { 979*7044Smk117520 uint_t c; 980*7044Smk117520 int i; 981*7044Smk117520 int j; 982*7044Smk117520 int fd; 983*7044Smk117520 int rec_size; 984*7044Smk117520 char *setname; 985*7044Smk117520 uint_t setnum; 986*7044Smk117520 med_rec_t *rec_buf = NULL; 987*7044Smk117520 med_db_hdr_t *dbhbr; 988*7044Smk117520 med_rec_t *medrecp; 989*7044Smk117520 med_data_t medd; 990*7044Smk117520 med_data_t *save_medd; 991*7044Smk117520 md_h_t mdh; 992*7044Smk117520 uint_t latest_med_dat_cc = 0; 993*7044Smk117520 int retval; 994*7044Smk117520 int medok = 0; 995*7044Smk117520 int golden = 0; 996*7044Smk117520 bool_t obandiskset; 997*7044Smk117520 998*7044Smk117520 /* Open the meddb file */ 999*7044Smk117520 if ((fd = open(MED_DB_FILE, O_RDONLY, 0)) == -1) { 1000*7044Smk117520 mde_perror(ep, "Error in opening meddb file"); 1001*7044Smk117520 return (1); 1002*7044Smk117520 } 1003*7044Smk117520 1004*7044Smk117520 /* Initialize rec_size */ 1005*7044Smk117520 rec_size = roundup(sizeof (med_rec_t), DEV_BSIZE); 1006*7044Smk117520 1007*7044Smk117520 /* Allocate a record buffer */ 1008*7044Smk117520 if ((rec_buf = malloc(rec_size)) == NULL) { 1009*7044Smk117520 mde_perror(ep, "Error in allocating memory"); 1010*7044Smk117520 goto out; 1011*7044Smk117520 } 1012*7044Smk117520 1013*7044Smk117520 /* read the file header */ 1014*7044Smk117520 if ((read(fd, rec_buf, rec_size)) != rec_size) { 1015*7044Smk117520 mde_perror(ep, "Error in reading mediator record"); 1016*7044Smk117520 goto out; 1017*7044Smk117520 } 1018*7044Smk117520 1019*7044Smk117520 dbhbr = (med_db_hdr_t *)rec_buf; 1020*7044Smk117520 1021*7044Smk117520 /* Number of records in the mediator file */ 1022*7044Smk117520 c = dbhbr->med_dbh_nm; 1023*7044Smk117520 1024*7044Smk117520 for (i = 0; i < c; i++) { 1025*7044Smk117520 (void) memset(rec_buf, 0, rec_size); 1026*7044Smk117520 1027*7044Smk117520 if (read(fd, rec_buf, rec_size) == -1) { 1028*7044Smk117520 mde_perror(ep, "Error in reading mediator record"); 1029*7044Smk117520 goto out; 1030*7044Smk117520 } 1031*7044Smk117520 1032*7044Smk117520 medrecp = (med_rec_t *)rec_buf; 1033*7044Smk117520 1034*7044Smk117520 /* 1035*7044Smk117520 * For oban diskset first entry in the rec_nodes field is 1036*7044Smk117520 * "multiowner" and all other entries are null 1037*7044Smk117520 * Check if this is really multiowner diskset. 1038*7044Smk117520 */ 1039*7044Smk117520 1040*7044Smk117520 if ((strcmp(medrecp->med_rec_nodes[0], MED_MN_CALLER) == 0) && 1041*7044Smk117520 (medrecp->med_rec_nodes[1] == NULL)) 1042*7044Smk117520 obandiskset = TRUE; 1043*7044Smk117520 else 1044*7044Smk117520 obandiskset = FALSE; 1045*7044Smk117520 1046*7044Smk117520 if (sname != NULL) { 1047*7044Smk117520 /* 1048*7044Smk117520 * Continue if the set name is not in our interest. 1049*7044Smk117520 * This is required when this routine is called 1050*7044Smk117520 * from medstat 1051*7044Smk117520 */ 1052*7044Smk117520 1053*7044Smk117520 if (strcmp(sname, medrecp->med_rec_snm) != 0) { 1054*7044Smk117520 continue; 1055*7044Smk117520 } 1056*7044Smk117520 1057*7044Smk117520 if (verbose) 1058*7044Smk117520 (void) printf("%8.8s\t\t%6.6s\t%6.6s\n", 1059*7044Smk117520 gettext("Mediator"), gettext("Status"), 1060*7044Smk117520 gettext("Golden")); 1061*7044Smk117520 1062*7044Smk117520 if (medrecp->med_rec_meds.n_cnt == 0) { 1063*7044Smk117520 if (verbose) 1064*7044Smk117520 (void) printf(gettext( 1065*7044Smk117520 "No mediator hosts configured for" 1066*7044Smk117520 " set \"%s\".\n"), 1067*7044Smk117520 sname); 1068*7044Smk117520 goto out; 1069*7044Smk117520 } 1070*7044Smk117520 setname = sname; 1071*7044Smk117520 } else { 1072*7044Smk117520 setname = medrecp->med_rec_snm; 1073*7044Smk117520 } 1074*7044Smk117520 setnum = medrecp->med_rec_sn; 1075*7044Smk117520 1076*7044Smk117520 for (j = 0; j < medrecp->med_rec_meds.n_cnt; j ++) { 1077*7044Smk117520 (void) memset(&medd, 0, sizeof (medd)); 1078*7044Smk117520 (void) memset(&mdh, 0, sizeof (mdh)); 1079*7044Smk117520 mdh = medrecp->med_rec_meds.n_lst[j]; 1080*7044Smk117520 1081*7044Smk117520 if ((sname != NULL) && (verbose)) 1082*7044Smk117520 (void) printf("%-17.17s\t", 1083*7044Smk117520 medrecp->med_rec_meds.n_lst[j].a_nm[0]); 1084*7044Smk117520 1085*7044Smk117520 if (clnt_user_med_get_data(&mdh, obandiskset, 1086*7044Smk117520 setname, setnum, &medd, ep) == -1) { 1087*7044Smk117520 if (sname == NULL) { 1088*7044Smk117520 continue; 1089*7044Smk117520 } else { 1090*7044Smk117520 if (mdanyrpcerror(ep)) { 1091*7044Smk117520 if (verbose) 1092*7044Smk117520 (void) printf("%s\n", 1093*7044Smk117520 gettext("Unreach" 1094*7044Smk117520 "able")); 1095*7044Smk117520 continue; 1096*7044Smk117520 } else if (mdiserror(ep, 1097*7044Smk117520 MDE_MED_ERROR)) { 1098*7044Smk117520 if (verbose) 1099*7044Smk117520 (void) printf("%s\n", 1100*7044Smk117520 gettext("Bad")); 1101*7044Smk117520 } else { 1102*7044Smk117520 if (verbose) 1103*7044Smk117520 (void) printf("%s\n", 1104*7044Smk117520 gettext("Fatal")); 1105*7044Smk117520 } 1106*7044Smk117520 mde_perror(ep, ""); 1107*7044Smk117520 if (mdiserror(ep, MDE_MED_ERROR)) 1108*7044Smk117520 continue; 1109*7044Smk117520 goto out; 1110*7044Smk117520 } 1111*7044Smk117520 } else { 1112*7044Smk117520 if (sname == NULL) { 1113*7044Smk117520 if (latest_med_dat_cc < 1114*7044Smk117520 medd.med_dat_cc) { 1115*7044Smk117520 latest_med_dat_cc = 1116*7044Smk117520 medd.med_dat_cc; 1117*7044Smk117520 save_medd = &medd; 1118*7044Smk117520 } 1119*7044Smk117520 } else { 1120*7044Smk117520 if (verbose) 1121*7044Smk117520 (void) printf("%s", 1122*7044Smk117520 gettext("Ok")); 1123*7044Smk117520 if (medd.med_dat_fl & MED_DFL_GOLDEN) { 1124*7044Smk117520 if (verbose) 1125*7044Smk117520 (void) printf("\t%s", 1126*7044Smk117520 gettext("Yes")); 1127*7044Smk117520 golden++; 1128*7044Smk117520 } else { 1129*7044Smk117520 if (verbose) 1130*7044Smk117520 (void) printf("\t%s", 1131*7044Smk117520 gettext("No")); 1132*7044Smk117520 } 1133*7044Smk117520 if (verbose) 1134*7044Smk117520 (void) printf("\n"); 1135*7044Smk117520 medok++; 1136*7044Smk117520 } 1137*7044Smk117520 } 1138*7044Smk117520 } 1139*7044Smk117520 if (sname == NULL) { 1140*7044Smk117520 /* 1141*7044Smk117520 * Update the latest mediator information 1142*7044Smk117520 * on this node 1143*7044Smk117520 */ 1144*7044Smk117520 (void) strlcpy(mdh.a_nm[0], mynode(), 1145*7044Smk117520 sizeof (mdh.a_nm[0])); 1146*7044Smk117520 if (clnt_user_med_upd_data(&mdh, obandiskset, 1147*7044Smk117520 setname, setnum, save_medd, ep) == -1) { 1148*7044Smk117520 /* 1149*7044Smk117520 * We had some errors while updaing the 1150*7044Smk117520 * record. This means this metaset is 1151*7044Smk117520 * not updated with latest mediator 1152*7044Smk117520 * information. 1153*7044Smk117520 */ 1154*7044Smk117520 mde_perror(ep, ""); 1155*7044Smk117520 continue; 1156*7044Smk117520 } 1157*7044Smk117520 } else { 1158*7044Smk117520 if (golden) { 1159*7044Smk117520 retval = 0; 1160*7044Smk117520 goto out; 1161*7044Smk117520 } 1162*7044Smk117520 if (medok < ((medrecp->med_rec_meds.n_cnt / 2) + 1)) 1163*7044Smk117520 retval = 1; 1164*7044Smk117520 } 1165*7044Smk117520 } 1166*7044Smk117520 1167*7044Smk117520 out: 1168*7044Smk117520 if (rec_buf != NULL) 1169*7044Smk117520 Free(rec_buf); 1170*7044Smk117520 if (close(fd) < 0) { 1171*7044Smk117520 mde_perror(ep, "Error in closing meddb file"); 1172*7044Smk117520 return (1); 1173*7044Smk117520 } 1174*7044Smk117520 return (retval); 1175*7044Smk117520 } 1176