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