Example #1
0
int
topo_fmri_contains(topo_hdl_t *thp, nvlist_t *fmri, nvlist_t *subfmri, int *err)
{
	int rc;
	char *scheme;
	nvlist_t *in, *out = NULL;
	tnode_t *rnode;

	if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_CONTAINS, out));

	if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_CONTAINS, out));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS,
		    out));

	if (nvlist_add_nvlist(in, "fmri", fmri) != 0 ||
	    nvlist_add_nvlist(in, "subfmri", subfmri) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS,
		    out));

	if (topo_hdl_nvalloc(thp, &out, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS,
		    out));

	if ((rc = topo_method_invoke(rnode, TOPO_METH_CONTAINS,
	    TOPO_METH_CONTAINS_VERSION, fmri, &out, err)) < 0)
		return (set_error(thp, *err, err, TOPO_METH_CONTAINS, out));

	return (rc);
}
Example #2
0
int
topo_fmri_contains(topo_hdl_t *thp, nvlist_t *fmri, nvlist_t *subfmri, int *err)
{
	uint32_t contains;
	char *scheme;
	nvlist_t *in = NULL, *out = NULL;
	tnode_t *rnode;

	if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_CONTAINS, NULL));

	if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_CONTAINS, NULL));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS,
		    NULL));

	if (nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_FMRI, fmri) != 0 ||
	    nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_SUBFMRI, subfmri) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS,
		    in));

	if (topo_method_invoke(rnode, TOPO_METH_CONTAINS,
	    TOPO_METH_CONTAINS_VERSION, in, &out, err) < 0)
		return (set_error(thp, *err, err, TOPO_METH_CONTAINS, in));

	(void) nvlist_lookup_uint32(out, TOPO_METH_CONTAINS_RET, &contains);
	nvlist_free(in);
	nvlist_free(out);

	return (contains);
}
Example #3
0
int
topo_prop_getpgrp(tnode_t *node, const char *pgname, nvlist_t **pgrp,
    int *err)
{
	int ret;
	topo_hdl_t *thp = node->tn_hdl;
	nvlist_t *nvl, *pvnvl;
	topo_pgroup_t *pg;
	topo_propval_t *pv;
	topo_proplist_t *pvl;

	if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) {
		*err = ETOPO_NOMEM;
		return (-1);
	}

	topo_node_lock(node);
	for (pg = topo_list_next(&node->tn_pgroups); pg != NULL;
	    pg = topo_list_next(pg)) {

		if (strcmp(pgname, pg->tpg_info->tpi_name) != 0)
			continue;

		if (nvlist_add_string(nvl, TOPO_PROP_GROUP_NAME,
		    pg->tpg_info->tpi_name) != 0 ||
		    nvlist_add_string(nvl, TOPO_PROP_GROUP_NSTAB,
		    topo_stability2name(pg->tpg_info->tpi_namestab)) != 0 ||
		    nvlist_add_string(nvl, TOPO_PROP_GROUP_DSTAB,
		    topo_stability2name(pg->tpg_info->tpi_datastab)) != 0 ||
		    nvlist_add_int32(nvl, TOPO_PROP_GROUP_VERSION,
		    pg->tpg_info->tpi_version) != 0)
			return (get_pgrp_seterror(node, nvl, err,
			    ETOPO_PROP_NVL));

		for (pvl = topo_list_next(&pg->tpg_pvals); pvl != NULL;
		    pvl = topo_list_next(pvl)) {

			pv = pvl->tp_pval;
			if (prop_val_add(node, &pvnvl, pv, err) < 0) {
				return (get_pgrp_seterror(node, nvl, err,
				    *err));
			}
			if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL,
			    pvnvl)) != 0) {
				nvlist_free(pvnvl);
				return (get_pgrp_seterror(node, nvl, err, ret));
			}

			nvlist_free(pvnvl);
		}
		topo_node_unlock(node);
		*pgrp = nvl;
		return (0);
	}

	topo_node_unlock(node);
	*err = ETOPO_PROP_NOENT;
	return (-1);
}
Example #4
0
static int
prop_method_get(tnode_t *node, topo_propval_t *pv, topo_propmethod_t *pm,
    nvlist_t *pargs, int *err)
{
	int ret;
	nvlist_t *args, *nvl;
	char *name;
	topo_type_t type;

	if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0 ||
	    nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args) != 0)
		return (method_geterror(NULL, ETOPO_PROP_NVL, err));

	if (pargs != NULL)
		if (nvlist_add_nvlist(args, TOPO_PROP_PARGS, pargs) != 0)
			return (method_geterror(args, ETOPO_PROP_NVL, err));

	/*
	 * Now, get the latest value
	 *
	 * Grab a reference to the property and then unlock the node.  This will
	 * allow property methods to safely re-enter the prop_get codepath,
	 * making it possible for property methods to access other property
	 * values on the same node w\o causing a deadlock.
	 */
	topo_prop_hold(pv);
	topo_node_unlock(node);
	if (topo_method_call(node, pm->tpm_name, pm->tpm_version,
	    args, &nvl, err) < 0) {
		topo_node_lock(node);
		topo_prop_rele(pv);
		return (method_geterror(args, *err, err));
	}
	topo_node_lock(node);
	topo_prop_rele(pv);

	nvlist_free(args);

	/* Verify the property contents */
	ret = nvlist_lookup_string(nvl, TOPO_PROP_VAL_NAME, &name);
	if (ret != 0 || strcmp(name, pv->tp_name) != 0)
		return (method_geterror(nvl, ETOPO_PROP_NAME, err));

	ret = nvlist_lookup_uint32(nvl, TOPO_PROP_VAL_TYPE, (uint32_t *)&type);
	if (ret != 0 || type != pv->tp_type)
		return (method_geterror(nvl, ETOPO_PROP_TYPE, err));

	/* Release the last value and re-assign to the new value */
	if (pv->tp_val != NULL)
		nvlist_free(pv->tp_val);
	pv->tp_val = nvl;

	return (0);
}
Example #5
0
static int
fmri_prop(topo_hdl_t *thp, nvlist_t *rsrc, const char *pgname,
    const char *pname, nvlist_t *args, nvlist_t **prop,
    int *err)
{
	int rv;
	nvlist_t *in = NULL;
	tnode_t *rnode;
	char *scheme;

	if (nvlist_lookup_string(rsrc, FM_FMRI_SCHEME, &scheme) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_PROP_GET, in));

	if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_PROP_GET, in));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_PROP_GET, in));

	rv = nvlist_add_nvlist(in, TOPO_PROP_RESOURCE, rsrc);
	rv |= nvlist_add_string(in, TOPO_PROP_GROUP, pgname);
	rv |= nvlist_add_string(in, TOPO_PROP_VAL_NAME, pname);
	if (args != NULL)
		rv |= nvlist_add_nvlist(in, TOPO_PROP_PARGS, args);
	if (rv != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_PROP_GET, in));

	*prop = NULL;
	rv = topo_method_invoke(rnode, TOPO_METH_PROP_GET,
	    TOPO_METH_PROP_GET_VERSION, in, prop, err);

	nvlist_free(in);

	if (rv != 0)
		return (-1); /* *err is set for us */

	if (*prop == NULL)
		return (set_error(thp, ETOPO_PROP_NOENT, err,
		    TOPO_METH_PROP_GET, NULL));
	return (0);
}
Example #6
0
int topo_fmri_setprop(topo_hdl_t *thp, nvlist_t *nvl, const char *pg,
    nvlist_t *prop, int flag, nvlist_t *args, int *err)
{
	int rv;
	nvlist_t *in = NULL, *out = NULL;
	tnode_t *rnode;
	char *scheme;

	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &scheme) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_PROP_SET, in));

	if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_PROP_SET, in));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_PROP_SET, in));

	rv = nvlist_add_nvlist(in, TOPO_PROP_RESOURCE, nvl);
	rv |= nvlist_add_string(in, TOPO_PROP_GROUP, pg);
	rv |= nvlist_add_nvlist(in, TOPO_PROP_VAL, prop);
	rv |= nvlist_add_int32(in, TOPO_PROP_FLAG, (int32_t)flag);
	if (args != NULL)
		rv |= nvlist_add_nvlist(in, TOPO_PROP_PARGS, args);
	if (rv != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_PROP_SET, in));

	rv = topo_method_invoke(rnode, TOPO_METH_PROP_SET,
	    TOPO_METH_PROP_SET_VERSION, in, &out, err);

	nvlist_free(in);

	/* no return values */
	nvlist_free(out);

	if (rv)
		return (-1);

	return (0);

}
Example #7
0
int
topo_fmri_compare(topo_hdl_t *thp, nvlist_t *f1, nvlist_t *f2, int *err)
{
	uint32_t compare;
	char *scheme1, *scheme2;
	nvlist_t *in;
	nvlist_t *out = NULL;
	tnode_t *rnode;

	if (nvlist_lookup_string(f1, FM_FMRI_SCHEME, &scheme1) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_COMPARE, NULL));
	if (nvlist_lookup_string(f2, FM_FMRI_SCHEME, &scheme2) != 0)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_COMPARE, NULL));

	if (strcmp(scheme1, scheme2) != 0)
		return (0);

	if ((rnode = topo_hdl_root(thp, scheme1)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_COMPARE, NULL));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_COMPARE,
		    NULL));

	if (nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_NV1, f1) != 0 ||
	    nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_NV2, f2) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_COMPARE,
		    in));

	if (topo_method_invoke(rnode, TOPO_METH_COMPARE,
	    TOPO_METH_COMPARE_VERSION, in, &out, err) < 0)
		return (set_error(thp, *err, err, TOPO_METH_COMPARE, in));

	(void) nvlist_lookup_uint32(out, TOPO_METH_COMPARE_RET, &compare);
	nvlist_free(out);
	nvlist_free(in);

	return (compare);
}
Example #8
0
int
topo_fmri_str2nvl(topo_hdl_t *thp, const char *fmristr, nvlist_t **fmri,
    int *err)
{
	char *f, buf[PATH_MAX];
	nvlist_t *out = NULL, *in = NULL;
	tnode_t *rnode;

	(void) strlcpy(buf, fmristr, sizeof (buf));
	if ((f = strchr(buf, ':')) == NULL)
		return (set_error(thp, ETOPO_FMRI_MALFORM, err,
		    TOPO_METH_STR2NVL, in));

	*f = '\0'; /* strip trailing FMRI path */

	if ((rnode = topo_hdl_root(thp, buf)) == NULL)
		return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_STR2NVL, in));

	if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_STR2NVL,
		    in));

	if (nvlist_add_string(in, "fmri-string", fmristr) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_STR2NVL,
		    in));

	if (topo_method_invoke(rnode, TOPO_METH_STR2NVL,
	    TOPO_METH_STR2NVL_VERSION, in, &out, err) != 0)
		return (set_error(thp, *err, err, TOPO_METH_STR2NVL, in));

	nvlist_free(in);

	if (out == NULL ||
	    topo_hdl_nvdup(thp, out, fmri) != 0)
		return (set_error(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_STR2NVL, out));

	nvlist_free(out);

	return (0);
}
Example #9
0
/*
 * topo_fmri_create
 *
 *	If possible, creates an FMRI of the requested version in the
 *	requested scheme.  Args are passed as part of the inputs to the
 *	fmri-create method of the scheme.
 */
