Пример #1
0
int
pi_walker_init(topo_mod_t *mod)
{
	int			result;
	pi_enum_functions_t	*fp;
	pi_methods_t		*mp;

	result = topo_mod_nvalloc(mod, &pi_enum_fns, NV_UNIQUE_NAME);
	result |= topo_mod_nvalloc(mod, &pi_meths, NV_UNIQUE_NAME);
	if (result != 0) {
		topo_mod_dprintf(mod, "pi_walker_init failed\n");
		nvlist_free(pi_enum_fns);
		nvlist_free(pi_meths);
		return (-1);
	}

	/* Add the builtin functions to the list */
	fp = pi_enum_fns_builtin;
	while (fp != NULL && fp->hc_name != NULL) {
		uint64_t	faddr;

		faddr = (uint64_t)(uintptr_t)*(fp->func);
		result |= nvlist_add_uint64(pi_enum_fns, fp->hc_name, faddr);
		fp++;
	}

	/* Add the builtin methods to the list */
	mp = pi_meths_builtin;
	while (mp != NULL && mp->hc_name != NULL) {
		uint64_t	maddr;

		maddr = (uint64_t)(uintptr_t)mp->meths;
		result |= nvlist_add_uint64(pi_meths, mp->hc_name, maddr);
		mp++;
	}

	if (result != 0) {
		topo_mod_dprintf(mod, "pi_walker_init failed\n");
		nvlist_free(pi_enum_fns);
		nvlist_free(pi_meths);
		return (-1);
	}

	return (0);
}
Пример #2
0
static tnode_t *
iob_tnode_create(tnode_t *parent,
    const char *name, topo_instance_t i, void *priv, topo_mod_t *mod)
{
	topo_hdl_t *thp;
	nvlist_t *args, *fmri, *pfmri;
	tnode_t *ntn;
	int err;

	thp = topo_mod_handle(mod);

	if (topo_node_resource(parent, &pfmri, &err) < 0) {
		topo_mod_seterrno(mod, err);
		topo_mod_dprintf(mod,
		    "Unable to retrieve parent resource.\n");
		return (NULL);
	}
	if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) {
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		nvlist_free(pfmri);
		return (NULL);
	}
	err = nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri);
	if (err != 0) {
		nvlist_free(pfmri);
		nvlist_free(args);
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		return (NULL);
	}
	fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, i, args, &err);
	if (fmri == NULL) {
		topo_mod_dprintf(mod,
		    "Unable to make nvlist for %s bind.\n", name);
		return (NULL);
	}
	ntn = topo_node_bind(mod, parent, name, i, fmri, priv);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (NULL);
	}
	nvlist_free(fmri);
	if (topo_method_register(mod, ntn, Iob_methods) < 0) {
		topo_mod_dprintf(mod, "topo_method_register failed: %s\n",
		    topo_strerror(topo_mod_errno(mod)));
		topo_node_unbind(ntn);
		return (NULL);
	}
	return (ntn);
}
Пример #3
0
/*ARGSUSED*/
static int
disk_temp_reading(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
    nvlist_t *in, nvlist_t **out)
{
	char *devid;
	uint32_t temp;
	dm_descriptor_t drive_descr = NULL;
	nvlist_t *drive_stats, *pargs, *nvl;
	int err;

	if (vers > TOPO_METH_DISK_TEMP_VERSION)
		return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));

	if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &pargs) != 0 ||
	    nvlist_lookup_string(pargs, TOPO_IO_DEVID, &devid) != 0) {
		topo_mod_dprintf(mod, "Failed to lookup %s arg",
		    TOPO_IO_DEVID);
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}

	if ((drive_descr = dm_get_descriptor_by_name(DM_DRIVE, devid,
	    &err)) == NULL) {
		topo_mod_dprintf(mod, "failed to get drive decriptor for %s",
		    devid);
		return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
	}

	if ((drive_stats = dm_get_stats(drive_descr, DM_DRV_STAT_TEMPERATURE,
	    &err)) == NULL ||
	    nvlist_lookup_uint32(drive_stats, DM_TEMPERATURE, &temp) != 0) {
		topo_mod_dprintf(mod, "failed to read disk temp for %s",
		    devid);
		dm_free_descriptor(drive_descr);
		return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
	}
	dm_free_descriptor(drive_descr);

	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
	    nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
	    TOPO_SENSOR_READING) != 0 ||
	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) !=
	    0 || nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, (double)temp) != 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);
}
Пример #4
0
/*ARGSUSED*/
static int
label_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	nvlist_t *in, *out;
	char *label;
	int err;

	mp = did_mod(pd);
	/*
	 * If this is a PCIEX_BUS and its parent is a PCIEX_ROOT,
	 * check for a CPUBOARD predecessor.  If found, inherit its
	 * parent's Label.  Otherwise, continue with label set.
	 */
	if ((strcmp(topo_node_name(tn), PCIEX_BUS) == 0) &&
	    (strcmp(topo_node_name(topo_node_parent(tn)), PCIEX_ROOT) == 0)) {

		if (use_predecessor_label(mp, tn, CPUBOARD) == 0)
			return (0);
	}
	if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0)
		return (topo_mod_seterrno(mp, EMOD_FMRI_NVL));
	if (nvlist_add_uint64(in, TOPO_METH_LABEL_ARG_NVL, (uintptr_t)pd) !=
	    0) {
		nvlist_free(in);
		return (topo_mod_seterrno(mp, EMOD_NOMEM));
	}
	if (topo_method_invoke(tn,
	    TOPO_METH_LABEL, TOPO_METH_LABEL_VERSION, in, &out, &err) != 0) {
		nvlist_free(in);
		return (topo_mod_seterrno(mp, err));
	}
	nvlist_free(in);
	if (out != NULL &&
	    nvlist_lookup_string(out, TOPO_METH_LABEL_RET_STR, &label) == 0) {
		if (topo_prop_set_string(tn, TOPO_PGROUP_PROTOCOL,
		    TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label, &err) != 0) {
			nvlist_free(out);
			return (topo_mod_seterrno(mp, err));
		}
		nvlist_free(out);
	}
	return (0);
}
Пример #5
0
static int
set_retnvl(topo_mod_t *mod, nvlist_t **out, const char *retname, uint32_t ret)
{
	nvlist_t *nvl;

	topo_mod_dprintf(mod, "topo method set \"%s\" = %u\n", retname, ret);

	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) < 0)
		return (topo_mod_seterrno(mod, EMOD_NOMEM));

	if (nvlist_add_uint32(nvl, retname, ret) != 0) {
		nvlist_free(nvl);
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}

	*out = nvl;
	return (0);
}
Пример #6
0
/*ARGSUSED*/
int
platform_iob_label(topo_mod_t *mod, tnode_t *node, nvlist_t *ignored,
    nvlist_t **out)
{
	/*
	 * For E15K, the label is simply IOXX where XX is the
	 * instance number of the ioboard.
	 */
	char buf[10];	/* up to a million I/O boards :-) */

	*out = NULL;
	(void) snprintf(buf, 10, "IO%d", topo_node_instance(node));
	if (topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) == 0 &&
	    nvlist_add_string(*out, TOPO_METH_LABEL_RET_STR, buf) == 0)
		return (0);
	nvlist_free(*out);
	*out = NULL;
	return (-1);
}
Пример #7
0
static nvlist_t *
mem_fmri_create(topo_mod_t *mod, char *serial, char *label)
{
	int err;
	nvlist_t *fmri;

	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
		return (NULL);
	err = nvlist_add_uint8(fmri, FM_VERSION, FM_MEM_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM);
	if (serial != NULL)
		err |= nvlist_add_string_array(fmri, FM_FMRI_MEM_SERIAL_ID,
		    &serial, 1);
	if (label != NULL)
		err |= nvlist_add_string(fmri, FM_FMRI_MEM_UNUM, label);
	if (err != 0) {
		nvlist_free(fmri);
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		return (NULL);
	}

	return (fmri);
}
Пример #8
0
/* Topo Methods */
static int
mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	nvlist_t *asru, *pargs, *args, *hcsp;
	int err;
	char *serial = NULL, *label = NULL;
	uint64_t pa, offset;

	if (version > TOPO_METH_ASRU_COMPUTE_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (strcmp(topo_node_name(node), DIMM) != 0)
		return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));

	pargs = NULL;

	if (nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0)
		(void) nvlist_lookup_string(pargs, FM_FMRI_HC_SERIAL_ID,
		    &serial);
	if (serial == NULL &&
	    nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) == 0)
		(void) nvlist_lookup_string(args, FM_FMRI_HC_SERIAL_ID,
		    &serial);

	(void) topo_node_label(node, &label, &err);

	asru = mem_fmri_create(mod, serial, label);

	if (label != NULL)
		topo_mod_strfree(mod, label);

	if (asru == NULL)
		return (topo_mod_seterrno(mod, EMOD_NOMEM));

	err = 0;

	/*
	 * For a memory page, 'in' includes an hc-specific member which
	 * specifies physaddr and/or offset. Set them in asru as well.
	 */
	if (pargs && nvlist_lookup_nvlist(pargs,
	    FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
		if (nvlist_lookup_uint64(hcsp,
		    FM_FMRI_HC_SPECIFIC_PHYSADDR, &pa) == 0)
			err += nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR,
			    pa);
		if (nvlist_lookup_uint64(hcsp,
		    FM_FMRI_HC_SPECIFIC_OFFSET, &offset) == 0)
			err += nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET,
			    offset);
	}


	if (err != 0 || topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) < 0) {
		nvlist_free(asru);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}

	err = nvlist_add_string(*out, TOPO_PROP_VAL_NAME, TOPO_PROP_ASRU);
	err |= nvlist_add_uint32(*out, TOPO_PROP_VAL_TYPE, TOPO_TYPE_FMRI);
	err |= nvlist_add_nvlist(*out, TOPO_PROP_VAL_VAL, asru);
	nvlist_free(asru);

	if (err != 0) {
		nvlist_free(*out);
		*out = NULL;
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}

	return (0);
}
Пример #9
0
/*ARGSUSED*/
static int
FRU_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	char *nm;
	int e = 0, err = 0;

	nm = topo_node_name(tn);
	mp = did_mod(pd);

	/*
	 * If this is a PCIEX_BUS and its parent is a PCIEX_ROOT,
	 * check for a CPUBOARD predecessor.  If found, inherit its
	 * parent's FRU.  Otherwise, continue with FRU set.
	 */
	if ((strcmp(nm, PCIEX_BUS) == 0) &&
	    (strcmp(topo_node_name(topo_node_parent(tn)), PCIEX_ROOT) == 0)) {

		if (use_predecessor_fru(tn, CPUBOARD) == 0)
			return (0);
	}
	/*
	 * If this topology node represents something other than an
	 * ioboard or a device that implements a slot, inherit the
	 * parent's FRU value.  If there is no label, inherit our
	 * parent's FRU value.  Otherwise, munge up an fmri based on
	 * the label.
	 */
	if (strcmp(nm, IOBOARD) != 0 && strcmp(nm, PCI_DEVICE) != 0 &&
	    strcmp(nm, PCIEX_DEVICE) != 0 && strcmp(nm, PCIEX_BUS) != 0) {
		(void) topo_node_fru_set(tn, NULL, 0, &e);
		return (0);
	}

	/*
	 * If ioboard, set fru fmri to hc fmri
	 */
	if (strcmp(nm, IOBOARD) == 0) {
		e = FRU_fmri_set(mp, tn);
		return (e);
	} else if (strcmp(nm, PCI_DEVICE) == 0 ||
	    strcmp(nm, PCIEX_DEVICE) == 0 || strcmp(nm, PCIEX_BUS) == 0) {
		nvlist_t *in, *out;

		mp = did_mod(pd);
		if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0)
			return (topo_mod_seterrno(mp, EMOD_FMRI_NVL));
		if (nvlist_add_uint64(in, "nv1", (uintptr_t)pd) != 0) {
			nvlist_free(in);
			return (topo_mod_seterrno(mp, EMOD_NOMEM));
		}
		if (topo_method_invoke(tn,
		    TOPO_METH_FRU_COMPUTE, TOPO_METH_FRU_COMPUTE_VERSION,
		    in, &out, &err) != 0) {
			nvlist_free(in);
			return (topo_mod_seterrno(mp, err));
		}
		nvlist_free(in);
		(void) topo_node_fru_set(tn, out, 0, &err);
		if (out != NULL)
			nvlist_free(out);
	} else
		(void) topo_node_fru_set(tn, NULL, 0, &err);

	return (0);
}
Пример #10
0
static int
mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
    nvlist_t *in, nvlist_t **nvout)
{
	int err, ret = 0;
	tnode_t *pnode = topo_node_parent(node);
	uint32_t type, ledmode = 0;
	nvlist_t *pargs, *nvl;
	char *driver = NULL, *devctl = NULL;
	uint32_t enclosure, slot;
	uint8_t mptsas_led;
	boolean_t set;

	if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
		return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));

	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_DRIVER, &driver, &err) != 0 ||
	    strcmp("mpt_sas", driver) != 0) {
		topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas",
		    __func__);
		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
		goto out;
	}
	if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
	    &type, &err) != 0) {
		topo_mod_dprintf(mod, "%s: Failed to lookup %s property "
		    "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err));
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}
	switch (type) {
	case (TOPO_LED_TYPE_SERVICE):
		mptsas_led = MPTSAS_LEDCTL_LED_FAIL;
		break;
	case (TOPO_LED_TYPE_LOCATE):
		mptsas_led = MPTSAS_LEDCTL_LED_IDENT;
		break;
	case (TOPO_LED_TYPE_OK2RM):
		mptsas_led = MPTSAS_LEDCTL_LED_OK2RM;
		break;
	default:
		topo_mod_dprintf(mod, "%s: Invalid LED type: 0x%x\n", __func__,
		    type);
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}
	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_DEVCTL, &devctl, &err) != 0 ||
	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 ||
	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_SLOT, &slot, &err) != 0) {
		topo_mod_dprintf(mod, "%s: Facility was missing mpt_sas binding"
		    " properties\n", __func__);
		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
		goto out;
	}

	if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
	    nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
		/*
		 * Set the LED mode
		 */
		set = B_TRUE;
		if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
		    &ledmode)) != 0) {
			topo_mod_dprintf(mod, "%s: Failed to lookup %s nvpair "
			    "(%s)\n", __func__, TOPO_PROP_VAL_VAL,
			    strerror(ret));
			ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
			goto out;
		}
		topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__,
		    ledmode ? "ON" : "OFF");
	} else {
		/*
		 * Get the LED mode
		 */
		set = B_FALSE;
		topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
	}

	if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode,
	    set) != 0) {
		topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
		goto out;
	}

	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
	    nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
		topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n",
		    __func__);
		nvlist_free(nvl);
		ret = topo_mod_seterrno(mod, EMOD_NOMEM);
		goto out;
	}
	*nvout = nvl;

