Пример #1
0
int
topo_fmri_fru(topo_hdl_t *thp, nvlist_t *nvl, nvlist_t **fru,
    int *err)
{
	char *uuid = NULL;
	struct rsrc r;

	if (thp->th_uuid == NULL) {
		if ((uuid = topo_snap_hold(thp, NULL, err)) == NULL)
			return (set_error(thp, *err, err, "topo_fmri_fru",
			    NULL));
	}

	r.rs_flag = 1;
	r.rs_err = 0;
	r.rs_priv = nvl;
	r.rs_fprop = fru;
	if (topo_fmri_invoke(thp, nvl, get_prop, &r, err) < 0) {
		if (uuid != NULL) {
			topo_hdl_strfree(thp, uuid);
			topo_snap_release(thp);
		}

		return (set_error(thp, *err, err, "topo_fmri_fru", NULL));
	}

	if (uuid != NULL) {
		topo_hdl_strfree(thp, uuid);
		topo_snap_release(thp);
	}

	return (0);
}
Пример #2
0
static int
dl_fault_walk_inner(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	dl_fault_walk_inner_t *fwi = arg;
	char *facname = NULL, *factype = NULL;
	int err;

	/*
	 * We're only interested in BAY children that are valid Facility Nodes.
	 */
	if (topo_node_flags(node) != TOPO_NODE_FACILITY ||
	    get_facility_props(thp, node, &facname, &factype) != 0) {
		goto out;
	}

	if (strcmp(fwi->fwi_name, facname) != 0)
		goto out;

	/*
	 * Attempt to set the LED mode appropriately.  If this fails, give up
	 * and move on.
	 */
	(void) topo_prop_set_uint32(node, TOPO_PGROUP_FACILITY, TOPO_LED_MODE,
	    TOPO_PROP_MUTABLE, fwi->fwi_mode, &err);

out:
	topo_hdl_strfree(thp, facname);
	topo_hdl_strfree(thp, factype);
	return (TOPO_WALK_NEXT);
}
Пример #3
0
static void
print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri)
{
	int err, ret;

	(void) printf("%s\n", (char *)fmri);

	if (opt_p && !(pcnt > 0 || opt_V || opt_all)) {
		char *aname = NULL, *fname = NULL, *lname = NULL;
		nvlist_t *asru = NULL;
		nvlist_t *fru = NULL;

		if (topo_node_asru(node, &asru, NULL, &err) == 0)
			(void) topo_fmri_nvl2str(thp, asru, &aname, &err);
		if (topo_node_fru(node, &fru, NULL, &err) == 0)
			(void) topo_fmri_nvl2str(thp, fru, &fname, &err);
		(void) topo_node_label(node, &lname, &err);
		if (aname != NULL) {
			nvlist_free(asru);
			(void) printf("\tASRU: %s\n", aname);
			topo_hdl_strfree(thp, aname);
		} else {
			(void) printf("\tASRU: -\n");
		}
		if (fname != NULL) {
			nvlist_free(fru);
			(void) printf("\tFRU: %s\n", fname);
			topo_hdl_strfree(thp, fname);
		} else {
			(void) printf("\tFRU: -\n");
		}
		if (lname != NULL) {
			(void) printf("\tLabel: %s\n", lname);
			topo_hdl_strfree(thp, lname);
		} else {
			(void) printf("\tLabel: -\n");
		}
	}

	if (opt_S) {
		if ((ret = topo_fmri_present(thp, nvl, &err)) < 0)
			(void) printf("\tPresent: -\n");
		else
			(void) printf("\tPresent: %s\n",
			    ret ? "true" : "false");

		if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0)
			(void) printf("\tUnusable: -\n");
		else
			(void) printf("\tUnusable: %s\n",
			    ret ? "true" : "false");
	}
}
Пример #4
0
void
topo_close(topo_hdl_t *thp)
{
	ttree_t *tp;

	topo_hdl_lock(thp);
	if (thp->th_platform != NULL)
		topo_hdl_strfree(thp, thp->th_platform);
	if (thp->th_isa != NULL)
		topo_hdl_strfree(thp, thp->th_isa);
	if (thp->th_machine != NULL)
		topo_hdl_strfree(thp, thp->th_machine);
	if (thp->th_product != NULL)
		topo_hdl_strfree(thp, thp->th_product);
	if (thp->th_rootdir != NULL)
		topo_hdl_strfree(thp, thp->th_rootdir);
	if (thp->th_ipmi != NULL)
		ipmi_close(thp->th_ipmi);
	if (thp->th_smbios != NULL)
		smbios_close(thp->th_smbios);
	if (thp->th_pcidb != NULL)
		pcidb_close(thp->th_pcidb);

	/*
	 * Clean-up snapshot
	 */
	topo_snap_destroy(thp);

	/*
	 * Clean-up trees
	 */
	while ((tp = topo_list_next(&thp->th_trees)) != NULL) {
		topo_list_delete(&thp->th_trees, tp);
		topo_tree_destroy(tp);
	}

	/*
	 * Unload all plugins
	 */
	topo_modhash_unload_all(thp);

	if (thp->th_modhash != NULL)
		topo_modhash_destroy(thp);
	if (thp->th_alloc != NULL)
		topo_free(thp->th_alloc, sizeof (topo_alloc_t));

	topo_hdl_unlock(thp);

	topo_free(thp, sizeof (topo_hdl_t));
}
Пример #5
0
/*
 * Look up the FMRI corresponding to the node in the global
 * hash table and return the pointer stored (if any).  Save the
 * FMRI string in *str if str is non-NULL.
 */
