1b7d3956bSstephh /* 2b7d3956bSstephh * 3b7d3956bSstephh * CDDL HEADER START 4b7d3956bSstephh * 5b7d3956bSstephh * The contents of this file are subject to the terms of the 6b7d3956bSstephh * Common Development and Distribution License (the "License"). 7b7d3956bSstephh * You may not use this file except in compliance with the License. 8b7d3956bSstephh * 9b7d3956bSstephh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10b7d3956bSstephh * or http://www.opensolaris.org/os/licensing. 11b7d3956bSstephh * See the License for the specific language governing permissions 12b7d3956bSstephh * and limitations under the License. 13b7d3956bSstephh * 14b7d3956bSstephh * When distributing Covered Code, include this CDDL HEADER in each 15b7d3956bSstephh * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16b7d3956bSstephh * If applicable, add the following below this CDDL HEADER, with the 17b7d3956bSstephh * fields enclosed by brackets "[]" replaced with your own identifying 18b7d3956bSstephh * information: Portions Copyright [yyyy] [name of copyright owner] 19b7d3956bSstephh * 20b7d3956bSstephh * CDDL HEADER END 21b7d3956bSstephh */ 22b7d3956bSstephh 23b7d3956bSstephh /* 24*f6e214c7SGavin Maltby * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 25b7d3956bSstephh */ 26b7d3956bSstephh 27b7d3956bSstephh 28b7d3956bSstephh #include <stdio.h> 29b7d3956bSstephh #include <stdlib.h> 30b7d3956bSstephh #include <string.h> 31b7d3956bSstephh #include <errno.h> 32b7d3956bSstephh #include <ctype.h> 33b7d3956bSstephh #include <alloca.h> 34b7d3956bSstephh #include <limits.h> 35b7d3956bSstephh #include <fm/topo_mod.h> 36b7d3956bSstephh #include <sys/param.h> 37b7d3956bSstephh #include <sys/systeminfo.h> 38b7d3956bSstephh #include <sys/fm/protocol.h> 39b7d3956bSstephh #include <sys/stat.h> 40b7d3956bSstephh 41b7d3956bSstephh #include <topo_method.h> 42b7d3956bSstephh #include <topo_subr.h> 43b7d3956bSstephh #include <fmd.h> 44b7d3956bSstephh 45b7d3956bSstephh static int fmd_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, 46b7d3956bSstephh topo_instance_t, void *, void *); 47b7d3956bSstephh static void fmd_release(topo_mod_t *, tnode_t *); 48b7d3956bSstephh static int fmd_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, 49b7d3956bSstephh nvlist_t *, nvlist_t **); 50b7d3956bSstephh 51b7d3956bSstephh const topo_method_t fmd_methods[] = { 52b7d3956bSstephh { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, 53b7d3956bSstephh TOPO_STABILITY_INTERNAL, fmd_fmri_nvl2str }, 54b7d3956bSstephh { NULL } 55b7d3956bSstephh }; 56b7d3956bSstephh 57b7d3956bSstephh static const topo_modops_t fmd_ops = 58b7d3956bSstephh { fmd_enum, fmd_release }; 59b7d3956bSstephh static const topo_modinfo_t fmd_info = 60b7d3956bSstephh { FMD, FM_FMRI_SCHEME_FMD, FMD_VERSION, &fmd_ops }; 61b7d3956bSstephh 62b7d3956bSstephh int 63b7d3956bSstephh fmd_init(topo_mod_t *mod, topo_version_t version) 64b7d3956bSstephh { 65b7d3956bSstephh /* 66b7d3956bSstephh * Turn on module debugging output 67b7d3956bSstephh */ 68b7d3956bSstephh if (getenv("TOPOFMDDEBUG")) 69b7d3956bSstephh topo_mod_setdebug(mod); 70b7d3956bSstephh 71b7d3956bSstephh topo_mod_dprintf(mod, "initializing fmd builtin\n"); 72b7d3956bSstephh 73b7d3956bSstephh if (version != FMD_VERSION) 74b7d3956bSstephh return (topo_mod_seterrno(mod, EMOD_VER_NEW)); 75b7d3956bSstephh 76b7d3956bSstephh if (topo_mod_register(mod, &fmd_info, TOPO_VERSION) != 0) { 77b7d3956bSstephh topo_mod_dprintf(mod, "failed to register fmd: " 78b7d3956bSstephh "%s\n", topo_mod_errmsg(mod)); 79b7d3956bSstephh return (-1); /* mod errno already set */ 80b7d3956bSstephh } 81b7d3956bSstephh 82b7d3956bSstephh return (0); 83b7d3956bSstephh } 84b7d3956bSstephh 85b7d3956bSstephh void 86b7d3956bSstephh fmd_fini(topo_mod_t *mod) 87b7d3956bSstephh { 88b7d3956bSstephh topo_mod_unregister(mod); 89b7d3956bSstephh } 90b7d3956bSstephh 91b7d3956bSstephh 92b7d3956bSstephh /*ARGSUSED*/ 93b7d3956bSstephh int 94b7d3956bSstephh fmd_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, 95b7d3956bSstephh topo_instance_t max, void *notused1, void *notused2) 96b7d3956bSstephh { 97*f6e214c7SGavin Maltby /* 98*f6e214c7SGavin Maltby * Methods are registered, but there is no enumeration. Should 99*f6e214c7SGavin Maltby * enumeration be added be sure to cater for global vs non-global 100*f6e214c7SGavin Maltby * zones. 101*f6e214c7SGavin Maltby */ 102b7d3956bSstephh (void) topo_method_register(mod, pnode, fmd_methods); 103b7d3956bSstephh return (0); 104b7d3956bSstephh } 105b7d3956bSstephh 106b7d3956bSstephh /*ARGSUSED*/ 107b7d3956bSstephh static void 108b7d3956bSstephh fmd_release(topo_mod_t *mp, tnode_t *node) 109b7d3956bSstephh { 110b7d3956bSstephh topo_method_unregister_all(mp, node); 111b7d3956bSstephh } 112b7d3956bSstephh 113b7d3956bSstephh static ssize_t 114b7d3956bSstephh fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) 115b7d3956bSstephh { 116b7d3956bSstephh char *name; 117b7d3956bSstephh 118b7d3956bSstephh if (nvlist_lookup_string(nvl, FM_FMRI_FMD_NAME, &name) != 0) 119b7d3956bSstephh return (0); 120b7d3956bSstephh 121b7d3956bSstephh return (snprintf(buf, buflen, 122b7d3956bSstephh "%s:///module/%s", FM_FMRI_SCHEME_FMD, name)); 123b7d3956bSstephh } 124b7d3956bSstephh 125b7d3956bSstephh /*ARGSUSED*/ 126b7d3956bSstephh static int 127b7d3956bSstephh fmd_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, 128b7d3956bSstephh nvlist_t *nvl, nvlist_t **out) 129b7d3956bSstephh { 130b7d3956bSstephh ssize_t len; 131b7d3956bSstephh char *name = NULL; 132b7d3956bSstephh nvlist_t *fmristr; 133b7d3956bSstephh 134b7d3956bSstephh if (version > TOPO_METH_NVL2STR_VERSION) 135b7d3956bSstephh return (topo_mod_seterrno(mod, EMOD_VER_NEW)); 136b7d3956bSstephh 137b7d3956bSstephh if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0 || 138b7d3956bSstephh (name = topo_mod_alloc(mod, len + 1)) == NULL || 139b7d3956bSstephh fmri_nvl2str(nvl, name, len + 1) == 0) { 140b7d3956bSstephh if (name != NULL) 141b7d3956bSstephh topo_mod_free(mod, name, len + 1); 142b7d3956bSstephh return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); 143b7d3956bSstephh } 144b7d3956bSstephh 145b7d3956bSstephh if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) { 146b7d3956bSstephh topo_mod_free(mod, name, len + 1); 147b7d3956bSstephh return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); 148b7d3956bSstephh } 149b7d3956bSstephh if (nvlist_add_string(fmristr, "fmri-string", name) != 0) { 150b7d3956bSstephh topo_mod_free(mod, name, len + 1); 151b7d3956bSstephh nvlist_free(fmristr); 152b7d3956bSstephh return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); 153b7d3956bSstephh } 154b7d3956bSstephh topo_mod_free(mod, name, len + 1); 155b7d3956bSstephh *out = fmristr; 156b7d3956bSstephh 157b7d3956bSstephh return (0); 158b7d3956bSstephh } 159