out:
	if (driver != NULL)
		topo_mod_strfree(mod, driver);
	if (devctl != NULL)
		topo_mod_strfree(mod, devctl);
	return (ret);
}
Пример #11
0
static int
disk_add_temp_sensor(topo_mod_t *mod, tnode_t *pnode, const char *devid)
{
	tnode_t *fnode;
	topo_pgroup_info_t pgi;
	nvlist_t *arg_nvl = NULL;
	int err;

	if ((fnode = topo_node_facbind(mod, pnode, "temp",
	    TOPO_FAC_TYPE_SENSOR)) == NULL) {
		topo_mod_dprintf(mod, "failed to bind facility node");
		/* errno set */
		return (-1);
	}

	/*
	 * Set props:
	 * - facility/sensor-class
	 * - facility/sensor-type
	 * - facility/units
	 */
	pgi.tpi_name = TOPO_PGROUP_FACILITY;
	pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
	pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
	pgi.tpi_version = 1;
	if (topo_pgroup_create(fnode, &pgi, &err) != 0) {
		if (err != ETOPO_PROP_DEFD) {
			topo_mod_dprintf(mod,  "pgroups create failure (%s)\n",
			    topo_strerror(err));
			/* errno set */
			goto err;
		}
	}
	if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY,
	    TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE,
	    TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 ||
	    topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
	    TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP,
	    &err) != 0 ||
	    topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
	    TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE,
	    TOPO_SENSOR_UNITS_DEGREES_C, &err) != 0) {
		topo_mod_dprintf(mod, "Failed to set props on facnode (%s)",
		    topo_strerror(err));
		/* errno set */
		goto err;
	}

	/*
	 * Register a property method for facility/reading
	 */
	if (topo_method_register(mod, fnode, disk_fac_methods) < 0) {
		topo_mod_dprintf(mod, "failed to register facility methods");
		goto err;
	}
	if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0 ||
	    nvlist_add_string(arg_nvl, TOPO_IO_DEVID, devid) != 0) {
		topo_mod_dprintf(mod, "Failed build arg nvlist\n");
		(void) topo_mod_seterrno(mod, EMOD_NOMEM);
		goto err;
	}
	if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY,
	    TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "disk_temp_reading",
	    arg_nvl, &err) != 0) {
		topo_mod_dprintf(mod, "Failed to register %s propmeth "
		    "on fac node %s (%s)\n", TOPO_SENSOR_READING,
		    topo_node_name(fnode), topo_strerror(err));
		/* errno set */
		goto err;
	}
	nvlist_free(arg_nvl);
	return (0);