static void *
fmri2ptr(topo_hdl_t *thp, tnode_t *node, char **str, int *err)
{
	nvlist_t	*fmri = NULL;
	char		*cstr = NULL;
	uint64_t	u64val;
	void		*p = NULL;

	if (topo_node_resource(node, &fmri, err) != 0)
		return (NULL);

	if (topo_fmri_nvl2str(thp, fmri, &cstr, err) != 0) {
		nvlist_free(fmri);
		return (NULL);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &u64val) == 0) {

		p = (void *)(uintptr_t)u64val;
	}

	nvlist_free(fmri);
	if (str != NULL)
		*str = dstrdup(cstr);
	topo_hdl_strfree(thp, cstr);
	return (p);
}
Пример #6
0
void
topo_pgroup_destroy_all(tnode_t *node)
{
	topo_hdl_t *thp = node->tn_hdl;
	topo_pgroup_t *pg;
	topo_proplist_t *pvl;
	topo_ipgroup_info_t *pip;

	topo_node_lock(node);
	while ((pg = topo_list_next(&node->tn_pgroups)) != NULL) {
		while ((pvl = topo_list_next(&pg->tpg_pvals)) != NULL) {
			topo_list_delete(&pg->tpg_pvals, pvl);
			topo_prop_rele(pvl->tp_pval);
			topo_hdl_free(thp, pvl, sizeof (topo_proplist_t));
		}

		topo_list_delete(&node->tn_pgroups, pg);

		pip = pg->tpg_info;
		if (pip != NULL) {
			if (pip->tpi_name != NULL)
				topo_hdl_strfree(thp, (char *)pip->tpi_name);
			topo_hdl_free(thp, pip, sizeof (topo_pgroup_info_t));
		}

		topo_hdl_free(thp, pg, sizeof (topo_pgroup_t));
	}
	topo_node_unlock(node);
}
Пример #7
0
ssize_t
fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
{
	int err;
	ssize_t len;
	topo_hdl_t *thp;
	char *str;

	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
		return (fmd_fmri_set_errno(EINVAL));

	if (topo_fmri_nvl2str(thp, nvl, &str, &err) != 0) {
		fmd_fmri_topo_rele(thp);
		return (fmd_fmri_set_errno(EINVAL));
	}

	if (buf != NULL)
		len = snprintf(buf, buflen, "%s", str);
	else
		len = strlen(str);

	topo_hdl_strfree(thp, str);
	fmd_fmri_topo_rele(thp);

	return (len);
}
Пример #8
0
diskmon_t *
dm_fmri_to_diskmon(fmd_hdl_t *hdl, nvlist_t *fmri)
{
	topo_hdl_t *thdl;
	nvlist_t *dupfmri;
	diskmon_t *diskp;
	char *buf;
	int err;

	if (nvlist_dup(fmri, &dupfmri, 0) != 0)
		return (NULL);

	(void) nvlist_remove(dupfmri, FM_FMRI_HC_REVISION, DATA_TYPE_STRING);
	(void) nvlist_remove(dupfmri, FM_FMRI_HC_SERIAL_ID, DATA_TYPE_STRING);
	(void) nvlist_remove(dupfmri, FM_FMRI_HC_PART, DATA_TYPE_STRING);

	thdl = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
	if (topo_fmri_nvl2str(thdl, dupfmri, &buf, &err) != 0) {
		fmd_hdl_topo_rele(hdl, thdl);
		nvlist_free(dupfmri);
		return (NULL);
	}
	fmd_hdl_topo_rele(hdl, thdl);

	diskp = dm_fmristring_to_diskmon(buf);

	nvlist_free(dupfmri);
	topo_hdl_strfree(thdl, buf);

	return (diskp);
}
Пример #9
0
int
update_configuration_from_topo(diskmon_t *diskp)
{
	int err;
	topo_hdl_t *thp;
	topo_walk_t *twp;
	char *uuid;

	if ((thp = topo_open(TOPO_VERSION, NULL, &err)) == NULL) {

		return (TOPO_OPEN_ERROR);
	}

	if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) {

		topo_close(thp);
		return (TOPO_SNAP_ERROR);
	}


	if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, gather_topo_cfg,
	    diskp, &err)) == NULL) {

		topo_snap_release(thp);
		topo_hdl_strfree(thp, uuid);
		topo_close(thp);

		return (err ? TOPO_WALK_INIT_ERROR : TOPO_SUCCESS);
	}

	topo_hdl_strfree(thp, uuid);

	if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) {

		topo_walk_fini(twp);
		topo_snap_release(thp);
		topo_close(thp);

		return (TOPO_WALK_ERROR);
	}

	topo_walk_fini(twp);
	topo_snap_release(thp);
	topo_close(thp);

	return (TOPO_SUCCESS);
}
Пример #10
0
/*ARGSUSED*/
static int
fru_by_label_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	char *lbl;
	int err;
	char *target = (char *)arg;

	if (topo_node_label(node, &lbl, &err) < 0)
		return (TOPO_WALK_NEXT);	/* no label, try next */

	if ((strcmp(target, lbl) == 0) &&
	    (topo_node_fru(node, &br_memb_nvl, NULL, &err) == 0)) {
		topo_hdl_strfree(thp, lbl);
		return (TOPO_WALK_TERMINATE);
	}
	topo_hdl_strfree(thp, lbl);
	return (TOPO_WALK_NEXT);
}
Пример #11
0
static void
propmethod_destroy(topo_hdl_t *thp, topo_propval_t *pv)
{
	topo_propmethod_t *pm;

	pm = pv->tp_method;
	if (pm != NULL) {
		if (pm->tpm_name != NULL)
			topo_hdl_strfree(thp, pm->tpm_name);
		if (pm->tpm_args != NULL)
			nvlist_free(pm->tpm_args);
		topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
		pv->tp_method = NULL;
	}
}
Пример #12
0
static int
pgroup_seterr(tnode_t *node, topo_pgroup_t *pg, topo_ipgroup_info_t *pip,
    int *err)
{
	topo_hdl_t *thp = node->tn_hdl;

	if (pip != NULL) {
		if (pip->tpi_name != NULL)
			topo_hdl_strfree(thp, (char *)pip->tpi_name);
		topo_hdl_free(thp, pip, sizeof (topo_ipgroup_info_t));
	}

	topo_hdl_free(thp, pg, sizeof (topo_pgroup_t));
	*err = ETOPO_NOMEM;

	topo_node_unlock(node);

	return (-1);
}
Пример #13
0
static void
topo_propval_destroy(topo_propval_t *pv)
{
	topo_hdl_t *thp;

	if (pv == NULL)
		return;

	thp = pv->tp_hdl;

	if (pv->tp_name != NULL)
		topo_hdl_strfree(thp, pv->tp_name);

	if (pv->tp_val != NULL)
		nvlist_free(pv->tp_val);

	propmethod_destroy(thp, pv);

	topo_hdl_free(thp, pv, sizeof (topo_propval_t));
}
Пример #14
0
int
fmtopo_exit(topo_hdl_t *thp, char *uuid, int err)
{
	if (uuid != NULL)
		topo_hdl_strfree(thp, uuid);

	if (thp != NULL) {
		topo_snap_release(thp);
		topo_close(thp);
	}

	if (pargs) {
		int i;
		for (i = 0; i < pcnt; ++i)
			free(pargs[i]);
		free(pargs);
	}

	return (err);
}
Пример #15
0
static int
register_methoderror(tnode_t *node, topo_propmethod_t *pm, int *errp, int l,
    int err)
{
	topo_hdl_t *thp = node->tn_hdl;

	if (pm != NULL) {
		if (pm->tpm_name != NULL)
			topo_hdl_strfree(thp, pm->tpm_name);
		if (pm->tpm_args != NULL)
			nvlist_free(pm->tpm_args);
		topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
	}

	*errp = err;

	if (l != 0)
		topo_node_unlock(node);

	return (-1);
}
Пример #16
0
void
topo_pgroup_destroy(tnode_t *node, const char *pname)
{
	topo_hdl_t *thp = node->tn_hdl;
	topo_pgroup_t *pg;
	topo_proplist_t *pvl;
	topo_ipgroup_info_t *pip;

	topo_node_lock(node);
	for (pg = topo_list_next(&node->tn_pgroups); pg != NULL;
	    pg = topo_list_next(pg)) {
		if (strcmp(pg->tpg_info->tpi_name, pname) == 0) {
			break;
		}
	}

	if (pg == NULL) {
		topo_node_unlock(node);
		return;
	}

	while ((pvl = topo_list_next(&pg->tpg_list)) != NULL) {
		topo_list_delete(&pg->tpg_pvals, pvl);
		topo_prop_rele(pvl->tp_pval);
		topo_hdl_free(thp, pvl, sizeof (topo_proplist_t));
	}

	topo_list_delete(&node->tn_pgroups, pg);
	topo_node_unlock(node);

	pip = pg->tpg_info;
	if (pip != NULL) {
		if (pip->tpi_name != NULL)
			topo_hdl_strfree(thp, (char *)pip->tpi_name);
		topo_hdl_free(thp, pip, sizeof (topo_ipgroup_info_t));
	}

	topo_hdl_free(thp, pg, sizeof (topo_pgroup_t));
}
Пример #17
0
static void
print_pgroup(topo_hdl_t *thp, tnode_t *node, const char *pgn, char *dstab,
    char *nstab, int32_t version)
{
	int err;
	char buf[30];
	topo_pgroup_info_t *pgi = NULL;

	if (pgn == NULL)
		return;

	if (node != NULL && (dstab == NULL || nstab == NULL || version == -1)) {
		if ((pgi = topo_pgroup_info(node, pgn, &err)) != NULL) {
			dstab = (char *)topo_stability2name(pgi->tpi_datastab);
			nstab = (char *)topo_stability2name(pgi->tpi_namestab);
			version = pgi->tpi_version;
		}
	}

	if (dstab == NULL || nstab == NULL || version == -1) {
		(void) printf("  group: %-30s version: - stability: -/-\n",
		    pgn);
	} else if (!opt_V && strlen(pgn) > 30) {
		(void) snprintf(buf, 26, "%s", pgn);
		(void) snprintf(&buf[27], 4, "%s", DOTS);
		(void) printf("  group: %-30s version: %-3d stability: %s/%s\n",
		    buf, version, nstab, dstab);
	} else {
		(void) printf("  group: %-30s version: %-3d stability: %s/%s\n",
		    pgn, version, nstab, dstab);
	}

	if (pgi != NULL) {
		topo_hdl_strfree(thp, (char *)pgi->tpi_name);
		topo_hdl_free(thp, pgi, sizeof (topo_pgroup_info_t));
	}
}
Пример #18
0
/*ARGSUSED*/
int
do_prominfo(int opt_v, char *progname, int opt_l, int opt_p)
{
	smbios_hdl_t *shp;
	smbios_system_t sys;
	smbios_bios_t bios;
	smbios_ipmi_t ipmi;
	smbios_info_t info;
	topo_hdl_t *thp;
	char *uuid;

	const char *s;
	id_t id;
	int err;

	if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL) {
		(void) fprintf(stderr,
		    gettext("%s: failed to open SMBIOS: %s\n"),
		    progname, smbios_errmsg(err));
		return (1);
	}

	if ((id = smbios_info_system(shp, &sys)) != SMB_ERR &&
	    smbios_info_common(shp, id, &info) != SMB_ERR) {
		(void) printf(gettext("System Configuration: %s %s\n"),
		    info.smbi_manufacturer, info.smbi_product);
	} else {
		(void) fprintf(stderr,
		    gettext("%s: failed to get system info: %s\n"),
		    progname, smbios_errmsg(smbios_errno(shp)));
	}

	if (smbios_info_bios(shp, &bios) != SMB_ERR) {
		(void) printf(gettext("BIOS Configuration: %s %s %s\n"),
		    bios.smbb_vendor, bios.smbb_version, bios.smbb_reldate);
	} else {
		(void) fprintf(stderr,
		    gettext("%s: failed to get bios info: %s\n"),
		    progname, smbios_errmsg(smbios_errno(shp)));
	}

	if (smbios_info_ipmi(shp, &ipmi) != SMB_ERR) {
		if ((s = smbios_ipmi_type_desc(ipmi.smbip_type)) == NULL)
			s = gettext("Unknown");

		(void) printf(gettext("BMC Configuration: IPMI %u.%u (%s)\n"),
		    ipmi.smbip_vers.smbv_major, ipmi.smbip_vers.smbv_minor, s);
	}

	/*
	 * Silently swallow all libtopo and libpcidb related errors.
	 */
	uuid = NULL;
	if ((thp = topo_open(TOPO_VERSION, NULL, &err)) != NULL) {
		if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) {
			topo_close(thp);
			thp = NULL;
		}
	}

	prt_php = pcidb_open(PCIDB_VERSION);

	(void) printf(gettext(
	    "\n==== Processor Sockets ====================================\n"));

	(void) printf(gettext("\n%-32s %s"), "Version", "Location Tag");

	(void) printf(gettext(
	    "\n-------------------------------- --------------------------\n"));
	(void) smbios_iter(shp, do_procs, NULL);

	(void) printf(gettext(
	    "\n==== Memory Device Sockets ================================\n"));

	(void) printf(gettext("\n%-11s %-6s %-3s %-19s %s"),
	    "Type", "Status", "Set", "Device Locator", "Bank Locator");

	(void) printf(gettext(
	    "\n----------- ------ --- ------------------- ----------------\n"));
	(void) smbios_iter(shp, do_memdevs, NULL);

	(void) printf(gettext(
	    "\n==== On-Board Devices =====================================\n"));
	(void) smbios_iter(shp, do_obdevs, NULL);

	(void) printf(gettext(
	    "\n==== Upgradeable Slots ====================================\n"));

	(void) printf(gettext("\n%-3s %-9s %-16s %s"),
	    "ID", "Status", "Type", "Description");

	(void) printf(gettext(
	    "\n--- --------- ---------------- ----------------------------\n"));
	(void) smbios_iter(shp, do_slots, thp);

	smbios_close(shp);

	topo_hdl_strfree(thp, uuid);
	if (thp != NULL) {
		topo_snap_release(thp);
		topo_close(thp);
	}
	pcidb_close(prt_php);

	return (0);
}
Пример #19
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*label;
	uint64_t	ptr = 0;
	int		err;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	if (wdp->pfmri == NULL) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		return (0);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, wdp->pfmri, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for %s: parent of node %p.\n",
		    wdp->pfmri, node);
		dstrfree(wdp->pfmri);
		/* Skip this disk: */
		return (0);
	}

	dstrfree(wdp->pfmri);
	wdp->pfmri = NULL;

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	if (model)
		topo_hdl_strfree(thp, model);
	if (manuf)
		topo_hdl_strfree(thp, manuf);
	if (serial)
		topo_hdl_strfree(thp, serial);
	if (firmrev)
		topo_hdl_strfree(thp, firmrev);
	if (capacity)
		topo_hdl_strfree(thp, capacity);

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Пример #20
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp)
{
	nvlist_t	*fmri = NULL;
	nvlist_t	*asru_fmri;
	nvlist_t	*fru_fmri;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*cstr = NULL;
	char		*buf;
	char		*label;
	char		*p;
	uint64_t	ptr = 0;
	int		buflen;
	int		err;
	int		orig_cstr_len;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	/*
	 * Match this node to a disk in the configuration by looking at
	 * our parent's fmri (and do that by getting our FMRI and chopping
	 * off the last part).
	 */
	if (topo_node_resource(node, &fmri, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for "
		    "node %p!\n", (void *)node);
		return (-1);
	}

	if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not create string for "
		    "node %p's FMRI!\n", (void *)node);
		nvlist_free(fmri);
		return (-1);
	}

	nvlist_free(fmri);

	/*
	 * Chop off all but last path (since there's no way to get
	 * the node's parent in the libtopo API).
	 */
	orig_cstr_len = strlen(cstr) + 1;
	p = strrchr(cstr, '/');
	dm_assert(p != NULL);
	*p = 0;
	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		topo_hdl_free(thp, cstr, orig_cstr_len);
		/* Skip this disk: */
		return (0);
	}

	topo_hdl_free(thp, cstr, orig_cstr_len);

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's ASRU and FRU with our information (this
	 * information is cached in the diskmon so we don't have to do a
	 * time-consuming topo traversal when we get an ereport).
	 */
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU,
	    &asru_fmri, &err) == 0) {
		diskmon_add_asru(diskp, asru_fmri);
		nvlist_free(asru_fmri);
	}
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU,
	    &fru_fmri, &err) == 0) {
		diskmon_add_fru(diskp, fru_fmri);
		nvlist_free(fru_fmri);
	}
	if (topo_node_resource(node, &fmri, &err) == 0) {
		diskmon_add_disk_fmri(diskp, fmri);
		nvlist_free(fmri);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	/*
	 * Update the disk's resource FMRI with the
	 * SunService-required members:
	 * FM_FMRI_HC_SERIAL_ID, FM_FMRI_HC_PART, and
	 * FM_FMRI_HC_REVISION
	 */
	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	transform_model_string(manuf, model, &buf, &buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_PART, buf);

	/*
	 * Add the serial number to the ASRU so that when the resource
	 * is marked faulty in the fmd resource cache, the hc scheme
	 * plugin can detect when the disk is no longer installed (and so,
	 * can clear the faulty state automatically across fmd restarts).
	 *
	 * The serial number is only updated when a disk comes online
	 * because that's when the disk node exists in the topo tree.
	 * It's ok to keep a stale value in the ASRU when the disk is removed
	 * because it's only used as part of fault creation when the disk
	 * is configured (online), at which point it will be updated with
	 * the (current) serial number of the disk inserted.
	 */
	(void) nvlist_add_string(diskp->asru_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	dfree(buf, buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_REVISION, firmrev);

	if (model) {
		topo_hdl_strfree(thp, model);
	}

	if (manuf) {
		topo_hdl_strfree(thp, manuf);
	}

	if (serial) {
		topo_hdl_strfree(thp, serial);
	}

	if (firmrev) {
		topo_hdl_strfree(thp, firmrev);
	}

	if (capacity) {
		topo_hdl_strfree(thp, capacity);
	}

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Пример #21
0
/*ARGSUSED*/
static int
walk_node(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *nvl;
	nvlist_t *rsrc, *out;
	char *s;

	if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) {
		print_everstyle(node);
		return (TOPO_WALK_NEXT);
	}

	if (topo_node_resource(node, &rsrc, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to get resource: "
		    "%s", g_pname, topo_strerror(err));
		return (TOPO_WALK_NEXT);
	}
	if (topo_fmri_nvl2str(thp, rsrc, &s, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to convert "
		    "resource to FMRI string: %s", g_pname,
		    topo_strerror(err));
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	if (g_fmri != NULL && fnmatch(g_fmri, s, 0) != 0) {
		nvlist_free(rsrc);
		topo_hdl_strfree(thp, s);
		return (TOPO_WALK_NEXT);
	}

	print_node(thp, node, rsrc, s);
	topo_hdl_strfree(thp, s);
	nvlist_free(rsrc);

	if (opt_m != NULL) {
		if (topo_method_invoke(node, opt_m, 0, NULL, &out, &err) == 0) {
			nvlist_print(stdout, out);
			nvlist_free(out);
		} else if (err != ETOPO_METHOD_NOTSUP)
			(void) fprintf(stderr, "%s: method failed unexpectedly "
			    "on %s=%d (%s)\n", g_pname, topo_node_name(node),
			    topo_node_instance(node), topo_strerror(err));
	}

	if (opt_V || opt_all) {
		if ((nvl = topo_prop_getprops(node, &err)) == NULL) {
			(void) fprintf(stderr, "%s: failed to get "
			    "properties for %s=%d: %s\n", g_pname,
			    topo_node_name(node), topo_node_instance(node),
			    topo_strerror(err));
		} else {
			print_all_props(thp, node, nvl, ALL);
			nvlist_free(nvl);
		}
	} else if (pcnt > 0)
		print_props(thp, node);

	(void) printf("\n");

	return (TOPO_WALK_NEXT);
}
Пример #22
0
static void
print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl)
{
	int err;
	topo_type_t type;
	char *tstr, *propn, buf[48], *factype;
	nvpair_t *pv_nvp;
	int i;
	uint_t nelem;

	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL)
		return;

	/* Print property name */
	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) {
		(void) fprintf(stderr, "%s: malformed property name\n",
		    g_pname);
		return;
	} else {
		(void) nvpair_value_string(pv_nvp, &propn);
	}

	if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 ||
	    nvpair_type(pv_nvp) != DATA_TYPE_UINT32)  {
		(void) fprintf(stderr, "%s: malformed property type for %s\n",
		    g_pname, propn);
		return;
	} else {
		(void) nvpair_value_uint32(pv_nvp, (uint32_t *)&type);
	}

	switch (type) {
		case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break;
		case TOPO_TYPE_INT32: tstr = "int32"; break;
		case TOPO_TYPE_UINT32: tstr = "uint32"; break;
		case TOPO_TYPE_INT64: tstr = "int64"; break;
		case TOPO_TYPE_UINT64: tstr = "uint64"; break;
		case TOPO_TYPE_DOUBLE: tstr = "double"; break;
		case TOPO_TYPE_STRING: tstr = "string"; break;
		case TOPO_TYPE_FMRI: tstr = "fmri"; break;
		case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break;
		case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break;
		case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break;
		case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break;
		case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break;
		case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break;
		default: tstr = "unknown type";
	}

	(void) printf("    %-17s %-8s ", propn, tstr);

	/*
	 * Get property value
	 */
	if (nvpair_name(pv_nvp) == NULL ||
	    (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) {
		(void) fprintf(stderr, "%s: malformed property value\n",
		    g_pname);
		return;
	}

	switch (nvpair_type(pv_nvp)) {
		case DATA_TYPE_INT32: {
			int32_t val;
			(void) nvpair_value_int32(pv_nvp, &val);
			(void) printf(" %d", val);
			break;
		}
		case DATA_TYPE_UINT32: {
			uint32_t val, type;
			char val_str[49];
			nvlist_t *fac, *rsrc = NULL;

			(void) nvpair_value_uint32(pv_nvp, &val);
			if (node == NULL || topo_node_flags(node) !=
			    TOPO_NODE_FACILITY)
				goto uint32_def;

			if (topo_node_resource(node, &rsrc, &err) != 0)
				goto uint32_def;

			if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0)
				goto uint32_def;

			if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE,
			    &factype) != 0)
				goto uint32_def;

			nvlist_free(rsrc);
			rsrc = NULL;

			/*
			 * Special case code to do friendlier printing of
			 * facility node properties
			 */
			if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				topo_sensor_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) {
				topo_led_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) {
				topo_sensor_units_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_LED_MODE) == 0) {
				topo_led_state_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				if (topo_prop_get_uint32(node,
				    TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
				    &type, &err) != 0) {
					goto uint32_def;
				}
				topo_sensor_state_name(type, val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			}
uint32_def:
			(void) printf(" 0x%x", val);
			if (rsrc != NULL)
				nvlist_free(rsrc);
			break;
		}
		case DATA_TYPE_INT64: {
			int64_t val;
			(void) nvpair_value_int64(pv_nvp, &val);
			(void) printf(" %lld", (longlong_t)val);
			break;
		}
		case DATA_TYPE_UINT64: {
			uint64_t val;
			(void) nvpair_value_uint64(pv_nvp, &val);
			(void) printf(" 0x%llx", (u_longlong_t)val);
			break;
		}
		case DATA_TYPE_DOUBLE: {
			double val;
			(void) nvpair_value_double(pv_nvp, &val);
			(void) printf(" %lf", (double)val);
			break;
		}
		case DATA_TYPE_STRING: {
			char *val;
			(void) nvpair_value_string(pv_nvp, &val);
			if (!opt_V && strlen(val) > 48) {
				(void) snprintf(buf, 48, "%s...", val);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", val);
			}
			break;
		}
		case DATA_TYPE_NVLIST: {
			nvlist_t *val;
			char *fmri;
			(void) nvpair_value_nvlist(pv_nvp, &val);
			if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) {
				if (opt_V)
					nvlist_print(stdout, nvl);
				break;
			}

			if (!opt_V && strlen(fmri) > 48) {
				(void) snprintf(buf, 48, "%s", fmri);
				(void) snprintf(&buf[45], 4, "%s", DOTS);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", fmri);
			}

			topo_hdl_strfree(thp, fmri);
			break;
		}
		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;

			(void) nvpair_value_int32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%d ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;

			(void) nvpair_value_uint32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%u ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;

			(void) nvpair_value_int64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%lld ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;

			(void) nvpair_value_uint64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%llu ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_STRING_ARRAY: {
			char **val;

			(void) nvpair_value_string_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("\"%s\" ", val[i]);
			(void) printf("]");
			break;
		}
		default:
			(void) fprintf(stderr, " unknown data type (%d)",
			    nvpair_type(pv_nvp));
			break;
		}
		(void) printf("\n");
}
Пример #23
0
static char *
topo_snap_create(topo_hdl_t *thp, int *errp, boolean_t need_force)
{
	uuid_t uuid;
	char *ustr = NULL;

	topo_hdl_lock(thp);
	if (thp->th_uuid != NULL) {
		*errp = ETOPO_HDL_UUID;
		topo_hdl_unlock(thp);
		return (NULL);
	}

	if ((thp->th_uuid = topo_hdl_zalloc(thp, TOPO_UUID_SIZE)) == NULL) {
		*errp = ETOPO_NOMEM;
		topo_dprintf(thp, TOPO_DBG_ERR, "unable to allocate uuid: %s\n",
		    topo_strerror(*errp));
		topo_hdl_unlock(thp);
		return (NULL);
	}

	uuid_generate(uuid);
	uuid_unparse(uuid, thp->th_uuid);
	if ((ustr = topo_hdl_strdup(thp, thp->th_uuid)) == NULL) {
		*errp = ETOPO_NOMEM;
		topo_hdl_unlock(thp);
		return (NULL);
	}

	if (need_force) {
		topo_dprintf(thp, TOPO_DBG_FORCE,
		    "taking a DINFOFORCE snapshot\n");
		thp->th_di = di_init("/", DINFOFORCE |
		    DINFOSUBTREE | DINFOMINOR | DINFOPROP | DINFOPATH);
	} else {
		thp->th_di = di_init("/", DINFOCACHE);
	}
	thp->th_pi = di_prom_init();

	if (topo_tree_enum_all(thp) < 0) {
		topo_dprintf(thp, TOPO_DBG_ERR, "enumeration failure: %s\n",
		    topo_hdl_errmsg(thp));
		if (topo_hdl_errno(thp) == ETOPO_ENUM_FATAL) {
			*errp = thp->th_errno;

			if (thp->th_di != DI_NODE_NIL) {
				di_fini(thp->th_di);
				thp->th_di = DI_NODE_NIL;
			}
			if (thp->th_pi != DI_PROM_HANDLE_NIL) {
				di_prom_fini(thp->th_pi);
				thp->th_pi = DI_PROM_HANDLE_NIL;
			}

			topo_hdl_strfree(thp, ustr);
			topo_hdl_unlock(thp);
			return (NULL);
		}
	}

	if (thp->th_ipmi != NULL &&
	    ipmi_sdr_changed(thp->th_ipmi) &&
	    ipmi_sdr_refresh(thp->th_ipmi) != 0) {
		topo_dprintf(thp, TOPO_DBG_ERR,
		    "failed to refresh IPMI sdr repository: %s\n",
		    ipmi_errmsg(thp->th_ipmi));
	}

	topo_hdl_unlock(thp);

	return (ustr);
}
Пример #24
0
/*ARGSUSED*/
static int
do_slot_mapping_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err, ret;
	nvlist_t *rsrc = NULL;
	const char *match = arg;
	char *s, *fmri = NULL;
	char *didstr = NULL, *driver = NULL, *vidstr = NULL;
	boolean_t printed = B_FALSE;

	ret = TOPO_WALK_NEXT;
	if (topo_node_resource(node, &rsrc, &err) < 0)
		goto next;
	if (topo_fmri_nvl2str(thp, rsrc, &fmri, &err) < 0)
		goto next;

	if ((s = strstr(fmri, match)) == NULL)
		goto next;
	if (s[strlen(match)] != '\0')
		goto next;

	/* At this point we think we've found a match */
	ret = TOPO_WALK_TERMINATE;
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DRIVER, &driver,
	    &err) != 0)
		driver = NULL;

	if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_VENDID,
	    &vidstr, &err) != 0)
		goto next;

	if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_DEVID,
	    &didstr, &err) != 0)
		goto next;

	if (prt_php != NULL) {
		long vid, did;

		vid = strtol(vidstr, NULL, 16);
		did = strtol(didstr, NULL, 16);
		if (vid >= 0 && vid <= UINT16_MAX &&
		    did >= 0 && did <= UINT16_MAX) {
			pcidb_device_t *pdev;

			pdev = pcidb_lookup_device(prt_php, vid, did);
			if (pdev != NULL) {
				pcidb_vendor_t *pvend;
				pvend = pcidb_device_vendor(pdev);
				(void) printf(gettext(", %s %s (%s)"),
				    pcidb_vendor_name(pvend),
				    pcidb_device_name(pdev),
				    driver != NULL ? driver : "<unknown>");
				printed = B_TRUE;
			}
		}
	}

	if (printed == B_FALSE) {
		(void) printf(gettext(", pci%s,%s (%s)"), vidstr, didstr,
		    driver != NULL ? driver : "<unknown>");
	}
