diff options
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/amd64/Makefile | 4 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/fmd.c | 155 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/fmd.h | 46 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/legacy_hc.c | 216 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/legacy_hc.h | 46 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/mod.c | 21 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/pkg.c | 111 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/zfs.c | 203 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/zfs.h | 46 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/i386/Makefile | 4 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/sparc/Makefile | 2 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/sparcv9/Makefile | 2 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/chip/chip_amd.c | 11 |
14 files changed, 859 insertions, 11 deletions
diff --git a/usr/src/lib/fm/topo/libtopo/Makefile.com b/usr/src/lib/fm/topo/libtopo/Makefile.com index 295f33d885..e2e2a4e69a 100644 --- a/usr/src/lib/fm/topo/libtopo/Makefile.com +++ b/usr/src/lib/fm/topo/libtopo/Makefile.com @@ -32,6 +32,9 @@ BUILTINSRCS = \ cpu.c \ dev.c \ hc.c \ + zfs.c \ + fmd.c \ + legacy_hc.c \ mem.c \ mod.c \ pkg.c diff --git a/usr/src/lib/fm/topo/libtopo/amd64/Makefile b/usr/src/lib/fm/topo/libtopo/amd64/Makefile index f81fcaa5f0..2506edb291 100644 --- a/usr/src/lib/fm/topo/libtopo/amd64/Makefile +++ b/usr/src/lib/fm/topo/libtopo/amd64/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,4 +28,6 @@ include ../Makefile.com include ../../../../Makefile.lib.64 +LDLIBS += -lzfs + install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/fm/topo/libtopo/common/fmd.c b/usr/src/lib/fm/topo/libtopo/common/fmd.c new file mode 100644 index 0000000000..1b8898770e --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/fmd.c @@ -0,0 +1,155 @@ +/* + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <alloca.h> +#include <limits.h> +#include <fm/topo_mod.h> +#include <sys/param.h> +#include <sys/systeminfo.h> +#include <sys/fm/protocol.h> +#include <sys/stat.h> + +#include <topo_method.h> +#include <topo_subr.h> +#include <fmd.h> + +static int fmd_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, + topo_instance_t, void *, void *); +static void fmd_release(topo_mod_t *, tnode_t *); +static int fmd_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +const topo_method_t fmd_methods[] = { + { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, + TOPO_STABILITY_INTERNAL, fmd_fmri_nvl2str }, + { NULL } +}; + +static const topo_modops_t fmd_ops = + { fmd_enum, fmd_release }; +static const topo_modinfo_t fmd_info = + { FMD, FM_FMRI_SCHEME_FMD, FMD_VERSION, &fmd_ops }; + +int +fmd_init(topo_mod_t *mod, topo_version_t version) +{ + /* + * Turn on module debugging output + */ + if (getenv("TOPOFMDDEBUG")) + topo_mod_setdebug(mod); + + topo_mod_dprintf(mod, "initializing fmd builtin\n"); + + if (version != FMD_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &fmd_info, TOPO_VERSION) != 0) { + topo_mod_dprintf(mod, "failed to register fmd: " + "%s\n", topo_mod_errmsg(mod)); + return (-1); /* mod errno already set */ + } + + return (0); +} + +void +fmd_fini(topo_mod_t *mod) +{ + topo_mod_unregister(mod); +} + + +/*ARGSUSED*/ +int +fmd_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, + topo_instance_t max, void *notused1, void *notused2) +{ + (void) topo_method_register(mod, pnode, fmd_methods); + return (0); +} + +/*ARGSUSED*/ +static void +fmd_release(topo_mod_t *mp, tnode_t *node) +{ + topo_method_unregister_all(mp, node); +} + +static ssize_t +fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) +{ + char *name; + + if (nvlist_lookup_string(nvl, FM_FMRI_FMD_NAME, &name) != 0) + return (0); + + return (snprintf(buf, buflen, + "%s:///module/%s", FM_FMRI_SCHEME_FMD, name)); +} + +/*ARGSUSED*/ +static int +fmd_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *nvl, nvlist_t **out) +{ + ssize_t len; + char *name = NULL; + nvlist_t *fmristr; + + if (version > TOPO_METH_NVL2STR_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0 || + (name = topo_mod_alloc(mod, len + 1)) == NULL || + fmri_nvl2str(nvl, name, len + 1) == 0) { + if (name != NULL) + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + + if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) { + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + if (nvlist_add_string(fmristr, "fmri-string", name) != 0) { + topo_mod_free(mod, name, len + 1); + nvlist_free(fmristr); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + topo_mod_free(mod, name, len + 1); + *out = fmristr; + + return (0); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/fmd.h b/usr/src/lib/fm/topo/libtopo/common/fmd.h new file mode 100644 index 0000000000..64d48b8d41 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/fmd.h @@ -0,0 +1,46 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FMD_H +#define _FMD_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FMD_VERSION 1 +#define FMD "fmd" + +extern int fmd_init(topo_mod_t *, topo_version_t); /* see fmd.c */ +extern void fmd_fini(topo_mod_t *); /* see fmd.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FMD_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/legacy_hc.c b/usr/src/lib/fm/topo/libtopo/common/legacy_hc.c new file mode 100644 index 0000000000..f62cb767cb --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/legacy_hc.c @@ -0,0 +1,216 @@ +/* + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <alloca.h> +#include <limits.h> +#include <fm/topo_mod.h> +#include <sys/param.h> +#include <sys/systeminfo.h> +#include <sys/fm/protocol.h> +#include <sys/stat.h> + +#include <topo_method.h> +#include <topo_subr.h> +#include <legacy_hc.h> + +static int legacy_hc_enum(topo_mod_t *, tnode_t *, const char *, + topo_instance_t, topo_instance_t, void *, void *); +static void legacy_hc_release(topo_mod_t *, tnode_t *); +static int legacy_hc_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +const topo_method_t legacy_hc_methods[] = { + { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, + TOPO_STABILITY_INTERNAL, legacy_hc_fmri_nvl2str }, + { NULL } +}; + +static const topo_modops_t legacy_hc_ops = + { legacy_hc_enum, legacy_hc_release }; +static const topo_modinfo_t legacy_hc_info = + { LEGACY_HC, FM_FMRI_SCHEME_LEGACY, LEGACY_HC_VERSION, &legacy_hc_ops }; + +int +legacy_hc_init(topo_mod_t *mod, topo_version_t version) +{ + /* + * Turn on module debugging output + */ + if (getenv("TOPOLEGACY_HCDEBUG")) + topo_mod_setdebug(mod); + + topo_mod_dprintf(mod, "initializing legacy_hc builtin\n"); + + if (version != LEGACY_HC_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &legacy_hc_info, TOPO_VERSION) != 0) { + topo_mod_dprintf(mod, "failed to register legacy_hc: " + "%s\n", topo_mod_errmsg(mod)); + return (-1); /* mod errno already set */ + } + + return (0); +} + +void +legacy_hc_fini(topo_mod_t *mod) +{ + topo_mod_unregister(mod); +} + + +/*ARGSUSED*/ +int +legacy_hc_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) +{ + (void) topo_method_register(mod, pnode, legacy_hc_methods); + return (0); +} + +/*ARGSUSED*/ +static void +legacy_hc_release(topo_mod_t *mp, tnode_t *node) +{ + topo_method_unregister_all(mp, node); +} + +/* + * Convert an input string to a URI escaped string and return the new string. + * RFC2396 Section 2.4 says that data must be escaped if it does not have a + * representation using an unreserved character, where an unreserved character + * is one that is either alphanumeric or one of the marks defined in S2.3. + */ +static size_t +mem_fmri_uriescape(const char *s, const char *xmark, char *buf, size_t len) +{ + static const char rfc2396_mark[] = "-_.!~*'()"; + static const char hex_digits[] = "0123456789ABCDEF"; + static const char empty_str[] = ""; + + const char *p; + char c, *q; + size_t n = 0; + + if (s == NULL) + s = empty_str; + + if (xmark == NULL) + xmark = empty_str; + + for (p = s; (c = *p) != '\0'; p++) { + if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c)) + n++; /* represent c as itself */ + else + n += 3; /* represent c as escape */ + } + + if (buf == NULL) + return (n); + + for (p = s, q = buf; (c = *p) != '\0' && q < buf + len; p++) { + if (isalnum(c) || strchr(rfc2396_mark, c) || strchr(xmark, c)) { + *q++ = c; + } else { + *q++ = '%'; + *q++ = hex_digits[((uchar_t)c & 0xf0) >> 4]; + *q++ = hex_digits[(uchar_t)c & 0xf]; + } + } + + if (q == buf + len) + q--; /* len is too small: truncate output string */ + + *q = '\0'; + return (n); +} + +static ssize_t +fmri_nvl2str(topo_mod_t *mod, nvlist_t *nvl, char *buf, size_t buflen) +{ + uint8_t version; + ssize_t size; + char *c; + char *escc; + int i; + + if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || + version > FM_LEGACY_SCHEME_VERSION || + nvlist_lookup_string(nvl, FM_FMRI_LEGACY_HC, &c) != 0) + return (0); + + i = mem_fmri_uriescape(c, ":,/", NULL, 0); + escc = topo_mod_alloc(mod, i + 1); + (void) mem_fmri_uriescape(c, ":,/", escc, i + 1); + size = snprintf(buf, buflen, "legacy-hc:///component=%s", escc); + topo_mod_free(mod, escc, i + 1); + + return (size); +} + +/*ARGSUSED*/ +static int +legacy_hc_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *nvl, nvlist_t **out) +{ + ssize_t len; + char *name = NULL; + nvlist_t *fmristr; + + if (version > TOPO_METH_NVL2STR_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if ((len = fmri_nvl2str(mod, nvl, NULL, 0)) == 0 || + (name = topo_mod_alloc(mod, len + 1)) == NULL || + fmri_nvl2str(mod, nvl, name, len + 1) == 0) { + if (name != NULL) + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + + if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) { + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + if (nvlist_add_string(fmristr, "fmri-string", name) != 0) { + topo_mod_free(mod, name, len + 1); + nvlist_free(fmristr); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + topo_mod_free(mod, name, len + 1); + *out = fmristr; + + return (0); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/legacy_hc.h b/usr/src/lib/fm/topo/libtopo/common/legacy_hc.h new file mode 100644 index 0000000000..4425fad98d --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/legacy_hc.h @@ -0,0 +1,46 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LEGACY_HC_H +#define _LEGACY_HC_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LEGACY_HC_VERSION 1 +#define LEGACY_HC "legacy-hc" + +extern int legacy_hc_init(topo_mod_t *, topo_version_t); +extern void legacy_hc_fini(topo_mod_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _LEGACY_HC_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/mod.c b/usr/src/lib/fm/topo/libtopo/common/mod.c index efa986cb1b..4961739949 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mod.c +++ b/usr/src/lib/fm/topo/libtopo/common/mod.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -266,11 +266,12 @@ fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) ssize_t size = 0; int32_t modid; char *achas = NULL; + char *adom = NULL; char *aprod = NULL; char *asrvr = NULL; + char *ahost = NULL; char *modname = NULL; char numbuf[MAXINTSTR]; - int more_auth = 0; int err; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || @@ -304,13 +305,11 @@ fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) (void) nvlist_lookup_string(anvl, FM_FMRI_AUTH_CHASSIS, &achas); (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_DOMAIN, &adom); + (void) nvlist_lookup_string(anvl, FM_FMRI_AUTH_SERVER, &asrvr); - if (aprod != NULL) - more_auth++; - if (achas != NULL) - more_auth++; - if (asrvr != NULL) - more_auth++; + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_HOST, &ahost); } /* mod:// */ @@ -323,9 +322,15 @@ fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) if (achas != NULL) topo_fmristr_build(&size, buf, buflen, achas, ":" FM_FMRI_AUTH_CHASSIS "=", NULL); + if (adom != NULL) + topo_fmristr_build(&size, buf, buflen, adom, + ":" FM_FMRI_AUTH_DOMAIN "=", NULL); if (asrvr != NULL) topo_fmristr_build(&size, buf, buflen, asrvr, ":" FM_FMRI_AUTH_SERVER "=", NULL); + if (ahost != NULL) + topo_fmristr_build(&size, buf, buflen, ahost, + ":" FM_FMRI_AUTH_HOST "=", NULL); /* module parts */ topo_fmristr_build(&size, buf, buflen, modname, diff --git a/usr/src/lib/fm/topo/libtopo/common/pkg.c b/usr/src/lib/fm/topo/libtopo/common/pkg.c index 81aa321cae..e952907f59 100644 --- a/usr/src/lib/fm/topo/libtopo/common/pkg.c +++ b/usr/src/lib/fm/topo/libtopo/common/pkg.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,6 +45,7 @@ #include <gelf.h> #include <topo_method.h> +#include <topo_subr.h> #include <pkg.h> #define BUFLEN (2 * PATH_MAX) @@ -54,10 +55,14 @@ static int pkg_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, static void pkg_release(topo_mod_t *, tnode_t *); static int pkg_fmri_create_meth(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); +static int pkg_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); static const topo_method_t pkg_methods[] = { { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION, TOPO_STABILITY_INTERNAL, pkg_fmri_create_meth }, + { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, + TOPO_STABILITY_INTERNAL, pkg_fmri_nvl2str }, { NULL } }; @@ -238,3 +243,107 @@ pkg_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, return (-1); return (0); } + +static ssize_t +fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) +{ + nvlist_t *anvl = NULL; + uint8_t version; + ssize_t size = 0; + char *pkgname = NULL; + char *achas = NULL; + char *adom = NULL; + char *aprod = NULL; + char *asrvr = NULL; + char *ahost = NULL; + int err; + + if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || + version > FM_PKG_SCHEME_VERSION) + return (-1); + + /* Get authority, if present */ + err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl); + if (err != 0 && err != ENOENT) + return (-1); + + /* + * For brevity, we only include the pkgname and any authority + * info present in the FMRI in our output string. The FMRI + * also has data on the package directory and version. + */ + err = nvlist_lookup_string(nvl, FM_FMRI_PKG_INST, &pkgname); + if (err != 0 || pkgname == NULL) + return (-1); + + if (anvl != NULL) { + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_PRODUCT, &aprod); + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_CHASSIS, &achas); + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_DOMAIN, &adom); + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_SERVER, &asrvr); + (void) nvlist_lookup_string(anvl, + FM_FMRI_AUTH_HOST, &ahost); + } + + /* pkg:// */ + topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_PKG, NULL, "://"); + + /* authority, if any */ + if (aprod != NULL) + topo_fmristr_build(&size, buf, buflen, aprod, + FM_FMRI_AUTH_PRODUCT "=", NULL); + if (achas != NULL) + topo_fmristr_build(&size, buf, buflen, achas, + FM_FMRI_AUTH_CHASSIS "=", NULL); + if (adom != NULL) + topo_fmristr_build(&size, buf, buflen, adom, + FM_FMRI_AUTH_DOMAIN "=", NULL); + if (asrvr != NULL) + topo_fmristr_build(&size, buf, buflen, asrvr, + FM_FMRI_AUTH_SERVER "=", NULL); + if (ahost != NULL) + topo_fmristr_build(&size, buf, buflen, ahost, + FM_FMRI_AUTH_HOST "=", NULL); + + /* pkg-name part */ + topo_fmristr_build(&size, buf, buflen, pkgname, "/", NULL); + + return (size); +} + +/*ARGSUSED*/ +static int +pkg_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *nvl, nvlist_t **out) +{ + ssize_t len; + char *name = NULL; + nvlist_t *fmristr; + + if (version > TOPO_METH_NVL2STR_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0 || + (name = topo_mod_alloc(mod, len + 1)) == NULL || + fmri_nvl2str(nvl, name, len + 1) == 0) { + if (name != NULL) + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + + if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + if (nvlist_add_string(fmristr, "fmri-string", name) != 0) { + topo_mod_free(mod, name, len + 1); + nvlist_free(fmristr); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + topo_mod_free(mod, name, len + 1); + *out = fmristr; + + return (0); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/zfs.c b/usr/src/lib/fm/topo/libtopo/common/zfs.c new file mode 100644 index 0000000000..b7bcda4974 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/zfs.c @@ -0,0 +1,203 @@ +/* + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <alloca.h> +#include <limits.h> +#include <fm/topo_mod.h> +#include <sys/param.h> +#include <sys/systeminfo.h> +#include <sys/fm/protocol.h> +#include <sys/stat.h> + +#include <topo_method.h> +#include <topo_subr.h> +#include <libzfs.h> +#include <zfs.h> + +static int zfs_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, + topo_instance_t, void *, void *); +static void zfs_release(topo_mod_t *, tnode_t *); +static int zfs_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +const topo_method_t zfs_methods[] = { + { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, + TOPO_STABILITY_INTERNAL, zfs_fmri_nvl2str }, + { NULL } +}; + +static const topo_modops_t zfs_ops = + { zfs_enum, zfs_release }; +static const topo_modinfo_t zfs_info = + { ZFS, FM_FMRI_SCHEME_ZFS, ZFS_VERSION, &zfs_ops }; + +int +zfs_init(topo_mod_t *mod, topo_version_t version) +{ + /* + * Turn on module debugging output + */ + if (getenv("TOPOZFSDEBUG")) + topo_mod_setdebug(mod); + + topo_mod_dprintf(mod, "initializing zfs builtin\n"); + + if (version != ZFS_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &zfs_info, TOPO_VERSION) != 0) { + topo_mod_dprintf(mod, "failed to register zfs: " + "%s\n", topo_mod_errmsg(mod)); + return (-1); /* mod errno already set */ + } + + return (0); +} + +void +zfs_fini(topo_mod_t *mod) +{ + topo_mod_unregister(mod); +} + + +/*ARGSUSED*/ +int +zfs_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, + topo_instance_t max, void *notused1, void *notused2) +{ + (void) topo_method_register(mod, pnode, zfs_methods); + return (0); +} + +/*ARGSUSED*/ +static void +zfs_release(topo_mod_t *mp, tnode_t *node) +{ + topo_method_unregister_all(mp, node); +} + +typedef struct cbdata { + uint64_t cb_guid; + zpool_handle_t *cb_pool; +} cbdata_t; + +libzfs_handle_t *g_zfs; + +static int +find_pool(zpool_handle_t *zhp, void *data) +{ + cbdata_t *cbp = data; + + if (zpool_get_prop_int(zhp, ZPOOL_PROP_GUID, NULL) == cbp->cb_guid) { + cbp->cb_pool = zhp; + return (1); + } + + zpool_close(zhp); + + return (0); +} + +static ssize_t +fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) +{ + uint64_t pool_guid, vdev_guid; + cbdata_t cb; + ssize_t len; + const char *name; + char guidbuf[64]; + + (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); + + /* + * Attempt to convert the pool guid to a name. + */ + cb.cb_guid = pool_guid; + cb.cb_pool = NULL; + + if (zpool_iter(g_zfs, find_pool, &cb) == 1) { + name = zpool_get_name(cb.cb_pool); + } else { + (void) snprintf(guidbuf, sizeof (guidbuf), "%llx", pool_guid); + name = guidbuf; + } + + if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) == 0) + len = snprintf(buf, buflen, "%s://pool=%s/vdev=%llx", + FM_FMRI_SCHEME_ZFS, name, vdev_guid); + else + len = snprintf(buf, buflen, "%s://pool=%s", + FM_FMRI_SCHEME_ZFS, name); + + if (cb.cb_pool) + zpool_close(cb.cb_pool); + + return (len); +} + +/*ARGSUSED*/ +static int +zfs_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *nvl, nvlist_t **out) +{ + ssize_t len; + char *name = NULL; + nvlist_t *fmristr; + + if (version > TOPO_METH_NVL2STR_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0 || + (name = topo_mod_alloc(mod, len + 1)) == NULL || + fmri_nvl2str(nvl, name, len + 1) == 0) { + if (name != NULL) + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + + if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) { + topo_mod_free(mod, name, len + 1); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + if (nvlist_add_string(fmristr, "fmri-string", name) != 0) { + topo_mod_free(mod, name, len + 1); + nvlist_free(fmristr); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + topo_mod_free(mod, name, len + 1); + *out = fmristr; + + return (0); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/zfs.h b/usr/src/lib/fm/topo/libtopo/common/zfs.h new file mode 100644 index 0000000000..c3adcc3537 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/zfs.h @@ -0,0 +1,46 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _ZFS_H +#define _ZFS_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZFS_VERSION 1 +#define ZFS "zfs" + +extern int zfs_init(topo_mod_t *, topo_version_t); /* see zfs.c */ +extern void zfs_fini(topo_mod_t *); /* see zfs.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_H */ diff --git a/usr/src/lib/fm/topo/libtopo/i386/Makefile b/usr/src/lib/fm/topo/libtopo/i386/Makefile index a333224278..cd8a4643d9 100644 --- a/usr/src/lib/fm/topo/libtopo/i386/Makefile +++ b/usr/src/lib/fm/topo/libtopo/i386/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -27,4 +27,6 @@ include ../Makefile.com +LDLIBS += -lzfs + install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/fm/topo/libtopo/sparc/Makefile b/usr/src/lib/fm/topo/libtopo/sparc/Makefile index ddd13b2c7d..976e50cd5f 100644 --- a/usr/src/lib/fm/topo/libtopo/sparc/Makefile +++ b/usr/src/lib/fm/topo/libtopo/sparc/Makefile @@ -30,4 +30,6 @@ include ../Makefile.com CPPFLAGS += -I $(ROOT)/usr/platform/sun4v/include LDLIBS += -L$(ROOTLIBDIR) +LDLIBS += -lzfs + install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile b/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile index 0db0f4bdc2..9a45e99e29 100644 --- a/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile +++ b/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile @@ -31,4 +31,6 @@ include ../../../../Makefile.lib.64 CPPFLAGS += -I $(ROOT)/usr/platform/sun4v/include LDLIBS += -L$(ROOTLIBDIR64) +LDLIBS += -lzfs + install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_amd.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_amd.c index 789398cfac..69a8804082 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_amd.c +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_amd.c @@ -484,6 +484,8 @@ amd_cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc, (void) topo_node_asru_set(csnode, fmri, 0, &err); + (void) topo_node_fru_set(csnode, fmri, 0, &err); + (void) topo_pgroup_create(csnode, &cs_pgroup, &err); for (nvp = nvlist_next_nvpair(csarr[i], NULL); nvp != NULL; @@ -503,6 +505,7 @@ amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *fmri; char *socket; int i, nchan; + nvlist_t *pfmri = NULL; int err, nerr = 0; /* @@ -521,6 +524,8 @@ amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, if (topo_node_range_create(mod, pnode, name, 0, nchan - 1) < 0) return (-1); + (void) topo_node_fru(pnode, &pfmri, NULL, &err); + for (i = 0; i < nchan; i++) { if (mkrsrc(mod, pnode, name, i, auth, &fmri) != 0) { whinge(mod, &nerr, "amd_dramchan_create: mkrsrc " @@ -536,6 +541,10 @@ amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, continue; } + (void) topo_node_asru_set(chnode, fmri, 0, &err); + if (pfmri) + (void) topo_node_fru_set(chnode, pfmri, 0, &err); + nvlist_free(fmri); (void) topo_pgroup_create(chnode, &chan_pgroup, &err); @@ -543,6 +552,8 @@ amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, (void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel", TOPO_PROP_IMMUTABLE, i == 0 ? "A" : "B", &err); } + if (pfmri) + nvlist_free(pfmri); return (nerr == 0 ? 0 : -1); } |