err:
	topo_node_unbind(fnode);
	nvlist_free(arg_nvl);
	return (-1);
}
Пример #12
0
/*ARGSUSED*/
int
topo_method_sensor_failure(topo_mod_t *mod, tnode_t *node,
    topo_version_t version, nvlist_t *in, nvlist_t **out)
{
	const char *name = topo_node_name(node);
	topo_faclist_t faclist, *fp;
	int err;
	nvlist_t *nvl, *props, *propval, *tmp;
	int ret = -1;
	uint32_t type, state, units;
	nvpair_t *elem;
	double reading;
	char *propname;
	boolean_t has_reading;
	struct sensor_errinfo seinfo;

	if (strcmp(name, PSU) != 0 && strcmp(name, FAN) != 0)
		return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP));

	if (topo_node_facility(mod->tm_hdl, node, TOPO_FAC_TYPE_SENSOR,
	    TOPO_FAC_TYPE_ANY, &faclist, &err) != 0)
		return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP));

	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0)
		goto error;

	for (fp = topo_list_next(&faclist.tf_list); fp != NULL;
	    fp = topo_list_next(fp)) {
		if (topo_prop_getpgrp(fp->tf_node, TOPO_PGROUP_FACILITY,
		    &props, &err) != 0) {
			nvlist_free(nvl);
			goto error;
		}
		type = state = units = 0;
		reading = 0;
		has_reading = B_FALSE;

		elem = NULL;
		while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
			if (strcmp(nvpair_name(elem), TOPO_PROP_VAL) != 0 ||
			    nvpair_type(elem) != DATA_TYPE_NVLIST)
				continue;

			(void) nvpair_value_nvlist(elem, &propval);
			if (nvlist_lookup_string(propval,
			    TOPO_PROP_VAL_NAME, &propname) != 0)
				continue;

			if (strcmp(propname, TOPO_FACILITY_TYPE) == 0) {
				(void) nvlist_lookup_uint32(propval,
				    TOPO_PROP_VAL_VAL, &type);
			} else if (strcmp(propname, TOPO_SENSOR_STATE) == 0) {
				(void) nvlist_lookup_uint32(propval,
				    TOPO_PROP_VAL_VAL, &state);
			} else if (strcmp(propname, TOPO_SENSOR_UNITS) == 0) {
				(void) nvlist_lookup_uint32(propval,
				    TOPO_PROP_VAL_VAL, &units);
			} else if (strcmp(propname, TOPO_SENSOR_READING) == 0) {
				has_reading = B_TRUE;
				(void) nvlist_lookup_double(propval,
				    TOPO_PROP_VAL_VAL, &reading);
			}
		}

		if (topo_sensor_failed(type, state, &seinfo)) {
			tmp = NULL;
			if (topo_mod_nvalloc(mod, &tmp, NV_UNIQUE_NAME) != 0 ||
			    nvlist_add_uint32(tmp, TOPO_FACILITY_TYPE,
			    type) != 0 ||
			    nvlist_add_uint32(tmp, TOPO_SENSOR_STATE,
			    state) != 0 ||
			    nvlist_add_uint32(tmp, TOPO_SENSOR_UNITS,
			    units) != 0 ||
			    nvlist_add_boolean_value(tmp,
			    "nonrecov", seinfo.se_nonrecov) != 0 ||
			    nvlist_add_boolean_value(tmp,
			    "predictive", seinfo.se_predictive) != 0 ||
			    nvlist_add_uint32(tmp, "source",
			    seinfo.se_src) != 0 ||
			    (has_reading && nvlist_add_double(tmp,
			    TOPO_SENSOR_READING, reading) != 0) ||
			    nvlist_add_nvlist(nvl, topo_node_name(fp->tf_node),
			    tmp) != 0) {
				nvlist_free(props);
				nvlist_free(tmp);
				nvlist_free(nvl);
				ret = topo_mod_seterrno(mod,
				    ETOPO_METHOD_NOMEM);
				goto error;
			}

			nvlist_free(tmp);
		}

		nvlist_free(props);
	}

	*out = nvl;
	ret = 0;
