xref: /onnv-gate/usr/src/cmd/fm/fmd/common/fmd_fmri.c (revision 7532:bb6372f778bb)
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
53062Scindi  * Common Development and Distribution License (the "License").
63062Scindi  * 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 /*
237275Sstephh  * 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 #include <ctype.h>
280Sstevel@tonic-gate #include <errno.h>
290Sstevel@tonic-gate #include <stdarg.h>
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <fmd_alloc.h>
320Sstevel@tonic-gate #include <fmd_subr.h>
330Sstevel@tonic-gate #include <fmd_error.h>
340Sstevel@tonic-gate #include <fmd_string.h>
350Sstevel@tonic-gate #include <fmd_scheme.h>
360Sstevel@tonic-gate #include <fmd_fmri.h>
373062Scindi #include <fmd_topo.h>
380Sstevel@tonic-gate #include <fmd.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate  * Interfaces to be used by the plugins
420Sstevel@tonic-gate  */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate void *
fmd_fmri_alloc(size_t size)450Sstevel@tonic-gate fmd_fmri_alloc(size_t size)
460Sstevel@tonic-gate {
470Sstevel@tonic-gate 	return (fmd_alloc(size, FMD_SLEEP));
480Sstevel@tonic-gate }
490Sstevel@tonic-gate 
500Sstevel@tonic-gate void *
fmd_fmri_zalloc(size_t size)510Sstevel@tonic-gate fmd_fmri_zalloc(size_t size)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	return (fmd_zalloc(size, FMD_SLEEP));
540Sstevel@tonic-gate }
550Sstevel@tonic-gate 
560Sstevel@tonic-gate void
fmd_fmri_free(void * data,size_t size)570Sstevel@tonic-gate fmd_fmri_free(void *data, size_t size)
580Sstevel@tonic-gate {
590Sstevel@tonic-gate 	fmd_free(data, size);
600Sstevel@tonic-gate }
610Sstevel@tonic-gate 
620Sstevel@tonic-gate int
fmd_fmri_set_errno(int err)630Sstevel@tonic-gate fmd_fmri_set_errno(int err)
640Sstevel@tonic-gate {
650Sstevel@tonic-gate 	errno = err;
660Sstevel@tonic-gate 	return (-1);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate 
690Sstevel@tonic-gate void
fmd_fmri_warn(const char * format,...)700Sstevel@tonic-gate fmd_fmri_warn(const char *format, ...)
710Sstevel@tonic-gate {
720Sstevel@tonic-gate 	va_list ap;
730Sstevel@tonic-gate 
740Sstevel@tonic-gate 	va_start(ap, format);
750Sstevel@tonic-gate 	fmd_verror(EFMD_FMRI_SCHEME, format, ap);
760Sstevel@tonic-gate 	va_end(ap);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate  * Convert an input string to a URI escaped string and return the new string.
810Sstevel@tonic-gate  * RFC2396 Section 2.4 says that data must be escaped if it does not have a
820Sstevel@tonic-gate  * representation using an unreserved character, where an unreserved character
834198Seschrock  * is one that is either alphanumeric or one of the marks defined in S2.3.
840Sstevel@tonic-gate  */
851193Smws static size_t
fmd_fmri_uriescape(const char * s,const char * xmark,char * buf,size_t len)861193Smws fmd_fmri_uriescape(const char *s, const char *xmark, char *buf, size_t len)
870Sstevel@tonic-gate {
881193Smws 	static const char rfc2396_mark[] = "-_.!~*'()";
890Sstevel@tonic-gate 	static const char hex_digits[] = "0123456789ABCDEF";
901193Smws 	static const char empty_str[] = "";
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	const char *p;
931193Smws 	char c, *q;
940Sstevel@tonic-gate 	size_t n = 0;
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	if (s == NULL)
971193Smws 		s = empty_str;
981193Smws 
991193Smws 	if (xmark == NULL)
1001193Smws 		xmark = empty_str;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	for (p = s; (c = *p) != '\0'; p++) {
1031193Smws 		if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c))
1040Sstevel@tonic-gate 			n++;	/* represent c as itself */
1050Sstevel@tonic-gate 		else
1060Sstevel@tonic-gate 			n += 3; /* represent c as escape */
1070Sstevel@tonic-gate 	}
1080Sstevel@tonic-gate 
1091193Smws 	if (buf == NULL)
1101193Smws 		return (n);
1110Sstevel@tonic-gate 
1121193Smws 	for (p = s, q = buf; (c = *p) != '\0' && q < buf + len; p++) {
1131193Smws 		if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c)) {
1140Sstevel@tonic-gate 			*q++ = c;
1150Sstevel@tonic-gate 		} else {
1160Sstevel@tonic-gate 			*q++ = '%';
1170Sstevel@tonic-gate 			*q++ = hex_digits[((uchar_t)c & 0xf0) >> 4];
1180Sstevel@tonic-gate 			*q++ = hex_digits[(uchar_t)c & 0xf];
1190Sstevel@tonic-gate 		}
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 
1221193Smws 	if (q == buf + len)
1231193Smws 		q--; /* len is too small: truncate output string */
1241193Smws 
1250Sstevel@tonic-gate 	*q = '\0';
1261193Smws 	return (n);
1271193Smws }
1281193Smws 
1291193Smws /*
1301193Smws  * Convert a name-value pair list representing an FMRI authority into the
1311193Smws  * corresponding RFC2396 string representation and return the new string.
1321193Smws  */
1331193Smws char *
fmd_fmri_auth2str(nvlist_t * nvl)1341193Smws fmd_fmri_auth2str(nvlist_t *nvl)
1351193Smws {
1361193Smws 	nvpair_t *nvp;
1371193Smws 	char *s, *p, *v;
1381193Smws 	size_t n = 0;
1391193Smws 
1401193Smws 	for (nvp = nvlist_next_nvpair(nvl, NULL);
1411193Smws 	    nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
1421193Smws 
1431193Smws 		if (nvpair_type(nvp) != DATA_TYPE_STRING)
1441193Smws 			continue; /* do not format non-string elements */
1451193Smws 
1461193Smws 		n += fmd_fmri_uriescape(nvpair_name(nvp), NULL, NULL, 0) + 1;
1471193Smws 		(void) nvpair_value_string(nvp, &v);
1481193Smws 		n += fmd_fmri_uriescape(v, ":", NULL, 0) + 1;
1491193Smws 	}
1501193Smws 
1511193Smws 	p = s = fmd_alloc(n, FMD_SLEEP);
1521193Smws 
1531193Smws 	for (nvp = nvlist_next_nvpair(nvl, NULL);
1541193Smws 	    nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
1551193Smws 
1561193Smws 		if (nvpair_type(nvp) != DATA_TYPE_STRING)
1571193Smws 			continue; /* do not format non-string elements */
1581193Smws 
1591193Smws 		if (p != s)
1601193Smws 			*p++ = ',';
1611193Smws 
1621193Smws 		p += fmd_fmri_uriescape(nvpair_name(nvp), NULL, p, n);
1631193Smws 		*p++ = '=';
1641193Smws 		(void) nvpair_value_string(nvp, &v);
1651193Smws 		p += fmd_fmri_uriescape(v, ":", p, n);
1661193Smws 	}
1671193Smws 
1681193Smws 	return (s);
1691193Smws }
1701193Smws 
1711193Smws /*
1721193Smws  * Convert an input string to a URI escaped string and return the new string.
1731193Smws  * We amend the unreserved character list to include commas and colons,
1741193Smws  * as both are needed to make FMRIs readable without escaping.  We also permit
1751193Smws  * "/" to pass through unescaped as any path delimiters used by the event
1761193Smws  * creator are presumably intended to appear in the final path.
1771193Smws  */
1781193Smws char *
fmd_fmri_strescape(const char * s)1791193Smws fmd_fmri_strescape(const char *s)
1801193Smws {
1811193Smws 	char *s2;
1821193Smws 	size_t n;
1831193Smws 
1841193Smws 	if (s == NULL)
1851193Smws 		return (NULL);
1861193Smws 
1871193Smws 	n = fmd_fmri_uriescape(s, ":,/", NULL, 0);
1881193Smws 	s2 = fmd_alloc(n + 1, FMD_SLEEP);
1891193Smws 	(void) fmd_fmri_uriescape(s, ":,/", s2, n + 1);
1901193Smws 
1910Sstevel@tonic-gate 	return (s2);
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate char *
fmd_fmri_strdup(const char * s)1950Sstevel@tonic-gate fmd_fmri_strdup(const char *s)
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate 	return (fmd_strdup(s, FMD_SLEEP));
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate void
fmd_fmri_strfree(char * s)2010Sstevel@tonic-gate fmd_fmri_strfree(char *s)
2020Sstevel@tonic-gate {
2030Sstevel@tonic-gate 	fmd_strfree(s);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate const char *
fmd_fmri_get_rootdir(void)2070Sstevel@tonic-gate fmd_fmri_get_rootdir(void)
2080Sstevel@tonic-gate {
2090Sstevel@tonic-gate 	return (fmd.d_rootdir);
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate const char *
fmd_fmri_get_platform(void)2130Sstevel@tonic-gate fmd_fmri_get_platform(void)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate 	return (fmd.d_platform);
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate uint64_t
fmd_fmri_get_drgen(void)2190Sstevel@tonic-gate fmd_fmri_get_drgen(void)
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate 	uint64_t gen;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	(void) pthread_mutex_lock(&fmd.d_stats_lock);
2240Sstevel@tonic-gate 	gen = fmd.d_stats->ds_dr_gen.fmds_value.ui64;
2250Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&fmd.d_stats_lock);
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	return (gen);
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate 
2301414Scindi struct topo_hdl *
fmd_fmri_topo_hold(int version)2314198Seschrock fmd_fmri_topo_hold(int version)
2321414Scindi {
2334198Seschrock 	fmd_topo_t *ftp;
2344198Seschrock 
2354198Seschrock 	if (version != TOPO_VERSION)
2364198Seschrock 		return (NULL);
2374198Seschrock 
2384198Seschrock 	ftp = fmd_topo_hold();
2394198Seschrock 
2404198Seschrock 	return (ftp->ft_hdl);
2414198Seschrock }
2424198Seschrock 
2434198Seschrock void
fmd_fmri_topo_rele(struct topo_hdl * thp)2444198Seschrock fmd_fmri_topo_rele(struct topo_hdl *thp)
2454198Seschrock {
2464198Seschrock 	fmd_topo_rele_hdl(thp);
2471414Scindi }
2481414Scindi 
2490Sstevel@tonic-gate /*
2500Sstevel@tonic-gate  * Interfaces for users of the plugins
2510Sstevel@tonic-gate  */
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate static fmd_scheme_t *
nvl2scheme(nvlist_t * nvl)2540Sstevel@tonic-gate nvl2scheme(nvlist_t *nvl)
2550Sstevel@tonic-gate {
2560Sstevel@tonic-gate 	char *name;
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) {
2590Sstevel@tonic-gate 		(void) fmd_set_errno(EFMD_FMRI_INVAL);
2600Sstevel@tonic-gate 		return (NULL);
2610Sstevel@tonic-gate 	}
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	return (fmd_scheme_hash_lookup(fmd.d_schemes, name));
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate ssize_t
fmd_fmri_nvl2str(nvlist_t * nvl,char * buf,size_t buflen)2670Sstevel@tonic-gate fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
2680Sstevel@tonic-gate {
2690Sstevel@tonic-gate 	fmd_scheme_t *sp;
2700Sstevel@tonic-gate 	char c;
2710Sstevel@tonic-gate 	ssize_t rv;
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 	if (buf == NULL && buflen == 0) {
2740Sstevel@tonic-gate 		buf = &c;
2750Sstevel@tonic-gate 		buflen = sizeof (c);
2760Sstevel@tonic-gate 	}
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
2790Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
2820Sstevel@tonic-gate 	ASSERT(buf != NULL || buflen == 0);
2830Sstevel@tonic-gate 	rv = sp->sch_ops.sop_nvl2str(nvl, buf, buflen);
2840Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
2870Sstevel@tonic-gate 	return (rv);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate int
fmd_fmri_expand(nvlist_t * nvl)2910Sstevel@tonic-gate fmd_fmri_expand(nvlist_t *nvl)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate 	fmd_scheme_t *sp;
2940Sstevel@tonic-gate 	int rv;
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
2970Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3000Sstevel@tonic-gate 	rv = sp->sch_ops.sop_expand(nvl);
3010Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3040Sstevel@tonic-gate 	return (rv);
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate int
fmd_fmri_present(nvlist_t * nvl)3080Sstevel@tonic-gate fmd_fmri_present(nvlist_t *nvl)
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate 	fmd_scheme_t *sp;
3110Sstevel@tonic-gate 	int rv;
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
3140Sstevel@tonic-gate 		return (-1); /* errno is set for us */
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3170Sstevel@tonic-gate 	rv = sp->sch_ops.sop_present(nvl);
3180Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3210Sstevel@tonic-gate 	return (rv);
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate int
fmd_fmri_replaced(nvlist_t * nvl)3257275Sstephh fmd_fmri_replaced(nvlist_t *nvl)
3267275Sstephh {
3277275Sstephh 	fmd_scheme_t *sp;
3287275Sstephh 	int rv;
3297275Sstephh 
3307275Sstephh 	if ((sp = nvl2scheme(nvl)) == NULL)
3317275Sstephh 		return (-1); /* errno is set for us */
3327275Sstephh 
3337275Sstephh 	(void) pthread_mutex_lock(&sp->sch_opslock);
3347275Sstephh 	rv = sp->sch_ops.sop_replaced(nvl);
3357275Sstephh 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3367275Sstephh 
3377275Sstephh 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3387275Sstephh 	return (rv);
3397275Sstephh }
3407275Sstephh 
3417275Sstephh int
fmd_fmri_service_state(nvlist_t * nvl)3427275Sstephh fmd_fmri_service_state(nvlist_t *nvl)
3437275Sstephh {
3447275Sstephh 	fmd_scheme_t *sp;
3457275Sstephh 	int rv;
3467275Sstephh 
3477275Sstephh 	if ((sp = nvl2scheme(nvl)) == NULL)
3487275Sstephh 		return (-1); /* errno is set for us */
3497275Sstephh 
3507275Sstephh 	(void) pthread_mutex_lock(&sp->sch_opslock);
3517275Sstephh 	rv = sp->sch_ops.sop_service_state(nvl);
3527275Sstephh 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3537275Sstephh 
3547275Sstephh 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3557275Sstephh 	return (rv);
3567275Sstephh }
3577275Sstephh 
3587275Sstephh int
fmd_fmri_unusable(nvlist_t * nvl)3590Sstevel@tonic-gate fmd_fmri_unusable(nvlist_t *nvl)
3600Sstevel@tonic-gate {
3610Sstevel@tonic-gate 	fmd_scheme_t *sp;
3620Sstevel@tonic-gate 	int rv;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
3650Sstevel@tonic-gate 		return (-1); /* errno is set for us */
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3680Sstevel@tonic-gate 	rv = sp->sch_ops.sop_unusable(nvl);
3690Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3720Sstevel@tonic-gate 	return (rv);
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate 
375*7532SSean.Ye@Sun.COM /*
376*7532SSean.Ye@Sun.COM  * Someday we'll retire the scheme plugins.  For the
377*7532SSean.Ye@Sun.COM  * retire/unretire operations, the topo interfaces
378*7532SSean.Ye@Sun.COM  * are called directly.
379*7532SSean.Ye@Sun.COM  */
380*7532SSean.Ye@Sun.COM int
fmd_fmri_retire(nvlist_t * nvl)381*7532SSean.Ye@Sun.COM fmd_fmri_retire(nvlist_t *nvl)
382*7532SSean.Ye@Sun.COM {
383*7532SSean.Ye@Sun.COM 	topo_hdl_t *thp;
384*7532SSean.Ye@Sun.COM 	int rv, err;
385*7532SSean.Ye@Sun.COM 
386*7532SSean.Ye@Sun.COM 	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
387*7532SSean.Ye@Sun.COM 		return (-1);
388*7532SSean.Ye@Sun.COM 
389*7532SSean.Ye@Sun.COM 	rv = topo_fmri_retire(thp, nvl, &err);
390*7532SSean.Ye@Sun.COM 	fmd_fmri_topo_rele(thp);
391*7532SSean.Ye@Sun.COM 
392*7532SSean.Ye@Sun.COM 	return (rv);
393*7532SSean.Ye@Sun.COM }
394*7532SSean.Ye@Sun.COM 
395*7532SSean.Ye@Sun.COM int
fmd_fmri_unretire(nvlist_t * nvl)396*7532SSean.Ye@Sun.COM fmd_fmri_unretire(nvlist_t *nvl)
397*7532SSean.Ye@Sun.COM {
398*7532SSean.Ye@Sun.COM 	topo_hdl_t *thp;
399*7532SSean.Ye@Sun.COM 	int rv, err;
400*7532SSean.Ye@Sun.COM 
401*7532SSean.Ye@Sun.COM 	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
402*7532SSean.Ye@Sun.COM 		return (-1);
403*7532SSean.Ye@Sun.COM 
404*7532SSean.Ye@Sun.COM 	rv = topo_fmri_unretire(thp, nvl, &err);
405*7532SSean.Ye@Sun.COM 	fmd_fmri_topo_rele(thp);
406*7532SSean.Ye@Sun.COM 
407*7532SSean.Ye@Sun.COM 	return (rv);
408*7532SSean.Ye@Sun.COM }
409*7532SSean.Ye@Sun.COM 
4100Sstevel@tonic-gate int
fmd_fmri_contains(nvlist_t * er,nvlist_t * ee)4110Sstevel@tonic-gate fmd_fmri_contains(nvlist_t *er, nvlist_t *ee)
4120Sstevel@tonic-gate {
4130Sstevel@tonic-gate 	fmd_scheme_t *sp;
4140Sstevel@tonic-gate 	char *ername, *eename;
4150Sstevel@tonic-gate 	int rv;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	if (nvlist_lookup_string(er, FM_FMRI_SCHEME, &ername) != 0 ||
4180Sstevel@tonic-gate 	    nvlist_lookup_string(ee, FM_FMRI_SCHEME, &eename) != 0 ||
4190Sstevel@tonic-gate 	    strcmp(ername, eename) != 0)
4200Sstevel@tonic-gate 		return (fmd_set_errno(EFMD_FMRI_INVAL));
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	if ((sp = fmd_scheme_hash_lookup(fmd.d_schemes, ername)) == NULL)
4230Sstevel@tonic-gate 		return (-1); /* errno is set for us */
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
4260Sstevel@tonic-gate 	rv = sp->sch_ops.sop_contains(er, ee);
4270Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
4300Sstevel@tonic-gate 	return (rv);
4310Sstevel@tonic-gate }
4321193Smws 
4331193Smws nvlist_t *
fmd_fmri_translate(nvlist_t * fmri,nvlist_t * auth)4341193Smws fmd_fmri_translate(nvlist_t *fmri, nvlist_t *auth)
4351193Smws {
4361193Smws 	fmd_scheme_t *sp;
4371193Smws 	nvlist_t *nvl;
4381193Smws 
4391193Smws 	if ((sp = nvl2scheme(fmri)) == NULL)
4401193Smws 		return (NULL); /* errno is set for us */
4411193Smws 
4421193Smws 	(void) pthread_mutex_lock(&sp->sch_opslock);
4431193Smws 	nvl = sp->sch_ops.sop_translate(fmri, auth);
4441193Smws 	(void) pthread_mutex_unlock(&sp->sch_opslock);
4451193Smws 
4461193Smws 	fmd_scheme_hash_release(fmd.d_schemes, sp);
4471193Smws 	return (nvl);
4481193Smws }
449