xref: /titanic_41/usr/src/cmd/fm/fmd/common/fmd_fmri.c (revision e4b86885570d77af552e9cf94f142f4d744fb8c8)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50eb822a1Scindi  * Common Development and Distribution License (the "License").
60eb822a1Scindi  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21d9638e54Smws 
227c478bd9Sstevel@tonic-gate /*
2325c6ff4bSstephh  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <ctype.h>
287c478bd9Sstevel@tonic-gate #include <errno.h>
297c478bd9Sstevel@tonic-gate #include <stdarg.h>
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <fmd_alloc.h>
327c478bd9Sstevel@tonic-gate #include <fmd_subr.h>
337c478bd9Sstevel@tonic-gate #include <fmd_error.h>
347c478bd9Sstevel@tonic-gate #include <fmd_string.h>
357c478bd9Sstevel@tonic-gate #include <fmd_scheme.h>
367c478bd9Sstevel@tonic-gate #include <fmd_fmri.h>
370eb822a1Scindi #include <fmd_topo.h>
387c478bd9Sstevel@tonic-gate #include <fmd.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * Interfaces to be used by the plugins
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate void *
fmd_fmri_alloc(size_t size)457c478bd9Sstevel@tonic-gate fmd_fmri_alloc(size_t size)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	return (fmd_alloc(size, FMD_SLEEP));
487c478bd9Sstevel@tonic-gate }
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate void *
fmd_fmri_zalloc(size_t size)517c478bd9Sstevel@tonic-gate fmd_fmri_zalloc(size_t size)
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	return (fmd_zalloc(size, FMD_SLEEP));
547c478bd9Sstevel@tonic-gate }
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate void
fmd_fmri_free(void * data,size_t size)577c478bd9Sstevel@tonic-gate fmd_fmri_free(void *data, size_t size)
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate 	fmd_free(data, size);
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate int
fmd_fmri_set_errno(int err)637c478bd9Sstevel@tonic-gate fmd_fmri_set_errno(int err)
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate 	errno = err;
667c478bd9Sstevel@tonic-gate 	return (-1);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate void
fmd_fmri_warn(const char * format,...)707c478bd9Sstevel@tonic-gate fmd_fmri_warn(const char *format, ...)
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	va_list ap;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	va_start(ap, format);
757c478bd9Sstevel@tonic-gate 	fmd_verror(EFMD_FMRI_SCHEME, format, ap);
767c478bd9Sstevel@tonic-gate 	va_end(ap);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * Convert an input string to a URI escaped string and return the new string.
817c478bd9Sstevel@tonic-gate  * RFC2396 Section 2.4 says that data must be escaped if it does not have a
827c478bd9Sstevel@tonic-gate  * representation using an unreserved character, where an unreserved character
8324db4641Seschrock  * is one that is either alphanumeric or one of the marks defined in S2.3.
847c478bd9Sstevel@tonic-gate  */
85d9638e54Smws static size_t
fmd_fmri_uriescape(const char * s,const char * xmark,char * buf,size_t len)86d9638e54Smws fmd_fmri_uriescape(const char *s, const char *xmark, char *buf, size_t len)
877c478bd9Sstevel@tonic-gate {
88d9638e54Smws 	static const char rfc2396_mark[] = "-_.!~*'()";
897c478bd9Sstevel@tonic-gate 	static const char hex_digits[] = "0123456789ABCDEF";
90d9638e54Smws 	static const char empty_str[] = "";
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	const char *p;
93d9638e54Smws 	char c, *q;
947c478bd9Sstevel@tonic-gate 	size_t n = 0;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	if (s == NULL)
97d9638e54Smws 		s = empty_str;
98d9638e54Smws 
99d9638e54Smws 	if (xmark == NULL)
100d9638e54Smws 		xmark = empty_str;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	for (p = s; (c = *p) != '\0'; p++) {
103d9638e54Smws 		if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c))
1047c478bd9Sstevel@tonic-gate 			n++;	/* represent c as itself */
1057c478bd9Sstevel@tonic-gate 		else
1067c478bd9Sstevel@tonic-gate 			n += 3; /* represent c as escape */
1077c478bd9Sstevel@tonic-gate 	}
1087c478bd9Sstevel@tonic-gate 
109d9638e54Smws 	if (buf == NULL)
110d9638e54Smws 		return (n);
1117c478bd9Sstevel@tonic-gate 
112d9638e54Smws 	for (p = s, q = buf; (c = *p) != '\0' && q < buf + len; p++) {
113d9638e54Smws 		if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c)) {
1147c478bd9Sstevel@tonic-gate 			*q++ = c;
1157c478bd9Sstevel@tonic-gate 		} else {
1167c478bd9Sstevel@tonic-gate 			*q++ = '%';
1177c478bd9Sstevel@tonic-gate 			*q++ = hex_digits[((uchar_t)c & 0xf0) >> 4];
1187c478bd9Sstevel@tonic-gate 			*q++ = hex_digits[(uchar_t)c & 0xf];
1197c478bd9Sstevel@tonic-gate 		}
1207c478bd9Sstevel@tonic-gate 	}
1217c478bd9Sstevel@tonic-gate 
122d9638e54Smws 	if (q == buf + len)
123d9638e54Smws 		q--; /* len is too small: truncate output string */
124d9638e54Smws 
1257c478bd9Sstevel@tonic-gate 	*q = '\0';
126d9638e54Smws 	return (n);
127d9638e54Smws }
128d9638e54Smws 
129d9638e54Smws /*
130d9638e54Smws  * Convert a name-value pair list representing an FMRI authority into the
131d9638e54Smws  * corresponding RFC2396 string representation and return the new string.
132d9638e54Smws  */
133d9638e54Smws char *
fmd_fmri_auth2str(nvlist_t * nvl)134d9638e54Smws fmd_fmri_auth2str(nvlist_t *nvl)
135d9638e54Smws {
136d9638e54Smws 	nvpair_t *nvp;
137d9638e54Smws 	char *s, *p, *v;
138d9638e54Smws 	size_t n = 0;
139d9638e54Smws 
140d9638e54Smws 	for (nvp = nvlist_next_nvpair(nvl, NULL);
141d9638e54Smws 	    nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
142d9638e54Smws 
143d9638e54Smws 		if (nvpair_type(nvp) != DATA_TYPE_STRING)
144d9638e54Smws 			continue; /* do not format non-string elements */
145d9638e54Smws 
146d9638e54Smws 		n += fmd_fmri_uriescape(nvpair_name(nvp), NULL, NULL, 0) + 1;
147d9638e54Smws 		(void) nvpair_value_string(nvp, &v);
148d9638e54Smws 		n += fmd_fmri_uriescape(v, ":", NULL, 0) + 1;
149d9638e54Smws 	}
150d9638e54Smws 
151d9638e54Smws 	p = s = fmd_alloc(n, FMD_SLEEP);
152d9638e54Smws 
153d9638e54Smws 	for (nvp = nvlist_next_nvpair(nvl, NULL);
154d9638e54Smws 	    nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
155d9638e54Smws 
156d9638e54Smws 		if (nvpair_type(nvp) != DATA_TYPE_STRING)
157d9638e54Smws 			continue; /* do not format non-string elements */
158d9638e54Smws 
159d9638e54Smws 		if (p != s)
160d9638e54Smws 			*p++ = ',';
161d9638e54Smws 
162d9638e54Smws 		p += fmd_fmri_uriescape(nvpair_name(nvp), NULL, p, n);
163d9638e54Smws 		*p++ = '=';
164d9638e54Smws 		(void) nvpair_value_string(nvp, &v);
165d9638e54Smws 		p += fmd_fmri_uriescape(v, ":", p, n);
166d9638e54Smws 	}
167d9638e54Smws 
168d9638e54Smws 	return (s);
169d9638e54Smws }
170d9638e54Smws 
171d9638e54Smws /*
172d9638e54Smws  * Convert an input string to a URI escaped string and return the new string.
173d9638e54Smws  * We amend the unreserved character list to include commas and colons,
174d9638e54Smws  * as both are needed to make FMRIs readable without escaping.  We also permit
175d9638e54Smws  * "/" to pass through unescaped as any path delimiters used by the event
176d9638e54Smws  * creator are presumably intended to appear in the final path.
177d9638e54Smws  */
178d9638e54Smws char *
fmd_fmri_strescape(const char * s)179d9638e54Smws fmd_fmri_strescape(const char *s)
180d9638e54Smws {
181d9638e54Smws 	char *s2;
182d9638e54Smws 	size_t n;
183d9638e54Smws 
184d9638e54Smws 	if (s == NULL)
185d9638e54Smws 		return (NULL);
186d9638e54Smws 
187d9638e54Smws 	n = fmd_fmri_uriescape(s, ":,/", NULL, 0);
188d9638e54Smws 	s2 = fmd_alloc(n + 1, FMD_SLEEP);
189d9638e54Smws 	(void) fmd_fmri_uriescape(s, ":,/", s2, n + 1);
190d9638e54Smws 
1917c478bd9Sstevel@tonic-gate 	return (s2);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate char *
fmd_fmri_strdup(const char * s)1957c478bd9Sstevel@tonic-gate fmd_fmri_strdup(const char *s)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate 	return (fmd_strdup(s, FMD_SLEEP));
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate void
fmd_fmri_strfree(char * s)2017c478bd9Sstevel@tonic-gate fmd_fmri_strfree(char *s)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	fmd_strfree(s);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate const char *
fmd_fmri_get_rootdir(void)2077c478bd9Sstevel@tonic-gate fmd_fmri_get_rootdir(void)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	return (fmd.d_rootdir);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate const char *
fmd_fmri_get_platform(void)2137c478bd9Sstevel@tonic-gate fmd_fmri_get_platform(void)
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate 	return (fmd.d_platform);
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate uint64_t
fmd_fmri_get_drgen(void)2197c478bd9Sstevel@tonic-gate fmd_fmri_get_drgen(void)
2207c478bd9Sstevel@tonic-gate {
2217c478bd9Sstevel@tonic-gate 	uint64_t gen;
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&fmd.d_stats_lock);
2247c478bd9Sstevel@tonic-gate 	gen = fmd.d_stats->ds_dr_gen.fmds_value.ui64;
2257c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&fmd.d_stats_lock);
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	return (gen);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307aec1d6eScindi struct topo_hdl *
fmd_fmri_topo_hold(int version)23124db4641Seschrock fmd_fmri_topo_hold(int version)
2327aec1d6eScindi {
23324db4641Seschrock 	fmd_topo_t *ftp;
23424db4641Seschrock 
23524db4641Seschrock 	if (version != TOPO_VERSION)
23624db4641Seschrock 		return (NULL);
23724db4641Seschrock 
23824db4641Seschrock 	ftp = fmd_topo_hold();
23924db4641Seschrock 
24024db4641Seschrock 	return (ftp->ft_hdl);
24124db4641Seschrock }
24224db4641Seschrock 
24324db4641Seschrock void
fmd_fmri_topo_rele(struct topo_hdl * thp)24424db4641Seschrock fmd_fmri_topo_rele(struct topo_hdl *thp)
24524db4641Seschrock {
24624db4641Seschrock 	fmd_topo_rele_hdl(thp);
2477aec1d6eScindi }
2487aec1d6eScindi 
2497c478bd9Sstevel@tonic-gate /*
2507c478bd9Sstevel@tonic-gate  * Interfaces for users of the plugins
2517c478bd9Sstevel@tonic-gate  */
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate static fmd_scheme_t *
nvl2scheme(nvlist_t * nvl)2547c478bd9Sstevel@tonic-gate nvl2scheme(nvlist_t *nvl)
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate 	char *name;
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) {
2597c478bd9Sstevel@tonic-gate 		(void) fmd_set_errno(EFMD_FMRI_INVAL);
2607c478bd9Sstevel@tonic-gate 		return (NULL);
2617c478bd9Sstevel@tonic-gate 	}
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	return (fmd_scheme_hash_lookup(fmd.d_schemes, name));
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate ssize_t
fmd_fmri_nvl2str(nvlist_t * nvl,char * buf,size_t buflen)2677c478bd9Sstevel@tonic-gate fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
2707c478bd9Sstevel@tonic-gate 	char c;
2717c478bd9Sstevel@tonic-gate 	ssize_t rv;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	if (buf == NULL && buflen == 0) {
2747c478bd9Sstevel@tonic-gate 		buf = &c;
2757c478bd9Sstevel@tonic-gate 		buflen = sizeof (c);
2767c478bd9Sstevel@tonic-gate 	}
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
2797c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
2827c478bd9Sstevel@tonic-gate 	ASSERT(buf != NULL || buflen == 0);
2837c478bd9Sstevel@tonic-gate 	rv = sp->sch_ops.sop_nvl2str(nvl, buf, buflen);
2847c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
2877c478bd9Sstevel@tonic-gate 	return (rv);
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate int
fmd_fmri_expand(nvlist_t * nvl)2917c478bd9Sstevel@tonic-gate fmd_fmri_expand(nvlist_t *nvl)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
2947c478bd9Sstevel@tonic-gate 	int rv;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
2977c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3007c478bd9Sstevel@tonic-gate 	rv = sp->sch_ops.sop_expand(nvl);
3017c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3047c478bd9Sstevel@tonic-gate 	return (rv);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate int
fmd_fmri_present(nvlist_t * nvl)3087c478bd9Sstevel@tonic-gate fmd_fmri_present(nvlist_t *nvl)
3097c478bd9Sstevel@tonic-gate {
3107c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
3117c478bd9Sstevel@tonic-gate 	int rv;
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
3147c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3177c478bd9Sstevel@tonic-gate 	rv = sp->sch_ops.sop_present(nvl);
3187c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3217c478bd9Sstevel@tonic-gate 	return (rv);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate int
fmd_fmri_replaced(nvlist_t * nvl)32525c6ff4bSstephh fmd_fmri_replaced(nvlist_t *nvl)
32625c6ff4bSstephh {
32725c6ff4bSstephh 	fmd_scheme_t *sp;
32825c6ff4bSstephh 	int rv;
32925c6ff4bSstephh 
33025c6ff4bSstephh 	if ((sp = nvl2scheme(nvl)) == NULL)
33125c6ff4bSstephh 		return (-1); /* errno is set for us */
33225c6ff4bSstephh 
33325c6ff4bSstephh 	(void) pthread_mutex_lock(&sp->sch_opslock);
33425c6ff4bSstephh 	rv = sp->sch_ops.sop_replaced(nvl);
33525c6ff4bSstephh 	(void) pthread_mutex_unlock(&sp->sch_opslock);
33625c6ff4bSstephh 
33725c6ff4bSstephh 	fmd_scheme_hash_release(fmd.d_schemes, sp);
33825c6ff4bSstephh 	return (rv);
33925c6ff4bSstephh }
34025c6ff4bSstephh 
34125c6ff4bSstephh int
fmd_fmri_service_state(nvlist_t * nvl)34225c6ff4bSstephh fmd_fmri_service_state(nvlist_t *nvl)
34325c6ff4bSstephh {
34425c6ff4bSstephh 	fmd_scheme_t *sp;
34525c6ff4bSstephh 	int rv;
34625c6ff4bSstephh 
34725c6ff4bSstephh 	if ((sp = nvl2scheme(nvl)) == NULL)
34825c6ff4bSstephh 		return (-1); /* errno is set for us */
34925c6ff4bSstephh 
35025c6ff4bSstephh 	(void) pthread_mutex_lock(&sp->sch_opslock);
35125c6ff4bSstephh 	rv = sp->sch_ops.sop_service_state(nvl);
35225c6ff4bSstephh 	(void) pthread_mutex_unlock(&sp->sch_opslock);
35325c6ff4bSstephh 
35425c6ff4bSstephh 	fmd_scheme_hash_release(fmd.d_schemes, sp);
35525c6ff4bSstephh 	return (rv);
35625c6ff4bSstephh }
35725c6ff4bSstephh 
35825c6ff4bSstephh int
fmd_fmri_unusable(nvlist_t * nvl)3597c478bd9Sstevel@tonic-gate fmd_fmri_unusable(nvlist_t *nvl)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
3627c478bd9Sstevel@tonic-gate 	int rv;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if ((sp = nvl2scheme(nvl)) == NULL)
3657c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
3687c478bd9Sstevel@tonic-gate 	rv = sp->sch_ops.sop_unusable(nvl);
3697c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
3727c478bd9Sstevel@tonic-gate 	return (rv);
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate 
375*e4b86885SCheng Sean Ye /*
376*e4b86885SCheng Sean Ye  * Someday we'll retire the scheme plugins.  For the
377*e4b86885SCheng Sean Ye  * retire/unretire operations, the topo interfaces
378*e4b86885SCheng Sean Ye  * are called directly.
379*e4b86885SCheng Sean Ye  */
380*e4b86885SCheng Sean Ye int
fmd_fmri_retire(nvlist_t * nvl)381*e4b86885SCheng Sean Ye fmd_fmri_retire(nvlist_t *nvl)
382*e4b86885SCheng Sean Ye {
383*e4b86885SCheng Sean Ye 	topo_hdl_t *thp;
384*e4b86885SCheng Sean Ye 	int rv, err;
385*e4b86885SCheng Sean Ye 
386*e4b86885SCheng Sean Ye 	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
387*e4b86885SCheng Sean Ye 		return (-1);
388*e4b86885SCheng Sean Ye 
389*e4b86885SCheng Sean Ye 	rv = topo_fmri_retire(thp, nvl, &err);
390*e4b86885SCheng Sean Ye 	fmd_fmri_topo_rele(thp);
391*e4b86885SCheng Sean Ye 
392*e4b86885SCheng Sean Ye 	return (rv);
393*e4b86885SCheng Sean Ye }
394*e4b86885SCheng Sean Ye 
395*e4b86885SCheng Sean Ye int
fmd_fmri_unretire(nvlist_t * nvl)396*e4b86885SCheng Sean Ye fmd_fmri_unretire(nvlist_t *nvl)
397*e4b86885SCheng Sean Ye {
398*e4b86885SCheng Sean Ye 	topo_hdl_t *thp;
399*e4b86885SCheng Sean Ye 	int rv, err;
400*e4b86885SCheng Sean Ye 
401*e4b86885SCheng Sean Ye 	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
402*e4b86885SCheng Sean Ye 		return (-1);
403*e4b86885SCheng Sean Ye 
404*e4b86885SCheng Sean Ye 	rv = topo_fmri_unretire(thp, nvl, &err);
405*e4b86885SCheng Sean Ye 	fmd_fmri_topo_rele(thp);
406*e4b86885SCheng Sean Ye 
407*e4b86885SCheng Sean Ye 	return (rv);
408*e4b86885SCheng Sean Ye }
409*e4b86885SCheng Sean Ye 
4107c478bd9Sstevel@tonic-gate int
fmd_fmri_contains(nvlist_t * er,nvlist_t * ee)4117c478bd9Sstevel@tonic-gate fmd_fmri_contains(nvlist_t *er, nvlist_t *ee)
4127c478bd9Sstevel@tonic-gate {
4137c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
4147c478bd9Sstevel@tonic-gate 	char *ername, *eename;
4157c478bd9Sstevel@tonic-gate 	int rv;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_string(er, FM_FMRI_SCHEME, &ername) != 0 ||
4187c478bd9Sstevel@tonic-gate 	    nvlist_lookup_string(ee, FM_FMRI_SCHEME, &eename) != 0 ||
4197c478bd9Sstevel@tonic-gate 	    strcmp(ername, eename) != 0)
4207c478bd9Sstevel@tonic-gate 		return (fmd_set_errno(EFMD_FMRI_INVAL));
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if ((sp = fmd_scheme_hash_lookup(fmd.d_schemes, ername)) == NULL)
4237c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&sp->sch_opslock);
4267c478bd9Sstevel@tonic-gate 	rv = sp->sch_ops.sop_contains(er, ee);
4277c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&sp->sch_opslock);
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate 	fmd_scheme_hash_release(fmd.d_schemes, sp);
4307c478bd9Sstevel@tonic-gate 	return (rv);
4317c478bd9Sstevel@tonic-gate }
432d9638e54Smws 
433d9638e54Smws nvlist_t *
fmd_fmri_translate(nvlist_t * fmri,nvlist_t * auth)434d9638e54Smws fmd_fmri_translate(nvlist_t *fmri, nvlist_t *auth)
435d9638e54Smws {
436d9638e54Smws 	fmd_scheme_t *sp;
437d9638e54Smws 	nvlist_t *nvl;
438d9638e54Smws 
439d9638e54Smws 	if ((sp = nvl2scheme(fmri)) == NULL)
440d9638e54Smws 		return (NULL); /* errno is set for us */
441d9638e54Smws 
442d9638e54Smws 	(void) pthread_mutex_lock(&sp->sch_opslock);
443d9638e54Smws 	nvl = sp->sch_ops.sop_translate(fmri, auth);
444d9638e54Smws 	(void) pthread_mutex_unlock(&sp->sch_opslock);
445d9638e54Smws 
446d9638e54Smws 	fmd_scheme_hash_release(fmd.d_schemes, sp);
447d9638e54Smws 	return (nvl);
448d9638e54Smws }
449