error:
	while ((fp = topo_list_next(&faclist.tf_list)) != NULL) {
		topo_list_delete(&faclist.tf_list, fp);
		topo_mod_free(mod, fp, sizeof (topo_faclist_t));
	}
	return (ret);
}
Пример #13
0
/*ARGSUSED*/
static int
sw_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *nvl, nvlist_t **out)
{
	nvlist_t *object, *site = NULL, *anvl = NULL;
	char *file, *func, *token;
	uint8_t scheme_version;
	char *path, *root;
	nvlist_t *fmristr;
	size_t buflen = 0;
	int linevalid = 0;
	char *buf = NULL;
	ssize_t size = 0;
	char linebuf[32];
	int64_t line;
	int pass;
	int err;

	if (version > TOPO_METH_NVL2STR_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (nvlist_lookup_uint8(nvl, FM_VERSION, &scheme_version) != 0 ||
	    scheme_version > FM_SW_SCHEME_VERSION)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* Get authority, if present */
	err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl);
	if (err != 0 && err != ENOENT)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/*
	 * The 'object' nvlist is required. It must include the path,
	 * but the root is optional.
	 */
	if (nvlist_lookup_nvlist(nvl, FM_FMRI_SW_OBJ, &object) != 0 ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_PATH, &path, B_TRUE) ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_ROOT, &root, B_FALSE))
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* The 'site' nvlist is optional */
	file = func = token = NULL;
	linevalid = 0;
	if ((err = nvlist_lookup_nvlist(nvl, FM_FMRI_SW_SITE, &site)) == 0) {
		/*
		 * Prefer 'token' to file/func/line
		 */
		if (lookup_string(site, FM_FMRI_SW_SITE_TOKEN, &token,
		    B_FALSE) <= 0) {
			/*
			 * If no token then try file, func, line - but
			 * func and line are meaningless without file.
			 */
			if (lookup_string(site, FM_FMRI_SW_SITE_FILE,
			    &file, B_FALSE) == 1) {
				(void) lookup_string(site, FM_FMRI_SW_SITE_FUNC,
				    &func, B_FALSE);
				if (nvlist_lookup_int64(site,
				    FM_FMRI_SW_SITE_LINE, &line) == 0)
					linevalid = 1;
			}
		}
	} else if (err != ENOENT) {
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
	}

	/* On the first pass buf is NULL and size and buflen are 0 */
	pass = 1;
