diff options
| author | cindi <none@none> | 2006-11-04 01:18:55 -0800 |
|---|---|---|
| committer | cindi <none@none> | 2006-11-04 01:18:55 -0800 |
| commit | 0eb822a1c0c2bea495647510b75f77f0e57633eb (patch) | |
| tree | d104741eef4bddb27171407d1243e37790c7d499 /usr/src/lib/fm/topo/libtopo/common/hc.c | |
| parent | 389056bd4327caca73482e60b80da00f4eaf3de9 (diff) | |
| download | illumos-joyent-0eb822a1c0c2bea495647510b75f77f0e57633eb.tar.gz | |
6396916 verification of dtd file name is wrong
6399876 libtopo does not properly support an alternate root path
6399927 libtopo debug information indicates "no topology file found" when it is unable to parse file.
6421101 fmsim doesn't allow simulated topology to be specified with new libtopo
6422759 fmd memory leaks detected on system experiencing significant pcie fabric errors
6429072 memory leak in iob_tnode_create
6448718 libtopo needs better enum module APIs
6467144 topo_fmri_str2nvl doesn't handle authority or properties
6473916 fmd should return a full populated topo snapshot in fmd_hdl_topology() and fmd_fmri_topology()
6473918 hc scheme plugin is_present routine is broken
6477382 Need public header file for hc scheme component names and properties
6477385 fmtopo -V needs to be more friendly
6477426 fmtopo -d should not be so chatty
6477430 Need ability to load additional libtopo map files
6477442 libtopo should allow alternate platform topo map files
6477446 Remove unused topo methods from enumerator modules
6477453 pcibus and hostbridge interface boundaries are a mess
6477456 hc enumerators must support authority information
6477461 topo_fru_compute and topo_asru_compute should return static props when computation fails
6480930 fmtopo should support a -x option
--HG--
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile => deleted_files/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile
rename : usr/src/lib/fm/topo/modules/common/pcifn_enum.c => deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.c
rename : usr/src/lib/fm/topo/modules/common/pcifn_enum.h => deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.h
rename : usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile => deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile
rename : usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c => deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c
rename : usr/src/lib/fm/topo/libtopo/common/hc_canon.h => usr/src/lib/fm/topo/libtopo/common/topo_hc.h
rename : usr/src/lib/fm/topo/files/Makefile => usr/src/lib/fm/topo/maps/Makefile
rename : usr/src/lib/fm/topo/files/Makefile.file => usr/src/lib/fm/topo/maps/Makefile.map
rename : usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/Makefile => usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/SPARC-Enterprise-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Sun-Fire-hc-topology.xml
rename : usr/src/lib/fm/topo/files/common/topology.dtd.1 => usr/src/lib/fm/topo/maps/common/topology.dtd.1
rename : usr/src/lib/fm/topo/files/i86pc/Makefile => usr/src/lib/fm/topo/maps/i86pc/Makefile
rename : usr/src/lib/fm/topo/files/i86pc/hc-topology.xml => usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml
rename : usr/src/lib/fm/topo/files/sun4u/Makefile => usr/src/lib/fm/topo/maps/sun4u/Makefile
rename : usr/src/lib/fm/topo/files/sun4u/hc-topology.xml => usr/src/lib/fm/topo/maps/sun4u/sun4u-hc-topology.xml
rename : usr/src/lib/fm/topo/files/sun4v/Makefile => usr/src/lib/fm/topo/maps/sun4v/Makefile
rename : usr/src/lib/fm/topo/files/sun4v/hc-topology.xml => usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml
rename : usr/src/lib/fm/topo/modules/common/hostbridge.c => usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.c
rename : usr/src/lib/fm/topo/modules/common/hostbridge.h => usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.h
rename : usr/src/lib/fm/topo/modules/common/did.c => usr/src/lib/fm/topo/modules/common/pcibus/did.c
rename : usr/src/lib/fm/topo/modules/common/did.h => usr/src/lib/fm/topo/modules/common/pcibus/did.h
rename : usr/src/lib/fm/topo/modules/common/did_hash.c => usr/src/lib/fm/topo/modules/common/pcibus/did_hash.c
rename : usr/src/lib/fm/topo/modules/common/did_impl.h => usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h
rename : usr/src/lib/fm/topo/modules/common/did_props.c => usr/src/lib/fm/topo/modules/common/pcibus/did_props.c
rename : usr/src/lib/fm/topo/modules/common/did_props.h => usr/src/lib/fm/topo/modules/common/pcibus/did_props.h
rename : usr/src/lib/fm/topo/modules/common/pcibus.c => usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c
rename : usr/src/lib/fm/topo/modules/common/pcibus.h => usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h
rename : usr/src/lib/fm/topo/modules/common/pcibus_labels.c => usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c
rename : usr/src/lib/fm/topo/modules/common/pcibus_labels.h => usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h
rename : usr/src/lib/fm/topo/modules/common/util.c => usr/src/lib/fm/topo/modules/common/pcibus/util.c
rename : usr/src/lib/fm/topo/modules/common/util.h => usr/src/lib/fm/topo/modules/common/pcibus/util.h
Diffstat (limited to 'usr/src/lib/fm/topo/libtopo/common/hc.c')
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/hc.c | 411 |
1 files changed, 303 insertions, 108 deletions
diff --git a/usr/src/lib/fm/topo/libtopo/common/hc.c b/usr/src/lib/fm/topo/libtopo/common/hc.c index b94e02699e..9719af0684 100644 --- a/usr/src/lib/fm/topo/libtopo/common/hc.c +++ b/usr/src/lib/fm/topo/libtopo/common/hc.c @@ -35,26 +35,21 @@ #include <alloca.h> #include <limits.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <sys/param.h> #include <sys/systeminfo.h> #include <sys/fm/protocol.h> -#include <topo_parse.h> -#include <topo_subr.h> - -#include <hc_canon.h> +#include <sys/stat.h> +#include <sys/systeminfo.h> +#include <sys/utsname.h> -#define HC "hc" -#define HC_VERSION TOPO_VERSION +#include <topo_method.h> +#include <topo_subr.h> +#include <hc.h> static int hc_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void hc_release(topo_mod_t *, tnode_t *); -static int hc_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hc_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hc_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); static int hc_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static int hc_fmri_str2nvl(topo_mod_t *, tnode_t *, topo_version_t, @@ -69,12 +64,6 @@ static nvlist_t *hc_fmri_create(topo_mod_t *, nvlist_t *, int, const char *, const char *); const topo_method_t hc_methods[] = { - { "hc_contains", "Hardware Component Contains", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_contains }, - { "hc_present", "Hardware Component Present", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_present }, - { "hc_unusable", "Hardware Component Unusable", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_unusable }, { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, TOPO_STABILITY_INTERNAL, hc_fmri_nvl2str }, { TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_DESC, TOPO_METH_STR2NVL_VERSION, @@ -86,67 +75,187 @@ const topo_method_t hc_methods[] = { { NULL } }; -const topo_modinfo_t hc_info = - { HC, HC_VERSION, hc_enum, hc_release }; +static const topo_modops_t hc_ops = + { hc_enum, hc_release }; +static const topo_modinfo_t hc_info = + { HC, FM_FMRI_SCHEME_HC, HC_VERSION, &hc_ops }; + +static const hcc_t hc_canon[] = { + { CMP, TOPO_STABILITY_PRIVATE }, + { CENTERPLANE, TOPO_STABILITY_PRIVATE }, + { CHASSIS, TOPO_STABILITY_PRIVATE }, + { CHIP, TOPO_STABILITY_PRIVATE }, + { CHIP_SELECT, TOPO_STABILITY_PRIVATE }, + { CPU, TOPO_STABILITY_PRIVATE }, + { DIMM, TOPO_STABILITY_PRIVATE }, + { DISK, TOPO_STABILITY_PRIVATE }, + { DRAMCHANNEL, TOPO_STABILITY_PRIVATE }, + { HOSTBRIDGE, TOPO_STABILITY_PRIVATE }, + { INTERCONNECT, TOPO_STABILITY_PRIVATE }, + { IOBOARD, TOPO_STABILITY_PRIVATE }, + { MEMORYCONTROL, TOPO_STABILITY_PRIVATE }, + { MOTHERBOARD, TOPO_STABILITY_PRIVATE }, + { PCI_BUS, TOPO_STABILITY_PRIVATE }, + { PCI_DEVICE, TOPO_STABILITY_PRIVATE }, + { PCI_FUNCTION, TOPO_STABILITY_PRIVATE }, + { PCIEX_BUS, TOPO_STABILITY_PRIVATE }, + { PCIEX_DEVICE, TOPO_STABILITY_PRIVATE }, + { PCIEX_FUNCTION, TOPO_STABILITY_PRIVATE }, + { PCIEX_ROOT, TOPO_STABILITY_PRIVATE }, + { PCIEX_SWUP, TOPO_STABILITY_PRIVATE }, + { PCIEX_SWDWN, TOPO_STABILITY_PRIVATE }, + { RANK, TOPO_STABILITY_PRIVATE }, + { SATA_PORT, TOPO_STABILITY_PRIVATE }, + { SYSTEMBOARD, TOPO_STABILITY_PRIVATE } +}; + +static int hc_ncanon = sizeof (hc_canon) / sizeof (hcc_t); -void -hc_init(topo_mod_t *mp) +int +hc_init(topo_mod_t *mod, topo_version_t version) { /* * Turn on module debugging output */ - topo_mod_setdebug(mp, TOPO_DBG_ALL); - topo_mod_dprintf(mp, "initializing hc builtin\n"); + if (getenv("TOPOHCDEBUG")) + topo_mod_setdebug(mod); + + topo_mod_dprintf(mod, "initializing hc builtin\n"); - if (topo_mod_register(mp, &hc_info, NULL) != 0) { - topo_mod_dprintf(mp, "failed to register hc: " - "%s\n", topo_mod_errmsg(mp)); + if (version != HC_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &hc_info, TOPO_VERSION) != 0) { + topo_mod_dprintf(mod, "failed to register hc: " + "%s\n", topo_mod_errmsg(mod)); + return (-1); /* mod errno already set */ } + + return (0); } void -hc_fini(topo_mod_t *mp) +hc_fini(topo_mod_t *mod) { - topo_mod_unregister(mp); + topo_mod_unregister(mod); +} + + +static const topo_pgroup_info_t sys_pgroup = { + TOPO_PGROUP_SYSTEM, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +static const topo_pgroup_info_t auth_pgroup = { + FM_FMRI_AUTHORITY, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +static void +hc_prop_set(tnode_t *node, nvlist_t *auth) +{ + int err; + char isa[MAXNAMELEN]; + struct utsname uts; + char *prod, *csn, *server; + + if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) { + if (err != ETOPO_PROP_DEFD) + return; + } + + /* + * Inherit if we can, it saves memory + */ + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) + == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, + &err); + } + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, + &err); + } + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) + == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, + &err); + } + + if (topo_pgroup_create(node, &sys_pgroup, &err) != 0) + return; + + isa[0] = '\0'; + (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); + (void) uname(&uts); + (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, + TOPO_PROP_IMMUTABLE, isa, &err); + (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, + TOPO_PROP_IMMUTABLE, uts.machine, &err); } /*ARGSUSED*/ int -hc_enum(topo_mod_t *mp, tnode_t *pnode, const char *name, topo_instance_t min, - topo_instance_t max, void *notused) +hc_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, + topo_instance_t max, void *notused1, void *arg) { nvlist_t *pfmri = NULL; nvlist_t *nvl; + nvlist_t *auth; + tnode_t *node; int err; /* * Register root node methods */ if (strcmp(name, HC) == 0) { - (void) topo_method_register(mp, pnode, hc_methods); + (void) topo_method_register(mod, pnode, hc_methods); return (0); } if (min != max) { - topo_mod_dprintf(mp, + topo_mod_dprintf(mod, "Request to enumerate %s component with an " "ambiguous instance number, min (%d) != max (%d).\n", HC, min, max); - return (topo_mod_seterrno(mp, EINVAL)); + return (topo_mod_seterrno(mod, EINVAL)); } (void) topo_node_resource(pnode, &pfmri, &err); - nvl = hc_fmri_create(mp, pfmri, FM_HC_SCHEME_VERSION, name, min, - NULL, NULL, NULL, NULL); + if (arg == NULL) + auth = topo_mod_auth(mod, pnode); + nvl = hc_fmri_create(mod, pfmri, FM_HC_SCHEME_VERSION, name, min, + auth, NULL, NULL, NULL); nvlist_free(pfmri); /* callee ignores NULLs */ - if (nvl == NULL) + if (nvl == NULL) { + nvlist_free(auth); return (-1); + } - if (topo_node_bind(mp, pnode, name, min, nvl, NULL) == NULL) { - topo_mod_dprintf(mp, "topo_node_bind failed: %s\n", - topo_strerror(topo_mod_errno(mp))); + if ((node = topo_node_bind(mod, pnode, name, min, nvl)) == NULL) { + topo_mod_dprintf(mod, "topo_node_bind failed: %s\n", + topo_strerror(topo_mod_errno(mod))); + nvlist_free(auth); nvlist_free(nvl); return (-1); } + + if (arg == NULL) + hc_prop_set(node, auth); nvlist_free(nvl); + nvlist_free(auth); + return (0); } @@ -159,31 +268,7 @@ hc_release(topo_mod_t *mp, tnode_t *node) /*ARGSUSED*/ static int -hc_contains(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_present(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_unusable(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, +hc_compare(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { uint8_t v1, v2; @@ -193,21 +278,21 @@ hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, uint_t nhcp1, nhcp2; if (version > TOPO_METH_COMPARE_VERSION) - return (topo_mod_seterrno(mp, EMOD_VER_NEW)); + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (nvlist_lookup_nvlist(in, "nv1", &nv1) != 0 || nvlist_lookup_nvlist(in, "nv2", &nv2) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); if (nvlist_lookup_uint8(nv1, FM_VERSION, &v1) != 0 || nvlist_lookup_uint8(nv2, FM_VERSION, &v2) != 0 || v1 > FM_HC_SCHEME_VERSION || v2 > FM_HC_SCHEME_VERSION) - return (topo_mod_seterrno(mp, EMOD_FMRI_VERSION)); + return (topo_mod_seterrno(mod, EMOD_FMRI_VERSION)); err = nvlist_lookup_nvlist_array(nv1, FM_FMRI_HC_LIST, &hcp1, &nhcp1); err |= nvlist_lookup_nvlist_array(nv2, FM_FMRI_HC_LIST, &hcp2, &nhcp2); if (err != 0) - return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); if (nhcp1 != nhcp2) return (0); @@ -223,7 +308,7 @@ hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, (void) nvlist_lookup_string(hcp1[i], FM_FMRI_HC_ID, &id1); (void) nvlist_lookup_string(hcp2[i], FM_FMRI_HC_ID, &id2); if (nm1 == NULL || nm2 == NULL || id1 == NULL || id2 == NULL) - return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); if (strcmp(nm1, nm2) == 0 && strcmp(id1, id2) == 0) continue; @@ -303,28 +388,19 @@ fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) /* authority, if any */ if (aprod != NULL) topo_fmristr_build(&size, - buf, buflen, aprod, FM_FMRI_AUTH_PRODUCT "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, aprod, ":" FM_FMRI_AUTH_PRODUCT "=", NULL); if (achas != NULL) topo_fmristr_build(&size, - buf, buflen, achas, FM_FMRI_AUTH_CHASSIS "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, achas, ":" FM_FMRI_AUTH_CHASSIS "=", NULL); if (adom != NULL) topo_fmristr_build(&size, - buf, buflen, adom, FM_FMRI_AUTH_DOMAIN "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, adom, ":" FM_FMRI_AUTH_DOMAIN "=", NULL); if (asrvr != NULL) topo_fmristr_build(&size, - buf, buflen, asrvr, FM_FMRI_AUTH_SERVER "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, asrvr, ":" FM_FMRI_AUTH_SERVER "=", NULL); if (ahost != NULL) topo_fmristr_build(&size, - buf, buflen, ahost, FM_FMRI_AUTH_HOST "=", - NULL); - - /* separating slash */ - if (serial != NULL || part != NULL || rev != NULL) - topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL); + buf, buflen, ahost, ":" FM_FMRI_AUTH_HOST "=", NULL); /* hardware-id part */ topo_fmristr_build(&size, @@ -430,9 +506,10 @@ hc_base_fmri_create(topo_mod_t *mod, const nvlist_t *auth, const char *part, } static nvlist_t ** -make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) +make_hc_pairs(topo_mod_t *mod, char *fmri, int *num) { nvlist_t **pa; + char *hc, *fromstr; char *starti, *startn, *endi, *endi2; char *ne, *ns; char *cname; @@ -442,12 +519,18 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) int npairs = 0; int i, e; + if ((hc = topo_mod_strdup(mod, fmri + 5)) == NULL) + return (NULL); + /* * Count equal signs and slashes to determine how many * hc-pairs will be present in the final FMRI. There should * be at least as many slashes as equal signs. There can be * more, though if the string after an = includes them. */ + if ((fromstr = strchr(hc, '/')) == NULL) + return (NULL); + find = fromstr; while ((ne = strchr(find, '=')) != NULL) { find = ne + 1; @@ -463,8 +546,10 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) /* * Do we appear to have a well-formed string version of the FMRI? */ - if (nslashes < npairs || npairs == 0) + if (nslashes < npairs || npairs == 0) { + topo_mod_strfree(mod, hc); return (NULL); + } *num = npairs; @@ -528,12 +613,101 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) if (pa[i--] != NULL) nvlist_free(pa[i + 1]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + topo_mod_strfree(mod, hc); return (NULL); } + topo_mod_strfree(mod, hc); + return (pa); } +void +make_hc_auth(topo_mod_t *mod, char *fmri, char **serial, char **part, +char **rev, nvlist_t **auth) +{ + char *starti, *startn, *endi, *copy; + char *aname, *aid, *fs; + nvlist_t *na = NULL; + size_t len; + + if ((copy = topo_mod_strdup(mod, fmri + 5)) == NULL) + return; + + len = strlen(copy); + + /* + * Make sure there are a valid authority members + */ + startn = strchr(copy, ':'); + fs = strchr(copy, '/'); + + if (startn == NULL || fs == NULL) { + topo_mod_strfree(mod, copy); + return; + } + + /* + * The first colon we encounter must occur before the + * first slash + */ + if (startn > fs) + return; + + do { + if (++startn >= copy + len) + break; + + if ((starti = strchr(startn, '=')) == NULL) + break; + + *starti = '\0'; + if (++starti > copy + len) + break; + + if ((aname = topo_mod_strdup(mod, startn)) == NULL) + break; + + startn = endi = strchr(starti, ':'); + if (endi == NULL) + if ((endi = strchr(starti, '/')) == NULL) + break; + + *endi = '\0'; + if ((aid = topo_mod_strdup(mod, starti)) == NULL) { + topo_mod_strfree(mod, aname); + break; + } + + /* + * Return possible serial, part and revision + */ + if (strcmp(aname, FM_FMRI_HC_SERIAL_ID) == 0) { + *serial = aid; + } else if (strcmp(aname, FM_FMRI_HC_PART) == 0) { + *part = aid; + } else if (strcmp(aname, FM_FMRI_HC_REVISION) == 0) { + *rev = aid; + } else { + if (na == NULL) { + if (topo_mod_nvalloc(mod, &na, + NV_UNIQUE_NAME) == 0) { + nvlist_add_string(na, aname, aid); + } + } else { + (void) nvlist_add_string(na, aname, aid); + } + } + topo_mod_strfree(mod, aname); + topo_mod_strfree(mod, aid); + + } while (startn != NULL); + + *auth = na; + + topo_mod_free(mod, copy, len + 1); +} + /*ARGSUSED*/ static int hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, @@ -541,7 +715,9 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, { nvlist_t **pa = NULL; nvlist_t *nf = NULL; - char *str, *copy; + nvlist_t *auth = NULL; + char *str; + char *serial = NULL, *part = NULL, *rev = NULL; int npairs; int i, e; @@ -552,17 +728,14 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); /* We're expecting a string version of an hc scheme FMRI */ - if (strncmp(str, "hc:///", 6) != 0) + if (strncmp(str, "hc://", 5) != 0) return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); - copy = topo_mod_strdup(mod, str + 5); - if ((pa = make_hc_pairs(mod, copy, &npairs)) == NULL) { - topo_mod_strfree(mod, copy); + if ((pa = make_hc_pairs(mod, str, &npairs)) == NULL) return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); - } - topo_mod_strfree(mod, copy); - if ((nf = hc_base_fmri_create(mod, NULL, NULL, NULL, NULL)) == NULL) + make_hc_auth(mod, str, &serial, &part, &rev, &auth); + if ((nf = hc_base_fmri_create(mod, auth, part, rev, serial)) == NULL) goto hcfmbail; if ((e = nvlist_add_uint32(nf, FM_FMRI_HC_LIST_SZ, npairs)) == 0) e = nvlist_add_nvlist_array(nf, FM_FMRI_HC_LIST, pa, npairs); @@ -573,6 +746,14 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, for (i = 0; i < npairs; i++) nvlist_free(pa[i]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + if (serial != NULL) + topo_mod_strfree(mod, serial); + if (part != NULL) + topo_mod_strfree(mod, part); + if (rev != NULL) + topo_mod_strfree(mod, rev); + nvlist_free(auth); + *out = nf; return (0); @@ -583,6 +764,13 @@ hcfmbail: for (i = 0; i < npairs; i++) nvlist_free(pa[i]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + if (serial != NULL) + topo_mod_strfree(mod, serial); + if (part != NULL) + topo_mod_strfree(mod, part); + if (rev != NULL) + topo_mod_strfree(mod, rev); + nvlist_free(auth); return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); } @@ -629,20 +817,27 @@ hc_create_seterror(topo_mod_t *mod, nvlist_t **hcl, int n, nvlist_t *fmri, } static int -hc_name_canonical(const char *name) +hc_name_canonical(topo_mod_t *mod, const char *name) { int i; + + if (getenv("NOHCCHECK") != NULL) + return (1); + /* * Only enumerate elements with correct canonical names */ - for (i = 0; i < Hc_ncanon; i++) { - if (strcmp(name, Hc_canon[i]) == 0) + for (i = 0; i < hc_ncanon; i++) { + if (strcmp(name, hc_canon[i].hcc_name) == 0) break; } - if (i >= Hc_ncanon) + if (i >= hc_ncanon) { + topo_mod_dprintf(mod, "non-canonical name %s\n", + name); return (0); - else + } else { return (1); + } } static nvlist_t * @@ -667,7 +862,7 @@ hc_fmri_create(topo_mod_t *mod, nvlist_t *pfmri, int version, const char *name, /* * Check that the requested name is in our canonical list */ - if (hc_name_canonical(name) == 0) + if (hc_name_canonical(mod, name) == 0) return (hc_create_seterror(mod, hcl, pelems, fmri, EMOD_NONCANON)); /* @@ -717,7 +912,7 @@ hc_fmri_create(topo_mod_t *mod, nvlist_t *pfmri, int version, const char *name, /*ARGSUSED*/ static int -hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, +hc_fmri_create_meth(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { int ret; @@ -727,13 +922,13 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, char *name, *serial, *rev, *part; if (version > TOPO_METH_FMRI_VERSION) - return (topo_mod_seterrno(mp, EMOD_VER_NEW)); + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); /* First the must-have fields */ if (nvlist_lookup_string(in, TOPO_METH_FMRI_ARG_NAME, &name) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); if (nvlist_lookup_uint32(in, TOPO_METH_FMRI_ARG_INST, &inst) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); /* * args is optional @@ -744,7 +939,7 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, if ((ret = nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args)) != 0) { if (ret != ENOENT) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); } else { /* And then optional arguments */ @@ -759,8 +954,8 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, &serial); } - *out = hc_fmri_create(mp, - pfmri, version, name, inst, auth, part, rev, serial); + *out = hc_fmri_create(mod, pfmri, version, name, inst, auth, part, + rev, serial); if (*out == NULL) return (-1); return (0); |
