示例#1
0
static int
ippctl_attach_modname_array(
	nvlist_t	*nvlp,
	char		**modname_array,
	int		nelt)
{
	/*
	 * Add a module name array to an nvlist for passing back to user
	 * space.
	 */

	return (nvlist_add_string_array(nvlp, IPPCTL_MODNAME_ARRAY,
	    modname_array, nelt));
}
示例#2
0
static int
ippctl_attach_aname_array(
	nvlist_t	*nvlp,
	char		**aname_array,
	int		nelt)
{
	/*
	 * Add an action name array to an nvlist for passing back to user
	 * space.
	 */

	return (nvlist_add_string_array(nvlp, IPPCTL_ANAME_ARRAY,
	    aname_array, nelt));
}
示例#3
0
/*
 * Set the named string array from the given nvlist_t.
 *
 * @param       attrs
 *              the nvlist_t to search
 *
 * @param       which
 *              the string key for this element in the list
 *
 * @param       val
 *              the value of the requested string array
 *
 * @param       nelem
 *              the number of elements in the array
 *
 * @return      0
 *              if successful
 *
 * @return      EINVAL
 *              if there is an invalid argument
 *
 * @return      ENOMEM
 *              if there is insufficient memory
 */
int
set_string_array(
    nvlist_t *attrs,
    char *which,
    char **val,
    uint_t nelem)
{
    int error = 0;

    if ((error = nvlist_add_string_array(
                     attrs, which, val, nelem)) != 0) {
        volume_set_error(
            gettext("nvlist_add_string_array(%s) failed: %d.\n"),
            which, error);
    }

    return (error);
}
示例#4
0
static int
ch_add_string(list_wrap_t **lw, boolean_t array, int argc, char **argv)
{
	nvlist_t *nvl = (*lw)->lw_nvl[(*lw)->lw_pos];

	if (array) {
		if (nvlist_add_string_array(nvl, argv[0], &argv[1],
		    argc - 1) != 0) {
			(void) fprintf(stderr, "fail at "
			    "nvlist_add_string_array\n");
			return (-1);
		}
	} else {
		if (nvlist_add_string(nvl, argv[0], argv[1]) != 0) {
			(void) fprintf(stderr, "fail at nvlist_add_string\n");
			return (-1);
		}
	}

	return (0);
}
示例#5
0
文件: devctl.c 项目: andreiw/polaris
/*
 * define a string array property
 */
int
devctl_ddef_string_array(devctl_ddef_t ddef_hdl, char *name, int nelements,
    char **value)
{
	int rv, i;

	if (ddef_hdl == NULL || name == NULL || *name == '\0') {
		errno = EINVAL;
		return (-1);
	}

	rv = nvlist_add_string_array((nvlist_t *)ddef_hdl, name,
	    value, nelements);

	if (_libdevice_debug) {
		(void) printf("devctl_ddef_string_array: rv %d nvp %p "
		    "name %s:\n", rv, (void *)ddef_hdl, name);
		for (i = 0; i < nelements; i++)
			(void) printf("\t%d: \"%s\"\n", i, value[i]);
	}
	return (rv);
}
示例#6
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);
}
示例#7
0
文件: fnvpair.c 项目: 2asoft/freebsd
void
fnvlist_add_string_array(nvlist_t *nvl, const char *name,
    char * const *val, uint_t n)
{
	VERIFY0(nvlist_add_string_array(nvl, name, val, n));
}
示例#8
0
/*
 * Pack internal format cache data to a single nvlist.
 * Used when writing the nvlist file.
 * Note this is called indirectly by the nvpflush daemon.
 */
