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 5*8451SRameshkumar.Ramasamy@Sun.COM * Common Development and Distribution License (the "License"). 6*8451SRameshkumar.Ramasamy@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 217044Smk117520 220Sstevel@tonic-gate /* 237044Smk117520 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* 280Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that 290Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 320Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 330Sstevel@tonic-gate #endif 340Sstevel@tonic-gate 350Sstevel@tonic-gate /* 360Sstevel@tonic-gate * Mediator functions 370Sstevel@tonic-gate */ 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <meta.h> 400Sstevel@tonic-gate #include <metamed.h> 410Sstevel@tonic-gate #include <dlfcn.h> 420Sstevel@tonic-gate #include <sdssc.h> 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * There are too many external factors that affect the timing of the 460Sstevel@tonic-gate * operations, so we set the timeout to a very large value, in this 470Sstevel@tonic-gate * case 1 day, which should handle HW timeouts, large configurations, 480Sstevel@tonic-gate * and other potential delays. 490Sstevel@tonic-gate */ 500Sstevel@tonic-gate #define CL_LONG_TMO 86400L /* 1 day */ 510Sstevel@tonic-gate #define CL_MEDIUM_TMO 3600L /* 1 hour */ 520Sstevel@tonic-gate #define CL_SHORT_TMO 600L /* 10 minutes */ 530Sstevel@tonic-gate #define CL_DEF_TMO 10L /* 10 seconds */ 540Sstevel@tonic-gate 550Sstevel@tonic-gate static md_timeval32_t def_rpcb_timeout = { MD_CLNT_CREATE_TOUT, 0 }; 560Sstevel@tonic-gate 570Sstevel@tonic-gate /* 580Sstevel@tonic-gate * RPC handle 590Sstevel@tonic-gate */ 600Sstevel@tonic-gate typedef struct { 610Sstevel@tonic-gate char *hostname; 620Sstevel@tonic-gate CLIENT *clntp; 630Sstevel@tonic-gate } med_handle_t; 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* 660Sstevel@tonic-gate * Data to be sent from med_clnt_create_timed to med_create_helper via 670Sstevel@tonic-gate * meta_client_create_retry. 680Sstevel@tonic-gate */ 690Sstevel@tonic-gate typedef struct { 700Sstevel@tonic-gate rpcprog_t mcd_program; /* RPC program designation */ 710Sstevel@tonic-gate rpcvers_t mcd_version; /* RPC version */ 720Sstevel@tonic-gate char *mcd_nettype; /* Type of network to use for RPC */ 730Sstevel@tonic-gate } med_create_data_t; 740Sstevel@tonic-gate 750Sstevel@tonic-gate /* 760Sstevel@tonic-gate * Perform the work of actually doing the clnt_create for 770Sstevel@tonic-gate * meta_client_create_retry. 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate static CLIENT * 800Sstevel@tonic-gate med_create_helper(char *hostname, void *private, struct timeval *time_out) 810Sstevel@tonic-gate { 820Sstevel@tonic-gate med_create_data_t *cd = (med_create_data_t *)private; 830Sstevel@tonic-gate 840Sstevel@tonic-gate return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version, 85*8451SRameshkumar.Ramasamy@Sun.COM cd->mcd_nettype, time_out)); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate 880Sstevel@tonic-gate static 890Sstevel@tonic-gate CLIENT *med_clnt_create_timed( 900Sstevel@tonic-gate char *hostname, 910Sstevel@tonic-gate const ulong_t prog, 920Sstevel@tonic-gate const ulong_t vers, 930Sstevel@tonic-gate char *nettype, 940Sstevel@tonic-gate const md_timeval32_t *tp 950Sstevel@tonic-gate ) 960Sstevel@tonic-gate { 970Sstevel@tonic-gate med_create_data_t cd; /* Create data. */ 980Sstevel@tonic-gate 990Sstevel@tonic-gate cd.mcd_program = prog; 1000Sstevel@tonic-gate cd.mcd_version = vers; 1010Sstevel@tonic-gate cd.mcd_nettype = nettype; 1020Sstevel@tonic-gate return (meta_client_create_retry(hostname, med_create_helper, 103*8451SRameshkumar.Ramasamy@Sun.COM (void *)&cd, (time_t)tp->tv_sec, NULL)); 1040Sstevel@tonic-gate } 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate /* 1070Sstevel@tonic-gate * Set the timeout value for this client handle. 1080Sstevel@tonic-gate */ 1090Sstevel@tonic-gate static int 1100Sstevel@tonic-gate cl_sto_medd( 1110Sstevel@tonic-gate CLIENT *clntp, 1120Sstevel@tonic-gate char *hostname, 1130Sstevel@tonic-gate long time_out, 1140Sstevel@tonic-gate md_error_t *ep 1150Sstevel@tonic-gate ) 1160Sstevel@tonic-gate { 1170Sstevel@tonic-gate md_timeval32_t nto; 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate (void) memset(&nto, '\0', sizeof (nto)); 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate nto.tv_sec = time_out; 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE) 1240Sstevel@tonic-gate return (mdrpcerror(ep, clntp, hostname, 1250Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "metad client set timeout"))); 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate return (0); 1280Sstevel@tonic-gate } 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate /* 1310Sstevel@tonic-gate * close RPC connection 1320Sstevel@tonic-gate */ 1330Sstevel@tonic-gate static void 1340Sstevel@tonic-gate close_medd( 1350Sstevel@tonic-gate med_handle_t *hp 1360Sstevel@tonic-gate ) 1370Sstevel@tonic-gate { 1380Sstevel@tonic-gate assert(hp != NULL); 1390Sstevel@tonic-gate if (hp->hostname != NULL) { 1400Sstevel@tonic-gate Free(hp->hostname); 1410Sstevel@tonic-gate } 1420Sstevel@tonic-gate if (hp->clntp != NULL) { 1430Sstevel@tonic-gate auth_destroy(hp->clntp->cl_auth); 1440Sstevel@tonic-gate clnt_destroy(hp->clntp); 1450Sstevel@tonic-gate } 1460Sstevel@tonic-gate Free(hp); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate /* 1500Sstevel@tonic-gate * open RPC connection to rpc.medd 1510Sstevel@tonic-gate */ 1520Sstevel@tonic-gate static med_handle_t * 1530Sstevel@tonic-gate open_medd( 1540Sstevel@tonic-gate char *hostname, 1550Sstevel@tonic-gate long time_out, 1560Sstevel@tonic-gate md_error_t *ep 1570Sstevel@tonic-gate ) 1580Sstevel@tonic-gate { 1590Sstevel@tonic-gate CLIENT *clntp; 1600Sstevel@tonic-gate med_handle_t *hp; 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate /* default to local host */ 1630Sstevel@tonic-gate if ((hostname == NULL) || (*hostname == '\0')) 1640Sstevel@tonic-gate hostname = mynode(); 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate /* open RPC connection */ 1670Sstevel@tonic-gate assert(hostname != NULL); 1680Sstevel@tonic-gate if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS, 1690Sstevel@tonic-gate "tcp", &def_rpcb_timeout)) == NULL) { 1700Sstevel@tonic-gate if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) 1710Sstevel@tonic-gate clnt_pcreateerror(hostname); 1720Sstevel@tonic-gate (void) mdrpccreateerror(ep, hostname, 1730Sstevel@tonic-gate "medd med_clnt_create_timed"); 1740Sstevel@tonic-gate return (NULL); 1750Sstevel@tonic-gate } else { 1760Sstevel@tonic-gate auth_destroy(clntp->cl_auth); 1770Sstevel@tonic-gate clntp->cl_auth = authsys_create_default(); 1780Sstevel@tonic-gate assert(clntp->cl_auth != NULL); 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate if (cl_sto_medd(clntp, hostname, time_out, ep) != 0) 1820Sstevel@tonic-gate return (NULL); 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate /* return connection */ 1850Sstevel@tonic-gate hp = Zalloc(sizeof (*hp)); 1860Sstevel@tonic-gate hp->hostname = Strdup(hostname); 1870Sstevel@tonic-gate hp->clntp = clntp; 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate return (hp); 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate /* 1930Sstevel@tonic-gate * steal and convert med_err_t 1940Sstevel@tonic-gate */ 1950Sstevel@tonic-gate int 1960Sstevel@tonic-gate meddstealerror( 1970Sstevel@tonic-gate md_error_t *ep, 1980Sstevel@tonic-gate med_err_t *medep 1990Sstevel@tonic-gate ) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate char buf[BUFSIZ]; 2020Sstevel@tonic-gate char *p = buf; 2030Sstevel@tonic-gate size_t psize = BUFSIZ; 2040Sstevel@tonic-gate char *emsg; 2050Sstevel@tonic-gate int rval = -1; 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate /* no error */ 2080Sstevel@tonic-gate if (medep->med_errno == 0) { 2090Sstevel@tonic-gate /* assert(medep->name == NULL); */ 2100Sstevel@tonic-gate rval = 0; 2110Sstevel@tonic-gate goto out; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* steal error */ 2150Sstevel@tonic-gate if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) { 2160Sstevel@tonic-gate (void) snprintf(p, psize, "%s: ", medep->med_node); 2170Sstevel@tonic-gate p = &buf[strlen(buf)]; 2180Sstevel@tonic-gate psize = buf + BUFSIZ - p; 2190Sstevel@tonic-gate } 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) { 2220Sstevel@tonic-gate (void) snprintf(p, psize, "%s: ", medep->med_misc); 2230Sstevel@tonic-gate p = &buf[strlen(buf)]; 2240Sstevel@tonic-gate psize = buf + BUFSIZ - p; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate if (medep->med_errno < 0) { 2280Sstevel@tonic-gate if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL) 2290Sstevel@tonic-gate (void) snprintf(p, psize, "%s", emsg); 2300Sstevel@tonic-gate else 2310Sstevel@tonic-gate (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 2320Sstevel@tonic-gate "unknown mediator errno %d\n"), medep->med_errno); 2330Sstevel@tonic-gate } else { 2340Sstevel@tonic-gate if ((emsg = strerror(medep->med_errno)) != NULL) 2350Sstevel@tonic-gate (void) snprintf(p, psize, "%s", emsg); 2360Sstevel@tonic-gate else 2370Sstevel@tonic-gate (void) snprintf(p, psize, dgettext(TEXT_DOMAIN, 2380Sstevel@tonic-gate "errno %d out of range"), medep->med_errno); 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate (void) mderror(ep, MDE_MED_ERROR, buf); 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* cleanup, return success */ 2430Sstevel@tonic-gate out: 2440Sstevel@tonic-gate if (medep->med_node != NULL) 2450Sstevel@tonic-gate Free(medep->med_node); 2460Sstevel@tonic-gate if (medep->med_misc != NULL) 2470Sstevel@tonic-gate Free(medep->med_misc); 2480Sstevel@tonic-gate (void) memset(medep, 0, sizeof (*medep)); 2490Sstevel@tonic-gate return (rval); 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate static med_handle_t * 2530Sstevel@tonic-gate open_medd_wrap( 2540Sstevel@tonic-gate md_h_t *mdhp, 2550Sstevel@tonic-gate long time_out, 2560Sstevel@tonic-gate md_error_t *ep 2570Sstevel@tonic-gate ) 2580Sstevel@tonic-gate { 2590Sstevel@tonic-gate med_handle_t *hp = NULL; 2600Sstevel@tonic-gate int i; 2610Sstevel@tonic-gate char *hnm; 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate assert(mdhp && mdhp->a_cnt > 0); 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate /* Loop through the hosts listed */ 2660Sstevel@tonic-gate i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1; 2670Sstevel@tonic-gate for (; i >= 0; i--) { 2680Sstevel@tonic-gate hnm = mdhp->a_nm[i]; 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate if ((hp = open_medd(hnm, time_out, ep)) == NULL) { 2710Sstevel@tonic-gate if (mdanyrpcerror(ep) && i != 0) { 2720Sstevel@tonic-gate mdclrerror(ep); 2730Sstevel@tonic-gate continue; 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate return (hp); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_CANTSEND; 2800Sstevel@tonic-gate rpc_createerr.cf_error.re_status = 0; 2810Sstevel@tonic-gate (void) mdrpccreateerror(ep, mdhp->a_nm[0], 2820Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd open wrap")); 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate return (NULL); 2850Sstevel@tonic-gate } 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate static int 2880Sstevel@tonic-gate setup_med_transtab(md_error_t *ep) 2890Sstevel@tonic-gate { 2900Sstevel@tonic-gate mddb_med_t_parm_t *tp = NULL; 2910Sstevel@tonic-gate struct stat statb; 2920Sstevel@tonic-gate int i; 2930Sstevel@tonic-gate size_t alloc_size = 0; 2940Sstevel@tonic-gate int err = 0; 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL) 2980Sstevel@tonic-gate return (mdsyserror(ep, ENOMEM, "setup_med_transtab")); 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) { 3010Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3020Sstevel@tonic-gate goto out; 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate if (tp->med_tp_setup == 1) 3060Sstevel@tonic-gate goto out; 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) + 3090Sstevel@tonic-gate (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents); 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate if ((tp = Realloc(tp, alloc_size)) == NULL) { 3120Sstevel@tonic-gate err = mdsyserror(ep, ENOMEM, "setup_med_transtab"); 3130Sstevel@tonic-gate goto out; 3140Sstevel@tonic-gate } 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) { 3170Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3180Sstevel@tonic-gate goto out; 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate for (i = 0; i < tp->med_tp_nents; i++) { 3220Sstevel@tonic-gate if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) { 3230Sstevel@tonic-gate md_perror("setup_med_transtab(): stat():"); 3240Sstevel@tonic-gate tp->med_tp_ents[i].med_te_dev = NODEV64; 3250Sstevel@tonic-gate } else { 3260Sstevel@tonic-gate tp->med_tp_ents[i].med_te_dev = 327*8451SRameshkumar.Ramasamy@Sun.COM meta_expldev(statb.st_rdev); 3280Sstevel@tonic-gate } 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0) 3320Sstevel@tonic-gate err = mdstealerror(ep, &tp->med_tp_mde); 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate out: 3350Sstevel@tonic-gate Free(tp); 3360Sstevel@tonic-gate return (err); 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate /* 3400Sstevel@tonic-gate * Externals 3410Sstevel@tonic-gate */ 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate /* 3440Sstevel@tonic-gate * NULLPROC - just returns a response 3450Sstevel@tonic-gate */ 3460Sstevel@tonic-gate int 3470Sstevel@tonic-gate clnt_med_null( 3480Sstevel@tonic-gate char *hostname, 3490Sstevel@tonic-gate md_error_t *ep 3500Sstevel@tonic-gate ) 3510Sstevel@tonic-gate { 3520Sstevel@tonic-gate med_handle_t *hp; 3530Sstevel@tonic-gate med_err_t res; 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate /* initialize */ 3560Sstevel@tonic-gate mdclrerror(ep); 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate /* do it */ 3590Sstevel@tonic-gate if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 3600Sstevel@tonic-gate return (-1); 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 3630Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hostname, 3640Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd nullproc")); 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate close_medd(hp); 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate if (! mdisok(ep)) 3710Sstevel@tonic-gate return (-1); 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate return (0); 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate /* 3770Sstevel@tonic-gate * Update the mediator information on the mediator. 3787044Smk117520 * This function does the same functionality as 3797044Smk117520 * clnt_med_upd_data() except that it takes different 3807044Smk117520 * argument so that host which is just a mediator, can 3817044Smk117520 * still update its mediator record. 3827044Smk117520 */ 3837044Smk117520 int 3847044Smk117520 clnt_user_med_upd_data( 3857044Smk117520 md_h_t *mdhp, 3867044Smk117520 bool_t obandiskset, 3877044Smk117520 char *setname, 3887044Smk117520 uint_t setnum, 3897044Smk117520 med_data_t *meddp, 3907044Smk117520 md_error_t *ep 3917044Smk117520 ) 3927044Smk117520 { 3937044Smk117520 med_handle_t *hp; 3947044Smk117520 med_upd_data_args_t args; 3957044Smk117520 med_err_t res; 3967044Smk117520 3977044Smk117520 /* Initialize */ 3987044Smk117520 mdclrerror(ep); 3997044Smk117520 (void) memset(&args, 0, sizeof (args)); 4007044Smk117520 (void) memset(&res, 0, sizeof (res)); 4017044Smk117520 4027044Smk117520 /* Build args */ 4037044Smk117520 if (obandiskset) 4047044Smk117520 args.med.med_caller = Strdup(MED_MN_CALLER); 4057044Smk117520 else 4067044Smk117520 args.med.med_caller = Strdup(mynode()); 4077044Smk117520 4087044Smk117520 args.med.med_setname = Strdup(setname); 4097044Smk117520 args.med.med_setno = setnum; 4107044Smk117520 args.med_data = *meddp; 4117044Smk117520 4127044Smk117520 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 4137044Smk117520 return (-1); 4147044Smk117520 4157044Smk117520 if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 4167044Smk117520 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 4177044Smk117520 dgettext(TEXT_DOMAIN, "medd get record")); 4187044Smk117520 else 4197044Smk117520 (void) meddstealerror(ep, &res); 4207044Smk117520 4217044Smk117520 close_medd(hp); 4227044Smk117520 4237044Smk117520 xdr_free(xdr_med_upd_data_args_t, (char *)&args); 4247044Smk117520 xdr_free(xdr_med_err_t, (char *)&res); 4257044Smk117520 4267044Smk117520 if (! mdisok(ep)) 4277044Smk117520 return (-1); 4287044Smk117520 4297044Smk117520 return (0); 4307044Smk117520 } 4317044Smk117520 4327044Smk117520 /* 4337044Smk117520 * Get the mediator information from the client. 4347044Smk117520 * The code does same functinality as clnt_med_get_data() 4357044Smk117520 * except that it takes different arguments so that 4367044Smk117520 * host which doesn't have set information, can still 4377044Smk117520 * get access to mediator information 4387044Smk117520 */ 4397044Smk117520 int 4407044Smk117520 clnt_user_med_get_data( 4417044Smk117520 md_h_t *mdhp, 4427044Smk117520 bool_t obandiskset, 4437044Smk117520 char *setname, 4447044Smk117520 uint_t setnum, 4457044Smk117520 med_data_t *meddp, 4467044Smk117520 md_error_t *ep 4477044Smk117520 ) 4487044Smk117520 { 4497044Smk117520 int rval = -1; 4507044Smk117520 med_handle_t *hp; 4517044Smk117520 med_args_t args; 4527044Smk117520 med_get_data_res_t res; 4537044Smk117520 4547044Smk117520 /* Initialize */ 4557044Smk117520 mdclrerror(ep); 4567044Smk117520 (void) memset(&args, 0, sizeof (args)); 4577044Smk117520 (void) memset(&res, 0, sizeof (res)); 4587044Smk117520 4597044Smk117520 /* Build args */ 4607044Smk117520 if (obandiskset) 4617044Smk117520 args.med.med_caller = Strdup(MED_MN_CALLER); 4627044Smk117520 else 4637044Smk117520 args.med.med_caller = Strdup(mynode()); 4647044Smk117520 4657044Smk117520 args.med.med_setname = Strdup(setname); 4667044Smk117520 args.med.med_setno = setnum; 4677044Smk117520 4687044Smk117520 if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 4697044Smk117520 return (-1); 4707044Smk117520 4717044Smk117520 if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 4727044Smk117520 (void) mdrpcerror(ep, hp->clntp, hp->hostname, 4737044Smk117520 dgettext(TEXT_DOMAIN, "medd get record")); 4747044Smk117520 else 4757044Smk117520 (void) meddstealerror(ep, &res.med_status); 4767044Smk117520 4777044Smk117520 close_medd(hp); 4787044Smk117520 4797044Smk117520 if (mdisok(ep)) { 4807044Smk117520 /* copy the mediator data in meddp */ 4817044Smk117520 (void) memmove(meddp, &res.med_data, sizeof (med_data_t)); 4827044Smk117520 rval = 0; 4837044Smk117520 } 4847044Smk117520 4857044Smk117520 xdr_free(xdr_med_args_t, (char *)&args); 4867044Smk117520 xdr_free(xdr_med_get_data_res_t, (char *)&res); 4877044Smk117520 4887044Smk117520 return (rval); 4897044Smk117520 } 4907044Smk117520 4917044Smk117520 4927044Smk117520 /* 4937044Smk117520 * Update the mediator information on the mediator. 4940Sstevel@tonic-gate * *** This is not normally called from user code, the kernel does this! *** 4950Sstevel@tonic-gate */ 4960Sstevel@tonic-gate int 4970Sstevel@tonic-gate clnt_med_upd_data( 4980Sstevel@tonic-gate md_h_t *mdhp, 4990Sstevel@tonic-gate mdsetname_t *sp, 5000Sstevel@tonic-gate med_data_t *meddp, 5010Sstevel@tonic-gate md_error_t *ep 5020Sstevel@tonic-gate ) 5030Sstevel@tonic-gate { 5040Sstevel@tonic-gate med_handle_t *hp; 5050Sstevel@tonic-gate med_upd_data_args_t args; 5060Sstevel@tonic-gate med_err_t res; 5070Sstevel@tonic-gate md_set_desc *sd; 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate /* initialize */ 5100Sstevel@tonic-gate mdclrerror(ep); 5110Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 5120Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate /* build args */ 5150Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 5160Sstevel@tonic-gate return (-1); 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 5190Sstevel@tonic-gate /* 5200Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 5210Sstevel@tonic-gate * the node initiating the RPC request. This allows 5220Sstevel@tonic-gate * any node to access mediator information. 5230Sstevel@tonic-gate * 5240Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 5250Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 5260Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 5270Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 5280Sstevel@tonic-gate * 5290Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 5300Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 5310Sstevel@tonic-gate * mediator data. 5320Sstevel@tonic-gate */ 5330Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 5340Sstevel@tonic-gate else 5350Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 5360Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 5370Sstevel@tonic-gate args.med.med_setno = sp->setno; 5380Sstevel@tonic-gate args.med_data = *meddp; 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate /* do it */ 5410Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 5420Sstevel@tonic-gate return (-1); 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 5450Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 5460Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd update data")); 5470Sstevel@tonic-gate else 5480Sstevel@tonic-gate (void) meddstealerror(ep, &res); 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate close_medd(hp); 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate xdr_free(xdr_med_upd_data_args_t, (char *)&args); 5530Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate if (! mdisok(ep)) 5560Sstevel@tonic-gate return (-1); 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate return (0); 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate /* 5620Sstevel@tonic-gate * Get the mediator data for this client from the mediator 5630Sstevel@tonic-gate */ 5640Sstevel@tonic-gate int 5650Sstevel@tonic-gate clnt_med_get_data( 5660Sstevel@tonic-gate md_h_t *mdhp, 5670Sstevel@tonic-gate mdsetname_t *sp, 5680Sstevel@tonic-gate med_data_t *meddp, 5690Sstevel@tonic-gate md_error_t *ep 5700Sstevel@tonic-gate ) 5710Sstevel@tonic-gate { 5720Sstevel@tonic-gate med_handle_t *hp; 5730Sstevel@tonic-gate med_args_t args; 5740Sstevel@tonic-gate med_get_data_res_t res; 5750Sstevel@tonic-gate int rval = -1; 5760Sstevel@tonic-gate md_set_desc *sd; 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate /* initialize */ 5790Sstevel@tonic-gate mdclrerror(ep); 5800Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 5810Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate /* build args */ 5840Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 5850Sstevel@tonic-gate return (-1); 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 5880Sstevel@tonic-gate /* 5890Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 5900Sstevel@tonic-gate * the node initiating the RPC request. This allows 5910Sstevel@tonic-gate * any node to access mediator information. 5920Sstevel@tonic-gate * 5930Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 5940Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 5950Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 5960Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 5970Sstevel@tonic-gate * 5980Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 5990Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 6000Sstevel@tonic-gate * mediator data. 6010Sstevel@tonic-gate */ 6020Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 6030Sstevel@tonic-gate else 6040Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 6050Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 6060Sstevel@tonic-gate args.med.med_setno = sp->setno; 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate /* do it */ 6090Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 6100Sstevel@tonic-gate return (-1); 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS) 6130Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 6140Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd get data")); 6150Sstevel@tonic-gate else 6160Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate close_medd(hp); 6190Sstevel@tonic-gate 6200Sstevel@tonic-gate if (mdisok(ep)) { 6210Sstevel@tonic-gate /* do something with the results */ 6220Sstevel@tonic-gate (void) memmove(meddp, &res.med_data, sizeof (med_data_t)); 6230Sstevel@tonic-gate rval = 0; 6240Sstevel@tonic-gate } 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate xdr_free(xdr_med_args_t, (char *)&args); 6270Sstevel@tonic-gate xdr_free(xdr_med_get_data_res_t, (char *)&res); 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate return (rval); 6300Sstevel@tonic-gate } 6310Sstevel@tonic-gate 6320Sstevel@tonic-gate /* 6330Sstevel@tonic-gate * Update the mediator record on the mediator. 6340Sstevel@tonic-gate */ 6350Sstevel@tonic-gate int 6360Sstevel@tonic-gate clnt_med_upd_rec( 6370Sstevel@tonic-gate md_h_t *mdhp, 6380Sstevel@tonic-gate mdsetname_t *sp, 6390Sstevel@tonic-gate med_rec_t *medrp, 6400Sstevel@tonic-gate md_error_t *ep 6410Sstevel@tonic-gate ) 6420Sstevel@tonic-gate { 6430Sstevel@tonic-gate med_handle_t *hp; 6440Sstevel@tonic-gate med_upd_rec_args_t args; 6450Sstevel@tonic-gate med_err_t res; 6460Sstevel@tonic-gate md_set_desc *sd; 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate /* initialize */ 6490Sstevel@tonic-gate mdclrerror(ep); 6500Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 6510Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 6520Sstevel@tonic-gate 6530Sstevel@tonic-gate /* build args */ 6540Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 6550Sstevel@tonic-gate return (-1); 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 6580Sstevel@tonic-gate /* 6590Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 6600Sstevel@tonic-gate * the node initiating the RPC request. This allows 6610Sstevel@tonic-gate * any node to access mediator information. 6620Sstevel@tonic-gate * 6630Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 6640Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 6650Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 6660Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 6670Sstevel@tonic-gate * 6680Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 6690Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 6700Sstevel@tonic-gate * mediator data. 6710Sstevel@tonic-gate */ 6720Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 6730Sstevel@tonic-gate else 6740Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 6750Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 6760Sstevel@tonic-gate args.med.med_setno = sp->setno; 6770Sstevel@tonic-gate args.med_flags = 0; 6780Sstevel@tonic-gate args.med_rec = *medrp; /* structure assignment */ 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate /* do it */ 6810Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 6820Sstevel@tonic-gate return (-1); 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 6850Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 6860Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd update record")); 6870Sstevel@tonic-gate else 6880Sstevel@tonic-gate (void) meddstealerror(ep, &res); 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate close_medd(hp); 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate xdr_free(xdr_med_upd_rec_args_t, (char *)&args); 6930Sstevel@tonic-gate xdr_free(xdr_med_err_t, (char *)&res); 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate if (! mdisok(ep)) 6960Sstevel@tonic-gate return (-1); 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate return (0); 6990Sstevel@tonic-gate } 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate /* 7020Sstevel@tonic-gate * Get the mediator record for this client from the mediator 7030Sstevel@tonic-gate */ 7040Sstevel@tonic-gate int 7050Sstevel@tonic-gate clnt_med_get_rec( 7060Sstevel@tonic-gate md_h_t *mdhp, 7070Sstevel@tonic-gate mdsetname_t *sp, 7080Sstevel@tonic-gate med_rec_t *medrp, 7090Sstevel@tonic-gate md_error_t *ep 7100Sstevel@tonic-gate ) 7110Sstevel@tonic-gate { 7120Sstevel@tonic-gate med_handle_t *hp; 7130Sstevel@tonic-gate med_args_t args; 7140Sstevel@tonic-gate med_get_rec_res_t res; 7150Sstevel@tonic-gate int rval = -1; 7160Sstevel@tonic-gate md_set_desc *sd; 7170Sstevel@tonic-gate 7180Sstevel@tonic-gate /* initialize */ 7190Sstevel@tonic-gate mdclrerror(ep); 7200Sstevel@tonic-gate (void) memset(&args, 0, sizeof (args)); 7210Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate /* build args */ 7240Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 7250Sstevel@tonic-gate return (-1); 7260Sstevel@tonic-gate 7270Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 7280Sstevel@tonic-gate /* 7290Sstevel@tonic-gate * In the MN diskset, use a generic nodename, multiowner, as 7300Sstevel@tonic-gate * the node initiating the RPC request. This allows 7310Sstevel@tonic-gate * any node to access mediator information. 7320Sstevel@tonic-gate * 7330Sstevel@tonic-gate * MN diskset reconfig cycle forces consistent 7340Sstevel@tonic-gate * view of set/node/drive/mediator information across all nodes 7350Sstevel@tonic-gate * in the MN diskset. This allows the relaxation of 7360Sstevel@tonic-gate * node name checking in rpc.metamedd for MN disksets. 7370Sstevel@tonic-gate * 7380Sstevel@tonic-gate * In the traditional diskset, only a calling node that is 7390Sstevel@tonic-gate * in the mediator record's diskset nodelist can access 7400Sstevel@tonic-gate * mediator data. 7410Sstevel@tonic-gate */ 7420Sstevel@tonic-gate args.med.med_caller = Strdup(MED_MN_CALLER); 7430Sstevel@tonic-gate else 7440Sstevel@tonic-gate args.med.med_caller = Strdup(mynode()); 7450Sstevel@tonic-gate args.med.med_setname = Strdup(sp->setname); 7460Sstevel@tonic-gate args.med.med_setno = sp->setno; 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate /* do it */ 7490Sstevel@tonic-gate if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL) 7500Sstevel@tonic-gate return (-1); 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS) 7530Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hp->hostname, 7540Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd get record")); 7550Sstevel@tonic-gate else 7560Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate close_medd(hp); 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate if (mdisok(ep)) { 7610Sstevel@tonic-gate /* do something with the results */ 7620Sstevel@tonic-gate (void) memmove(medrp, &res.med_rec, sizeof (med_rec_t)); 7630Sstevel@tonic-gate rval = 0; 7640Sstevel@tonic-gate } 7650Sstevel@tonic-gate 7660Sstevel@tonic-gate xdr_free(xdr_med_args_t, (char *)&args); 7670Sstevel@tonic-gate xdr_free(xdr_med_get_rec_res_t, (char *)&res); 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate return (rval); 7700Sstevel@tonic-gate } 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate /* 7730Sstevel@tonic-gate * Get the name of the host from the mediator daemon. 7740Sstevel@tonic-gate */ 7750Sstevel@tonic-gate int 7760Sstevel@tonic-gate clnt_med_hostname( 7770Sstevel@tonic-gate char *hostname, 7780Sstevel@tonic-gate char **ret_hostname, 7790Sstevel@tonic-gate md_error_t *ep 7800Sstevel@tonic-gate ) 7810Sstevel@tonic-gate { 7820Sstevel@tonic-gate med_handle_t *hp; 7830Sstevel@tonic-gate med_hnm_res_t res; 7840Sstevel@tonic-gate int rval = -1; 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate /* initialize */ 7870Sstevel@tonic-gate mdclrerror(ep); 7880Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate /* No args */ 7910Sstevel@tonic-gate 7920Sstevel@tonic-gate /* do it */ 7930Sstevel@tonic-gate if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL) 7940Sstevel@tonic-gate return (-1); 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS) 7970Sstevel@tonic-gate (void) mdrpcerror(ep, hp->clntp, hostname, 7980Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "medd hostname")); 7990Sstevel@tonic-gate else 8000Sstevel@tonic-gate (void) meddstealerror(ep, &res.med_status); 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate close_medd(hp); 8030Sstevel@tonic-gate 8040Sstevel@tonic-gate if (mdisok(ep)) { 8050Sstevel@tonic-gate /* do something with the results */ 8060Sstevel@tonic-gate rval = 0; 8070Sstevel@tonic-gate 8080Sstevel@tonic-gate if (ret_hostname != NULL) 8090Sstevel@tonic-gate *ret_hostname = Strdup(res.med_hnm); 8100Sstevel@tonic-gate } 8110Sstevel@tonic-gate 8120Sstevel@tonic-gate xdr_free(xdr_med_hnm_res_t, (char *)&res); 8130Sstevel@tonic-gate 8140Sstevel@tonic-gate return (rval); 8150Sstevel@tonic-gate } 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate int 8180Sstevel@tonic-gate meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep) 8190Sstevel@tonic-gate { 8200Sstevel@tonic-gate int i, j; 8210Sstevel@tonic-gate int max_meds; 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 8240Sstevel@tonic-gate return (-1); 8250Sstevel@tonic-gate 8260Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 8270Sstevel@tonic-gate mp->n_lst[i].a_flg = 0; 8280Sstevel@tonic-gate /* See if this is the local host */ 8290Sstevel@tonic-gate if (mp->n_lst[i].a_cnt > 0 && 8300Sstevel@tonic-gate strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL) 8310Sstevel@tonic-gate mp->n_lst[i].a_flg |= NMIP_F_LOCAL; 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate for (j = 0; j < mp->n_lst[i].a_cnt; j++) { 8340Sstevel@tonic-gate struct hostent *hp; 8350Sstevel@tonic-gate char *hnm = mp->n_lst[i].a_nm[j]; 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate /* 8380Sstevel@tonic-gate * Cluster nodename support 8390Sstevel@tonic-gate * 8400Sstevel@tonic-gate * See if the clustering code can give us an IP addr 8410Sstevel@tonic-gate * for the stored name. If not, find it the old way 8420Sstevel@tonic-gate * which will use the public interface. 8430Sstevel@tonic-gate */ 8440Sstevel@tonic-gate if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j], 8450Sstevel@tonic-gate (struct in_addr *)&mp->n_lst[i].a_ip[j]) != 846*8451SRameshkumar.Ramasamy@Sun.COM SDSSC_OKAY) { 8470Sstevel@tonic-gate if ((hp = gethostbyname(hnm)) == NULL) 8480Sstevel@tonic-gate return (mdsyserror(ep, EADDRNOTAVAIL, 8490Sstevel@tonic-gate hnm)); 8500Sstevel@tonic-gate 8510Sstevel@tonic-gate /* We only do INET addresses */ 8520Sstevel@tonic-gate if (hp->h_addrtype != AF_INET) 8530Sstevel@tonic-gate return (mdsyserror(ep, EPFNOSUPPORT, 8540Sstevel@tonic-gate hnm)); 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate /* We take the first address only */ 8570Sstevel@tonic-gate if (*hp->h_addr_list) { 8580Sstevel@tonic-gate (void) memmove(&mp->n_lst[i].a_ip[j], 8590Sstevel@tonic-gate *hp->h_addr_list, 8600Sstevel@tonic-gate sizeof (struct in_addr)); 8610Sstevel@tonic-gate } else 8620Sstevel@tonic-gate return (mdsyserror(ep, EADDRNOTAVAIL, 8630Sstevel@tonic-gate hnm)); 8640Sstevel@tonic-gate } 8650Sstevel@tonic-gate 8660Sstevel@tonic-gate } 8670Sstevel@tonic-gate } 8680Sstevel@tonic-gate return (0); 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate int 8720Sstevel@tonic-gate meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep) 8730Sstevel@tonic-gate { 8740Sstevel@tonic-gate int i, j; 8750Sstevel@tonic-gate int max_meds; 8760Sstevel@tonic-gate 8770Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 8780Sstevel@tonic-gate return (-1); 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate mdhip->n_cnt = mdhp->n_cnt; 8810Sstevel@tonic-gate 8820Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 8830Sstevel@tonic-gate mdhip->n_lst[i].a_flg = 0; 8840Sstevel@tonic-gate mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt; 8850Sstevel@tonic-gate if (mdhp->n_lst[i].a_cnt == 0) 8860Sstevel@tonic-gate continue; 8870Sstevel@tonic-gate for (j = 0; j < mdhp->n_lst[i].a_cnt; j++) 8880Sstevel@tonic-gate (void) strcpy(mdhip->n_lst[i].a_nm[j], 8890Sstevel@tonic-gate mdhp->n_lst[i].a_nm[j]); 8900Sstevel@tonic-gate } 8910Sstevel@tonic-gate return (0); 8920Sstevel@tonic-gate } 8930Sstevel@tonic-gate 8940Sstevel@tonic-gate int 8950Sstevel@tonic-gate meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep) 8960Sstevel@tonic-gate { 8970Sstevel@tonic-gate int i, j; 8980Sstevel@tonic-gate int max_meds; 8990Sstevel@tonic-gate 9000Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 9010Sstevel@tonic-gate return (-1); 9020Sstevel@tonic-gate 9030Sstevel@tonic-gate mdhp->n_cnt = mdhip->n_cnt; 9040Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 9050Sstevel@tonic-gate mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt; 9060Sstevel@tonic-gate if (mdhip->n_lst[i].a_cnt == 0) 9070Sstevel@tonic-gate continue; 9080Sstevel@tonic-gate for (j = 0; j < mdhip->n_lst[i].a_cnt; j++) 9090Sstevel@tonic-gate (void) strcpy(mdhp->n_lst[i].a_nm[j], 9100Sstevel@tonic-gate mdhip->n_lst[i].a_nm[j]); 9110Sstevel@tonic-gate } 9120Sstevel@tonic-gate return (0); 9130Sstevel@tonic-gate } 9140Sstevel@tonic-gate 9150Sstevel@tonic-gate int 9160Sstevel@tonic-gate setup_med_cfg( 9170Sstevel@tonic-gate mdsetname_t *sp, 9180Sstevel@tonic-gate mddb_config_t *cp, 9190Sstevel@tonic-gate int force, 9200Sstevel@tonic-gate md_error_t *ep 9210Sstevel@tonic-gate ) 9220Sstevel@tonic-gate { 9230Sstevel@tonic-gate md_set_desc *sd; 9240Sstevel@tonic-gate int i; 9250Sstevel@tonic-gate int max_meds; 9260Sstevel@tonic-gate 9270Sstevel@tonic-gate if (metaislocalset(sp)) 9280Sstevel@tonic-gate return (0); 9290Sstevel@tonic-gate 9300Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 9310Sstevel@tonic-gate return (-1); 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate if (setup_med_transtab(ep)) 9340Sstevel@tonic-gate return (-1); 9350Sstevel@tonic-gate 9360Sstevel@tonic-gate if (meta_h2hi(&sd->sd_med, &cp->c_med, ep)) 9370Sstevel@tonic-gate return (-1); 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate /* Make sure the ip addresses are current */ 9400Sstevel@tonic-gate if (meta_med_hnm2ip(&cp->c_med, ep)) 9410Sstevel@tonic-gate return (-1); 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate if (force) 9440Sstevel@tonic-gate return (0); 9450Sstevel@tonic-gate 9460Sstevel@tonic-gate if ((max_meds = get_max_meds(ep)) == 0) 9470Sstevel@tonic-gate return (-1); 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate /* Make sure metamedd still running on host - only chk nodename */ 9500Sstevel@tonic-gate for (i = 0; i < max_meds; i++) { 9510Sstevel@tonic-gate char *hostname; 9520Sstevel@tonic-gate char *hnm; 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate if (sd->sd_med.n_lst[i].a_cnt == 0) 9550Sstevel@tonic-gate continue; 9560Sstevel@tonic-gate 9570Sstevel@tonic-gate hnm = sd->sd_med.n_lst[i].a_nm[0]; 9580Sstevel@tonic-gate 9590Sstevel@tonic-gate if (clnt_med_hostname(hnm, &hostname, ep)) 9600Sstevel@tonic-gate return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno, 9610Sstevel@tonic-gate hnm, NULL, sp->setname)); 9620Sstevel@tonic-gate Free(hostname); 9630Sstevel@tonic-gate } 9640Sstevel@tonic-gate return (0); 9650Sstevel@tonic-gate } 9667044Smk117520 9677044Smk117520 /* 9687044Smk117520 * This is a general routine to get mediator information from 9697044Smk117520 * file /etc/lvm/meddb. Commands medstat and metainit use this 9707044Smk117520 * routine to get mediator information from all mediator hosts or update 9717044Smk117520 * its mediator record respectively. 9727044Smk117520 */ 9737044Smk117520 int 9747044Smk117520 meta_mediator_info_from_file(char *sname, int verbose, md_error_t *ep) 9757044Smk117520 { 9767044Smk117520 uint_t c; 9777044Smk117520 int i; 9787044Smk117520 int j; 9797044Smk117520 int fd; 9807044Smk117520 int rec_size; 9817044Smk117520 char *setname; 9827044Smk117520 uint_t setnum; 9837044Smk117520 med_rec_t *rec_buf = NULL; 9847044Smk117520 med_db_hdr_t *dbhbr; 9857044Smk117520 med_rec_t *medrecp; 9867044Smk117520 med_data_t medd; 9877044Smk117520 med_data_t *save_medd; 9887044Smk117520 md_h_t mdh; 9897044Smk117520 uint_t latest_med_dat_cc = 0; 990*8451SRameshkumar.Ramasamy@Sun.COM int retval = 0; 9917044Smk117520 int medok = 0; 9927044Smk117520 int golden = 0; 9937044Smk117520 bool_t obandiskset; 9947044Smk117520 9957044Smk117520 /* Open the meddb file */ 9967044Smk117520 if ((fd = open(MED_DB_FILE, O_RDONLY, 0)) == -1) { 997*8451SRameshkumar.Ramasamy@Sun.COM 998*8451SRameshkumar.Ramasamy@Sun.COM /* 999*8451SRameshkumar.Ramasamy@Sun.COM * During the start up of the SVM services, this function 1000*8451SRameshkumar.Ramasamy@Sun.COM * will be called with an empty sname. In that case it is 1001*8451SRameshkumar.Ramasamy@Sun.COM * entirely possible for the MED_DB_FILE not to exist. 1002*8451SRameshkumar.Ramasamy@Sun.COM * If so, then no need to report an error. 1003*8451SRameshkumar.Ramasamy@Sun.COM */ 1004*8451SRameshkumar.Ramasamy@Sun.COM if (sname != NULL) { 1005*8451SRameshkumar.Ramasamy@Sun.COM (void) mdsyserror(ep, errno, MED_DB_FILE); 1006*8451SRameshkumar.Ramasamy@Sun.COM mde_perror(ep, dgettext(TEXT_DOMAIN, 1007*8451SRameshkumar.Ramasamy@Sun.COM "Error in opening meddb file")); 1008*8451SRameshkumar.Ramasamy@Sun.COM return (1); 1009*8451SRameshkumar.Ramasamy@Sun.COM } 1010*8451SRameshkumar.Ramasamy@Sun.COM return (0); 10117044Smk117520 } 10127044Smk117520 10137044Smk117520 /* Initialize rec_size */ 10147044Smk117520 rec_size = roundup(sizeof (med_rec_t), DEV_BSIZE); 10157044Smk117520 10167044Smk117520 /* Allocate a record buffer */ 10177044Smk117520 if ((rec_buf = malloc(rec_size)) == NULL) { 1018*8451SRameshkumar.Ramasamy@Sun.COM (void) mdsyserror(ep, errno, MED_DB_FILE); 1019*8451SRameshkumar.Ramasamy@Sun.COM mde_perror(ep, dgettext(TEXT_DOMAIN, 1020*8451SRameshkumar.Ramasamy@Sun.COM "Error in allocating memory")); 10217044Smk117520 goto out; 10227044Smk117520 } 10237044Smk117520 10247044Smk117520 /* read the file header */ 10257044Smk117520 if ((read(fd, rec_buf, rec_size)) != rec_size) { 1026*8451SRameshkumar.Ramasamy@Sun.COM (void) mdsyserror(ep, EINVAL, MED_DB_FILE); 1027*8451SRameshkumar.Ramasamy@Sun.COM mde_perror(ep, dgettext(TEXT_DOMAIN, 1028*8451SRameshkumar.Ramasamy@Sun.COM "Error in reading mediator record")); 10297044Smk117520 goto out; 10307044Smk117520 } 10317044Smk117520 10327044Smk117520 dbhbr = (med_db_hdr_t *)rec_buf; 10337044Smk117520 10347044Smk117520 /* Number of records in the mediator file */ 10357044Smk117520 c = dbhbr->med_dbh_nm; 10367044Smk117520 10377044Smk117520 for (i = 0; i < c; i++) { 10387044Smk117520 (void) memset(rec_buf, 0, rec_size); 10397044Smk117520 10407044Smk117520 if (read(fd, rec_buf, rec_size) == -1) { 1041*8451SRameshkumar.Ramasamy@Sun.COM (void) mdsyserror(ep, errno, MED_DB_FILE); 1042*8451SRameshkumar.Ramasamy@Sun.COM mde_perror(ep, dgettext(TEXT_DOMAIN, 1043*8451SRameshkumar.Ramasamy@Sun.COM "Error in reading mediator record")); 10447044Smk117520 goto out; 10457044Smk117520 } 10467044Smk117520 10477044Smk117520 medrecp = (med_rec_t *)rec_buf; 10487044Smk117520 10497044Smk117520 /* 10507044Smk117520 * For oban diskset first entry in the rec_nodes field is 10517044Smk117520 * "multiowner" and all other entries are null 10527044Smk117520 * Check if this is really multiowner diskset. 10537044Smk117520 */ 10547044Smk117520 10557044Smk117520 if ((strcmp(medrecp->med_rec_nodes[0], MED_MN_CALLER) == 0) && 10567044Smk117520 (medrecp->med_rec_nodes[1] == NULL)) 10577044Smk117520 obandiskset = TRUE; 10587044Smk117520 else 10597044Smk117520 obandiskset = FALSE; 10607044Smk117520 10617044Smk117520 if (sname != NULL) { 10627044Smk117520 /* 10637044Smk117520 * Continue if the set name is not in our interest. 10647044Smk117520 * This is required when this routine is called 10657044Smk117520 * from medstat 10667044Smk117520 */ 10677044Smk117520 10687044Smk117520 if (strcmp(sname, medrecp->med_rec_snm) != 0) { 10697044Smk117520 continue; 10707044Smk117520 } 10717044Smk117520 10727044Smk117520 if (verbose) 10737044Smk117520 (void) printf("%8.8s\t\t%6.6s\t%6.6s\n", 10747044Smk117520 gettext("Mediator"), gettext("Status"), 10757044Smk117520 gettext("Golden")); 10767044Smk117520 10777044Smk117520 if (medrecp->med_rec_meds.n_cnt == 0) { 10787044Smk117520 if (verbose) 10797044Smk117520 (void) printf(gettext( 10807044Smk117520 "No mediator hosts configured for" 10817044Smk117520 " set \"%s\".\n"), 10827044Smk117520 sname); 10837044Smk117520 goto out; 10847044Smk117520 } 10857044Smk117520 setname = sname; 10867044Smk117520 } else { 10877044Smk117520 setname = medrecp->med_rec_snm; 10887044Smk117520 } 10897044Smk117520 setnum = medrecp->med_rec_sn; 10907044Smk117520 10917044Smk117520 for (j = 0; j < medrecp->med_rec_meds.n_cnt; j ++) { 10927044Smk117520 (void) memset(&medd, 0, sizeof (medd)); 10937044Smk117520 (void) memset(&mdh, 0, sizeof (mdh)); 10947044Smk117520 mdh = medrecp->med_rec_meds.n_lst[j]; 10957044Smk117520 10967044Smk117520 if ((sname != NULL) && (verbose)) 10977044Smk117520 (void) printf("%-17.17s\t", 1098*8451SRameshkumar.Ramasamy@Sun.COM medrecp->med_rec_meds.n_lst[j].a_nm[0]); 10997044Smk117520 11007044Smk117520 if (clnt_user_med_get_data(&mdh, obandiskset, 11017044Smk117520 setname, setnum, &medd, ep) == -1) { 11027044Smk117520 if (sname == NULL) { 11037044Smk117520 continue; 11047044Smk117520 } else { 11057044Smk117520 if (mdanyrpcerror(ep)) { 11067044Smk117520 if (verbose) 11077044Smk117520 (void) printf("%s\n", 11087044Smk117520 gettext("Unreach" 11097044Smk117520 "able")); 11107044Smk117520 continue; 11117044Smk117520 } else if (mdiserror(ep, 1112*8451SRameshkumar.Ramasamy@Sun.COM MDE_MED_ERROR)) { 11137044Smk117520 if (verbose) 11147044Smk117520 (void) printf("%s\n", 11157044Smk117520 gettext("Bad")); 11167044Smk117520 } else { 11177044Smk117520 if (verbose) 11187044Smk117520 (void) printf("%s\n", 11197044Smk117520 gettext("Fatal")); 11207044Smk117520 } 11217044Smk117520 mde_perror(ep, ""); 11227044Smk117520 if (mdiserror(ep, MDE_MED_ERROR)) 11237044Smk117520 continue; 11247044Smk117520 goto out; 11257044Smk117520 } 11267044Smk117520 } else { 11277044Smk117520 if (sname == NULL) { 11287044Smk117520 if (latest_med_dat_cc < 11297044Smk117520 medd.med_dat_cc) { 11307044Smk117520 latest_med_dat_cc = 11317044Smk117520 medd.med_dat_cc; 11327044Smk117520 save_medd = &medd; 11337044Smk117520 } 11347044Smk117520 } else { 11357044Smk117520 if (verbose) 11367044Smk117520 (void) printf("%s", 11377044Smk117520 gettext("Ok")); 11387044Smk117520 if (medd.med_dat_fl & MED_DFL_GOLDEN) { 11397044Smk117520 if (verbose) 11407044Smk117520 (void) printf("\t%s", 11417044Smk117520 gettext("Yes")); 11427044Smk117520 golden++; 11437044Smk117520 } else { 11447044Smk117520 if (verbose) 11457044Smk117520 (void) printf("\t%s", 11467044Smk117520 gettext("No")); 11477044Smk117520 } 11487044Smk117520 if (verbose) 11497044Smk117520 (void) printf("\n"); 11507044Smk117520 medok++; 11517044Smk117520 } 11527044Smk117520 } 11537044Smk117520 } 11547044Smk117520 if (sname == NULL) { 11557044Smk117520 /* 11567044Smk117520 * Update the latest mediator information 11577044Smk117520 * on this node 11587044Smk117520 */ 11597044Smk117520 (void) strlcpy(mdh.a_nm[0], mynode(), 11607044Smk117520 sizeof (mdh.a_nm[0])); 11617044Smk117520 if (clnt_user_med_upd_data(&mdh, obandiskset, 11627044Smk117520 setname, setnum, save_medd, ep) == -1) { 11637044Smk117520 /* 11647044Smk117520 * We had some errors while updaing the 11657044Smk117520 * record. This means this metaset is 11667044Smk117520 * not updated with latest mediator 11677044Smk117520 * information. 11687044Smk117520 */ 11697044Smk117520 mde_perror(ep, ""); 11707044Smk117520 continue; 11717044Smk117520 } 11727044Smk117520 } else { 11737044Smk117520 if (golden) { 11747044Smk117520 retval = 0; 11757044Smk117520 goto out; 11767044Smk117520 } 11777044Smk117520 if (medok < ((medrecp->med_rec_meds.n_cnt / 2) + 1)) 11787044Smk117520 retval = 1; 11797044Smk117520 } 11807044Smk117520 } 11817044Smk117520 11827044Smk117520 out: 11837044Smk117520 if (rec_buf != NULL) 11847044Smk117520 Free(rec_buf); 11857044Smk117520 if (close(fd) < 0) { 1186*8451SRameshkumar.Ramasamy@Sun.COM (void) mdsyserror(ep, errno, MED_DB_FILE); 1187*8451SRameshkumar.Ramasamy@Sun.COM mde_perror(ep, dgettext(TEXT_DOMAIN, 1188*8451SRameshkumar.Ramasamy@Sun.COM "Error in closing meddb file")); 11897044Smk117520 return (1); 11907044Smk117520 } 11917044Smk117520 return (retval); 11927044Smk117520 } 1193