nvlist_t *
topo_fmri_create(topo_hdl_t *thp, const char *scheme, const char *name,
    topo_instance_t inst, nvlist_t *nvl, int *err)
{
	nvlist_t *ins;
	nvlist_t *out;
	tnode_t *rnode;

	ins = out = NULL;

	if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
		return (set_nverror(thp, ETOPO_METHOD_NOTSUP, err,
		    TOPO_METH_FMRI, NULL));

	if ((*err = topo_hdl_nvalloc(thp, &ins, NV_UNIQUE_NAME)) != 0)
		return (set_nverror(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_FMRI, NULL));

	if (nvlist_add_string(ins, TOPO_METH_FMRI_ARG_NAME, name) != 0 ||
	    nvlist_add_uint32(ins, TOPO_METH_FMRI_ARG_INST, inst) != 0) {
		return (set_nverror(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_FMRI, ins));
	}

	if (nvl != NULL &&
	    nvlist_add_nvlist(ins, TOPO_METH_FMRI_ARG_NVL, nvl) != 0) {
		return (set_nverror(thp, ETOPO_FMRI_NVL, err,
		    TOPO_METH_FMRI, ins));
	}
	if (topo_method_invoke(rnode,
	    TOPO_METH_FMRI, TOPO_METH_FMRI_VERSION, ins, &out, err) != 0) {
		return (set_nverror(thp, *err, err, TOPO_METH_FMRI, ins));
	}
	nvlist_free(ins);
	return (out);
}
Example #10
0
/*
 * topo_prop_setprop() is a private project function for fmtopo
 */