again:
	/*
	 * sw://[<authority>]/
	 *	[:root=<object.root]
	 *	:path=<object.path>
	 *	[#<fragment-identifier>]
	 *
	 *	<fragment-identifier> is one of
	 *
	 *		:token=<site.token>
	 *	or
	 *		:file=<site.file>[:func=<site.func>][:line=<site.line>]
	 */

	/* sw:// */
	topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_SW,
	    NULL, "://");

	/* authority, if any */
	if (anvl != NULL) {
		nvpair_t *apair;
		char *aname, *aval;

		for (apair = nvlist_next_nvpair(anvl, NULL);
		    apair != NULL; apair = nvlist_next_nvpair(anvl, apair)) {
			if (nvpair_type(apair) != DATA_TYPE_STRING ||
			    nvpair_value_string(apair, &aval) != 0)
				continue;
			aname = nvpair_name(apair);
			topo_fmristr_build(&size, buf, buflen, ":", NULL, NULL);
			topo_fmristr_build(&size, buf, buflen, "=",
			    aname, aval);
		}
	}

	/* separating slash */
	topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL);

	/* :root=... */
	if (root) {
		topo_fmristr_build(&size, buf, buflen, root,
		    ":" FM_FMRI_SW_OBJ_ROOT "=", NULL);
	}

	/* :path=... */
	topo_fmristr_build(&size, buf, buflen, path,
	    ":" FM_FMRI_SW_OBJ_PATH "=", NULL);

	if (token) {
		/* #:token=... */
		topo_fmristr_build(&size, buf, buflen, token,
		    "#:" FM_FMRI_SW_SITE_TOKEN "=", NULL);
	} else if (file) {
		/* #:file=... */
		topo_fmristr_build(&size, buf, buflen, file,
		    "#:" FM_FMRI_SW_SITE_FILE "=", NULL);

		/* :func=... */
		if (func) {
			topo_fmristr_build(&size, buf, buflen, func,
			    ":" FM_FMRI_SW_SITE_FUNC "=", NULL);
		}

		/* :line=... */
		if (linevalid) {
			if (pass == 1)
				(void) snprintf(linebuf, sizeof (linebuf),
				    "%lld", line);

			topo_fmristr_build(&size, buf, buflen, linebuf,
			    ":" FM_FMRI_SW_SITE_LINE "=", NULL);
		}
	}

	if (buf == NULL) {
		if ((buf = topo_mod_alloc(mod, size + 1)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		buflen = size + 1;
		size = 0;
		pass = 2;
		goto again;
	}

	/*
	 * Construct the nvlist to return as the result.
	 */
	if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) {
		topo_mod_strfree(mod, buf);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}

	if (nvlist_add_string(fmristr, "fmri-string", buf) != 0) {
		topo_mod_strfree(mod, buf);
		nvlist_free(fmristr);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}
	topo_mod_strfree(mod, buf);
	*out = fmristr;

	return (0);
}
Пример #14
0
/*ARGSUSED*/
static int
sw_fmri_create(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	nvlist_t *args, *fmri = NULL, *obj = NULL, *site = NULL, *ctxt = NULL;
	topo_mod_errno_t moderr;
	int err = 0;

	char *obj_path, *obj_root;
	nvlist_t *obj_pkg;

	char *site_token, *site_module, *site_file, *site_func;
	int64_t site_line;

	char *ctxt_origin, *ctxt_execname, *ctxt_zone;
	int64_t ctxt_pid, ctxt_ctid;
	char **ctxt_stack;
	uint_t ctxt_stackdepth;


	if (version > TOPO_METH_FMRI_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args) != 0)
		return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));

	if (nvlist_lookup_string(args, "obj_path", &obj_path) != 0)
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	err |= sw_get_optl_string(args, "obj_root", &obj_root);
	err |= sw_get_optl_nvlist(args, "obj-pkg", &obj_pkg);

	err |= sw_get_optl_string(args, "site_token", &site_token);
	err |= sw_get_optl_string(args, "site_module", &site_module);
	err |= sw_get_optl_string(args, "site_file", &site_file);
	err |= sw_get_optl_string(args, "site_func", &site_func);
	err |= sw_get_optl_int64(args, "site_line", &site_line);

	err |= sw_get_optl_string(args, "ctxt_origin", &ctxt_origin);
	err |= sw_get_optl_string(args, "ctxt_execname", &ctxt_execname);
	err |= sw_get_optl_string(args, "ctxt_zone", &ctxt_zone);
	err |= sw_get_optl_int64(args, "ctxt_pid", &ctxt_pid);
	err |= sw_get_optl_int64(args, "ctxt_ctid", &ctxt_ctid);

	if (nvlist_lookup_string_array(args, "stack", &ctxt_stack,
	    &ctxt_stackdepth) != 0) {
		if (errno == ENOENT)
			ctxt_stack = NULL;
		else
			err++;
	}

	if (err)
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);

	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0 ||
	    topo_mod_nvalloc(mod, &obj, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	/*
	 * Add standard FMRI members 'version' and 'scheme'.
	 */
	err |= nvlist_add_uint8(fmri, FM_VERSION, FM_SW_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW);

	/*
	 * Build up the 'object' nvlist.
	 */
	err |= nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, obj_path);
	err |= sw_add_optl_string(obj, FM_FMRI_SW_OBJ_ROOT, obj_root);
	if (obj_pkg)
		err |= nvlist_add_nvlist(obj, FM_FMRI_SW_OBJ_PKG, obj_pkg);

	/*
	 * Add 'object' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_OBJ, obj);

	if (err) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	/*
	 * Do we have anything for a 'site' nvlist?
	 */
	if (site_token == NULL && site_module == NULL && site_file == NULL &&
	    site_func == NULL && site_line == -1)
		goto context;

	/*
	 * Allocate and build 'site' nvlist.
	 */
	if (topo_mod_nvalloc(mod, &site, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_TOKEN, site_token);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_MODULE, site_module);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FILE, site_file);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FUNC, site_func);
	if ((site_token || site_module || site_file || site_func) &&
	    site_line != -1)
		err |= nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, site_line);

	/*
	 * Add 'site' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_SITE, site);

	if (err) {
		moderr = EMOD_NOMEM;
		goto out;
	}

context:
	/*
	 * Do we have anything for a 'context' nvlist?
	 */
	if (ctxt_origin || ctxt_execname || ctxt_zone ||
	    ctxt_pid != -1 || ctxt_ctid != -1 || ctxt_stack != NULL)
		goto out;

	/*
	 * Allocate and build 'context' nvlist.
	 */
	if (topo_mod_nvalloc(mod, &ctxt, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN, ctxt_origin);
	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME,
	    ctxt_execname);
	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ZONE, ctxt_zone);
	if (ctxt_pid != -1)
		err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_PID, ctxt_pid);
	if (ctxt_ctid != -1)
		err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_CTID, ctxt_ctid);
	if (ctxt_stack != NULL)
		err |= nvlist_add_string_array(ctxt, FM_FMRI_SW_CTXT_STACK,
		    ctxt_stack, ctxt_stackdepth);

	/*
	 * Add 'context' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_CTXT, ctxt);

	moderr = err ? EMOD_NOMEM : 0;
out:
	if (moderr == 0)
		*out = fmri;

	if (moderr != 0 && fmri)
		nvlist_free(fmri);

	if (obj)
		nvlist_free(obj);

	if (site)
		nvlist_free(site);

	if (ctxt)
		nvlist_free(ctxt);

	return (moderr == 0 ? 0 : topo_mod_seterrno(mod, moderr));
}