xref: /onnv-gate/usr/src/lib/fm/libfmd_adm/common/fmd_adm.c (revision 11400:718b14f230ae)
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
51303Swesolows  * Common Development and Distribution License (the "License").
61303Swesolows  * 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  */
211193Smws 
220Sstevel@tonic-gate /*
239874SStephen.Hanson@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <strings.h>
280Sstevel@tonic-gate #include <stdlib.h>
290Sstevel@tonic-gate #include <netdir.h>
300Sstevel@tonic-gate #include <errno.h>
311303Swesolows #include <alloca.h>
321303Swesolows #include <locale.h>
331303Swesolows #include <uuid/uuid.h>
340Sstevel@tonic-gate 
351303Swesolows #include <sys/fm/protocol.h>
360Sstevel@tonic-gate #include <fmd_adm_impl.h>
370Sstevel@tonic-gate #include <fmd_rpc_adm.h>
380Sstevel@tonic-gate 
390Sstevel@tonic-gate static const uint_t _fmd_adm_bufsize = 128 * 1024;
401303Swesolows static const char _url_fallback[] = "http://sun.com/msg/";
410Sstevel@tonic-gate 
420Sstevel@tonic-gate fmd_adm_t *
fmd_adm_open(const char * host,uint32_t prog,int version)430Sstevel@tonic-gate fmd_adm_open(const char *host, uint32_t prog, int version)
440Sstevel@tonic-gate {
450Sstevel@tonic-gate 	fmd_adm_t *ap;
460Sstevel@tonic-gate 	CLIENT *c;
470Sstevel@tonic-gate 	rpcvers_t v;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 	if (version != FMD_ADM_VERSION) {
500Sstevel@tonic-gate 		errno = ENOTSUP;
510Sstevel@tonic-gate 		return (NULL);
520Sstevel@tonic-gate 	}
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	if (host == NULL)
550Sstevel@tonic-gate 		host = HOST_SELF;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	if (prog == FMD_ADM_PROGRAM)
580Sstevel@tonic-gate 		prog = FMD_ADM;
590Sstevel@tonic-gate 
607238Seschrock 	if ((ap = malloc(sizeof (fmd_adm_t))) == NULL)
617238Seschrock 		return (NULL);
627238Seschrock 
637238Seschrock 	if (strcmp(host, HOST_SELF) == 0) {
640Sstevel@tonic-gate 		c = clnt_door_create(prog, FMD_ADM_VERSION_1, _fmd_adm_bufsize);
657238Seschrock 		ap->adm_maxretries = 1;
667238Seschrock 	} else {
670Sstevel@tonic-gate 		c = clnt_create_vers(host, prog, &v,
680Sstevel@tonic-gate 		    FMD_ADM_VERSION_1, FMD_ADM_VERSION_1, NULL);
697238Seschrock 		ap->adm_maxretries = 0;
700Sstevel@tonic-gate 	}
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	if (c == NULL) {
730Sstevel@tonic-gate 		errno = EPROTO;
747238Seschrock 		free(ap);
750Sstevel@tonic-gate 		return (NULL);
760Sstevel@tonic-gate 	}
770Sstevel@tonic-gate 
787238Seschrock 	ap->adm_prog = prog;
790Sstevel@tonic-gate 	ap->adm_clnt = c;
800Sstevel@tonic-gate 	ap->adm_version = version;
810Sstevel@tonic-gate 	ap->adm_svcerr = 0;
820Sstevel@tonic-gate 	ap->adm_errno = 0;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	return (ap);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
870Sstevel@tonic-gate void
fmd_adm_close(fmd_adm_t * ap)880Sstevel@tonic-gate fmd_adm_close(fmd_adm_t *ap)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	if (ap == NULL)
910Sstevel@tonic-gate 		return; /* permit NULL to simply caller code */
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	clnt_destroy(ap->adm_clnt);
940Sstevel@tonic-gate 	free(ap);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate 
970Sstevel@tonic-gate static const char *
fmd_adm_svc_errmsg(enum fmd_adm_error err)980Sstevel@tonic-gate fmd_adm_svc_errmsg(enum fmd_adm_error err)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate 	switch (err) {
1010Sstevel@tonic-gate 	case FMD_ADM_ERR_NOMEM:
1020Sstevel@tonic-gate 		return ("unable to perform request due to allocation failure");
1030Sstevel@tonic-gate 	case FMD_ADM_ERR_PERM:
1040Sstevel@tonic-gate 		return ("operation requires additional privilege");
1050Sstevel@tonic-gate 	case FMD_ADM_ERR_MODSRCH:
1060Sstevel@tonic-gate 		return ("specified module is not loaded in fault manager");
1070Sstevel@tonic-gate 	case FMD_ADM_ERR_MODBUSY:
1080Sstevel@tonic-gate 		return ("module is in use and cannot be unloaded");
1090Sstevel@tonic-gate 	case FMD_ADM_ERR_MODFAIL:
1100Sstevel@tonic-gate 		return ("module failed and can no longer export statistics");
1110Sstevel@tonic-gate 	case FMD_ADM_ERR_MODNOENT:
1120Sstevel@tonic-gate 		return ("file missing or cannot be accessed by fault manager");
1130Sstevel@tonic-gate 	case FMD_ADM_ERR_MODEXIST:
1140Sstevel@tonic-gate 		return ("module using same name is already loaded");
1150Sstevel@tonic-gate 	case FMD_ADM_ERR_MODINIT:
1160Sstevel@tonic-gate 		return ("module failed to initialize (consult fmd(1M) log)");
1170Sstevel@tonic-gate 	case FMD_ADM_ERR_MODLOAD:
1180Sstevel@tonic-gate 		return ("module failed to load (consult fmd(1M) log)");
1190Sstevel@tonic-gate 	case FMD_ADM_ERR_RSRCSRCH:
1200Sstevel@tonic-gate 		return ("specified resource is not cached by fault manager");
1210Sstevel@tonic-gate 	case FMD_ADM_ERR_RSRCNOTF:
1220Sstevel@tonic-gate 		return ("specified resource is not known to be faulty");
1230Sstevel@tonic-gate 	case FMD_ADM_ERR_SERDSRCH:
1240Sstevel@tonic-gate 		return ("specified serd engine not present in module");
1250Sstevel@tonic-gate 	case FMD_ADM_ERR_SERDFIRED:
1260Sstevel@tonic-gate 		return ("specified serd engine has already fired");
1270Sstevel@tonic-gate 	case FMD_ADM_ERR_ROTSRCH:
1280Sstevel@tonic-gate 		return ("invalid log file name");
1290Sstevel@tonic-gate 	case FMD_ADM_ERR_ROTFAIL:
1300Sstevel@tonic-gate 		return ("failed to rotate log file (consult fmd(1M) log)");
1310Sstevel@tonic-gate 	case FMD_ADM_ERR_ROTBUSY:
1320Sstevel@tonic-gate 		return ("log file is too busy to rotate (try again later)");
1330Sstevel@tonic-gate 	case FMD_ADM_ERR_CASESRCH:
1340Sstevel@tonic-gate 		return ("specified UUID is invalid or has been repaired");
1350Sstevel@tonic-gate 	case FMD_ADM_ERR_CASEOPEN:
1360Sstevel@tonic-gate 		return ("specified UUID is still being diagnosed");
1371193Smws 	case FMD_ADM_ERR_XPRTSRCH:
1381193Smws 		return ("specified transport ID is invalid or has been closed");
1391193Smws 	case FMD_ADM_ERR_CASEXPRT:
1401193Smws 		return ("specified UUID is owned by a different fault manager");
1419874SStephen.Hanson@Sun.COM 	case FMD_ADM_ERR_RSRCNOTR:
1429874SStephen.Hanson@Sun.COM 		return ("specified resource has not been replaced");
1430Sstevel@tonic-gate 	default:
1440Sstevel@tonic-gate 		return ("unknown fault manager error");
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate const char *
fmd_adm_errmsg(fmd_adm_t * ap)1490Sstevel@tonic-gate fmd_adm_errmsg(fmd_adm_t *ap)
1500Sstevel@tonic-gate {
1510Sstevel@tonic-gate 	if (ap == NULL) {
1520Sstevel@tonic-gate 		switch (errno) {
1530Sstevel@tonic-gate 		case ENOTSUP:
1540Sstevel@tonic-gate 			return ("client requires newer libfmd_adm version");
1550Sstevel@tonic-gate 		case EPROTO:
1560Sstevel@tonic-gate 			return (clnt_spcreateerror("failed to connect to fmd"));
1570Sstevel@tonic-gate 		}
1580Sstevel@tonic-gate 	}
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	switch (ap ? ap->adm_errno : errno) {
1610Sstevel@tonic-gate 	case EPROTO:
1620Sstevel@tonic-gate 		return (clnt_sperror(ap->adm_clnt, "rpc call failed"));
1630Sstevel@tonic-gate 	case EREMOTE:
1640Sstevel@tonic-gate 		return (fmd_adm_svc_errmsg(ap->adm_svcerr));
1650Sstevel@tonic-gate 	default:
1660Sstevel@tonic-gate 		return (strerror(ap->adm_errno));
1670Sstevel@tonic-gate 	}
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate static int
fmd_adm_set_svcerr(fmd_adm_t * ap,enum fmd_adm_error err)1710Sstevel@tonic-gate fmd_adm_set_svcerr(fmd_adm_t *ap, enum fmd_adm_error err)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate 	if (err != 0) {
1740Sstevel@tonic-gate 		ap->adm_svcerr = err;
1750Sstevel@tonic-gate 		ap->adm_errno = EREMOTE;
1760Sstevel@tonic-gate 		return (-1);
1770Sstevel@tonic-gate 	} else {
1780Sstevel@tonic-gate 		ap->adm_svcerr = err;
1790Sstevel@tonic-gate 		ap->adm_errno = 0;
1800Sstevel@tonic-gate 		return (0);
1810Sstevel@tonic-gate 	}
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate static int
fmd_adm_set_errno(fmd_adm_t * ap,int err)1850Sstevel@tonic-gate fmd_adm_set_errno(fmd_adm_t *ap, int err)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate 	ap->adm_errno = err;
1880Sstevel@tonic-gate 	errno = err;
1890Sstevel@tonic-gate 	return (-1);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate static int
fmd_adm_stats_cmp(const void * lp,const void * rp)1930Sstevel@tonic-gate fmd_adm_stats_cmp(const void *lp, const void *rp)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate 	return (strcmp(((fmd_stat_t *)lp)->fmds_name,
1960Sstevel@tonic-gate 	    ((fmd_stat_t *)rp)->fmds_name));
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate 
1997238Seschrock /*
2007238Seschrock  * If the server (fmd) is restarted, this will cause all future door calls to
2017238Seschrock  * fail.  Unfortunately, once the server comes back up, we have no way of
2027238Seschrock  * reestablishing the connection.  To get around this, if the error indicates
2037238Seschrock  * that the RPC call failed, we reopen the client handle and try again.  For
2047238Seschrock  * simplicity we only deal with the door case, as it's unclear whether the
2057238Seschrock  * remote case suffers from the same pathology.
2067238Seschrock  */
2077238Seschrock boolean_t
fmd_adm_retry(fmd_adm_t * ap,enum clnt_stat cs,uint_t * retries)2087238Seschrock fmd_adm_retry(fmd_adm_t *ap, enum clnt_stat cs, uint_t *retries)
2097238Seschrock {
2107238Seschrock 	CLIENT *c;
2117238Seschrock 	struct rpc_err err;
2127238Seschrock 
2137238Seschrock 	if (cs == RPC_SUCCESS || *retries == ap->adm_maxretries)
2147238Seschrock 		return (B_FALSE);
2157238Seschrock 
2167238Seschrock 	clnt_geterr(ap->adm_clnt, &err);
2177238Seschrock 	if (err.re_status != RPC_CANTSEND)
2187238Seschrock 		return (B_FALSE);
2197238Seschrock 
2207238Seschrock 	if ((c = clnt_door_create(ap->adm_prog, FMD_ADM_VERSION_1,
2217238Seschrock 	    _fmd_adm_bufsize)) == NULL)
2227238Seschrock 		return (B_FALSE);
2237238Seschrock 
2247238Seschrock 	(*retries)++;
2257238Seschrock 
2267238Seschrock 	clnt_destroy(ap->adm_clnt);
2277238Seschrock 	ap->adm_clnt = c;
2287238Seschrock 
2297238Seschrock 	return (B_TRUE);
2307238Seschrock }
2317238Seschrock 
2320Sstevel@tonic-gate int
fmd_adm_stats_read(fmd_adm_t * ap,const char * name,fmd_adm_stats_t * sp)2330Sstevel@tonic-gate fmd_adm_stats_read(fmd_adm_t *ap, const char *name, fmd_adm_stats_t *sp)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate 	struct fmd_rpc_modstat rms;
2360Sstevel@tonic-gate 	enum clnt_stat cs;
2377238Seschrock 	uint_t retries = 0;
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	if (sp == NULL)
2400Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
2430Sstevel@tonic-gate 
2447238Seschrock 	do {
2457238Seschrock 		if (name != NULL)
2467238Seschrock 			cs = fmd_adm_modcstat_1((char *)name, &rms,
2477238Seschrock 			    ap->adm_clnt);
2487238Seschrock 		else
2497238Seschrock 			cs = fmd_adm_modgstat_1(&rms, ap->adm_clnt);
2507238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	if (cs != RPC_SUCCESS)
2530Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	if (rms.rms_err != 0) {
2560Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
2570Sstevel@tonic-gate 		return (fmd_adm_set_svcerr(ap, rms.rms_err));
2580Sstevel@tonic-gate 	}
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate 	sp->ams_buf = rms.rms_buf.rms_buf_val;
2610Sstevel@tonic-gate 	sp->ams_len = rms.rms_buf.rms_buf_len;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	if (sp->ams_len != 0) {
2640Sstevel@tonic-gate 		qsort(sp->ams_buf, sp->ams_len,
2650Sstevel@tonic-gate 		    sizeof (fmd_stat_t), fmd_adm_stats_cmp);
2660Sstevel@tonic-gate 	}
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	return (0);
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate int
fmd_adm_stats_free(fmd_adm_t * ap,fmd_adm_stats_t * sp)2720Sstevel@tonic-gate fmd_adm_stats_free(fmd_adm_t *ap, fmd_adm_stats_t *sp)
2730Sstevel@tonic-gate {
2740Sstevel@tonic-gate 	struct fmd_rpc_modstat rms;
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 	if (sp == NULL)
2770Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	rms.rms_buf.rms_buf_val = sp->ams_buf;
2800Sstevel@tonic-gate 	rms.rms_buf.rms_buf_len = sp->ams_len;
2810Sstevel@tonic-gate 	rms.rms_err = 0;
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
2840Sstevel@tonic-gate 	bzero(sp, sizeof (fmd_adm_stats_t));
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	return (0);
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate static int
fmd_adm_module_cmp(const void * lp,const void * rp)2900Sstevel@tonic-gate fmd_adm_module_cmp(const void *lp, const void *rp)
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate 	return (strcmp((*(struct fmd_rpc_modinfo **)lp)->rmi_name,
2930Sstevel@tonic-gate 	    (*(struct fmd_rpc_modinfo **)rp)->rmi_name));
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate int
fmd_adm_module_iter(fmd_adm_t * ap,fmd_adm_module_f * func,void * arg)2970Sstevel@tonic-gate fmd_adm_module_iter(fmd_adm_t *ap, fmd_adm_module_f *func, void *arg)
2980Sstevel@tonic-gate {
2990Sstevel@tonic-gate 	struct fmd_rpc_modinfo *rmi, **rms, **rmp;
3000Sstevel@tonic-gate 	struct fmd_rpc_modlist rml;
3010Sstevel@tonic-gate 	fmd_adm_modinfo_t ami;
3027238Seschrock 	enum clnt_stat cs;
3037238Seschrock 	uint_t retries = 0;
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	bzero(&rml, sizeof (rml)); /* tell xdr to allocate memory for us */
3060Sstevel@tonic-gate 
3077238Seschrock 	do {
3087238Seschrock 		cs = fmd_adm_modinfo_1(&rml, ap->adm_clnt);
3097238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
3107238Seschrock 
3117238Seschrock 	if (cs != RPC_SUCCESS)
3120Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	if (rml.rml_err != 0 || rml.rml_len == 0) {
3150Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
3160Sstevel@tonic-gate 		return (fmd_adm_set_svcerr(ap, rml.rml_err));
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	if ((rms = rmp = malloc(sizeof (void *) * rml.rml_len)) == NULL) {
3200Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
3210Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EAGAIN));
3220Sstevel@tonic-gate 	}
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	for (rmi = rml.rml_list; rmi != NULL; rmi = rmi->rmi_next)
3250Sstevel@tonic-gate 		*rmp++ = rmi; /* store copy of pointer in array for sorting */
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 	qsort(rms, rml.rml_len, sizeof (void *), fmd_adm_module_cmp);
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	for (rmp = rms; rmp < rms + rml.rml_len; rmp++) {
3300Sstevel@tonic-gate 		rmi = *rmp;
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 		ami.ami_name = rmi->rmi_name;
3330Sstevel@tonic-gate 		ami.ami_desc = rmi->rmi_desc;
3340Sstevel@tonic-gate 		ami.ami_vers = rmi->rmi_vers;
3350Sstevel@tonic-gate 		ami.ami_flags = 0;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		if (rmi->rmi_faulty)
3380Sstevel@tonic-gate 			ami.ami_flags |= FMD_ADM_MOD_FAILED;
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 		if (func(&ami, arg) != 0)
3410Sstevel@tonic-gate 			break;
3420Sstevel@tonic-gate 	}
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	free(rms);
3450Sstevel@tonic-gate 	xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
3460Sstevel@tonic-gate 	return (0);
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate int
fmd_adm_module_load(fmd_adm_t * ap,const char * path)3500Sstevel@tonic-gate fmd_adm_module_load(fmd_adm_t *ap, const char *path)
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate 	char *str = (char *)path;
3530Sstevel@tonic-gate 	int err;
3547238Seschrock 	enum clnt_stat cs;
3557238Seschrock 	uint_t retries = 0;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	if (path == NULL || path[0] != '/')
3580Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
3590Sstevel@tonic-gate 
3607238Seschrock 	do {
3617238Seschrock 		cs = fmd_adm_modload_1(str, &err, ap->adm_clnt);
3627238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
3637238Seschrock 
3647238Seschrock 	if (cs != RPC_SUCCESS)
3650Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate int
fmd_adm_module_unload(fmd_adm_t * ap,const char * name)3710Sstevel@tonic-gate fmd_adm_module_unload(fmd_adm_t *ap, const char *name)
3720Sstevel@tonic-gate {
3730Sstevel@tonic-gate 	char *str = (char *)name;
3740Sstevel@tonic-gate 	int err;
3757238Seschrock 	enum clnt_stat cs;
3767238Seschrock 	uint_t retries = 0;
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 	if (name == NULL || strchr(name, '/') != NULL)
3790Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
3800Sstevel@tonic-gate 
3817238Seschrock 	do {
3827238Seschrock 		cs = fmd_adm_modunload_1(str, &err, ap->adm_clnt);
3837238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
3847238Seschrock 
3857238Seschrock 	if (cs != RPC_SUCCESS)
3860Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate int
fmd_adm_module_reset(fmd_adm_t * ap,const char * name)3920Sstevel@tonic-gate fmd_adm_module_reset(fmd_adm_t *ap, const char *name)
3930Sstevel@tonic-gate {
3940Sstevel@tonic-gate 	char *str = (char *)name;
3950Sstevel@tonic-gate 	int err;
3967238Seschrock 	enum clnt_stat cs;
3977238Seschrock 	uint_t retries = 0;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	if (name == NULL || strchr(name, '/') != NULL)
4000Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
4010Sstevel@tonic-gate 
4027238Seschrock 	do {
4037238Seschrock 		cs = fmd_adm_modreset_1(str, &err, ap->adm_clnt);
4047238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
4057238Seschrock 
4067238Seschrock 	if (cs != RPC_SUCCESS)
4070Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate int
fmd_adm_module_gc(fmd_adm_t * ap,const char * name)4130Sstevel@tonic-gate fmd_adm_module_gc(fmd_adm_t *ap, const char *name)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate 	char *str = (char *)name;
4160Sstevel@tonic-gate 	int err;
4177238Seschrock 	enum clnt_stat cs;
4187238Seschrock 	uint_t retries = 0;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	if (name == NULL || strchr(name, '/') != NULL)
4210Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
4220Sstevel@tonic-gate 
4237238Seschrock 	do {
4247238Seschrock 		cs = fmd_adm_modgc_1(str, &err, ap->adm_clnt);
4257238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
4267238Seschrock 
4277238Seschrock 	if (cs != RPC_SUCCESS)
4280Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate int
fmd_adm_module_stats(fmd_adm_t * ap,const char * name,fmd_adm_stats_t * sp)4340Sstevel@tonic-gate fmd_adm_module_stats(fmd_adm_t *ap, const char *name, fmd_adm_stats_t *sp)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate 	struct fmd_rpc_modstat rms;
4377238Seschrock 	enum clnt_stat cs;
4387238Seschrock 	uint_t retries = 0;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	if (name == NULL || sp == NULL)
4410Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
4440Sstevel@tonic-gate 
4457238Seschrock 	do {
4467238Seschrock 		cs = fmd_adm_moddstat_1((char *)name, &rms, ap->adm_clnt);
4477238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
4487238Seschrock 
4497238Seschrock 	if (cs != RPC_SUCCESS)
4500Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	if (rms.rms_err != 0) {
4530Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
4540Sstevel@tonic-gate 		return (fmd_adm_set_svcerr(ap, rms.rms_err));
4550Sstevel@tonic-gate 	}
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 	sp->ams_buf = rms.rms_buf.rms_buf_val;
4580Sstevel@tonic-gate 	sp->ams_len = rms.rms_buf.rms_buf_len;
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate 	return (0);
4610Sstevel@tonic-gate }
4620Sstevel@tonic-gate 
4631303Swesolows int
fmd_adm_rsrc_count(fmd_adm_t * ap,int all,uint32_t * rcp)4641303Swesolows fmd_adm_rsrc_count(fmd_adm_t *ap, int all, uint32_t *rcp)
4651303Swesolows {
4661303Swesolows 	struct fmd_rpc_rsrclist rrl;
4677238Seschrock 	enum clnt_stat cs;
4687238Seschrock 	uint_t retries = 0;
4691303Swesolows 
4701303Swesolows 	if (rcp == NULL)
4711303Swesolows 		return (fmd_adm_set_errno(ap, EINVAL));
4721303Swesolows 
4731303Swesolows 	bzero(&rrl, sizeof (rrl)); /* tell xdr to allocate memory for us */
4741303Swesolows 
4757238Seschrock 	do {
4767238Seschrock 		cs = fmd_adm_rsrclist_1(all, &rrl, ap->adm_clnt);
4777238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
4787238Seschrock 
4797238Seschrock 	if (cs != RPC_SUCCESS)
4801303Swesolows 		return (fmd_adm_set_errno(ap, EPROTO));
4811303Swesolows 
4821303Swesolows 	if (rrl.rrl_err != 0) {
4831303Swesolows 		xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
4841303Swesolows 		return (fmd_adm_set_svcerr(ap, rrl.rrl_err));
4851303Swesolows 	}
4861303Swesolows 
4871303Swesolows 	*rcp = rrl.rrl_cnt;
4881303Swesolows 	xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
4891303Swesolows 	return (0);
4901303Swesolows }
4911303Swesolows 
4920Sstevel@tonic-gate static int
fmd_adm_rsrc_cmp(const void * lp,const void * rp)4930Sstevel@tonic-gate fmd_adm_rsrc_cmp(const void *lp, const void *rp)
4940Sstevel@tonic-gate {
4950Sstevel@tonic-gate 	return (strcmp(*(char **)lp, *(char **)rp));
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate int
fmd_adm_rsrc_iter(fmd_adm_t * ap,int all,fmd_adm_rsrc_f * func,void * arg)4990Sstevel@tonic-gate fmd_adm_rsrc_iter(fmd_adm_t *ap, int all, fmd_adm_rsrc_f *func, void *arg)
5000Sstevel@tonic-gate {
5010Sstevel@tonic-gate 	struct fmd_rpc_rsrclist rrl;
5020Sstevel@tonic-gate 	struct fmd_rpc_rsrcinfo rri;
5030Sstevel@tonic-gate 	fmd_adm_rsrcinfo_t ari;
5040Sstevel@tonic-gate 	char **fmris, *p;
5050Sstevel@tonic-gate 	int i, rv;
5067238Seschrock 	enum clnt_stat cs;
5077238Seschrock 	uint_t retries = 0;
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	bzero(&rrl, sizeof (rrl)); /* tell xdr to allocate memory for us */
5100Sstevel@tonic-gate 
5117238Seschrock 	do {
5127238Seschrock 		cs = fmd_adm_rsrclist_1(all, &rrl, ap->adm_clnt);
5137238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
5147238Seschrock 
5157238Seschrock 	if (cs != RPC_SUCCESS)
5160Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 	if (rrl.rrl_err != 0) {
5190Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
5200Sstevel@tonic-gate 		return (fmd_adm_set_svcerr(ap, rrl.rrl_err));
5210Sstevel@tonic-gate 	}
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 	if ((fmris = malloc(sizeof (char *) * rrl.rrl_cnt)) == NULL) {
5240Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
5250Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EAGAIN));
5260Sstevel@tonic-gate 	}
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	/*
5290Sstevel@tonic-gate 	 * The fmd_adm_rsrclist_1 request returns an opaque XDR buffer that is
5300Sstevel@tonic-gate 	 * a string table of FMRIs (e.g. "fmriA\0fmriB\0...") where rrl_cnt is
5310Sstevel@tonic-gate 	 * the number of strings in the table and rrl_buf_val is its address.
5320Sstevel@tonic-gate 	 * We construct an array of pointers into the string table and sort it.
5330Sstevel@tonic-gate 	 */
5340Sstevel@tonic-gate 	p = rrl.rrl_buf.rrl_buf_val;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 	for (i = 0; i < rrl.rrl_cnt; i++, p += strlen(p) + 1)
5370Sstevel@tonic-gate 		fmris[i] = p; /* store fmri pointer in array for sorting */
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 	qsort(fmris, rrl.rrl_cnt, sizeof (char *), fmd_adm_rsrc_cmp);
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 	/*
5420Sstevel@tonic-gate 	 * For each FMRI in the resource cache snapshot, use fmd_adm_rsrcinfo_1
5430Sstevel@tonic-gate 	 * to get more information and the invoke the callback function.  If
5440Sstevel@tonic-gate 	 * FMD_ADM_ERR_RSRCSRCH is returned, the FMRI has been purged from the
5450Sstevel@tonic-gate 	 * cache since our snapshot: this error is therefore silently ignored.
5460Sstevel@tonic-gate 	 */
5470Sstevel@tonic-gate 	for (i = 0; i < rrl.rrl_cnt; i++) {
5480Sstevel@tonic-gate 		bzero(&rri, sizeof (rri));
5490Sstevel@tonic-gate 
5507238Seschrock 		retries = 0;
5517238Seschrock 		do {
5527238Seschrock 			cs = fmd_adm_rsrcinfo_1(fmris[i], &rri, ap->adm_clnt);
5537238Seschrock 		} while (fmd_adm_retry(ap, cs, &retries));
5547238Seschrock 
5557238Seschrock 		if (cs != RPC_SUCCESS) {
5560Sstevel@tonic-gate 			free(fmris);
5570Sstevel@tonic-gate 			xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
5580Sstevel@tonic-gate 			return (fmd_adm_set_errno(ap, EPROTO));
5590Sstevel@tonic-gate 		}
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 		if (rri.rri_err != 0 && rri.rri_err != FMD_ADM_ERR_RSRCSRCH) {
5620Sstevel@tonic-gate 			xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
5630Sstevel@tonic-gate 			free(fmris);
5640Sstevel@tonic-gate 			xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
5650Sstevel@tonic-gate 			return (fmd_adm_set_svcerr(ap, rri.rri_err));
5660Sstevel@tonic-gate 		}
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate 		if (rri.rri_err == FMD_ADM_ERR_RSRCSRCH) {
5690Sstevel@tonic-gate 			xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
5700Sstevel@tonic-gate 			continue;
5710Sstevel@tonic-gate 		}
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate 		ari.ari_fmri = rri.rri_fmri;
5740Sstevel@tonic-gate 		ari.ari_uuid = rri.rri_uuid;
5750Sstevel@tonic-gate 		ari.ari_case = rri.rri_case;
5760Sstevel@tonic-gate 		ari.ari_flags = 0;
5770Sstevel@tonic-gate 
5780Sstevel@tonic-gate 		if (rri.rri_faulty)
5790Sstevel@tonic-gate 			ari.ari_flags |= FMD_ADM_RSRC_FAULTY;
5800Sstevel@tonic-gate 		if (rri.rri_unusable)
5810Sstevel@tonic-gate 			ari.ari_flags |= FMD_ADM_RSRC_UNUSABLE;
5820Sstevel@tonic-gate 		if (rri.rri_invisible)
5830Sstevel@tonic-gate 			ari.ari_flags |= FMD_ADM_RSRC_INVISIBLE;
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate 		rv = func(&ari, arg);
5860Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
5870Sstevel@tonic-gate 
5880Sstevel@tonic-gate 		if (rv != 0)
5890Sstevel@tonic-gate 			break;
5900Sstevel@tonic-gate 	}
5910Sstevel@tonic-gate 
5920Sstevel@tonic-gate 	free(fmris);
5930Sstevel@tonic-gate 	xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
5940Sstevel@tonic-gate 	return (0);
5950Sstevel@tonic-gate }
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate int
fmd_adm_rsrc_flush(fmd_adm_t * ap,const char * fmri)5980Sstevel@tonic-gate fmd_adm_rsrc_flush(fmd_adm_t *ap, const char *fmri)
5990Sstevel@tonic-gate {
6000Sstevel@tonic-gate 	char *str = (char *)fmri;
6010Sstevel@tonic-gate 	int err;
6027238Seschrock 	enum clnt_stat cs;
6037238Seschrock 	uint_t retries = 0;
6040Sstevel@tonic-gate 
6050Sstevel@tonic-gate 	if (fmri == NULL)
6060Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
6070Sstevel@tonic-gate 
6087238Seschrock 	do {
6097238Seschrock 		cs = fmd_adm_rsrcflush_1(str, &err, ap->adm_clnt);
6107238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
6117238Seschrock 
6127238Seschrock 	if (cs != RPC_SUCCESS)
6130Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
6140Sstevel@tonic-gate 
6150Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate int
fmd_adm_rsrc_repaired(fmd_adm_t * ap,const char * fmri)6197275Sstephh fmd_adm_rsrc_repaired(fmd_adm_t *ap, const char *fmri)
6200Sstevel@tonic-gate {
6210Sstevel@tonic-gate 	char *str = (char *)fmri;
6220Sstevel@tonic-gate 	int err;
6237238Seschrock 	enum clnt_stat cs;
6247238Seschrock 	uint_t retries = 0;
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	if (fmri == NULL)
6270Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
6280Sstevel@tonic-gate 
6297238Seschrock 	do {
6307275Sstephh 		cs = fmd_adm_rsrcrepaired_1(str, &err, ap->adm_clnt);
6317275Sstephh 	} while (fmd_adm_retry(ap, cs, &retries));
6327275Sstephh 
6337275Sstephh 	if (cs != RPC_SUCCESS)
6347275Sstephh 		return (fmd_adm_set_errno(ap, EPROTO));
6357275Sstephh 
6367275Sstephh 	return (fmd_adm_set_svcerr(ap, err));
6377275Sstephh }
6387275Sstephh 
6397275Sstephh int
fmd_adm_rsrc_replaced(fmd_adm_t * ap,const char * fmri)6407275Sstephh fmd_adm_rsrc_replaced(fmd_adm_t *ap, const char *fmri)
6417275Sstephh {
6427275Sstephh 	char *str = (char *)fmri;
6437275Sstephh 	int err;
6447275Sstephh 	enum clnt_stat cs;
6457275Sstephh 	uint_t retries = 0;
6467275Sstephh 
6477275Sstephh 	if (fmri == NULL)
6487275Sstephh 		return (fmd_adm_set_errno(ap, EINVAL));
6497275Sstephh 
6507275Sstephh 	do {
6517275Sstephh 		cs = fmd_adm_rsrcreplaced_1(str, &err, ap->adm_clnt);
6527275Sstephh 	} while (fmd_adm_retry(ap, cs, &retries));
6537275Sstephh 
6547275Sstephh 	if (cs != RPC_SUCCESS)
6557275Sstephh 		return (fmd_adm_set_errno(ap, EPROTO));
6567275Sstephh 
6577275Sstephh 	return (fmd_adm_set_svcerr(ap, err));
6587275Sstephh }
6597275Sstephh 
6607275Sstephh int
fmd_adm_rsrc_acquit(fmd_adm_t * ap,const char * fmri,const char * uuid)6617275Sstephh fmd_adm_rsrc_acquit(fmd_adm_t *ap, const char *fmri, const char *uuid)
6627275Sstephh {
6637275Sstephh 	char *str = (char *)fmri;
6647275Sstephh 	char *str2 = (char *)uuid;
6657275Sstephh 	int err;
6667275Sstephh 	enum clnt_stat cs;
6677275Sstephh 	uint_t retries = 0;
6687275Sstephh 
6697275Sstephh 	if (fmri == NULL)
6707275Sstephh 		return (fmd_adm_set_errno(ap, EINVAL));
6717275Sstephh 
6727275Sstephh 	do {
6737275Sstephh 		cs = fmd_adm_rsrcacquit_1(str, str2, &err, ap->adm_clnt);
6747238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
6757238Seschrock 
6767238Seschrock 	if (cs != RPC_SUCCESS)
6770Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate int
fmd_adm_case_repair(fmd_adm_t * ap,const char * uuid)6830Sstevel@tonic-gate fmd_adm_case_repair(fmd_adm_t *ap, const char *uuid)
6840Sstevel@tonic-gate {
6850Sstevel@tonic-gate 	char *str = (char *)uuid;
6860Sstevel@tonic-gate 	int err;
6877238Seschrock 	enum clnt_stat cs;
6887238Seschrock 	uint_t retries = 0;
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 	if (uuid == NULL)
6910Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
6920Sstevel@tonic-gate 
6937238Seschrock 	do {
6947238Seschrock 		cs = fmd_adm_caserepair_1(str, &err, ap->adm_clnt);
6957238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
6967238Seschrock 
6977238Seschrock 	if (cs != RPC_SUCCESS)
6980Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate 
7037275Sstephh int
fmd_adm_case_acquit(fmd_adm_t * ap,const char * uuid)7047275Sstephh fmd_adm_case_acquit(fmd_adm_t *ap, const char *uuid)
7057275Sstephh {
7067275Sstephh 	char *str = (char *)uuid;
7077275Sstephh 	int err;
7087275Sstephh 	enum clnt_stat cs;
7097275Sstephh 	uint_t retries = 0;
7107275Sstephh 
7117275Sstephh 	if (uuid == NULL)
7127275Sstephh 		return (fmd_adm_set_errno(ap, EINVAL));
7137275Sstephh 
7147275Sstephh 	do {
7157275Sstephh 		cs = fmd_adm_caseacquit_1(str, &err, ap->adm_clnt);
7167275Sstephh 	} while (fmd_adm_retry(ap, cs, &retries));
7177275Sstephh 
7187275Sstephh 	if (cs != RPC_SUCCESS)
7197275Sstephh 		return (fmd_adm_set_errno(ap, EPROTO));
7207275Sstephh 
7217275Sstephh 	return (fmd_adm_set_svcerr(ap, err));
7227275Sstephh }
7237275Sstephh 
7240Sstevel@tonic-gate static int
fmd_adm_case_cmp(const void * lp,const void * rp)7251303Swesolows fmd_adm_case_cmp(const void *lp, const void *rp)
7261303Swesolows {
7271303Swesolows 	return (strcmp(*(char **)lp, *(char **)rp));
7281303Swesolows }
7291303Swesolows 
7301303Swesolows static int
fmd_adm_case_one(fmd_adm_caseinfo_t * acp,const char * url_token,fmd_adm_case_f * func,void * arg)7311303Swesolows fmd_adm_case_one(fmd_adm_caseinfo_t *acp, const char *url_token,
7321303Swesolows     fmd_adm_case_f *func, void *arg)
7331303Swesolows {
7341303Swesolows 	char *p, *urlcode, *dict, *olang;
7351303Swesolows 	const char *url;
7361303Swesolows 	size_t	len;
7371303Swesolows 
7381303Swesolows 	if ((p = strchr(acp->aci_code, '-')) == NULL ||
7391303Swesolows 	    p == acp->aci_code) {
7401303Swesolows 		acp->aci_url = NULL;
7411303Swesolows 	} else {
7421303Swesolows 		dict = alloca((size_t)(p - acp->aci_code) + 1);
7431303Swesolows 		(void) strncpy(dict, acp->aci_code,
7441303Swesolows 		    (size_t)(p - acp->aci_code));
7451303Swesolows 		dict[(size_t)(p - acp->aci_code)] = '\0';
7461303Swesolows 
7471303Swesolows 		/*
7481303Swesolows 		 * If we're given a token to use in looking up the URL, try
7491303Swesolows 		 * to use it.  Otherwise, or if we don't find it that way,
7501303Swesolows 		 * use the fallback.
7511303Swesolows 		 */
7521303Swesolows 		if (url_token == NULL) {
7531303Swesolows 			url = _url_fallback;
7541303Swesolows 		} else if ((url = dgettext(dict, url_token)) == url_token) {
7551303Swesolows 			/*
7561303Swesolows 			 * We didn't find a translation in the
7571303Swesolows 			 * dictionary for the current language.  Fall
7581303Swesolows 			 * back to C and try again.
7591303Swesolows 			 */
7601303Swesolows 			olang = setlocale(LC_MESSAGES, NULL);
7611303Swesolows 			(void) setlocale(LC_MESSAGES, "C");
7621303Swesolows 			if ((url = dgettext(dict, url_token)) == url_token)
7631303Swesolows 				url = _url_fallback;
7641303Swesolows 			(void) setlocale(LC_MESSAGES, olang);
7651303Swesolows 		}
7661303Swesolows 		len = strlen(url);
7671303Swesolows 		if (url[len - 1] == '/') {
7681303Swesolows 			len += strlen(acp->aci_code) + 1;
7691303Swesolows 			urlcode = alloca(len);
7701303Swesolows 			(void) snprintf(urlcode, len, "%s%s", url,
7711303Swesolows 			    acp->aci_code);
7721303Swesolows 		} else {
7731303Swesolows 			urlcode = (char *)url;
7741303Swesolows 		}
7751303Swesolows 		acp->aci_url = urlcode;
7761303Swesolows 	}
7771303Swesolows 
7781303Swesolows 	return (func(acp, arg));
7791303Swesolows }
7801303Swesolows 
7811303Swesolows /*
7821303Swesolows  * Our approach to cases is the same as for resources: we first obtain a
7831303Swesolows  * list of UUIDs, sort them, then obtain the case information for each.
7841303Swesolows  */
7851303Swesolows int
fmd_adm_case_iter(fmd_adm_t * ap,const char * url_token,fmd_adm_case_f * func,void * arg)7861303Swesolows fmd_adm_case_iter(fmd_adm_t *ap, const char *url_token, fmd_adm_case_f *func,
7871303Swesolows     void *arg)
7881303Swesolows {
7891303Swesolows 	struct fmd_rpc_caselist rcl;
7901303Swesolows 	struct fmd_rpc_caseinfo rci;
7911303Swesolows 	fmd_adm_caseinfo_t aci;
7921303Swesolows 	char **uuids, *p;
7931303Swesolows 	int i, rv;
7947238Seschrock 	enum clnt_stat cs;
7957238Seschrock 	uint_t retries = 0;
7961303Swesolows 
7971303Swesolows 	bzero(&rcl, sizeof (rcl)); /* tell xdr to allocate memory for us */
7981303Swesolows 
7997238Seschrock 	do {
8007238Seschrock 		cs = fmd_adm_caselist_1(&rcl, ap->adm_clnt);
8017238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
8027238Seschrock 
8037238Seschrock 	if (cs != RPC_SUCCESS)
8041303Swesolows 		return (fmd_adm_set_errno(ap, EPROTO));
8051303Swesolows 
8061303Swesolows 	if (rcl.rcl_err != 0) {
8071303Swesolows 		xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8081303Swesolows 		return (fmd_adm_set_svcerr(ap, rcl.rcl_err));
8091303Swesolows 	}
8101303Swesolows 
8111303Swesolows 	if ((uuids = malloc(sizeof (char *) * rcl.rcl_cnt)) == NULL) {
8121303Swesolows 		xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8131303Swesolows 		return (fmd_adm_set_errno(ap, EAGAIN));
8141303Swesolows 	}
8151303Swesolows 
8161303Swesolows 	p = rcl.rcl_buf.rcl_buf_val;
8171303Swesolows 
8181303Swesolows 	for (i = 0; i < rcl.rcl_cnt; i++, p += strlen(p) + 1)
8191303Swesolows 		uuids[i] = p;
8201303Swesolows 
8211303Swesolows 	qsort(uuids, rcl.rcl_cnt, sizeof (char *), fmd_adm_case_cmp);
8221303Swesolows 
8231303Swesolows 	for (i = 0; i < rcl.rcl_cnt; i++) {
8241303Swesolows 		bzero(&rci, sizeof (rci));
8251303Swesolows 
8267238Seschrock 		retries = 0;
8277238Seschrock 		do {
8287238Seschrock 			cs = fmd_adm_caseinfo_1(uuids[i], &rci, ap->adm_clnt);
8297238Seschrock 		} while (fmd_adm_retry(ap, cs, &retries));
8307238Seschrock 
8317238Seschrock 		if (cs != RPC_SUCCESS) {
8321303Swesolows 			free(uuids);
8331303Swesolows 			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8341303Swesolows 			return (fmd_adm_set_errno(ap, EPROTO));
8351303Swesolows 		}
8361303Swesolows 
8371303Swesolows 		if (rci.rci_err != 0 && rci.rci_err != FMD_ADM_ERR_CASESRCH) {
8381303Swesolows 			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8391303Swesolows 			free(uuids);
8401303Swesolows 			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8411303Swesolows 			return (fmd_adm_set_svcerr(ap, rci.rci_err));
8421303Swesolows 		}
8431303Swesolows 
8441303Swesolows 		if (rci.rci_err == FMD_ADM_ERR_CASESRCH) {
8451303Swesolows 			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8461303Swesolows 			continue;
8471303Swesolows 		}
8481303Swesolows 
8491303Swesolows 		bzero(&aci, sizeof (aci));
8501303Swesolows 
8511303Swesolows 		if ((rv = nvlist_unpack(rci.rci_evbuf.rci_evbuf_val,
8521303Swesolows 		    rci.rci_evbuf.rci_evbuf_len, &aci.aci_event, 0)) != 0) {
8531303Swesolows 			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8541303Swesolows 			free(uuids);
8551303Swesolows 			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8561303Swesolows 			return (fmd_adm_set_errno(ap, rv));
8571303Swesolows 		}
8581303Swesolows 
8591303Swesolows 		if ((rv = nvlist_lookup_string(aci.aci_event, FM_SUSPECT_UUID,
8601303Swesolows 		    (char **)&aci.aci_uuid)) != 0) {
8611303Swesolows 			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8621303Swesolows 			free(uuids);
8631303Swesolows 			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8641303Swesolows 			nvlist_free(aci.aci_event);
8651303Swesolows 			return (fmd_adm_set_errno(ap, rv));
8661303Swesolows 		}
8671303Swesolows 		if ((rv = nvlist_lookup_string(aci.aci_event,
8681303Swesolows 		    FM_SUSPECT_DIAG_CODE, (char **)&aci.aci_code)) != 0) {
8691303Swesolows 			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8701303Swesolows 			free(uuids);
8711303Swesolows 			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8721303Swesolows 			nvlist_free(aci.aci_event);
8731303Swesolows 			return (fmd_adm_set_errno(ap, rv));
8741303Swesolows 		}
8751303Swesolows 
8761303Swesolows 		rv = fmd_adm_case_one(&aci, url_token, func, arg);
8771303Swesolows 
8781303Swesolows 		xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
8791303Swesolows 		nvlist_free(aci.aci_event);
8801303Swesolows 
8811303Swesolows 		if (rv != 0)
8821303Swesolows 			break;
8831303Swesolows 	}
8841303Swesolows 
8851303Swesolows 	free(uuids);
8861303Swesolows 	xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
8871303Swesolows 	return (0);
8881303Swesolows }
8891303Swesolows 
8901303Swesolows static int
fmd_adm_serd_cmp(const void * lp,const void * rp)8910Sstevel@tonic-gate fmd_adm_serd_cmp(const void *lp, const void *rp)
8920Sstevel@tonic-gate {
893*11400SJakub.Jermar@Sun.COM 	return (strcmp(*(char **)lp, *(char **)rp));
8940Sstevel@tonic-gate }
8950Sstevel@tonic-gate 
8960Sstevel@tonic-gate int
fmd_adm_serd_iter(fmd_adm_t * ap,const char * name,fmd_adm_serd_f * func,void * arg)8970Sstevel@tonic-gate fmd_adm_serd_iter(fmd_adm_t *ap, const char *name,
8980Sstevel@tonic-gate     fmd_adm_serd_f *func, void *arg)
8990Sstevel@tonic-gate {
9000Sstevel@tonic-gate 	struct fmd_rpc_serdlist rsl;
901*11400SJakub.Jermar@Sun.COM 	struct fmd_rpc_serdinfo rsi;
902*11400SJakub.Jermar@Sun.COM 	char **serds, *p;
9030Sstevel@tonic-gate 	fmd_adm_serdinfo_t asi;
9047238Seschrock 	enum clnt_stat cs;
9057238Seschrock 	uint_t retries = 0;
906*11400SJakub.Jermar@Sun.COM 	int i, rv;
9070Sstevel@tonic-gate 
9080Sstevel@tonic-gate 	bzero(&rsl, sizeof (rsl)); /* tell xdr to allocate memory for us */
9090Sstevel@tonic-gate 
9107238Seschrock 	do {
911*11400SJakub.Jermar@Sun.COM 		cs = fmd_adm_serdlist_1((char *)name, &rsl, ap->adm_clnt);
9127238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
9137238Seschrock 
9147238Seschrock 	if (cs != RPC_SUCCESS)
9150Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
9160Sstevel@tonic-gate 
9170Sstevel@tonic-gate 	if (rsl.rsl_err != 0 || rsl.rsl_len == 0) {
9180Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
9190Sstevel@tonic-gate 		return (fmd_adm_set_svcerr(ap, rsl.rsl_err));
9200Sstevel@tonic-gate 	}
9210Sstevel@tonic-gate 
922*11400SJakub.Jermar@Sun.COM 	if ((serds = malloc(sizeof (char *) * rsl.rsl_cnt)) == NULL) {
9230Sstevel@tonic-gate 		xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
9240Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EAGAIN));
9250Sstevel@tonic-gate 	}
9260Sstevel@tonic-gate 
927*11400SJakub.Jermar@Sun.COM 	p = rsl.rsl_buf.rsl_buf_val;
928*11400SJakub.Jermar@Sun.COM 
929*11400SJakub.Jermar@Sun.COM 	for (i = 0; i < rsl.rsl_cnt; i++, p += strlen(p) + 1)
930*11400SJakub.Jermar@Sun.COM 		serds[i] = p;
931*11400SJakub.Jermar@Sun.COM 
932*11400SJakub.Jermar@Sun.COM 	qsort(serds, rsl.rsl_cnt, sizeof (char *), fmd_adm_serd_cmp);
9330Sstevel@tonic-gate 
934*11400SJakub.Jermar@Sun.COM 	for (i = 0; i < rsl.rsl_cnt; i++) {
935*11400SJakub.Jermar@Sun.COM 		bzero(&rsi, sizeof (rsi));
936*11400SJakub.Jermar@Sun.COM 
937*11400SJakub.Jermar@Sun.COM 		retries = 0;
938*11400SJakub.Jermar@Sun.COM 		do {
939*11400SJakub.Jermar@Sun.COM 			cs = fmd_adm_serdinfo_1((char *)name, serds[i], &rsi,
940*11400SJakub.Jermar@Sun.COM 			    ap->adm_clnt);
941*11400SJakub.Jermar@Sun.COM 		} while (fmd_adm_retry(ap, cs, &retries));
9420Sstevel@tonic-gate 
943*11400SJakub.Jermar@Sun.COM 		if (cs != RPC_SUCCESS) {
944*11400SJakub.Jermar@Sun.COM 			free(serds);
945*11400SJakub.Jermar@Sun.COM 			xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
946*11400SJakub.Jermar@Sun.COM 			return (fmd_adm_set_errno(ap, EPROTO));
947*11400SJakub.Jermar@Sun.COM 		}
948*11400SJakub.Jermar@Sun.COM 
949*11400SJakub.Jermar@Sun.COM 		if (rsi.rsi_err != 0 && rsi.rsi_err != FMD_ADM_ERR_SERDSRCH) {
950*11400SJakub.Jermar@Sun.COM 			free(serds);
951*11400SJakub.Jermar@Sun.COM 			xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
952*11400SJakub.Jermar@Sun.COM 			xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
953*11400SJakub.Jermar@Sun.COM 			return (fmd_adm_set_svcerr(ap, rsi.rsi_err));
954*11400SJakub.Jermar@Sun.COM 		}
9550Sstevel@tonic-gate 
956*11400SJakub.Jermar@Sun.COM 		if (rsi.rsi_err == FMD_ADM_ERR_SERDSRCH) {
957*11400SJakub.Jermar@Sun.COM 			xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
958*11400SJakub.Jermar@Sun.COM 			continue;
959*11400SJakub.Jermar@Sun.COM 		}
960*11400SJakub.Jermar@Sun.COM 
961*11400SJakub.Jermar@Sun.COM 		bzero(&asi, sizeof (asi));
962*11400SJakub.Jermar@Sun.COM 
963*11400SJakub.Jermar@Sun.COM 		asi.asi_name = rsi.rsi_name;
964*11400SJakub.Jermar@Sun.COM 		asi.asi_delta = rsi.rsi_delta;
965*11400SJakub.Jermar@Sun.COM 		asi.asi_n = rsi.rsi_n;
966*11400SJakub.Jermar@Sun.COM 		asi.asi_t = rsi.rsi_t;
967*11400SJakub.Jermar@Sun.COM 		asi.asi_count = rsi.rsi_count;
9680Sstevel@tonic-gate 		asi.asi_flags = 0;
9690Sstevel@tonic-gate 
970*11400SJakub.Jermar@Sun.COM 		if (rsi.rsi_fired)
9710Sstevel@tonic-gate 			asi.asi_flags |= FMD_ADM_SERD_FIRED;
9720Sstevel@tonic-gate 
973*11400SJakub.Jermar@Sun.COM 		rv = func(&asi, arg);
974*11400SJakub.Jermar@Sun.COM 
975*11400SJakub.Jermar@Sun.COM 		xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
976*11400SJakub.Jermar@Sun.COM 
977*11400SJakub.Jermar@Sun.COM 		if (rv != 0)
9780Sstevel@tonic-gate 			break;
9790Sstevel@tonic-gate 	}
9800Sstevel@tonic-gate 
981*11400SJakub.Jermar@Sun.COM 	free(serds);
9820Sstevel@tonic-gate 	xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
9830Sstevel@tonic-gate 	return (0);
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate int
fmd_adm_serd_reset(fmd_adm_t * ap,const char * mod,const char * name)9870Sstevel@tonic-gate fmd_adm_serd_reset(fmd_adm_t *ap, const char *mod, const char *name)
9880Sstevel@tonic-gate {
9890Sstevel@tonic-gate 	char *s1 = (char *)mod, *s2 = (char *)name;
9900Sstevel@tonic-gate 	int err;
9917238Seschrock 	enum clnt_stat cs;
9927238Seschrock 	uint_t retries = 0;
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate 	if (mod == NULL || name == NULL || strchr(mod, '/') != NULL)
9950Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
9960Sstevel@tonic-gate 
9977238Seschrock 	do {
9987238Seschrock 		cs = fmd_adm_serdreset_1(s1, s2, &err, ap->adm_clnt);
9997238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
10007238Seschrock 
10017238Seschrock 	if (cs != RPC_SUCCESS)
10020Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
10030Sstevel@tonic-gate 
10040Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
10050Sstevel@tonic-gate }
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate int
fmd_adm_xprt_iter(fmd_adm_t * ap,fmd_adm_xprt_f * func,void * arg)10081193Smws fmd_adm_xprt_iter(fmd_adm_t *ap, fmd_adm_xprt_f *func, void *arg)
10091193Smws {
10101193Smws 	struct fmd_rpc_xprtlist rxl;
10111193Smws 	uint_t i;
10127238Seschrock 	enum clnt_stat cs;
10137238Seschrock 	uint_t retries = 0;
10141193Smws 
10151193Smws 	bzero(&rxl, sizeof (rxl)); /* tell xdr to allocate memory for us */
10161193Smws 
10177238Seschrock 	do {
10187238Seschrock 		cs = fmd_adm_xprtlist_1(&rxl, ap->adm_clnt);
10197238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
10207238Seschrock 
10217238Seschrock 	if (cs != RPC_SUCCESS)
10221193Smws 		return (fmd_adm_set_errno(ap, EPROTO));
10231193Smws 
10241193Smws 	if (rxl.rxl_err != 0) {
10251193Smws 		xdr_free(xdr_fmd_rpc_xprtlist, (char *)&rxl);
10261193Smws 		return (fmd_adm_set_svcerr(ap, rxl.rxl_err));
10271193Smws 	}
10281193Smws 
10291193Smws 	for (i = 0; i < rxl.rxl_len; i++)
10301193Smws 		func(rxl.rxl_buf.rxl_buf_val[i], arg);
10311193Smws 
10321193Smws 	xdr_free(xdr_fmd_rpc_xprtlist, (char *)&rxl);
10331193Smws 	return (0);
10341193Smws }
10351193Smws 
10361193Smws int
fmd_adm_xprt_stats(fmd_adm_t * ap,id_t id,fmd_adm_stats_t * sp)10371193Smws fmd_adm_xprt_stats(fmd_adm_t *ap, id_t id, fmd_adm_stats_t *sp)
10381193Smws {
10391193Smws 	struct fmd_rpc_modstat rms;
10407238Seschrock 	enum clnt_stat cs;
10417238Seschrock 	uint_t retries = 0;
10421193Smws 
10431193Smws 	if (sp == NULL)
10441193Smws 		return (fmd_adm_set_errno(ap, EINVAL));
10451193Smws 
10461193Smws 	bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
10471193Smws 
10487238Seschrock 	do {
10497238Seschrock 		cs = fmd_adm_xprtstat_1(id, &rms, ap->adm_clnt);
10507238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
10517238Seschrock 
10527238Seschrock 	if (cs != RPC_SUCCESS)
10531193Smws 		return (fmd_adm_set_errno(ap, EPROTO));
10541193Smws 
10551193Smws 	if (rms.rms_err != 0) {
10561193Smws 		xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
10571193Smws 		return (fmd_adm_set_svcerr(ap, rms.rms_err));
10581193Smws 	}
10591193Smws 
10601193Smws 	sp->ams_buf = rms.rms_buf.rms_buf_val;
10611193Smws 	sp->ams_len = rms.rms_buf.rms_buf_len;
10621193Smws 
10631193Smws 	return (0);
10641193Smws }
10651193Smws 
10661193Smws int
fmd_adm_log_rotate(fmd_adm_t * ap,const char * log)10670Sstevel@tonic-gate fmd_adm_log_rotate(fmd_adm_t *ap, const char *log)
10680Sstevel@tonic-gate {
10690Sstevel@tonic-gate 	int err;
10707238Seschrock 	enum clnt_stat cs;
10717238Seschrock 	uint_t retries = 0;
10720Sstevel@tonic-gate 
10730Sstevel@tonic-gate 	if (log == NULL)
10740Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EINVAL));
10750Sstevel@tonic-gate 
10767238Seschrock 	do {
10777238Seschrock 		cs = fmd_adm_logrotate_1((char *)log, &err, ap->adm_clnt);
10787238Seschrock 	} while (fmd_adm_retry(ap, cs, &retries));
10797238Seschrock 
10807238Seschrock 	if (cs != RPC_SUCCESS)
10810Sstevel@tonic-gate 		return (fmd_adm_set_errno(ap, EPROTO));
10820Sstevel@tonic-gate 
10830Sstevel@tonic-gate 	return (fmd_adm_set_svcerr(ap, err));
10840Sstevel@tonic-gate }
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate /*
10870Sstevel@tonic-gate  * Custom XDR routine for our API structure fmd_stat_t.  This function must
10880Sstevel@tonic-gate  * match the definition of fmd_stat_t in <fm/fmd_api.h> and must also match
10890Sstevel@tonic-gate  * the corresponding routine in usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c.
10900Sstevel@tonic-gate  */
10910Sstevel@tonic-gate bool_t
xdr_fmd_stat(XDR * xp,fmd_stat_t * sp)10920Sstevel@tonic-gate xdr_fmd_stat(XDR *xp, fmd_stat_t *sp)
10930Sstevel@tonic-gate {
10940Sstevel@tonic-gate 	bool_t rv = TRUE;
10950Sstevel@tonic-gate 
10960Sstevel@tonic-gate 	rv &= xdr_opaque(xp, sp->fmds_name, sizeof (sp->fmds_name));
10970Sstevel@tonic-gate 	rv &= xdr_u_int(xp, &sp->fmds_type);
10980Sstevel@tonic-gate 	rv &= xdr_opaque(xp, sp->fmds_desc, sizeof (sp->fmds_desc));
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate 	switch (sp->fmds_type) {
11010Sstevel@tonic-gate 	case FMD_TYPE_BOOL:
11020Sstevel@tonic-gate 		rv &= xdr_int(xp, &sp->fmds_value.bool);
11030Sstevel@tonic-gate 		break;
11040Sstevel@tonic-gate 	case FMD_TYPE_INT32:
11050Sstevel@tonic-gate 		rv &= xdr_int32_t(xp, &sp->fmds_value.i32);
11060Sstevel@tonic-gate 		break;
11070Sstevel@tonic-gate 	case FMD_TYPE_UINT32:
11080Sstevel@tonic-gate 		rv &= xdr_uint32_t(xp, &sp->fmds_value.ui32);
11090Sstevel@tonic-gate 		break;
11100Sstevel@tonic-gate 	case FMD_TYPE_INT64:
11110Sstevel@tonic-gate 		rv &= xdr_int64_t(xp, &sp->fmds_value.i64);
11120Sstevel@tonic-gate 		break;
11130Sstevel@tonic-gate 	case FMD_TYPE_UINT64:
11140Sstevel@tonic-gate 	case FMD_TYPE_TIME:
11150Sstevel@tonic-gate 	case FMD_TYPE_SIZE:
11160Sstevel@tonic-gate 		rv &= xdr_uint64_t(xp, &sp->fmds_value.ui64);
11170Sstevel@tonic-gate 		break;
11180Sstevel@tonic-gate 	case FMD_TYPE_STRING:
11190Sstevel@tonic-gate 		rv &= xdr_string(xp, &sp->fmds_value.str, ~0);
11200Sstevel@tonic-gate 		break;
11210Sstevel@tonic-gate 	}
11220Sstevel@tonic-gate 
11230Sstevel@tonic-gate 	return (rv);
11240Sstevel@tonic-gate }
1125