int
topo_prop_setprop(tnode_t *node, const char *pgname, nvlist_t *prop,
    int flag, nvlist_t *pargs, int *err)
{
	int ret;
	topo_hdl_t *thp = node->tn_hdl;
	topo_propval_t *pv;
	nvlist_t *nvl, *args;
	char *name;
	topo_type_t type;

	if (nvlist_lookup_string(prop, TOPO_PROP_VAL_NAME, &name) != 0) {
		*err = ETOPO_PROP_NAME;
		return (-1);
	}
	if (nvlist_lookup_uint32(prop, TOPO_PROP_VAL_TYPE, (uint32_t *)&type)
	    != 0) {
		*err = ETOPO_PROP_TYPE;
		return (-1);
	}

	topo_node_lock(node);
	if ((pv = prop_create(node, pgname, name, type, flag, err)) == NULL)
		return (-1); /* unlocked and err set */

	/*
	 * Set by method or set to new prop value.  If we fail, leave
	 * property in list with old value.
	 */
	if (pv->tp_method != NULL) {
		topo_propmethod_t *pm = pv->tp_method;

		if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0) {
			topo_node_unlock(node);
			*err = ETOPO_PROP_NOMEM;
			return (-1);
		}
		ret = nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args);
		if (pargs != NULL)
			ret |= nvlist_add_nvlist(args, TOPO_PROP_PARGS, pargs);

		if (ret != 0) {
			topo_node_unlock(node);
			nvlist_free(args);
			*err = ETOPO_PROP_NVL;
			return (-1);
		}

		/*
		 *
		 * Grab a reference to the property and then unlock the node.
		 * This will allow property methods to safely re-enter the
		 * prop_get codepath, making it possible for property methods
		 * to access other property values on the same node w\o causing
		 * a deadlock.
		 *
		 * We don't technically need this now, since this interface is
		 * currently only used by fmtopo (which is single-threaded), but
		 * we may make this interface available to other parts of
		 * libtopo in the future, so best to make it MT-safe now.
		 */
		topo_prop_hold(pv);
		topo_node_unlock(node);
		ret = topo_method_call(node, pm->tpm_name, pm->tpm_version,
		    args, &nvl, err);
		topo_node_lock(node);
		topo_prop_rele(pv);

		nvlist_free(args);
	} else {
		if ((ret = topo_hdl_nvdup(thp, prop, &nvl)) != 0)
			*err = ETOPO_PROP_NOMEM;
	}

	if (ret != 0) {
		topo_node_unlock(node);
		return (-1);
	}

	pv->tp_val = nvl;
	topo_node_unlock(node);
	return (0);
}
Example #11
0
static int
topo_prop_set(tnode_t *node, const char *pgname, const char *pname,
    topo_type_t type, int flag, void *val, int nelems, int *err)
{
	int ret;
	topo_hdl_t *thp = node->tn_hdl;
	nvlist_t *nvl;

	if (topo_hdl_nvalloc(thp, &nvl, NV_UNIQUE_NAME) < 0) {
		*err = ETOPO_PROP_NVL;
		return (-1);
	}

	ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pname);
	ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type);
	switch (type) {
		case TOPO_TYPE_INT32:
			ret |= nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL,
			    *(int32_t *)val);
			break;
		case TOPO_TYPE_UINT32:
			ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL,
			    *(uint32_t *)val);
			break;
		case TOPO_TYPE_INT64:
			ret |= nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL,
			    *(int64_t *)val);
			break;
		case TOPO_TYPE_UINT64:
			ret |= nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL,
			    *(uint64_t *)val);
			break;
		case TOPO_TYPE_DOUBLE:
			ret |= nvlist_add_double(nvl, TOPO_PROP_VAL_VAL,
			    *(double *)val);
			break;
		case TOPO_TYPE_STRING:
			ret |= nvlist_add_string(nvl, TOPO_PROP_VAL_VAL,
			    (char *)val);
			break;
		case TOPO_TYPE_FMRI:
			ret |= nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL,
			    (nvlist_t *)val);
			break;
		case TOPO_TYPE_INT32_ARRAY:
			ret |= nvlist_add_int32_array(nvl,
			    TOPO_PROP_VAL_VAL, (int32_t *)val, nelems);
			break;
		case TOPO_TYPE_UINT32_ARRAY:
			ret |= nvlist_add_uint32_array(nvl,
			    TOPO_PROP_VAL_VAL, (uint32_t *)val, nelems);
			break;
		case TOPO_TYPE_INT64_ARRAY:
			ret |= nvlist_add_int64_array(nvl,
			    TOPO_PROP_VAL_VAL, (int64_t *)val, nelems);
			break;
		case TOPO_TYPE_UINT64_ARRAY:
			ret |= nvlist_add_uint64_array(nvl,
			    TOPO_PROP_VAL_VAL, (uint64_t *)val, nelems);
			break;
		case TOPO_TYPE_STRING_ARRAY:
			ret |= nvlist_add_string_array(nvl,
			    TOPO_PROP_VAL_VAL, (char **)val, nelems);
			break;
		case TOPO_TYPE_FMRI_ARRAY:
			ret |= nvlist_add_nvlist_array(nvl,
			    TOPO_PROP_VAL_VAL, (nvlist_t **)val, nelems);
			break;
		default:
			*err = ETOPO_PROP_TYPE;
			return (-1);
	}

	if (ret != 0) {
		nvlist_free(nvl);
		if (ret == ENOMEM) {
			*err = ETOPO_PROP_NOMEM;
			return (-1);
		} else {
			*err = ETOPO_PROP_NVL;
			return (-1);
		}
	}

	if (topo_prop_setprop(node, pgname, nvl, flag, nvl, err) != 0) {
		nvlist_free(nvl);
		return (-1); /* err set */
	}
	nvlist_free(nvl);
	return (ret);
}