static int
sdev_ncache_pack_list(nvf_handle_t fd, nvlist_t **ret_nvl)
{
	nvlist_t	*nvl, *sub_nvl;
	nvp_devname_t	*np;
	int		rval;
	list_t		*listp;

	ASSERT(fd == sdevfd_handle);
	ASSERT(RW_WRITE_HELD(nvf_lock(fd)));

	rval = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
	if (rval != 0) {
		nvf_error("%s: nvlist alloc error %d\n",
		    nvf_cache_name(fd), rval);
		return (DDI_FAILURE);
	}

	listp = nvf_list(sdevfd_handle);
	if ((np = list_head(listp)) != NULL) {
		ASSERT(list_next(listp, np) == NULL);

		rval = nvlist_alloc(&sub_nvl, NV_UNIQUE_NAME, KM_SLEEP);
		if (rval != 0) {
			nvf_error("%s: nvlist alloc error %d\n",
			    nvf_cache_name(fd), rval);
			sub_nvl = NULL;
			goto err;
		}

		rval = nvlist_add_string_array(sub_nvl,
		    DP_DEVNAME_NCACHE_ID, np->nvp_paths, np->nvp_npaths);
		if (rval != 0) {
			nvf_error("%s: nvlist add error %d (sdev)\n",
			    nvf_cache_name(fd), rval);
			goto err;
		}

		rval = nvlist_add_int32_array(sub_nvl,
		    DP_DEVNAME_NC_EXPIRECNT_ID,
		    np->nvp_expirecnts, np->nvp_npaths);
		if (rval != 0) {
			nvf_error("%s: nvlist add error %d (sdev)\n",
			    nvf_cache_name(fd), rval);
			goto err;
		}

		rval = nvlist_add_nvlist(nvl, DP_DEVNAME_ID, sub_nvl);
		if (rval != 0) {
			nvf_error("%s: nvlist add error %d (sublist)\n",
			    nvf_cache_name(fd), rval);
			goto err;
		}
		nvlist_free(sub_nvl);
	}

	*ret_nvl = nvl;
	return (DDI_SUCCESS);

err:
	nvlist_free(sub_nvl);
	nvlist_free(nvl);
	*ret_nvl = NULL;
	return (DDI_FAILURE);
}
示例#9
0
/*
 * Create the storage dirs, and pass the path list to the kernel.
 * This requires the nfssrv module to be loaded; the _nfssys() syscall
 * will fail ENOTSUP if it is not.
 * Use libnvpair(3LIB) to pass the data to the kernel.
 */
static int
dss_init(uint_t npaths, char **pathnames)
{
	int i, j, nskipped, error;
	char *bufp;
	uint32_t bufsize;
	size_t buflen;
	nvlist_t *nvl;

	if (npaths > 1) {
		/*
		 * We need to remove duplicate paths; this might be user error
		 * in the general case, but HA-NFSv4 can also cause this.
		 * Sort the pathnames array, and NULL out duplicates,
		 * then write the non-NULL entries to a new array.
		 * Sorting will also allow the kernel to optimise its searches.
		 */

		qsort(pathnames, npaths, sizeof (char *), qstrcmp);

		/* now NULL out any duplicates */
		i = 0; j = 1; nskipped = 0;
		while (j < npaths) {
			if (strcmp(pathnames[i], pathnames[j]) == NULL) {
				pathnames[j] = NULL;
				j++;
				nskipped++;
				continue;
			}

			/* skip i over any of its NULLed duplicates */
			i = j++;
		}

		/* finally, write the non-NULL entries to a new array */
		if (nskipped > 0) {
			int nreal;
			size_t sz;
			char **tmp_pathnames;

			nreal = npaths - nskipped;

			sz = nreal * sizeof (char *);
			tmp_pathnames = (char **)malloc(sz);
			if (tmp_pathnames == NULL) {
				fprintf(stderr, "tmp_pathnames malloc "
				    "failed\n");
				exit(1);
			}

			for (i = 0, j = 0; i < npaths; i++)
				if (pathnames[i] != NULL)
					tmp_pathnames[j++] = pathnames[i];
			free(pathnames);
			pathnames = tmp_pathnames;
			npaths = nreal;
		}

	}

	/* Create directories to store the distributed state files */
	dss_mkleafdirs(npaths, pathnames);

	/* Create the name-value pair list */
	error = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
	if (error) {
		fprintf(stderr, "nvlist_alloc failed: %s\n", strerror(errno));
		return (1);
	}

	/* Add the pathnames array as a single name-value pair */
	error = nvlist_add_string_array(nvl, NFS4_DSS_NVPAIR_NAME,
	    pathnames, npaths);
	if (error) {
		fprintf(stderr, "nvlist_add_string_array failed: %s\n",
		    strerror(errno));
		nvlist_free(nvl);
		return (1);
	}

	/*
	 * Pack list into contiguous memory, for passing to kernel.
	 * nvlist_pack() will allocate the memory for the buffer,
	 * which we should free() when no longer needed.
	 * NV_ENCODE_XDR for safety across ILP32/LP64 kernel boundary.
	 */
	bufp = NULL;
	error = nvlist_pack(nvl, &bufp, &buflen, NV_ENCODE_XDR, 0);
	if (error) {
		fprintf(stderr, "nvlist_pack failed: %s\n", strerror(errno));
		nvlist_free(nvl);
		return (1);
	}

	/* Now we have the packed buffer, we no longer need the list */
	nvlist_free(nvl);

	/*
	 * Let the kernel know in advance how big the buffer is.
	 * NOTE: we cannot just pass buflen, since size_t is a long, and
	 * thus a different size between ILP32 userland and LP64 kernel.
	 * Use an int for the transfer, since that should be big enough;
	 * this is a no-op at the moment, here, since nfsd is 32-bit, but
	 * that could change.
	 */
	bufsize = (uint32_t)buflen;
	error = _nfssys(NFS4_DSS_SETPATHS_SIZE, &bufsize);
	if (error) {
		fprintf(stderr,
		    "_nfssys(NFS4_DSS_SETPATHS_SIZE) failed: %s\n",
		    strerror(errno));
		free(bufp);
		return (1);
	}

	/* Pass the packed buffer to the kernel */
	error = _nfssys(NFS4_DSS_SETPATHS, bufp);
	if (error) {
		fprintf(stderr,
		    "_nfssys(NFS4_DSS_SETPATHS) failed: %s\n", strerror(errno));
		free(bufp);
		return (1);
	}

	/*
	 * The kernel has now unpacked the buffer and extracted the
	 * pathnames array, we no longer need the buffer.
	 */
	free(bufp);

	return (0);
}
示例#10
0
文件: devctl.c 项目: andreiw/polaris
/*
 * Convert a list of nvp_list_t's to a single nvlist
 * Used when writing the nvlist file.
 */
