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 * 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 * 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 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 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 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 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 * 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 * 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 * 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 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 * 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 * 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 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 * 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 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 * 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 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 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 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 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 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 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 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 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 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 * 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