diff options
| author | Rob Johnston <rob.johnston@joyent.com> | 2019-03-21 03:50:37 +0000 |
|---|---|---|
| committer | Gordon Ross <gwr@nexenta.com> | 2019-05-14 15:01:56 -0400 |
| commit | 8abca89f418632e2ebd3bcbc8b0d814c394ebef1 (patch) | |
| tree | 17d07bddbfd865edbbd1b5620cb1777422aae1cc | |
| parent | 881aaecd29563bc45bf78a3c8f1e534275021925 (diff) | |
| download | illumos-joyent-8abca89f418632e2ebd3bcbc8b0d814c394ebef1.tar.gz | |
10898 Add topo method to determine occupant status
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Gordon Ross <gwr@nexenta.com>
| -rw-r--r-- | usr/src/cmd/fm/fmtopo/common/fmtopo.c | 10 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/hc.c | 18 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/libtopo.h | 3 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/mapfile-vers | 4 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_method.h | 6 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_mod.c | 34 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_mod.h | 4 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_mod.map | 3 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_node.c | 17 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/pcibus/pcibus_hba.c | 18 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/ses/ses.c | 21 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/shared/topo_port.c | 16 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c | 18 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c | 17 |
14 files changed, 179 insertions, 10 deletions
diff --git a/usr/src/cmd/fm/fmtopo/common/fmtopo.c b/usr/src/cmd/fm/fmtopo/common/fmtopo.c index 07fe40fafd..fb27c6c13f 100644 --- a/usr/src/cmd/fm/fmtopo/common/fmtopo.c +++ b/usr/src/cmd/fm/fmtopo/common/fmtopo.c @@ -89,7 +89,7 @@ usage(FILE *fp) "\t-p display of FMRI protocol properties\n" "\t-R set root directory for libtopo plug-ins and other files\n" "\t-s display topology for the specified FMRI scheme\n" - "\t-S display FMRI status (present/usable)\n" + "\t-S display FMRI status (present/usable/occupied)\n" "\t-V set verbose mode\n" "\t-x display a xml formatted topology\n"); @@ -127,6 +127,7 @@ static void print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) { int err, ret; + boolean_t is_occupied; (void) printf("%s\n", (char *)fmri); @@ -174,6 +175,13 @@ print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) else (void) printf("\tUnusable: %s\n", ret ? "true" : "false"); + + ret = topo_node_occupied(node, &is_occupied); + if (ret == 0) + (void) printf("\tOccupied: %s\n", + is_occupied ? "true" : "false"); + else if (ret != ETOPO_METHOD_NOTSUP) + (void) printf("\tOccupied: -\n"); } } diff --git a/usr/src/lib/fm/topo/libtopo/common/hc.c b/usr/src/lib/fm/topo/libtopo/common/hc.c index 8b6b57aeb1..9c64077549 100644 --- a/usr/src/lib/fm/topo/libtopo/common/hc.c +++ b/usr/src/lib/fm/topo/libtopo/common/hc.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <stdio.h> @@ -133,6 +133,13 @@ const topo_method_t hc_methods[] = { { NULL } }; +static const topo_method_t fru_container_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + static const topo_modops_t hc_ops = { hc_enum, hc_release }; static const topo_modinfo_t hc_info = @@ -280,6 +287,15 @@ hc_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, nvlist_free(nvl); return (-1); } + if (strcmp(name, BAY) == 0 || strcmp(name, PORT) == 0 || + strcmp(name, RECEPTACLE) == 0 || strcmp(name, SLOT) == 0) { + if (topo_method_register(mod, node, fru_container_methods) < + 0) { + topo_mod_dprintf(mod, "failed to register methods on " + "%s=%d\n", name, min); + return (-1); + } + } /* * Set FRU for the motherboard node diff --git a/usr/src/lib/fm/topo/libtopo/common/libtopo.h b/usr/src/lib/fm/topo/libtopo/common/libtopo.h index d3babc9340..b230510afd 100644 --- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h +++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h @@ -23,7 +23,7 @@ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2018, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. */ #ifndef _LIBTOPO_H @@ -142,6 +142,7 @@ extern int topo_node_facility(topo_hdl_t *, tnode_t *, const char *, uint32_t, topo_faclist_t *, int *); extern int topo_node_child_walk(topo_hdl_t *, tnode_t *, topo_walk_cb_t, void *, int *); +extern int topo_node_occupied(tnode_t *, boolean_t *); /* * Node flags: denotes type of node diff --git a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers index 5bafce8002..c7b02e9958 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers +++ b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers @@ -20,7 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2018, Joyent, Inc. +# Copyright (c) 2019, Joyent, Inc. # # @@ -104,6 +104,7 @@ SYMBOL_VERSION SUNWprivate { topo_mod_free; topo_mod_getspecific; topo_mod_hcfmri; + topo_mod_hc_occupied; topo_mod_ipmi_hold; topo_mod_ipmi_rele; topo_mod_load; @@ -142,6 +143,7 @@ SYMBOL_VERSION SUNWprivate { topo_node_label_set; topo_node_lookup; topo_node_name; + topo_node_occupied; topo_node_parent; topo_node_range_create; topo_node_range_destroy; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_method.h b/usr/src/lib/fm/topo/libtopo/common/topo_method.h index 3cf14b92ec..c0ced1c188 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_method.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.h @@ -24,7 +24,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #ifndef _TOPO_METHOD_H #define _TOPO_METHOD_H @@ -76,6 +76,7 @@ extern int topo_prop_method_version_register(tnode_t *, const char *, #define TOPO_METH_PGRP_GET "topo_pgrp_get" #define TOPO_METH_PROP_SET "topo_prop_set" #define TOPO_METH_FACILITY "topo_facility" +#define TOPO_METH_OCCUPIED "topo_occupied" #define TOPO_METH_FMRI_VERSION 0 #define TOPO_METH_FRU_COMPUTE_VERSION 0 @@ -87,6 +88,7 @@ extern int topo_prop_method_version_register(tnode_t *, const char *, #define TOPO_METH_PGRP_GET_VERSION 0 #define TOPO_METH_PROP_SET_VERSION 0 #define TOPO_METH_FACILITY_VERSION 0 +#define TOPO_METH_OCCUPIED_VERSION 0 #define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor" #define TOPO_METH_FRU_COMPUTE_DESC "Dynamic FRU constructor" @@ -98,8 +100,10 @@ extern int topo_prop_method_version_register(tnode_t *, const char *, #define TOPO_METH_PGRP_GET_DESC "get property group for FMRI" #define TOPO_METH_PROP_SET_DESC "set properties for FMRI" #define TOPO_METH_FACILITY_DESC "get facility for FMRI" +#define TOPO_METH_OCCUPIED_DESC "get occupant status" #define TOPO_METH_COMPARE_RET "compare-return" +#define TOPO_METH_OCCUPIED_RET "occupied-return" #define TOPO_METH_FMRI_ARG_NAME "child-name" #define TOPO_METH_FMRI_ARG_INST "child-inst" diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c index cecb147f21..9c6f52ee00 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c @@ -937,3 +937,37 @@ topo_mod_file_search(topo_mod_t *mod, const char *file, int oflags) topo_mod_strfree(mod, path); return (ret); } + +/*ARGSUSED*/ +int +topo_mod_hc_occupied(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *in, nvlist_t **out) +{ + nvlist_t *nvl = NULL; + tnode_t *cnp; + boolean_t is_occupied = B_FALSE; + + if (version > TOPO_METH_OCCUPIED_VERSION) + return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); + + /* + * Iterate though the child nodes. If there are no non-facility + * node children then it is unoccupied. + */ + for (cnp = topo_child_first(node); cnp != NULL; + cnp = topo_child_next(node, cnp)) { + if (topo_node_flags(cnp) != TOPO_NODE_FACILITY) + is_occupied = B_TRUE; + } + + if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || + nvlist_add_boolean_value(nvl, TOPO_METH_OCCUPIED_RET, + is_occupied) != 0) { + topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n"); + nvlist_free(nvl); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + *out = nvl; + + return (0); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h index e384ff83cf..762cc9d05c 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h @@ -23,7 +23,7 @@ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2018, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. */ #ifndef _TOPO_MOD_H @@ -297,6 +297,8 @@ extern int topo_mod_seterrno(topo_mod_t *, int); */ extern int topo_mod_file_search(topo_mod_t *, const char *file, int oflags); +extern topo_method_f topo_mod_hc_occupied; + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map index c5eaab059f..53a0177ab3 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map @@ -1,6 +1,6 @@ # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2018, Joyent, Inc. +# Copyright (c) 2019, Joyent, Inc. # # CDDL HEADER START # @@ -66,6 +66,7 @@ SYMBOL_SCOPE { topo_mod_str2nvl { TYPE = FUNCTION; FLAGS = extern }; topo_mod_auth { TYPE = FUNCTION; FLAGS = extern }; topo_mod_clean_str { TYPE = FUNCTION; FLAGS = extern }; + topo_mod_hc_occupied { TYPE = FUNCTION; FLAGS = extern }; topo_mod_walk_init { TYPE = FUNCTION; FLAGS = extern }; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_node.c b/usr/src/lib/fm/topo/libtopo/common/topo_node.c index 4ec11c081e..9a44e9e666 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_node.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_node.c @@ -893,3 +893,20 @@ out: topo_node_rele(pnode); return (ret); } + +int +topo_node_occupied(tnode_t *node, boolean_t *is_occupied) +{ + nvlist_t *out; + int err; + + if (topo_method_invoke(node, TOPO_METH_OCCUPIED, + TOPO_METH_OCCUPIED_VERSION, NULL, &out, &err) != 0) { + return (err); + } + (void) nvlist_lookup_boolean_value(out, TOPO_METH_OCCUPIED_RET, + is_occupied); + + nvlist_free(out); + return (0); +} diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_hba.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_hba.c index 6c0dd41927..852a5f2ead 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_hba.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_hba.c @@ -21,11 +21,13 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. */ #include <sys/fm/protocol.h> #include <strings.h> #include <fm/topo_mod.h> +#include <fm/topo_method.h> #include <sys/scsi/impl/inquiry.h> #include <sys/scsi/impl/scsi_sas.h> #include <sys/scsi/scsi_address.h> @@ -35,6 +37,13 @@ static const topo_pgroup_info_t storage_pgroup = { TOPO_PGROUP_STORAGE, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_method_t recep_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + void pci_di_prop_set(tnode_t *tn, di_node_t din, char *dpnm, char *tpnm) { @@ -312,6 +321,15 @@ pci_receptacle_instantiate(topo_mod_t *mod, tnode_t *parent, di_node_t pnode) (void) topo_prop_set_string(recep, TOPO_PGROUP_STORAGE, TOPO_STORAGE_SAS_PHY_MASK, TOPO_PROP_IMMUTABLE, pm, &err); + + if (topo_method_register(mod, recep, recep_methods) != 0) { + topo_mod_dprintf(mod, "topo_method_register() failed " + "on %s=%d: %s", RECEPTACLE, i, + topo_mod_errmsg(mod)); + /* errno set */ + continue; + } + pm = pm + strlen(pm) + 1; } diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses.c b/usr/src/lib/fm/topo/modules/common/ses/ses.c index 081ed619ec..2ac0dfdd34 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/ses.c +++ b/usr/src/lib/fm/topo/modules/common/ses/ses.c @@ -23,7 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <alloca.h> @@ -267,6 +267,16 @@ static const topo_method_t ses_component_methods[] = { static const topo_method_t ses_bay_methods[] = { { TOPO_METH_FAC_ENUM, TOPO_METH_FAC_ENUM_DESC, 0, TOPO_STABILITY_INTERNAL, ses_node_enum_facility }, + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + +static const topo_method_t ses_recep_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, { NULL } }; @@ -2133,6 +2143,15 @@ ses_create_esc_sasspecific(ses_enum_data_t *sdp, ses_enum_node_t *snp, contn, connectors[i].scpd_pm) != 0) { continue; } + if (topo_method_register(mod, contn, + ses_recep_methods) != 0) { + topo_mod_dprintf(mod, + "topo_method_register() failed: " + "%s", + topo_mod_errmsg(mod)); + continue; + } + } } /* end indentation change */ diff --git a/usr/src/lib/fm/topo/modules/common/shared/topo_port.c b/usr/src/lib/fm/topo/modules/common/shared/topo_port.c index 8b6f1c726c..5dfd947c0e 100644 --- a/usr/src/lib/fm/topo/modules/common/shared/topo_port.c +++ b/usr/src/lib/fm/topo/modules/common/shared/topo_port.c @@ -10,7 +10,7 @@ */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <sys/fm/protocol.h> @@ -31,6 +31,13 @@ static const topo_pgroup_info_t port_pgroup = { 1 }; +static const topo_method_t port_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + int port_range_create(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min, topo_instance_t max) @@ -104,6 +111,13 @@ port_create_common(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst, goto error; } + if (topo_method_register(mod, tn, port_methods) != 0) { + topo_mod_dprintf(mod, "topo_method_register() failed on " + "%s=%d: %s", PORT, inst, topo_mod_errmsg(mod)); + /* errno set */ + goto error; + } + nvlist_free(fmri); nvlist_free(auth); nvlist_free(presource); diff --git a/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c b/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c index 4fe3c9fe02..cdbb9d566e 100644 --- a/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c +++ b/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c @@ -10,13 +10,14 @@ */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <assert.h> #include <fcntl.h> #include <fm/libtopo.h> #include <fm/topo_mod.h> +#include <fm/topo_method.h> #ifdef __x86 #include <sys/mc.h> #endif @@ -34,6 +35,13 @@ typedef struct smb_enum_data { char *sme_slot_form; } smb_enum_data_t; +static const topo_method_t slot_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + /* * This function serves two purposes. It filters out memory devices that * don't have a formfactor that represents a reasonably modern DIMM-like @@ -154,6 +162,14 @@ smbios_make_slot(smb_enum_data_t *smed, smbios_memdevice_t *smb_md) } nvlist_free(fmri); + if (topo_method_register(mod, slotnode, slot_methods) != 0) { + topo_mod_dprintf(mod, "topo_method_register() failed on " + "%s=%d: %s", SLOT, smed->sme_slot_inst, + topo_mod_errmsg(mod)); + /* errno set */ + return (NULL); + } + pgi.tpi_name = TOPO_PGROUP_SLOT; pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c index 3cbd41f0f9..f3e42bbc20 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c +++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. */ /* @@ -31,6 +32,7 @@ #include <sys/types.h> #include <strings.h> #include <fm/topo_mod.h> +#include <fm/topo_method.h> #include <fm/topo_hc.h> #include <sys/systeminfo.h> #include <sys/smbios_impl.h> @@ -56,6 +58,13 @@ static const topo_pgroup_info_t binding_pgroup = { 1 }; +static const topo_method_t bay_methods[] = { + { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC, + TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL, + topo_mod_hc_occupied }, + { NULL } +}; + /* * Return PCI Bus/Dev/Func */ @@ -332,6 +341,14 @@ x86pi_gen_bay(topo_mod_t *mod, tnode_t *t_parent, smbios_port_ext_t *eport, return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } + if (topo_method_register(mod, tn_bay, bay_methods) != 0) { + topo_mod_dprintf(mod, "topo_method_register() failed on " + "%s=%d: %s", BAY, instance, + topo_mod_errmsg(mod)); + /* errno set */ + return (-1); + } + /* * Call disk enum passing in decorated bay topo node. */ |