static int
sdev_nvp2nvl(nvfd_t *nvfd, nvlist_t **ret_nvl)
{
	nvlist_t	*nvl, *sub_nvl;
	nvp_devname_t	*np;
	int		rval;

	ASSERT(modrootloaded);

	rval = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
	if (rval != 0) {
		KFIOERR((CE_CONT, "%s: nvlist alloc error %d\n",
			nvfd->nvf_name, rval));
		return (DDI_FAILURE);
	}

	if ((np = NVF_DEVNAME_LIST(nvfd)) != NULL) {
		ASSERT(NVP_DEVNAME_NEXT(np) == NULL);

		rval = nvlist_alloc(&sub_nvl, NV_UNIQUE_NAME, KM_SLEEP);
		if (rval != 0) {
			KFIOERR((CE_CONT, "%s: nvlist alloc error %d\n",
				nvfd->nvf_name, rval));
			sub_nvl = NULL;
			goto err;
		}

		rval = nvlist_add_string_array(sub_nvl,
		    DP_DEVNAME_NCACHE_ID, np->nvp_paths, np->nvp_npaths);
		if (rval != 0) {
			KFIOERR((CE_CONT,
			    "%s: nvlist add error %d (sdev)\n",
			    nvfd->nvf_name, rval));
			goto err;
		}

		rval = nvlist_add_int32_array(sub_nvl,
		    DP_DEVNAME_NC_EXPIRECNT_ID,
		    np->nvp_expirecnts, np->nvp_npaths);
		if (rval != 0) {
			KFIOERR((CE_CONT,
			    "%s: nvlist add error %d (sdev)\n",
			    nvfd->nvf_name, rval));
			goto err;
		}

		rval = nvlist_add_nvlist(nvl, DP_DEVNAME_ID, sub_nvl);
		if (rval != 0) {
			KFIOERR((CE_CONT, "%s: nvlist add error %d (sublist)\n",
			    nvfd->nvf_name, rval));
			goto err;
		}
		nvlist_free(sub_nvl);
	}

	*ret_nvl = nvl;
	return (DDI_SUCCESS);

err:
	if (sub_nvl)
		nvlist_free(sub_nvl);
	nvlist_free(nvl);
	*ret_nvl = NULL;
	return (DDI_FAILURE);
}
示例#11
0
/*ARGSUSED*/
static int
net_getinfo(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flag,
    char **info, char **errstr, nvlist_t *proplist, rcm_info_t **depend_info)
{
	int		len;
	dladm_status_t	status;
	char		link[MAXLINKNAMELEN];
	char		errmsg[DLADM_STRSIZE];
	char		*exported;
	const char	*info_fmt;
	net_cache_t	*node;

	assert(hd != NULL);
	assert(rsrc != NULL);
	assert(id == (id_t)0);
	assert(info != NULL);
	assert(depend_info != NULL);

	rcm_log_message(RCM_TRACE1, _("NET: getinfo(%s)\n"), rsrc);

	info_fmt = _("Network interface %s");

	(void) mutex_lock(&cache_lock);
	node = cache_lookup(rsrc);
	if (!node) {
		rcm_log_message(RCM_WARNING,
		    _("NET: unrecognized resource %s\n"), rsrc);
		(void) mutex_unlock(&cache_lock);
		errno = ENOENT;
		return (RCM_FAILURE);
	}

	len = strlen(info_fmt) + MAXLINKNAMELEN + 1;
	if ((status = dladm_datalink_id2info(dld_handle, node->linkid, NULL,
	    NULL, NULL, link, sizeof (link))) != DLADM_STATUS_OK) {
		rcm_log_message(RCM_ERROR,
		    _("NET: usage(%s) get link name failure(%s)\n"),
		    node->resource, dladm_status2str(status, errmsg));
		(void) mutex_unlock(&cache_lock);
		return (RCM_FAILURE);
	} else if ((*info = (char *)malloc(len)) == NULL) {
		rcm_log_message(RCM_ERROR, _("NET: malloc failure"));
		(void) mutex_unlock(&cache_lock);
		return (RCM_FAILURE);
	}

	/* Fill in the string */
	(void) snprintf(*info, len, info_fmt, link);

	len = strlen("SUNW_datalink/") + LINKID_STR_WIDTH + 1;
	exported = malloc(len);
	if (!exported) {
		rcm_log_message(RCM_ERROR, _("NET: allocation failure"));
		free(*info);
		(void) mutex_unlock(&cache_lock);
		return (RCM_FAILURE);
	}
	(void) snprintf(exported, len, "SUNW_datalink/%u", node->linkid);
	(void) mutex_unlock(&cache_lock);

	/* Get dependent info if requested */
	if ((flag & RCM_INCLUDE_DEPENDENT) || (flag & RCM_INCLUDE_SUBTREE)) {
		(void) rcm_get_info(hd, exported, flag, depend_info);
	}

	(void) nvlist_add_string(proplist, RCM_CLIENT_NAME, "SunOS");
	(void) nvlist_add_string_array(proplist, RCM_CLIENT_EXPORTS,
	    &exported, 1);

	free(exported);
	return (RCM_SUCCESS);
}
示例#12
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);
}
示例#13
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));
}
示例#14
0
/*
 * Function:  it_config_setprop()
 *
 * Validate the provided property list and set the global properties
 * for iSCSI Target.  If errlist is not NULL, returns detailed
 * errors for each property that failed.  The format for errorlist
 * is key = property, value = error string.
 *
 * Parameters:
 *
 *    cfg		The current iSCSI configuration obtained from
 *			it_config_load()
 *    proplist		nvlist_t containing properties for this target.
 *    errlist		(optional)  nvlist_t of errors encountered when
 *                      validating the properties.
 *
 * Return Values:
 *    0			Success
 *    EINVAL		Invalid property
 *
 */