next:
	topo_hdl_strfree(thp, didstr);
	topo_hdl_strfree(thp, driver);
	topo_hdl_strfree(thp, vidstr);
	topo_hdl_strfree(thp, fmri);
	nvlist_free(rsrc);
	return (ret);
}
Пример #25
0
void
print_fmri(topo_hdl_t *thp, char *uuid)
{
	int ret, err;
	nvlist_t *nvl;
	char buf[32];
	time_t tod = time(NULL);

	if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to convert %s to nvlist: "
		    "%s\n", g_pname, g_fmri, topo_strerror(err));
		return;
	}

	(void) printf("TIME                 UUID\n");
	(void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod));
	(void) printf("%-15s %-32s\n", buf, uuid);
	(void) printf("\n");

	(void) printf("%s\n", (char *)g_fmri);

	if (opt_p && !(pcnt > 0 || opt_V || opt_all)) {
		char *aname = NULL, *fname = NULL, *lname = NULL;
		nvlist_t *asru = NULL;
		nvlist_t *fru = NULL;

		if (topo_fmri_asru(thp, nvl, &asru, &err) == 0)
			(void) topo_fmri_nvl2str(thp, asru, &aname, &err);
		if (topo_fmri_fru(thp, nvl, &fru, &err) == 0)
			(void) topo_fmri_nvl2str(thp, fru, &fname, &err);
		(void) topo_fmri_label(thp, nvl, &lname, &err);

		nvlist_free(fru);
		nvlist_free(asru);

		if (aname != NULL) {
			(void) printf("\tASRU: %s\n", aname);
			topo_hdl_strfree(thp, aname);
		} else {
			(void) printf("\tASRU: -\n");
		}
		if (fname != NULL) {
			(void) printf("\tFRU: %s\n", fname);
			topo_hdl_strfree(thp, fname);
		} else {
			(void) printf("\tFRU: -\n");
		}
		if (lname != NULL) {
			(void) printf("\tLabel: %s\n", lname);
			topo_hdl_strfree(thp, lname);
		} else {
			(void) printf("\tLabel: -\n");
		}
	}

	if (opt_S) {
		if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) {
			(void) printf("\tPresent: -\n");
			(void) printf("\tUnusable: -\n");
			return;
		}

		if ((ret = topo_fmri_present(thp, nvl, &err)) < 0)
			(void) printf("\tPresent: -\n");
		else
			(void) printf("\tPresent: %s\n",
			    ret ? "true" : "false");

		if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0)
			(void) printf("\tUnusable: -\n");
		else
			(void) printf("\tUnusable: %s\n",
			    ret ? "true" : "false");

		nvlist_free(nvl);
	}

	if (pargs && pcnt > 0)
		print_fmri_props(thp, nvl);
}
Пример #26
0
static int
topo_add_bay(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	nvlist_t	*nvlp = find_disk_monitor_private_pgroup(node);
	nvlist_t	*prop_nvlp;
	nvpair_t	*nvp = NULL;
	char		*prop_name, *prop_value;
#define	PNAME_MAX 128
	char		pname[PNAME_MAX];
	char		msgbuf[MAX_CONF_MSG_LEN];
	char		*indicator_name, *indicator_action;
	char		*indrule_states, *indrule_actions;
	int		err = 0, i;
	conf_err_t	conferr;
	boolean_t	conf_failure = B_FALSE;
	char		*unadj_physid = NULL;
	char		physid[MAXPATHLEN];
	char		*label;
	nvlist_t	*diskprops = NULL;
	char		*cstr = NULL;
	indicator_t	*indp = NULL;
	indrule_t	*indrp = NULL;
	void		*p;
	diskmon_t	*diskp;
	void		*ptr;

	/* No private properties -- just ignore the port */
	if (nvlp == NULL)
		return (0);

	/*
	 * Look for a diskmon based on this node's FMRI string.
	 * Once a diskmon has been created, it's not re-created.  This is
	 * essential for the times when the tree-walk is called after a
	 * disk is inserted (or removed) -- in that case, the disk node
	 * handler simply updates the FRU information in the diskmon.
	 */
	if ((p = fmri2ptr(thp, node, &cstr, &err)) != NULL) {

		diskp = (diskmon_t *)p;

		/*
		 * Delete the FRU information from the diskmon.  If a disk
		 * is connected, its FRU information will be refreshed by
		 * the disk node code.
		 */
		if (diskp->frup && (target_diskp == NULL ||
		    diskp == target_diskp)) {
			dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
			dmfru_free(diskp->frup);
			diskp->frup = NULL;
			dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);
		}

		wdp->pfmri = cstr;
		nvlist_free(nvlp);
		return (0);
	}

	/*
	 * Determine the physical path to the attachment point
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO,
	    TOPO_IO_AP_PATH, &unadj_physid, &err) == 0) {

		adjust_dynamic_ap(unadj_physid, physid);
		topo_hdl_strfree(thp, unadj_physid);
	} else {

		/* unadj_physid cannot have been allocated */
		if (cstr)
			dstrfree(cstr);
		nvlist_free(nvlp);
		return (-1);
	}

	/*
	 */

	/*
	 * Process the properties.  If we encounter a property that
	 * is not an indicator name, action, or rule, add it to the
	 * disk's props list.
	 */

	/* Process indicators */
	i = 0;
	indicator_name = NULL;
	indicator_action = NULL;
	do {
		if (indicator_name != NULL && indicator_action != NULL) {

			if (topoprop_indicator_add(&indp, indicator_name,
			    indicator_action) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indicator_name);
			topo_hdl_strfree(thp, indicator_action);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_IND_NAME "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_name, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_IND_ACTION "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_action, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indicator_name != NULL &&
	    indicator_action != NULL);

	if (!conf_failure && indp != NULL &&
	    (conferr = check_inds(indp)) != E_NO_ERROR) {
		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, NULL);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;
	}

	/* Process state rules and indicator actions */
	i = 0;
	indrule_states = NULL;
	indrule_actions = NULL;
	do {
		if (indrule_states != NULL && indrule_actions != NULL) {

			if (topoprop_indrule_add(&indrp, indrule_states,
			    indrule_actions) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indrule_states);
			topo_hdl_strfree(thp, indrule_actions);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_STATES "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_states, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_ACTIONS "-%d",
		    i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_actions, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indrule_states != NULL &&
	    indrule_actions != NULL);

	if (!conf_failure && indrp != NULL && indp != NULL &&
	    ((conferr = check_indrules(indrp, (state_transition_t **)&ptr))
	    != E_NO_ERROR ||
	    (conferr = check_consistent_ind_indrules(indp, indrp,
	    (ind_action_t **)&ptr)) != E_NO_ERROR)) {

		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, ptr);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;

	}

	/*
	 * Now collect miscellaneous properties.
	 * Each property is stored as an embedded nvlist named
	 * TOPO_PROP_VAL.  The property name is stored in the value for
	 * key=TOPO_PROP_VAL_NAME and the property's value is
	 * stored in the value for key=TOPO_PROP_VAL_VAL.  This is all
	 * necessary so we can subtractively decode the properties that
	 * we do not directly handle (so that these properties are added to
	 * the per-disk properties nvlist), increasing flexibility.
	 */
	(void) nvlist_alloc(&diskprops, NV_UNIQUE_NAME, 0);
	while ((nvp = nvlist_next_nvpair(nvlp, nvp)) != NULL) {
		/* Only care about embedded nvlists named TOPO_PROP_VAL */
		if (nvpair_type(nvp) != DATA_TYPE_NVLIST ||
		    strcmp(nvpair_name(nvp), TOPO_PROP_VAL) != 0 ||
		    nvpair_value_nvlist(nvp, &prop_nvlp) != 0)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp,
		    TOPO_PROP_VAL_NAME, &prop_name) != 0)
			continue;

		/* Filter out indicator properties */
		if (strstr(prop_name, BAY_IND_NAME) != NULL ||
		    strstr(prop_name, BAY_IND_ACTION) != NULL ||
		    strstr(prop_name, BAY_INDRULE_STATES) != NULL ||
		    strstr(prop_name, BAY_INDRULE_ACTIONS) != NULL)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp, TOPO_PROP_VAL_VAL,
		    &prop_value) != 0)
			continue;

		/* Add the property to the disk's prop list: */
		if (nvlist_add_string(diskprops, prop_name, prop_value) != 0)
			log_msg(MM_TOPO,
			    "Could not add disk property `%s' with "
			    "value `%s'\n", prop_name, prop_value);
	}

	nvlist_free(nvlp);

	if (cstr != NULL) {
		namevalpr_t nvpr;
		nvlist_t *dmap_nvl;

		nvpr.name = DISK_AP_PROP_APID;
		nvpr.value = strncmp(physid, "/devices", 8) == 0 ?
		    (physid + 8) : physid;

		/*
		 * Set the diskmon's location to the value in this port's label.
		 * If there's a disk plugged in, the location will be updated
		 * to be the disk label (e.g. HD_ID_00).  Until a disk is
		 * inserted, though, there won't be a disk libtopo node
		 * created.
		 */

		/* Pass physid without the leading "/devices": */
		dmap_nvl = namevalpr_to_nvlist(&nvpr);

		diskp = new_diskmon(dmap_nvl, indp, indrp, diskprops);

		if (topo_node_label(node, &label, &err) == 0) {
			diskp->location = dstrdup(label);
			topo_hdl_strfree(thp, label);
		} else
			diskp->location = dstrdup("unknown location");

		if (!conf_failure && diskp != NULL) {
			/* Add this diskmon to the disk list */
			cfgdata_add_diskmon(config_data, diskp);
			if (nvlist_add_uint64(g_topo2diskmon, cstr,
			    (uint64_t)(uintptr_t)diskp) != 0) {
				log_msg(MM_TOPO,
				    "Could not add pointer to nvlist "
				    "for `%s'!\n", cstr);
			}
		} else if (diskp != NULL) {
			diskmon_free(diskp);
		} else {
			if (dmap_nvl)
				nvlist_free(dmap_nvl);
			if (indp)
				ind_free(indp);
			if (indrp)
				indrule_free(indrp);
			if (diskprops)
				nvlist_free(diskprops);
		}

		wdp->pfmri = cstr;
	}


	return (0);
}
Пример #27
0
static int
xml_read(topo_hdl_t *hp, ttree_t *tp)
{
	topo_file_t *tfp;
	char *pplat, *pmach;
	int err, e;
	char _topo_file[MAXNAMELEN * 2];
	char _topo_path[PATH_MAX];


	tfp = (topo_file_t *)tp->tt_file;

	(void) snprintf(_topo_file,
	    2 * MAXNAMELEN, TOPO_DEFAULT_FILE, tp->tt_scheme);

	/*
	 * Look for a platform-specific topology file first
	 */
	e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM,
	    TOPO_PROP_PLATFORM, &pplat, &err);
	if (e < 0)
		return (topo_hdl_seterrno(hp, err));
	(void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH,
	    hp->th_rootdir, pplat, _topo_file);

	tfp->tf_fileinfo =
	    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	if (tfp->tf_fileinfo != NULL) {
		topo_hdl_strfree(hp, pplat);
		return (0);
	}

	topo_dprintf(TOPO_DBG_MOD, "failed to load topology file %s: %s\n",
	    _topo_path, topo_strerror(topo_hdl_errno(hp)));

	/*
	 * No luck with the platform-specific file, how about a
	 * machine-specific one?
	 */
	e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM,
	    TOPO_PROP_MACHINE, &pmach, &err);
	if (e < 0) {
		topo_hdl_strfree(hp, pplat);
		return (topo_hdl_seterrno(hp, err));
	}
	/*
	 * Don't waste time trying to open the same file twice in the
	 * cases where the platform name is identical to the machine
	 * name
	 */
	if (strcmp(pplat, pmach) != 0) {
		(void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH,
		    hp->th_rootdir, pmach, _topo_file);
		tfp->tf_fileinfo =
		    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	}
	if (tfp->tf_fileinfo != NULL) {
		topo_hdl_strfree(hp, pplat);
		topo_hdl_strfree(hp, pmach);
		return (0);
	} else {
		topo_dprintf(TOPO_DBG_MOD,
		    "failed to load topology file %s: %s\n",
		    _topo_path, topo_strerror(topo_hdl_errno(hp)));
	}
	topo_hdl_strfree(hp, pplat);
	topo_hdl_strfree(hp, pmach);
	(void) snprintf(_topo_path, PATH_MAX, COMMON_TOPO_PATH,
	    hp->th_rootdir, _topo_file);
	tfp->tf_fileinfo =
	    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	if (tfp->tf_fileinfo == NULL) {
		topo_dprintf(TOPO_DBG_MOD,
		    "failed to load topology file %s: %s\n",
		    _topo_path, topo_strerror(topo_hdl_errno(hp)));
		return (topo_hdl_seterrno(hp, ETOPO_FILE_NOENT));
	}
	return (0);
}