int
it_config_setprop(it_config_t *cfg, nvlist_t *proplist, nvlist_t **errlist)
{
	int		ret;
	nvlist_t	*errs = NULL;
	it_portal_t	*isns = NULL;
	it_portal_t	*pnext = NULL;
	it_portal_t	*newisnslist = NULL;
	char		**arr;
	uint32_t	count;
	uint32_t	newcount;
	nvlist_t	*cprops = NULL;
	char		*val = NULL;

	if (!cfg || !proplist) {
		return (EINVAL);
	}

	if (errlist) {
		(void) nvlist_alloc(&errs, 0, 0);
		*errlist = errs;
	}

	/*
	 * copy the existing properties, merge, then validate
	 * the merged properties before committing them.
	 */
	if (cfg->config_global_properties) {
		ret = nvlist_dup(cfg->config_global_properties, &cprops, 0);
	} else {
		ret = nvlist_alloc(&cprops, NV_UNIQUE_NAME, 0);
	}

	if (ret != 0) {
		return (ret);
	}

	ret = nvlist_merge(cprops, proplist, 0);
	if (ret != 0) {
		nvlist_free(cprops);
		return (ret);
	}

	/*
	 * base64 encode the radius secret, if it's changed.
	 */
	val = NULL;
	(void) nvlist_lookup_string(proplist, PROP_RADIUS_SECRET, &val);
	if (val) {
		char		bsecret[MAX_BASE64_LEN];

		ret = it_val_pass(PROP_RADIUS_SECRET, val, errs);

		if (ret == 0) {
			(void) memset(bsecret, 0, MAX_BASE64_LEN);

			ret = iscsi_binary_to_base64_str((uint8_t *)val,
			    strlen(val), bsecret, MAX_BASE64_LEN);

			if (ret == 0) {
				/* replace the value in the nvlist */
				ret = nvlist_add_string(cprops,
				    PROP_RADIUS_SECRET, bsecret);
			}
		}
	}

	if (ret != 0) {
		nvlist_free(cprops);
		return (ret);
	}

	/* see if we need to remove the radius server setting */
	val = NULL;
	(void) nvlist_lookup_string(cprops, PROP_RADIUS_SERVER, &val);
	if (val && (strcasecmp(val, "none") == 0)) {
		(void) nvlist_remove_all(cprops, PROP_RADIUS_SERVER);
	}

	/* and/or remove the alias */
	val = NULL;
	(void) nvlist_lookup_string(cprops, PROP_ALIAS, &val);
	if (val && (strcasecmp(val, "none") == 0)) {
		(void) nvlist_remove_all(cprops, PROP_ALIAS);
	}

	ret = it_validate_configprops(cprops, errs);
	if (ret != 0) {
		if (cprops) {
			nvlist_free(cprops);
		}
		return (ret);
	}

	/*
	 * Update iSNS server list, if exists in provided property list.
	 */
	ret = nvlist_lookup_string_array(proplist, PROP_ISNS_SERVER,
	    &arr, &count);

	if (ret == 0) {
		/* special case:  if "none", remove all defined */
		if (strcasecmp(arr[0], "none") != 0) {
			ret = it_array_to_portallist(arr, count,
			    ISNS_DEFAULT_SERVER_PORT, &newisnslist, &newcount);
		} else {
			newisnslist = NULL;
			newcount = 0;
			(void) nvlist_remove_all(cprops, PROP_ISNS_SERVER);
		}

		if (ret == 0) {
			isns = cfg->config_isns_svr_list;
			while (isns) {
				pnext = isns->portal_next;
				free(isns);
				isns = pnext;
			}

			cfg->config_isns_svr_list = newisnslist;
			cfg->config_isns_svr_count = newcount;

			/*
			 * Replace the array in the nvlist to ensure
			 * duplicates are properly removed & port numbers
			 * are added.
			 */
			if (newcount > 0) {
				int	i = 0;
				char	**newarray;

				newarray = malloc(sizeof (char *) * newcount);
				if (newarray == NULL) {
					ret = ENOMEM;
				} else {
					for (isns = newisnslist; isns != NULL;
					    isns = isns->portal_next) {
						(void) sockaddr_to_str(
						    &(isns->portal_addr),
						    &(newarray[i++]));
					}
					(void) nvlist_add_string_array(cprops,
					    PROP_ISNS_SERVER, newarray,
					    newcount);

					for (i = 0; i < newcount; i++) {
						if (newarray[i]) {
							free(newarray[i]);
						}
					}
					free(newarray);
				}
			}
		}
	} else if (ret == ENOENT) {
		/* not an error */
		ret = 0;
	}

	if (ret == 0) {
		/* replace the global properties list */
		nvlist_free(cfg->config_global_properties);
		cfg->config_global_properties = cprops;
	} else {
		if (cprops) {
			nvlist_free(cprops);
		}
	}

	if (ret == 0)
		free_empty_errlist(errlist);

	return (ret);
}