xref: /titanic_41/usr/src/lib/libpool/common/pool.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
568ae7850Sgarypen  * Common Development and Distribution License (the "License").
668ae7850Sgarypen  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2168ae7850Sgarypen 
227c478bd9Sstevel@tonic-gate /*
23*cb620785Sraf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <assert.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <string.h>
337c478bd9Sstevel@tonic-gate #include <thread.h>
34*cb620785Sraf #include <pthread.h>
357c478bd9Sstevel@tonic-gate #include <synch.h>
367c478bd9Sstevel@tonic-gate #include <unistd.h>
377c478bd9Sstevel@tonic-gate #include <stropts.h>
387c478bd9Sstevel@tonic-gate #include <fcntl.h>
397c478bd9Sstevel@tonic-gate #include <note.h>
407c478bd9Sstevel@tonic-gate #include <errno.h>
417c478bd9Sstevel@tonic-gate #include <ctype.h>
427c478bd9Sstevel@tonic-gate #include <libintl.h>
43c1c0ebd5Ssl108498 #include <libscf.h>
447c478bd9Sstevel@tonic-gate #include <pool.h>
457c478bd9Sstevel@tonic-gate #include <signal.h>
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #include <sys/pool.h>
487c478bd9Sstevel@tonic-gate #include <sys/priocntl.h>
497c478bd9Sstevel@tonic-gate #include <sys/types.h>
507c478bd9Sstevel@tonic-gate #include <sys/stat.h>
517c478bd9Sstevel@tonic-gate #include <sys/wait.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #include "pool_internal.h"
547c478bd9Sstevel@tonic-gate #include "pool_impl.h"
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * libpool Interface Routines
587c478bd9Sstevel@tonic-gate  *
597c478bd9Sstevel@tonic-gate  * pool.c implements (most of) the external interface to libpool
607c478bd9Sstevel@tonic-gate  * users. Some of the interface is implemented in pool_internal.c for
617c478bd9Sstevel@tonic-gate  * reasons of internal code organisation.  The core requirements for
627c478bd9Sstevel@tonic-gate  * pool.c are:
637c478bd9Sstevel@tonic-gate  *
647c478bd9Sstevel@tonic-gate  * Data Abstraction
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  * The abstraction of the actual datastore so that no details of the
677c478bd9Sstevel@tonic-gate  * underlying data representation mechanism are revealed to users of
687c478bd9Sstevel@tonic-gate  * the library. For instance, the fact that we use the kernel or files
697c478bd9Sstevel@tonic-gate  * to store our configurations is completely abstracted via the
707c478bd9Sstevel@tonic-gate  * various libpool APIs.
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  * External Interaction
737c478bd9Sstevel@tonic-gate  *
747c478bd9Sstevel@tonic-gate  * libpool users manipulate configuration components via the API
757c478bd9Sstevel@tonic-gate  * defined in pool.h. Most functions in this file act as interceptors,
767c478bd9Sstevel@tonic-gate  * validating parameters before redirecting the request into a
777c478bd9Sstevel@tonic-gate  * specific datastore implementation for the actual work to be done.
787c478bd9Sstevel@tonic-gate  *
797c478bd9Sstevel@tonic-gate  * These main sets of requirements have driven the design so that it
807c478bd9Sstevel@tonic-gate  * is possible to replace the entire datastore type without having to
817c478bd9Sstevel@tonic-gate  * modify the external (or internal provider) APIs. It is possible to
827c478bd9Sstevel@tonic-gate  * modify the storage technology used by libpool by implementing a new
837c478bd9Sstevel@tonic-gate  * set of datastore provider operations. Simply modify the
847c478bd9Sstevel@tonic-gate  * pool_conf_open() routine to establish a new datastore as the
857c478bd9Sstevel@tonic-gate  * provider for a configuration.
867c478bd9Sstevel@tonic-gate  *
877c478bd9Sstevel@tonic-gate  * The key components in a libpool configuration are :
887c478bd9Sstevel@tonic-gate  * pool_conf_t - This represents a complete configuration instance
897c478bd9Sstevel@tonic-gate  * pool_t - A pool inside a configuration
907c478bd9Sstevel@tonic-gate  * pool_resource_t - A resource inside a configuration
917c478bd9Sstevel@tonic-gate  * pool_component_t - A component of a resource
927c478bd9Sstevel@tonic-gate  *
937c478bd9Sstevel@tonic-gate  */
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate  * Used to control transfer setup.
977c478bd9Sstevel@tonic-gate  */
987c478bd9Sstevel@tonic-gate #define	XFER_FAIL	PO_FAIL
997c478bd9Sstevel@tonic-gate #define	XFER_SUCCESS	PO_SUCCESS
1007c478bd9Sstevel@tonic-gate #define	XFER_CONTINUE	1
1017c478bd9Sstevel@tonic-gate 
10226d8ba22Sgarypen #define	SMF_SVC_INSTANCE	"svc:/system/pools:default"
1037c478bd9Sstevel@tonic-gate #define	E_ERROR		1		/* Exit status for error */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate #ifndef	TEXT_DOMAIN
1067c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"
1077c478bd9Sstevel@tonic-gate #endif	/* TEXT_DOMAIN */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate const char pool_info_location[] =  "/dev/pool";
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate /*
1127c478bd9Sstevel@tonic-gate  * Static data
1137c478bd9Sstevel@tonic-gate  */
1147c478bd9Sstevel@tonic-gate static const char static_location[] = "/etc/pooladm.conf";
1157c478bd9Sstevel@tonic-gate static const char dynamic_location[] =  "/dev/poolctl";
116*cb620785Sraf static thread_key_t	errkey = THR_ONCE_KEY;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate  * libpool error code
1207c478bd9Sstevel@tonic-gate  */
1217c478bd9Sstevel@tonic-gate static int pool_errval = POE_OK;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * libpool version
1257c478bd9Sstevel@tonic-gate  */
1267c478bd9Sstevel@tonic-gate static uint_t pool_workver = POOL_VER_CURRENT;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static const char *data_type_tags[] = {
1297c478bd9Sstevel@tonic-gate 	"uint",
1307c478bd9Sstevel@tonic-gate 	"int",
1317c478bd9Sstevel@tonic-gate 	"float",
1327c478bd9Sstevel@tonic-gate 	"boolean",
1337c478bd9Sstevel@tonic-gate 	"string"
1347c478bd9Sstevel@tonic-gate };
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate  * static functions
1387c478bd9Sstevel@tonic-gate  */
1397c478bd9Sstevel@tonic-gate static int pool_elem_remove(pool_elem_t *);
1407c478bd9Sstevel@tonic-gate static int is_valid_prop_name(const char *);
1417c478bd9Sstevel@tonic-gate static int prop_buf_build_cb(pool_conf_t *, pool_elem_t *, const char *,
1427c478bd9Sstevel@tonic-gate     pool_value_t *, void *);
1437c478bd9Sstevel@tonic-gate static char *pool_base_info(const pool_elem_t *, char_buf_t *, int);
1447c478bd9Sstevel@tonic-gate static int choose_components(pool_resource_t *, pool_resource_t *, uint64_t);
1457c478bd9Sstevel@tonic-gate static int pool_conf_check(const pool_conf_t *);
1467c478bd9Sstevel@tonic-gate static void free_value_list(int, pool_value_t **);
1477c478bd9Sstevel@tonic-gate static int setup_transfer(pool_conf_t *, pool_resource_t *, pool_resource_t *,
1487c478bd9Sstevel@tonic-gate     uint64_t, uint64_t *, uint64_t *);
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate  * Return the "static" location string for libpool.
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate const char *
pool_static_location(void)1547c478bd9Sstevel@tonic-gate pool_static_location(void)
1557c478bd9Sstevel@tonic-gate {
1567c478bd9Sstevel@tonic-gate 	return (static_location);
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate  * Return the "dynamic" location string for libpool.
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate const char *
pool_dynamic_location(void)1637c478bd9Sstevel@tonic-gate pool_dynamic_location(void)
1647c478bd9Sstevel@tonic-gate {
1657c478bd9Sstevel@tonic-gate 	return (dynamic_location);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate  * Return the status for a configuration. If the configuration has
1707c478bd9Sstevel@tonic-gate  * been successfully opened, then the status will be POF_VALID or
1717c478bd9Sstevel@tonic-gate  * POF_DESTROY.  If the configuration failed to open properly or has
1727c478bd9Sstevel@tonic-gate  * been closed or removed, then the status will be POF_INVALID.
1737c478bd9Sstevel@tonic-gate  */
1747c478bd9Sstevel@tonic-gate pool_conf_state_t
pool_conf_status(const pool_conf_t * conf)1757c478bd9Sstevel@tonic-gate pool_conf_status(const pool_conf_t *conf)
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate 	return (conf->pc_state);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  * Bind idtype id to the pool name.
1827c478bd9Sstevel@tonic-gate  */
1837c478bd9Sstevel@tonic-gate int
pool_set_binding(const char * pool_name,idtype_t idtype,id_t id)1847c478bd9Sstevel@tonic-gate pool_set_binding(const char *pool_name, idtype_t idtype, id_t id)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 	pool_conf_t *conf;
1877c478bd9Sstevel@tonic-gate 	int result;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	if ((conf = pool_conf_alloc()) == NULL)
1907c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) < 0) {
1937c478bd9Sstevel@tonic-gate 		pool_conf_free(conf);
1947c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
1957c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
1967c478bd9Sstevel@tonic-gate 	}
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	result = conf->pc_prov->pc_set_binding(conf, pool_name, idtype, id);
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	(void) pool_conf_close(conf);
2017c478bd9Sstevel@tonic-gate 	pool_conf_free(conf);
2027c478bd9Sstevel@tonic-gate 	return (result);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate /*
2067c478bd9Sstevel@tonic-gate  * pool_get_resource_binding() returns the binding for a pid to the supplied
2077c478bd9Sstevel@tonic-gate  * type of resource. If a binding cannot be determined, NULL is returned.
2087c478bd9Sstevel@tonic-gate  */
2097c478bd9Sstevel@tonic-gate char *
pool_get_resource_binding(const char * sz_type,pid_t pid)2107c478bd9Sstevel@tonic-gate pool_get_resource_binding(const char *sz_type, pid_t pid)
2117c478bd9Sstevel@tonic-gate {
2127c478bd9Sstevel@tonic-gate 	pool_conf_t *conf;
2137c478bd9Sstevel@tonic-gate 	char *result;
2147c478bd9Sstevel@tonic-gate 	pool_resource_elem_class_t type;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	if ((type = pool_resource_elem_class_from_string(sz_type)) ==
2177c478bd9Sstevel@tonic-gate 	    PREC_INVALID) {
2187c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
2197c478bd9Sstevel@tonic-gate 		return (NULL);
2207c478bd9Sstevel@tonic-gate 	}
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	if ((conf = pool_conf_alloc()) == NULL)
2237c478bd9Sstevel@tonic-gate 		return (NULL);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
2267c478bd9Sstevel@tonic-gate 	    != PO_SUCCESS) {
2277c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
2287c478bd9Sstevel@tonic-gate 		pool_conf_free(conf);
2297c478bd9Sstevel@tonic-gate 		return (NULL);
2307c478bd9Sstevel@tonic-gate 	}
2317c478bd9Sstevel@tonic-gate 	result = conf->pc_prov->pc_get_resource_binding(conf, type, pid);
2327c478bd9Sstevel@tonic-gate 	(void) pool_conf_close(conf);
2337c478bd9Sstevel@tonic-gate 	pool_conf_free(conf);
2347c478bd9Sstevel@tonic-gate 	return (result);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate /*
2387c478bd9Sstevel@tonic-gate  * pool_get_binding() returns the binding for a pid to a pool. If a
2397c478bd9Sstevel@tonic-gate  * binding cannot be determined, NULL is returned.
2407c478bd9Sstevel@tonic-gate  */
2417c478bd9Sstevel@tonic-gate char *
pool_get_binding(pid_t pid)2427c478bd9Sstevel@tonic-gate pool_get_binding(pid_t pid)
2437c478bd9Sstevel@tonic-gate {
2447c478bd9Sstevel@tonic-gate 	pool_conf_t *conf;
2457c478bd9Sstevel@tonic-gate 	char *result;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	if ((conf = pool_conf_alloc()) == NULL)
2487c478bd9Sstevel@tonic-gate 		return (NULL);
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
2517c478bd9Sstevel@tonic-gate 	    != PO_SUCCESS) {
2527c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
2537c478bd9Sstevel@tonic-gate 		pool_conf_free(conf);
2547c478bd9Sstevel@tonic-gate 		return (NULL);
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 	result = conf->pc_prov->pc_get_binding(conf, pid);
2577c478bd9Sstevel@tonic-gate 	(void) pool_conf_close(conf);
2587c478bd9Sstevel@tonic-gate 	pool_conf_free(conf);
2597c478bd9Sstevel@tonic-gate 	return (result);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2637c478bd9Sstevel@tonic-gate int
prop_buf_build_cb(pool_conf_t * UNUSED,pool_elem_t * pe,const char * name,pool_value_t * pval,void * user)2647c478bd9Sstevel@tonic-gate prop_buf_build_cb(pool_conf_t *UNUSED, pool_elem_t *pe, const char *name,
2657c478bd9Sstevel@tonic-gate     pool_value_t *pval, void *user)
2667c478bd9Sstevel@tonic-gate {
2677c478bd9Sstevel@tonic-gate 	uint64_t u;
2687c478bd9Sstevel@tonic-gate 	int64_t i;
2697c478bd9Sstevel@tonic-gate 	uchar_t bool;
2707c478bd9Sstevel@tonic-gate 	const char *str;
2717c478bd9Sstevel@tonic-gate 	double d;
2727c478bd9Sstevel@tonic-gate 	char_buf_t *cb = (char_buf_t *)user;
2737c478bd9Sstevel@tonic-gate 	int type = pool_value_get_type(pval);
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	/*
2767c478bd9Sstevel@tonic-gate 	 * Ignore "type" and "<type>.name" properties as these are not
2777c478bd9Sstevel@tonic-gate 	 * to be displayed by this function
2787c478bd9Sstevel@tonic-gate 	 */
2797c478bd9Sstevel@tonic-gate 	if (strcmp(name, c_type) == 0 ||
2807c478bd9Sstevel@tonic-gate 	    strcmp(property_name_minus_ns(pe, name), c_name) == 0)
2817c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS);
2827c478bd9Sstevel@tonic-gate 	if (append_char_buf(cb, "\n%s\t%s\t%s ", cb->cb_tab_buf,
2837c478bd9Sstevel@tonic-gate 	    data_type_tags[type], name) == PO_FAIL)
2847c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
2857c478bd9Sstevel@tonic-gate 	switch (type) {
2867c478bd9Sstevel@tonic-gate 	case POC_UINT:
2877c478bd9Sstevel@tonic-gate 		(void) pool_value_get_uint64(pval, &u);
2887c478bd9Sstevel@tonic-gate 		if (append_char_buf(cb, "%llu", (u_longlong_t)u) == PO_FAIL)
2897c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
2907c478bd9Sstevel@tonic-gate 		break;
2917c478bd9Sstevel@tonic-gate 	case POC_INT:
2927c478bd9Sstevel@tonic-gate 		(void) pool_value_get_int64(pval, &i);
2937c478bd9Sstevel@tonic-gate 		if (append_char_buf(cb, "%lld", (longlong_t)i) == PO_FAIL)
2947c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
2957c478bd9Sstevel@tonic-gate 		break;
2967c478bd9Sstevel@tonic-gate 	case POC_STRING:
2977c478bd9Sstevel@tonic-gate 		(void) pool_value_get_string(pval, &str);
2987c478bd9Sstevel@tonic-gate 		if (append_char_buf(cb, "%s", str) == PO_FAIL)
2997c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
3007c478bd9Sstevel@tonic-gate 		break;
3017c478bd9Sstevel@tonic-gate 	case POC_BOOL:
3027c478bd9Sstevel@tonic-gate 		(void) pool_value_get_bool(pval, &bool);
3037c478bd9Sstevel@tonic-gate 		if (bool == 0) {
3047c478bd9Sstevel@tonic-gate 			if (append_char_buf(cb, "%s", "false") == PO_FAIL)
3057c478bd9Sstevel@tonic-gate 				return (PO_FAIL);
3067c478bd9Sstevel@tonic-gate 		} else {
3077c478bd9Sstevel@tonic-gate 			if (append_char_buf(cb, "%s", "true") == PO_FAIL)
3087c478bd9Sstevel@tonic-gate 				return (PO_FAIL);
3097c478bd9Sstevel@tonic-gate 		}
3107c478bd9Sstevel@tonic-gate 		break;
3117c478bd9Sstevel@tonic-gate 	case POC_DOUBLE:
3127c478bd9Sstevel@tonic-gate 		(void) pool_value_get_double(pval, &d);
3137c478bd9Sstevel@tonic-gate 		if (append_char_buf(cb, "%g", d) == PO_FAIL)
3147c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
3157c478bd9Sstevel@tonic-gate 		break;
3167c478bd9Sstevel@tonic-gate 	case POC_INVAL: /* Do nothing */
3177c478bd9Sstevel@tonic-gate 		break;
3187c478bd9Sstevel@tonic-gate 	default:
3197c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
3207c478bd9Sstevel@tonic-gate 	}
3217c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate /*
3257c478bd9Sstevel@tonic-gate  * Return a buffer which describes the element
3267c478bd9Sstevel@tonic-gate  * pe is a pointer to the element
3277c478bd9Sstevel@tonic-gate  * deep is PO_TRUE/PO_FALSE to indicate whether children should be included
3287c478bd9Sstevel@tonic-gate  */
3297c478bd9Sstevel@tonic-gate char *
pool_base_info(const pool_elem_t * pe,char_buf_t * cb,int deep)3307c478bd9Sstevel@tonic-gate pool_base_info(const pool_elem_t *pe, char_buf_t *cb, int deep)
3317c478bd9Sstevel@tonic-gate {
3327c478bd9Sstevel@tonic-gate 	const char *sres;
3337c478bd9Sstevel@tonic-gate 	uint_t i;
3347c478bd9Sstevel@tonic-gate 	uint_t nelem;
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
3377c478bd9Sstevel@tonic-gate 	pool_resource_t **rs;
3387c478bd9Sstevel@tonic-gate 	pool_elem_t *elem;
3397c478bd9Sstevel@tonic-gate 	pool_conf_t *conf = TO_CONF(pe);
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	if (cb == NULL) {
3427c478bd9Sstevel@tonic-gate 		char *ret = NULL;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 		if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
3457c478bd9Sstevel@tonic-gate 			return (NULL);
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 		/*
3487c478bd9Sstevel@tonic-gate 		 * Populate the buffer with element details
3497c478bd9Sstevel@tonic-gate 		 */
3507c478bd9Sstevel@tonic-gate 		(void) pool_base_info(pe, cb, deep);
3517c478bd9Sstevel@tonic-gate 		if (cb->cb_buf)
3527c478bd9Sstevel@tonic-gate 			ret = strdup(cb->cb_buf);
3537c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
3547c478bd9Sstevel@tonic-gate 		return (ret);
3557c478bd9Sstevel@tonic-gate 	}
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	if (append_char_buf(cb, "\n%s%s", cb->cb_tab_buf,
3587c478bd9Sstevel@tonic-gate 		pool_elem_class_string(pe)) == PO_FAIL) {
3597c478bd9Sstevel@tonic-gate 		return (NULL);
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	if (pool_get_ns_property(pe, c_name, &val) == POC_STRING) {
3637c478bd9Sstevel@tonic-gate 		(void) pool_value_get_string(&val, &sres);
3647c478bd9Sstevel@tonic-gate 		if (append_char_buf(cb, " %s", sres) == PO_FAIL) {
3657c478bd9Sstevel@tonic-gate 			return (NULL);
3667c478bd9Sstevel@tonic-gate 		}
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	/*
3707c478bd9Sstevel@tonic-gate 	 * Add in some details about the element
3717c478bd9Sstevel@tonic-gate 	 */
3727c478bd9Sstevel@tonic-gate 	if (pool_walk_properties(conf, (pool_elem_t *)pe, cb,
3737c478bd9Sstevel@tonic-gate 	    prop_buf_build_cb) == PO_FAIL) {
3747c478bd9Sstevel@tonic-gate 		(void) append_char_buf(cb, "\n%s%s\n", cb->cb_tab_buf,
3757c478bd9Sstevel@tonic-gate 		    "Cannot access the properties of this element.");
3767c478bd9Sstevel@tonic-gate 		return (NULL);
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate 	if (append_char_buf(cb, "%s", "\n") == PO_FAIL)
3797c478bd9Sstevel@tonic-gate 		return (NULL);
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	if (pe->pe_class == PEC_POOL) {
3827c478bd9Sstevel@tonic-gate 		/*
3837c478bd9Sstevel@tonic-gate 		 * A shallow display of a pool only lists the resources by name
3847c478bd9Sstevel@tonic-gate 		 */
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 		if ((rs = pool_query_pool_resources(conf, pool_elem_pool(pe),
3877c478bd9Sstevel@tonic-gate 		    &nelem, NULL)) == NULL) {
3887c478bd9Sstevel@tonic-gate 			return (NULL);
3897c478bd9Sstevel@tonic-gate 		}
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 		for (i = 0; i < nelem; i++) {
3927c478bd9Sstevel@tonic-gate 			const char *str;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 			elem = TO_ELEM(rs[i]);
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 			if (append_char_buf(cb, "\t%s%s", cb->cb_tab_buf,
3977c478bd9Sstevel@tonic-gate 			    pool_elem_class_string(elem)) == PO_FAIL) {
3987c478bd9Sstevel@tonic-gate 				free(rs);
3997c478bd9Sstevel@tonic-gate 				return (NULL);
4007c478bd9Sstevel@tonic-gate 			}
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 			if (pool_get_ns_property(elem, c_name, &val) !=
4037c478bd9Sstevel@tonic-gate 			    POC_STRING) {
4047c478bd9Sstevel@tonic-gate 				free(rs);
4057c478bd9Sstevel@tonic-gate 				pool_seterror(POE_INVALID_CONF);
4067c478bd9Sstevel@tonic-gate 				return (NULL);
4077c478bd9Sstevel@tonic-gate 			}
4087c478bd9Sstevel@tonic-gate 			(void) pool_value_get_string(&val, &str);
4097c478bd9Sstevel@tonic-gate 			if (append_char_buf(cb, "\t%s\n", str) == PO_FAIL) {
4107c478bd9Sstevel@tonic-gate 				free(rs);
4117c478bd9Sstevel@tonic-gate 				return (NULL);
4127c478bd9Sstevel@tonic-gate 			}
4137c478bd9Sstevel@tonic-gate 		}
4147c478bd9Sstevel@tonic-gate 		free(rs);
4157c478bd9Sstevel@tonic-gate 	}
4167c478bd9Sstevel@tonic-gate 	if (deep == PO_TRUE) {
4177c478bd9Sstevel@tonic-gate 		pool_t **ps;
4187c478bd9Sstevel@tonic-gate 		pool_component_t **cs;
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 		if (strlcat(cb->cb_tab_buf, "\t", CB_TAB_BUF_SIZE)
4217c478bd9Sstevel@tonic-gate 		    >= CB_TAB_BUF_SIZE) {
4227c478bd9Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
4237c478bd9Sstevel@tonic-gate 			return (NULL);
4247c478bd9Sstevel@tonic-gate 		}
4257c478bd9Sstevel@tonic-gate 		switch (pe->pe_class) {
4267c478bd9Sstevel@tonic-gate 		case PEC_SYSTEM:
4277c478bd9Sstevel@tonic-gate 			if ((ps = pool_query_pools(conf, &nelem, NULL)) !=
4287c478bd9Sstevel@tonic-gate 			    NULL) { /* process the pools */
4297c478bd9Sstevel@tonic-gate 				for (i = 0; i < nelem; i++) {
4307c478bd9Sstevel@tonic-gate 					elem = TO_ELEM(ps[i]);
4317c478bd9Sstevel@tonic-gate 					if (pool_base_info(elem, cb,
4327c478bd9Sstevel@tonic-gate 					    PO_FALSE) == NULL) {
4337c478bd9Sstevel@tonic-gate 						free(ps);
4347c478bd9Sstevel@tonic-gate 						return (NULL);
4357c478bd9Sstevel@tonic-gate 					}
4367c478bd9Sstevel@tonic-gate 				}
4377c478bd9Sstevel@tonic-gate 				free(ps);
4387c478bd9Sstevel@tonic-gate 			}
4397c478bd9Sstevel@tonic-gate 			if ((rs = pool_query_resources(conf, &nelem, NULL)) !=
4407c478bd9Sstevel@tonic-gate 			    NULL) {
4417c478bd9Sstevel@tonic-gate 				for (i = 0; i < nelem; i++) {
4427c478bd9Sstevel@tonic-gate 					elem = TO_ELEM(rs[i]);
4437c478bd9Sstevel@tonic-gate 					if (pool_base_info(elem, cb,
4447c478bd9Sstevel@tonic-gate 					    PO_TRUE) == NULL) {
4457c478bd9Sstevel@tonic-gate 						free(rs);
4467c478bd9Sstevel@tonic-gate 						return (NULL);
4477c478bd9Sstevel@tonic-gate 					}
4487c478bd9Sstevel@tonic-gate 				}
4497c478bd9Sstevel@tonic-gate 				free(rs);
4507c478bd9Sstevel@tonic-gate 			}
4517c478bd9Sstevel@tonic-gate 			break;
4527c478bd9Sstevel@tonic-gate 		case PEC_POOL:
4537c478bd9Sstevel@tonic-gate 			if ((rs = pool_query_pool_resources(conf,
4547c478bd9Sstevel@tonic-gate 			    pool_elem_pool(pe), &nelem, NULL)) == NULL)
4557c478bd9Sstevel@tonic-gate 				return (NULL);
4567c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++) {
4577c478bd9Sstevel@tonic-gate 				elem = TO_ELEM(rs[i]);
4587c478bd9Sstevel@tonic-gate 				if (pool_base_info(elem, cb, PO_TRUE) == NULL) {
4597c478bd9Sstevel@tonic-gate 					free(rs);
4607c478bd9Sstevel@tonic-gate 					return (NULL);
4617c478bd9Sstevel@tonic-gate 				}
4627c478bd9Sstevel@tonic-gate 			}
4637c478bd9Sstevel@tonic-gate 			free(rs);
4647c478bd9Sstevel@tonic-gate 			break;
4657c478bd9Sstevel@tonic-gate 		case PEC_RES_COMP:
4667c478bd9Sstevel@tonic-gate 			if ((cs = pool_query_resource_components(conf,
4677c478bd9Sstevel@tonic-gate 			    pool_elem_res(pe), &nelem, NULL)) != NULL) {
4687c478bd9Sstevel@tonic-gate 				for (i = 0; i < nelem; i++) {
4697c478bd9Sstevel@tonic-gate 					elem = TO_ELEM(cs[i]);
4707c478bd9Sstevel@tonic-gate 					if (pool_base_info(elem, cb,
4717c478bd9Sstevel@tonic-gate 					    PO_FALSE) == NULL) {
4727c478bd9Sstevel@tonic-gate 						free(cs);
4737c478bd9Sstevel@tonic-gate 						return (NULL);
4747c478bd9Sstevel@tonic-gate 					}
4757c478bd9Sstevel@tonic-gate 				}
4767c478bd9Sstevel@tonic-gate 				free(cs);
4777c478bd9Sstevel@tonic-gate 			}
4787c478bd9Sstevel@tonic-gate 			break;
4797c478bd9Sstevel@tonic-gate 		case PEC_RES_AGG:
4807c478bd9Sstevel@tonic-gate 		case PEC_COMP:
4817c478bd9Sstevel@tonic-gate 			break;
4827c478bd9Sstevel@tonic-gate 		default:
4837c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
4847c478bd9Sstevel@tonic-gate 			break;
4857c478bd9Sstevel@tonic-gate 		}
4867c478bd9Sstevel@tonic-gate 		if (cb->cb_tab_buf[0] != 0)
4877c478bd9Sstevel@tonic-gate 			cb->cb_tab_buf[strlen(cb->cb_tab_buf) - 1] = 0;
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate 	return (cb->cb_buf);
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate  * Returns	The information on the specified pool or NULL.
4947c478bd9Sstevel@tonic-gate  *
4957c478bd9Sstevel@tonic-gate  * Errors	If the status of the conf is INVALID or the supplied
4967c478bd9Sstevel@tonic-gate  *		value of deep is illegal, POE_BADPARAM.
4977c478bd9Sstevel@tonic-gate  *
4987c478bd9Sstevel@tonic-gate  * The caller is responsible for free(3c)ing the string returned.
4997c478bd9Sstevel@tonic-gate  */
5007c478bd9Sstevel@tonic-gate char *
pool_info(const pool_conf_t * conf,const pool_t * pool,int deep)5017c478bd9Sstevel@tonic-gate pool_info(const pool_conf_t *conf, const pool_t *pool, int deep)
5027c478bd9Sstevel@tonic-gate {
5037c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(pool);
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate 	if (TO_CONF(pe) != conf) {
5087c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5097c478bd9Sstevel@tonic-gate 		return (NULL);
5107c478bd9Sstevel@tonic-gate 	}
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5137c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5147c478bd9Sstevel@tonic-gate 		return (NULL);
5157c478bd9Sstevel@tonic-gate 	}
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	return (pool_base_info(pe, NULL, deep));
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate /*
5217c478bd9Sstevel@tonic-gate  * Returns	The information on the specified resource or NULL.
5227c478bd9Sstevel@tonic-gate  *
5237c478bd9Sstevel@tonic-gate  * Errors	If the status of the conf is INVALID or the supplied
5247c478bd9Sstevel@tonic-gate  *		value of deep is illegal, POE_BADPARAM.
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  * The caller is responsible for free(3c)ing the string returned.
5277c478bd9Sstevel@tonic-gate  */
5287c478bd9Sstevel@tonic-gate char *
pool_resource_info(const pool_conf_t * conf,const pool_resource_t * res,int deep)5297c478bd9Sstevel@tonic-gate pool_resource_info(const pool_conf_t *conf, const pool_resource_t *res,
5307c478bd9Sstevel@tonic-gate     int deep)
5317c478bd9Sstevel@tonic-gate {
5327c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(res);
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 	if (TO_CONF(pe) != conf) {
5377c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5387c478bd9Sstevel@tonic-gate 		return (NULL);
5397c478bd9Sstevel@tonic-gate 	}
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5427c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5437c478bd9Sstevel@tonic-gate 		return (NULL);
5447c478bd9Sstevel@tonic-gate 	}
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 	return (pool_base_info(pe, NULL, deep));
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate /*
5507c478bd9Sstevel@tonic-gate  * Returns	The information on the specified component or NULL.
5517c478bd9Sstevel@tonic-gate  *
5527c478bd9Sstevel@tonic-gate  * Errors	If the status of the conf is INVALID or the supplied
5537c478bd9Sstevel@tonic-gate  *		value of deep is illegal, POE_BADPARAM.
5547c478bd9Sstevel@tonic-gate  *
5557c478bd9Sstevel@tonic-gate  * The caller is responsible for free(3c)ing the string returned.
5567c478bd9Sstevel@tonic-gate  */
5577c478bd9Sstevel@tonic-gate char *
pool_component_info(const pool_conf_t * conf,const pool_component_t * comp,int deep)5587c478bd9Sstevel@tonic-gate pool_component_info(const pool_conf_t *conf, const pool_component_t *comp,
5597c478bd9Sstevel@tonic-gate     int deep)
5607c478bd9Sstevel@tonic-gate {
5617c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(comp);
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 	if (TO_CONF(pe) != conf) {
5667c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5677c478bd9Sstevel@tonic-gate 		return (NULL);
5687c478bd9Sstevel@tonic-gate 	}
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5717c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5727c478bd9Sstevel@tonic-gate 		return (NULL);
5737c478bd9Sstevel@tonic-gate 	}
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 	return (pool_base_info(pe, NULL, deep));
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate /*
5797c478bd9Sstevel@tonic-gate  * Returns	The information on the specified conf or NULL.
5807c478bd9Sstevel@tonic-gate  *
5817c478bd9Sstevel@tonic-gate  * Errors	If the status of the conf is INVALID or the supplied
5827c478bd9Sstevel@tonic-gate  *		value of deep is illegal, POE_BADPARAM.
5837c478bd9Sstevel@tonic-gate  *
5847c478bd9Sstevel@tonic-gate  * The caller is responsible for free(3c)ing the string returned.
5857c478bd9Sstevel@tonic-gate  */
5867c478bd9Sstevel@tonic-gate char *
pool_conf_info(const pool_conf_t * conf,int deep)5877c478bd9Sstevel@tonic-gate pool_conf_info(const pool_conf_t *conf, int deep)
5887c478bd9Sstevel@tonic-gate {
5897c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5927c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5937c478bd9Sstevel@tonic-gate 		return (NULL);
5947c478bd9Sstevel@tonic-gate 	}
5957c478bd9Sstevel@tonic-gate 	if ((pe = pool_conf_to_elem(conf)) == NULL) {
5967c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
5977c478bd9Sstevel@tonic-gate 		return (NULL);
5987c478bd9Sstevel@tonic-gate 	}
5997c478bd9Sstevel@tonic-gate 	return (pool_base_info(pe, NULL, deep));
6007c478bd9Sstevel@tonic-gate }
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate /*
6047c478bd9Sstevel@tonic-gate  * Set the thread specific error value.
6057c478bd9Sstevel@tonic-gate  */
6067c478bd9Sstevel@tonic-gate void
pool_seterror(int errval)6077c478bd9Sstevel@tonic-gate pool_seterror(int errval)
6087c478bd9Sstevel@tonic-gate {
6097c478bd9Sstevel@tonic-gate 	if (thr_main()) {
6107c478bd9Sstevel@tonic-gate 		pool_errval = errval;
6117c478bd9Sstevel@tonic-gate 		return;
6127c478bd9Sstevel@tonic-gate 	}
613*cb620785Sraf 	(void) thr_keycreate_once(&errkey, 0);
6147c478bd9Sstevel@tonic-gate 	(void) thr_setspecific(errkey, (void *)(intptr_t)errval);
6157c478bd9Sstevel@tonic-gate }
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate /*
6187c478bd9Sstevel@tonic-gate  * Return the current value of the error code.
6197c478bd9Sstevel@tonic-gate  * Returns: int error code
6207c478bd9Sstevel@tonic-gate  */
6217c478bd9Sstevel@tonic-gate int
pool_error(void)6227c478bd9Sstevel@tonic-gate pool_error(void)
6237c478bd9Sstevel@tonic-gate {
6247c478bd9Sstevel@tonic-gate 	if (thr_main())
6257c478bd9Sstevel@tonic-gate 		return (pool_errval);
626*cb620785Sraf 	if (errkey == THR_ONCE_KEY)
6277c478bd9Sstevel@tonic-gate 		return (POE_OK);
628*cb620785Sraf 	return ((uintptr_t)pthread_getspecific(errkey));
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate /*
6327c478bd9Sstevel@tonic-gate  * Return the text represenation for the current value of the error code.
6337c478bd9Sstevel@tonic-gate  * Returns: const char * error string
6347c478bd9Sstevel@tonic-gate  */
6357c478bd9Sstevel@tonic-gate const char *
pool_strerror(int error)6367c478bd9Sstevel@tonic-gate pool_strerror(int error)
6377c478bd9Sstevel@tonic-gate {
6387c478bd9Sstevel@tonic-gate 	char *str;
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 	switch (error) {
6417c478bd9Sstevel@tonic-gate 	case POE_OK:
6427c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Operation successful");
6437c478bd9Sstevel@tonic-gate 		break;
6447c478bd9Sstevel@tonic-gate 	case POE_BAD_PROP_TYPE:
6457c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN,
6467c478bd9Sstevel@tonic-gate 		    "Attempted to retrieve the wrong property type");
6477c478bd9Sstevel@tonic-gate 		break;
6487c478bd9Sstevel@tonic-gate 	case POE_INVALID_CONF:
6497c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Invalid configuration");
6507c478bd9Sstevel@tonic-gate 		break;
6517c478bd9Sstevel@tonic-gate 	case POE_NOTSUP:
6527c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Operation is not supported");
6537c478bd9Sstevel@tonic-gate 		break;
6547c478bd9Sstevel@tonic-gate 	case POE_INVALID_SEARCH:
6557c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Invalid search");
6567c478bd9Sstevel@tonic-gate 		break;
6577c478bd9Sstevel@tonic-gate 	case POE_BADPARAM:
6587c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Bad parameter supplied");
6597c478bd9Sstevel@tonic-gate 		break;
6607c478bd9Sstevel@tonic-gate 	case POE_PUTPROP:
6617c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Error putting property");
6627c478bd9Sstevel@tonic-gate 		break;
6637c478bd9Sstevel@tonic-gate 	case POE_DATASTORE:
6647c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Pools repository error");
6657c478bd9Sstevel@tonic-gate 		break;
6667c478bd9Sstevel@tonic-gate 	case POE_SYSTEM:
6677c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "System error");
6687c478bd9Sstevel@tonic-gate 		break;
6697c478bd9Sstevel@tonic-gate 	case POE_ACCESS:
6707c478bd9Sstevel@tonic-gate 		str = dgettext(TEXT_DOMAIN, "Permission denied");
6717c478bd9Sstevel@tonic-gate 		break;
6727c478bd9Sstevel@tonic-gate 	default:
6737c478bd9Sstevel@tonic-gate 		errno = ESRCH;
6747c478bd9Sstevel@tonic-gate 		str = NULL;
6757c478bd9Sstevel@tonic-gate 	}
6767c478bd9Sstevel@tonic-gate 	return (str);
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate int
pool_get_status(int * state)6807c478bd9Sstevel@tonic-gate pool_get_status(int *state)
6817c478bd9Sstevel@tonic-gate {
6827c478bd9Sstevel@tonic-gate 	int fd;
6837c478bd9Sstevel@tonic-gate 	pool_status_t status;
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	if ((fd = open(pool_info_location, O_RDONLY)) < 0) {
6867c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
6877c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
6887c478bd9Sstevel@tonic-gate 	}
6897c478bd9Sstevel@tonic-gate 	if (ioctl(fd, POOL_STATUSQ, &status) < 0) {
6907c478bd9Sstevel@tonic-gate 		(void) close(fd);
6917c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
6927c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate 	(void) close(fd);
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	*state = status.ps_io_state;
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate int
pool_set_status(int state)7027c478bd9Sstevel@tonic-gate pool_set_status(int state)
7037c478bd9Sstevel@tonic-gate {
7047c478bd9Sstevel@tonic-gate 	int old_state;
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 	if (pool_get_status(&old_state) != PO_SUCCESS) {
7077c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
7087c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
7097c478bd9Sstevel@tonic-gate 	}
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate 	if (old_state != state) {
7127c478bd9Sstevel@tonic-gate 		int fd;
7137c478bd9Sstevel@tonic-gate 		pool_status_t status;
714c1c0ebd5Ssl108498 		char *fmri;
7157c478bd9Sstevel@tonic-gate 
71626d8ba22Sgarypen 		/*
71726d8ba22Sgarypen 		 * Changing the status of pools is performed by enabling
71826d8ba22Sgarypen 		 * or disabling the pools service instance. If this
71926d8ba22Sgarypen 		 * function has not been invoked by startd then we simply
72026d8ba22Sgarypen 		 * enable/disable the service and return success.
72126d8ba22Sgarypen 		 *
72226d8ba22Sgarypen 		 * There is no way to specify that state changes must be
72326d8ba22Sgarypen 		 * synchronous using the library API as yet, so we use
72426d8ba22Sgarypen 		 * the -s option provided by svcadm.
72526d8ba22Sgarypen 		 */
726c1c0ebd5Ssl108498 		fmri = getenv("SMF_FMRI");
727c1c0ebd5Ssl108498 		if (fmri == NULL) {
72826d8ba22Sgarypen 			FILE *p;
729fb30ca63Sgarypen 			char *cmd;
730fb30ca63Sgarypen 
731c1c0ebd5Ssl108498 			if (state != 0) {
732fb30ca63Sgarypen 				cmd = "/usr/sbin/svcadm enable -s " \
73326d8ba22Sgarypen 				    SMF_SVC_INSTANCE;
73426d8ba22Sgarypen 			} else {
735fb30ca63Sgarypen 				cmd = "/usr/sbin/svcadm disable -s " \
73626d8ba22Sgarypen 				    SMF_SVC_INSTANCE;
737fb30ca63Sgarypen 			}
738fb30ca63Sgarypen 			if ((p = popen(cmd, "wF")) == NULL || pclose(p) != 0) {
739fb30ca63Sgarypen 				pool_seterror(POE_SYSTEM);
74026d8ba22Sgarypen 				return (PO_FAIL);
7417c478bd9Sstevel@tonic-gate 			}
74226d8ba22Sgarypen 			return (PO_SUCCESS);
7437c478bd9Sstevel@tonic-gate 		}
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 		if ((fd = open(pool_dynamic_location(), O_RDWR | O_EXCL)) < 0) {
7467c478bd9Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
7477c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
7487c478bd9Sstevel@tonic-gate 		}
7497c478bd9Sstevel@tonic-gate 
750c1c0ebd5Ssl108498 		/*
751c1c0ebd5Ssl108498 		 * If pools are being enabled/disabled by another smf service,
752c1c0ebd5Ssl108498 		 * enable the smf service instance.  This must be done
753c1c0ebd5Ssl108498 		 * asynchronously as one service cannot synchronously
754c1c0ebd5Ssl108498 		 * enable/disable another.
755c1c0ebd5Ssl108498 		 */
756c1c0ebd5Ssl108498 		if (strcmp(fmri, SMF_SVC_INSTANCE) != 0) {
757c1c0ebd5Ssl108498 			int res;
758c1c0ebd5Ssl108498 
759c1c0ebd5Ssl108498 			if (state != 0)
760c1c0ebd5Ssl108498 				res = smf_enable_instance(SMF_SVC_INSTANCE, 0);
761c1c0ebd5Ssl108498 			else
762c1c0ebd5Ssl108498 				res = smf_disable_instance(SMF_SVC_INSTANCE, 0);
763c1c0ebd5Ssl108498 
764c1c0ebd5Ssl108498 			if (res != 0) {
765c1c0ebd5Ssl108498 				(void) close(fd);
766c1c0ebd5Ssl108498 				pool_seterror(POE_SYSTEM);
767c1c0ebd5Ssl108498 				return (PO_FAIL);
768c1c0ebd5Ssl108498 			}
769c1c0ebd5Ssl108498 		}
7707c478bd9Sstevel@tonic-gate 		status.ps_io_state = state;
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 		if (ioctl(fd, POOL_STATUS, &status) < 0) {
7737c478bd9Sstevel@tonic-gate 			(void) close(fd);
7747c478bd9Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
7757c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
7767c478bd9Sstevel@tonic-gate 		}
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 		(void) close(fd);
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 	}
7817c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate /*
7857c478bd9Sstevel@tonic-gate  * General Data Provider Independent Access Methods
7867c478bd9Sstevel@tonic-gate  */
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate /*
7897c478bd9Sstevel@tonic-gate  * Property manipulation code.
7907c478bd9Sstevel@tonic-gate  *
7917c478bd9Sstevel@tonic-gate  * The pool_(get|rm|set)_property() functions consult the plugins before
7927c478bd9Sstevel@tonic-gate  * looking at the actual configuration. This allows plugins to provide
7937c478bd9Sstevel@tonic-gate  * "virtual" properties that may not exist in the configuration file per se,
7947c478bd9Sstevel@tonic-gate  * but behave like regular properties. This also allows plugins to reserve
7957c478bd9Sstevel@tonic-gate  * certain properties as read-only, non-removable, etc.
7967c478bd9Sstevel@tonic-gate  *
7977c478bd9Sstevel@tonic-gate  * A negative value returned from the plugin denotes error, 0 means that the
7987c478bd9Sstevel@tonic-gate  * property request should be forwarded to the backend, and 1 means the request
7997c478bd9Sstevel@tonic-gate  * was satisfied by the plugin and should not be processed further.
8007c478bd9Sstevel@tonic-gate  *
8017c478bd9Sstevel@tonic-gate  * The (get|rm|set)_property() functions bypass the plugin layer completely,
8027c478bd9Sstevel@tonic-gate  * and hence should not be generally used.
8037c478bd9Sstevel@tonic-gate  */
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate /*
8067c478bd9Sstevel@tonic-gate  * Return true if the string passed in matches the pattern
8077c478bd9Sstevel@tonic-gate  * [A-Za-z][A-Za-z0-9,._-]*
8087c478bd9Sstevel@tonic-gate  */
8097c478bd9Sstevel@tonic-gate int
is_valid_name(const char * name)8107c478bd9Sstevel@tonic-gate is_valid_name(const char *name)
8117c478bd9Sstevel@tonic-gate {
8127c478bd9Sstevel@tonic-gate 	int i;
8137c478bd9Sstevel@tonic-gate 	char c;
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	if (name == NULL)
8167c478bd9Sstevel@tonic-gate 		return (PO_FALSE);
8177c478bd9Sstevel@tonic-gate 	if (!isalpha(name[0]))
8187c478bd9Sstevel@tonic-gate 		return (PO_FALSE);
8197c478bd9Sstevel@tonic-gate 	for (i = 1; (c = name[i]) != '\0'; i++) {
8207c478bd9Sstevel@tonic-gate 		if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-')
8217c478bd9Sstevel@tonic-gate 			return (PO_FALSE);
8227c478bd9Sstevel@tonic-gate 	}
8237c478bd9Sstevel@tonic-gate 	return (PO_TRUE);
8247c478bd9Sstevel@tonic-gate }
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate /*
8277c478bd9Sstevel@tonic-gate  * Return true if the string passed in matches the pattern
8287c478bd9Sstevel@tonic-gate  * [A-Za-z_][A-Za-z0-9,._-]*
8297c478bd9Sstevel@tonic-gate  * A property name starting with a '_' is an "invisible" property that does not
8307c478bd9Sstevel@tonic-gate  * show up in a property walk.
8317c478bd9Sstevel@tonic-gate  */
8327c478bd9Sstevel@tonic-gate int
is_valid_prop_name(const char * prop_name)8337c478bd9Sstevel@tonic-gate is_valid_prop_name(const char *prop_name)
8347c478bd9Sstevel@tonic-gate {
8357c478bd9Sstevel@tonic-gate 	int i;
8367c478bd9Sstevel@tonic-gate 	char c;
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	if (prop_name == NULL)
8397c478bd9Sstevel@tonic-gate 		return (PO_FALSE);
8407c478bd9Sstevel@tonic-gate 	if (!isalpha(prop_name[0]) && prop_name[0] != '_')
8417c478bd9Sstevel@tonic-gate 		return (PO_FALSE);
8427c478bd9Sstevel@tonic-gate 	for (i = 1; (c = prop_name[i]) != '\0'; i++) {
8437c478bd9Sstevel@tonic-gate 		if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-')
8447c478bd9Sstevel@tonic-gate 			return (PO_FALSE);
8457c478bd9Sstevel@tonic-gate 	}
8467c478bd9Sstevel@tonic-gate 	return (PO_TRUE);
8477c478bd9Sstevel@tonic-gate }
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate /*
8507c478bd9Sstevel@tonic-gate  * Return the specified property value.
8517c478bd9Sstevel@tonic-gate  *
8527c478bd9Sstevel@tonic-gate  * POC_INVAL is returned if an error is detected and the error code is updated
8537c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
8547c478bd9Sstevel@tonic-gate  */
8557c478bd9Sstevel@tonic-gate pool_value_class_t
pool_get_property(const pool_conf_t * conf,const pool_elem_t * pe,const char * name,pool_value_t * val)8567c478bd9Sstevel@tonic-gate pool_get_property(const pool_conf_t *conf, const pool_elem_t *pe,
8577c478bd9Sstevel@tonic-gate     const char *name, pool_value_t *val)
8587c478bd9Sstevel@tonic-gate {
8597c478bd9Sstevel@tonic-gate 	const pool_prop_t *prop_info;
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
8627c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
8637c478bd9Sstevel@tonic-gate 		return (POC_INVAL);
8647c478bd9Sstevel@tonic-gate 	}
8657c478bd9Sstevel@tonic-gate 	if (pool_value_set_name(val, name) != PO_SUCCESS) {
8667c478bd9Sstevel@tonic-gate 		return (POC_INVAL);
8677c478bd9Sstevel@tonic-gate 	}
8687c478bd9Sstevel@tonic-gate 	/*
8697c478bd9Sstevel@tonic-gate 	 * Check to see if this is a property we are managing. If it
8707c478bd9Sstevel@tonic-gate 	 * is and it has an interceptor installed for property
8717c478bd9Sstevel@tonic-gate 	 * retrieval, use it.
8727c478bd9Sstevel@tonic-gate 	 */
8737c478bd9Sstevel@tonic-gate 	if ((prop_info = provider_get_prop(pe, name)) != NULL &&
8747c478bd9Sstevel@tonic-gate 	    prop_info->pp_op.ppo_get_value != NULL) {
8757c478bd9Sstevel@tonic-gate 		if (prop_info->pp_op.ppo_get_value(pe, val) == PO_FAIL)
8767c478bd9Sstevel@tonic-gate 			return (POC_INVAL);
8777c478bd9Sstevel@tonic-gate 		else
8787c478bd9Sstevel@tonic-gate 			return (pool_value_get_type(val));
8797c478bd9Sstevel@tonic-gate 	}
8807c478bd9Sstevel@tonic-gate 	return (pe->pe_get_prop(pe, name, val));
8817c478bd9Sstevel@tonic-gate }
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate /*
8847c478bd9Sstevel@tonic-gate  * Return the specified property value with the namespace prepended.
8857c478bd9Sstevel@tonic-gate  * e.g. If this function is used to get the property "name" on a pool, it will
8867c478bd9Sstevel@tonic-gate  * attempt to retrieve "pool.name".
8877c478bd9Sstevel@tonic-gate  *
8887c478bd9Sstevel@tonic-gate  * POC_INVAL is returned if an error is detected and the error code is updated
8897c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
8907c478bd9Sstevel@tonic-gate  */
8917c478bd9Sstevel@tonic-gate pool_value_class_t
pool_get_ns_property(const pool_elem_t * pe,const char * name,pool_value_t * val)8927c478bd9Sstevel@tonic-gate pool_get_ns_property(const pool_elem_t *pe, const char *name, pool_value_t *val)
8937c478bd9Sstevel@tonic-gate {
8947c478bd9Sstevel@tonic-gate 	int ret;
8957c478bd9Sstevel@tonic-gate 	char_buf_t *cb;
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 	if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
8987c478bd9Sstevel@tonic-gate 		return (POC_INVAL);
8997c478bd9Sstevel@tonic-gate 	if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
9007c478bd9Sstevel@tonic-gate 	    PO_FAIL) {
9017c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
9027c478bd9Sstevel@tonic-gate 		return (POC_INVAL);
9037c478bd9Sstevel@tonic-gate 	}
9047c478bd9Sstevel@tonic-gate 	ret = pool_get_property(TO_CONF(pe), pe, cb->cb_buf, val);
9057c478bd9Sstevel@tonic-gate 	free_char_buf(cb);
9067c478bd9Sstevel@tonic-gate 	return (ret);
9077c478bd9Sstevel@tonic-gate }
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate /*
9107c478bd9Sstevel@tonic-gate  * Update the specified property value.
9117c478bd9Sstevel@tonic-gate  *
9127c478bd9Sstevel@tonic-gate  * PO_FAIL is returned if an error is detected and the error code is updated
9137c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
9147c478bd9Sstevel@tonic-gate  */
9157c478bd9Sstevel@tonic-gate int
pool_put_property(pool_conf_t * conf,pool_elem_t * pe,const char * name,const pool_value_t * val)9167c478bd9Sstevel@tonic-gate pool_put_property(pool_conf_t *conf, pool_elem_t *pe, const char *name,
9177c478bd9Sstevel@tonic-gate     const pool_value_t *val)
9187c478bd9Sstevel@tonic-gate {
9197c478bd9Sstevel@tonic-gate 	const pool_prop_t *prop_info;
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
9227c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 	if (TO_CONF(pe) != conf) {
9257c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
9267c478bd9Sstevel@tonic-gate 		return (NULL);
9277c478bd9Sstevel@tonic-gate 	}
9287c478bd9Sstevel@tonic-gate 
9290209230bSgjelinek 	/* Don't allow (re)setting of the "temporary" property */
9300209230bSgjelinek 	if (!is_valid_prop_name(name) || strstr(name, ".temporary") != NULL) {
9317c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
9327c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
9337c478bd9Sstevel@tonic-gate 	}
9340209230bSgjelinek 
9350209230bSgjelinek 	/* Don't allow rename of temporary pools/resources */
9360209230bSgjelinek 	if (strstr(name, ".name") != NULL && elem_is_tmp(pe)) {
9370209230bSgjelinek 		boolean_t rename = B_TRUE;
9380209230bSgjelinek 		pool_value_t *pv = pool_value_alloc();
9390209230bSgjelinek 
9400209230bSgjelinek 		if (pe->pe_get_prop(pe, name, pv) != POC_INVAL) {
9410209230bSgjelinek 			const char *s1 = NULL;
9420209230bSgjelinek 			const char *s2 = NULL;
9430209230bSgjelinek 
9440209230bSgjelinek 			(void) pool_value_get_string(pv, &s1);
9450209230bSgjelinek 			(void) pool_value_get_string(val, &s2);
9460209230bSgjelinek 			if (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0)
9470209230bSgjelinek 				rename = B_FALSE;
9480209230bSgjelinek 		}
9490209230bSgjelinek 		pool_value_free(pv);
9500209230bSgjelinek 
9510209230bSgjelinek 		if (rename) {
9520209230bSgjelinek 			pool_seterror(POE_BADPARAM);
9530209230bSgjelinek 			return (PO_FAIL);
9540209230bSgjelinek 		}
9550209230bSgjelinek 	}
9560209230bSgjelinek 
9577c478bd9Sstevel@tonic-gate 	/*
9587c478bd9Sstevel@tonic-gate 	 * Check to see if this is a property we are managing. If it is,
9597c478bd9Sstevel@tonic-gate 	 * ensure that we are happy with what the user is doing.
9607c478bd9Sstevel@tonic-gate 	 */
9617c478bd9Sstevel@tonic-gate 	if ((prop_info = provider_get_prop(pe, name)) != NULL) {
9627c478bd9Sstevel@tonic-gate 		if (prop_is_readonly(prop_info) == PO_TRUE) {
9637c478bd9Sstevel@tonic-gate 			pool_seterror(POE_BADPARAM);
9647c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
9657c478bd9Sstevel@tonic-gate 		}
9667c478bd9Sstevel@tonic-gate 		if (prop_info->pp_op.ppo_set_value &&
9677c478bd9Sstevel@tonic-gate 		    prop_info->pp_op.ppo_set_value(pe, val) == PO_FAIL)
9687c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
9697c478bd9Sstevel@tonic-gate 	}
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 	return (pe->pe_put_prop(pe, name, val));
9727c478bd9Sstevel@tonic-gate }
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate /*
9750209230bSgjelinek  * Set temporary property to flag as a temporary element.
9760209230bSgjelinek  *
9770209230bSgjelinek  * PO_FAIL is returned if an error is detected and the error code is updated
9780209230bSgjelinek  * to indicate the cause of the error.
9790209230bSgjelinek  */
9800209230bSgjelinek int
pool_set_temporary(pool_conf_t * conf,pool_elem_t * pe)9810209230bSgjelinek pool_set_temporary(pool_conf_t *conf, pool_elem_t *pe)
9820209230bSgjelinek {
9830209230bSgjelinek 	int res;
9840209230bSgjelinek 	char name[128];
9850209230bSgjelinek 	pool_value_t *val;
9860209230bSgjelinek 
9870209230bSgjelinek 	if (pool_conf_check(conf) != PO_SUCCESS)
9880209230bSgjelinek 		return (PO_FAIL);
9890209230bSgjelinek 
9900209230bSgjelinek 	if (TO_CONF(pe) != conf) {
9910209230bSgjelinek 		pool_seterror(POE_BADPARAM);
9920209230bSgjelinek 		return (PO_FAIL);
9930209230bSgjelinek 	}
9940209230bSgjelinek 
9950209230bSgjelinek 	/* create property name based on element type */
9960209230bSgjelinek 	if (snprintf(name, sizeof (name), "%s.temporary",
9970209230bSgjelinek 	    pool_elem_class_string(pe)) > sizeof (name)) {
9980209230bSgjelinek 		pool_seterror(POE_SYSTEM);
9990209230bSgjelinek 		return (PO_FAIL);
10000209230bSgjelinek 	}
10010209230bSgjelinek 
10020209230bSgjelinek 	if ((val = pool_value_alloc()) == NULL)
10030209230bSgjelinek 		return (PO_FAIL);
10040209230bSgjelinek 
10050209230bSgjelinek 	pool_value_set_bool(val, (uchar_t)1);
10060209230bSgjelinek 
10070209230bSgjelinek 	res = pe->pe_put_prop(pe, name, val);
10080209230bSgjelinek 
10090209230bSgjelinek 	pool_value_free(val);
10100209230bSgjelinek 
10110209230bSgjelinek 	return (res);
10120209230bSgjelinek }
10130209230bSgjelinek 
10140209230bSgjelinek /*
10157c478bd9Sstevel@tonic-gate  * Update the specified property value with the namespace prepended.
10167c478bd9Sstevel@tonic-gate  * e.g. If this function is used to update the property "name" on a pool, it
10177c478bd9Sstevel@tonic-gate  * will attempt to update "pool.name".
10187c478bd9Sstevel@tonic-gate  *
10197c478bd9Sstevel@tonic-gate  * PO_FAIL is returned if an error is detected and the error code is updated
10207c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
10217c478bd9Sstevel@tonic-gate  */
10227c478bd9Sstevel@tonic-gate int
pool_put_ns_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10237c478bd9Sstevel@tonic-gate pool_put_ns_property(pool_elem_t *pe, const char *name,
10247c478bd9Sstevel@tonic-gate     const pool_value_t *val)
10257c478bd9Sstevel@tonic-gate {
10267c478bd9Sstevel@tonic-gate 	char_buf_t *cb;
10277c478bd9Sstevel@tonic-gate 	int ret;
10287c478bd9Sstevel@tonic-gate 
10297c478bd9Sstevel@tonic-gate 	if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
10307c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
10317c478bd9Sstevel@tonic-gate 	if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
10327c478bd9Sstevel@tonic-gate 	    PO_FAIL) {
10337c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
10347c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
10357c478bd9Sstevel@tonic-gate 	}
10367c478bd9Sstevel@tonic-gate 	ret = pool_put_property(TO_CONF(pe), pe, cb->cb_buf, val);
10377c478bd9Sstevel@tonic-gate 	free_char_buf(cb);
10387c478bd9Sstevel@tonic-gate 	return (ret);
10397c478bd9Sstevel@tonic-gate }
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate /*
10427c478bd9Sstevel@tonic-gate  * Update the specified property value. Do not use the property
10437c478bd9Sstevel@tonic-gate  * protection mechanism. This function should only be used for cases
10447c478bd9Sstevel@tonic-gate  * where the library must bypass the normal property protection
10457c478bd9Sstevel@tonic-gate  * mechanism. The only known use is to update properties in the static
10467c478bd9Sstevel@tonic-gate  * configuration when performing a commit.
10477c478bd9Sstevel@tonic-gate  *
10487c478bd9Sstevel@tonic-gate  * PO_FAIL is returned if an error is detected and the error code is
10497c478bd9Sstevel@tonic-gate  * updated to indicate the cause of the error.
10507c478bd9Sstevel@tonic-gate  */
10517c478bd9Sstevel@tonic-gate int
pool_put_any_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10527c478bd9Sstevel@tonic-gate pool_put_any_property(pool_elem_t *pe, const char *name,
10537c478bd9Sstevel@tonic-gate     const pool_value_t *val)
10547c478bd9Sstevel@tonic-gate {
10557c478bd9Sstevel@tonic-gate 	if (!is_valid_prop_name(name)) {
10567c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
10577c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	return (pe->pe_put_prop(pe, name, val));
10617c478bd9Sstevel@tonic-gate }
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate /*
10647c478bd9Sstevel@tonic-gate  * Update the specified property value with the namespace prepended.
10657c478bd9Sstevel@tonic-gate  * e.g. If this function is used to update the property "name" on a pool, it
10667c478bd9Sstevel@tonic-gate  * will attempt to update "pool.name".
10677c478bd9Sstevel@tonic-gate  *
10687c478bd9Sstevel@tonic-gate  * PO_FAIL is returned if an error is detected and the error code is updated
10697c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
10707c478bd9Sstevel@tonic-gate  */
10717c478bd9Sstevel@tonic-gate int
pool_put_any_ns_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10727c478bd9Sstevel@tonic-gate pool_put_any_ns_property(pool_elem_t *pe, const char *name,
10737c478bd9Sstevel@tonic-gate     const pool_value_t *val)
10747c478bd9Sstevel@tonic-gate {
10757c478bd9Sstevel@tonic-gate 	char_buf_t *cb;
10767c478bd9Sstevel@tonic-gate 	int ret;
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
10797c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
10807c478bd9Sstevel@tonic-gate 	if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
10817c478bd9Sstevel@tonic-gate 	    PO_FAIL) {
10827c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
10837c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
10847c478bd9Sstevel@tonic-gate 	}
10857c478bd9Sstevel@tonic-gate 	ret = pool_put_any_property(pe, cb->cb_buf, val);
10867c478bd9Sstevel@tonic-gate 	free_char_buf(cb);
10877c478bd9Sstevel@tonic-gate 	return (ret);
10887c478bd9Sstevel@tonic-gate }
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate /*
10917c478bd9Sstevel@tonic-gate  * Remove the specified property value. Note that some properties are
10927c478bd9Sstevel@tonic-gate  * mandatory and thus failure to remove these properties is inevitable.
10937c478bd9Sstevel@tonic-gate  * PO_FAIL is returned if an error is detected and the error code is updated
10947c478bd9Sstevel@tonic-gate  * to indicate the cause of the error.
10957c478bd9Sstevel@tonic-gate  */
10967c478bd9Sstevel@tonic-gate int
pool_rm_property(pool_conf_t * conf,pool_elem_t * pe,const char * name)10977c478bd9Sstevel@tonic-gate pool_rm_property(pool_conf_t *conf, pool_elem_t *pe, const char *name)
10987c478bd9Sstevel@tonic-gate {
10997c478bd9Sstevel@tonic-gate 	const pool_prop_t *prop_info;
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
11027c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
11037c478bd9Sstevel@tonic-gate 
11047c478bd9Sstevel@tonic-gate 	if (TO_CONF(pe) != conf) {
11057c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
11067c478bd9Sstevel@tonic-gate 		return (NULL);
11077c478bd9Sstevel@tonic-gate 	}
11087c478bd9Sstevel@tonic-gate 
11090209230bSgjelinek 	/* Don't allow removal of the "temporary" property */
11100209230bSgjelinek 	if (strstr(name, ".temporary") != NULL) {
11110209230bSgjelinek 		pool_seterror(POE_BADPARAM);
11120209230bSgjelinek 		return (PO_FAIL);
11130209230bSgjelinek 	}
11140209230bSgjelinek 
11157c478bd9Sstevel@tonic-gate 	/*
11167c478bd9Sstevel@tonic-gate 	 * Check to see if this is a property we are managing. If it is,
11177c478bd9Sstevel@tonic-gate 	 * ensure that we are happy with what the user is doing.
11187c478bd9Sstevel@tonic-gate 	 */
11197c478bd9Sstevel@tonic-gate 	if ((prop_info = provider_get_prop(pe, name)) != NULL) {
11207c478bd9Sstevel@tonic-gate 		if (prop_is_optional(prop_info) == PO_FALSE) {
11217c478bd9Sstevel@tonic-gate 			pool_seterror(POE_BADPARAM);
11227c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
11237c478bd9Sstevel@tonic-gate 		}
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate 	return (pe->pe_rm_prop(pe, name));
11267c478bd9Sstevel@tonic-gate }
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate /*
11297c478bd9Sstevel@tonic-gate  * Check if the supplied name is a namespace protected property for the supplied
11307c478bd9Sstevel@tonic-gate  * element, pe. If it is, return the prefix, otherwise just return NULL.
11317c478bd9Sstevel@tonic-gate  */
11327c478bd9Sstevel@tonic-gate const char *
is_ns_property(const pool_elem_t * pe,const char * name)11337c478bd9Sstevel@tonic-gate is_ns_property(const pool_elem_t *pe, const char *name)
11347c478bd9Sstevel@tonic-gate {
11357c478bd9Sstevel@tonic-gate 	const char *prefix;
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate 	if ((prefix = pool_elem_class_string(pe)) != NULL) {
11387c478bd9Sstevel@tonic-gate 		if (strncmp(name, prefix, strlen(prefix)) == 0)
11397c478bd9Sstevel@tonic-gate 			return (prefix);
11407c478bd9Sstevel@tonic-gate 	}
11417c478bd9Sstevel@tonic-gate 	return (NULL);
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate 
11447c478bd9Sstevel@tonic-gate /*
11457c478bd9Sstevel@tonic-gate  * Check if the supplied name is a namespace protected property for the supplied
11467c478bd9Sstevel@tonic-gate  * element, pe. If it is, return the property name with the namespace stripped,
11477c478bd9Sstevel@tonic-gate  * otherwise just return the name.
11487c478bd9Sstevel@tonic-gate  */
11497c478bd9Sstevel@tonic-gate const char *
property_name_minus_ns(const pool_elem_t * pe,const char * name)11507c478bd9Sstevel@tonic-gate property_name_minus_ns(const pool_elem_t *pe, const char *name)
11517c478bd9Sstevel@tonic-gate {
11527c478bd9Sstevel@tonic-gate 	const char *prefix;
11537c478bd9Sstevel@tonic-gate 	if ((prefix = is_ns_property(pe, name)) != NULL) {
11547c478bd9Sstevel@tonic-gate 		return (name + strlen(prefix) + 1);
11557c478bd9Sstevel@tonic-gate 	}
11567c478bd9Sstevel@tonic-gate 	return (name);
11577c478bd9Sstevel@tonic-gate }
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate /*
11607c478bd9Sstevel@tonic-gate  * Create an element to represent a pool and add it to the supplied
11617c478bd9Sstevel@tonic-gate  * configuration.
11627c478bd9Sstevel@tonic-gate  */
11637c478bd9Sstevel@tonic-gate pool_t *
pool_create(pool_conf_t * conf,const char * name)11647c478bd9Sstevel@tonic-gate pool_create(pool_conf_t *conf, const char *name)
11657c478bd9Sstevel@tonic-gate {
11667c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
11677c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
11687c478bd9Sstevel@tonic-gate 	const pool_prop_t *default_props;
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
11717c478bd9Sstevel@tonic-gate 		return (NULL);
11727c478bd9Sstevel@tonic-gate 
11737c478bd9Sstevel@tonic-gate 	if (!is_valid_name(name) || pool_get_pool(conf, name) != NULL) {
11747c478bd9Sstevel@tonic-gate 		/*
11757c478bd9Sstevel@tonic-gate 		 * A pool with the same name exists. Reject.
11767c478bd9Sstevel@tonic-gate 		 */
11777c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
11787c478bd9Sstevel@tonic-gate 		return (NULL);
11797c478bd9Sstevel@tonic-gate 	}
11807c478bd9Sstevel@tonic-gate 	if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_POOL, PREC_INVALID,
11817c478bd9Sstevel@tonic-gate 	    PCEC_INVALID)) == NULL) {
11827c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
11837c478bd9Sstevel@tonic-gate 		return (NULL);
11847c478bd9Sstevel@tonic-gate 	}
11857c478bd9Sstevel@tonic-gate 	if ((default_props = provider_get_props(pe)) != NULL) {
11867c478bd9Sstevel@tonic-gate 		int i;
11877c478bd9Sstevel@tonic-gate 		for (i = 0; default_props[i].pp_pname != NULL; i++) {
11887c478bd9Sstevel@tonic-gate 			if (prop_is_init(&default_props[i]) &&
11897c478bd9Sstevel@tonic-gate 			    (pool_put_any_property(pe,
11907c478bd9Sstevel@tonic-gate 			    default_props[i].pp_pname,
11917c478bd9Sstevel@tonic-gate 			    &default_props[i].pp_value) == PO_FAIL)) {
11927c478bd9Sstevel@tonic-gate 				(void) pool_destroy(conf, pool_elem_pool(pe));
11937c478bd9Sstevel@tonic-gate 				return (NULL);
11947c478bd9Sstevel@tonic-gate 			}
11957c478bd9Sstevel@tonic-gate 		}
11967c478bd9Sstevel@tonic-gate 	}
11977c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(&val, name) != PO_SUCCESS) {
11987c478bd9Sstevel@tonic-gate 		(void) pool_destroy(conf, pool_elem_pool(pe));
11997c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
12007c478bd9Sstevel@tonic-gate 		return (NULL);
12017c478bd9Sstevel@tonic-gate 	}
12027c478bd9Sstevel@tonic-gate 	if (pool_put_property(conf, pe, "pool.name", &val) == PO_FAIL) {
12037c478bd9Sstevel@tonic-gate 		(void) pool_destroy(conf, pool_elem_pool(pe));
12047c478bd9Sstevel@tonic-gate 		pool_seterror(POE_PUTPROP);
12057c478bd9Sstevel@tonic-gate 		return (NULL);
12067c478bd9Sstevel@tonic-gate 	}
12070209230bSgjelinek 
12080209230bSgjelinek 	/*
12090209230bSgjelinek 	 * If we are creating a temporary pool configuration, flag the pool.
12100209230bSgjelinek 	 */
12110209230bSgjelinek 	if (conf->pc_prov->pc_oflags & PO_TEMP) {
12120209230bSgjelinek 		if (pool_set_temporary(conf, pe) == PO_FAIL) {
12130209230bSgjelinek 			(void) pool_destroy(conf, pool_elem_pool(pe));
12140209230bSgjelinek 			return (NULL);
12150209230bSgjelinek 		}
12160209230bSgjelinek 	}
12170209230bSgjelinek 
12187c478bd9Sstevel@tonic-gate 	return (pool_elem_pool(pe));
12197c478bd9Sstevel@tonic-gate }
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate /*
12227c478bd9Sstevel@tonic-gate  * Create an element to represent a res.
12237c478bd9Sstevel@tonic-gate  */
12247c478bd9Sstevel@tonic-gate pool_resource_t *
pool_resource_create(pool_conf_t * conf,const char * sz_type,const char * name)12257c478bd9Sstevel@tonic-gate pool_resource_create(pool_conf_t *conf, const char *sz_type, const char *name)
12267c478bd9Sstevel@tonic-gate {
12277c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
12287c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
12297c478bd9Sstevel@tonic-gate 	const pool_prop_t *default_props;
12307c478bd9Sstevel@tonic-gate 	pool_resource_t **resources;
12317c478bd9Sstevel@tonic-gate 	int is_default = 0;
12327c478bd9Sstevel@tonic-gate 	uint_t nelem;
12337c478bd9Sstevel@tonic-gate 	pool_elem_class_t elem_class;
12347c478bd9Sstevel@tonic-gate 	pool_resource_elem_class_t type;
12357c478bd9Sstevel@tonic-gate 	pool_value_t *props[] = { NULL, NULL };
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
12387c478bd9Sstevel@tonic-gate 		return (NULL);
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	if ((type = pool_resource_elem_class_from_string(sz_type)) ==
12417c478bd9Sstevel@tonic-gate 	    PREC_INVALID) {
12427c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
12437c478bd9Sstevel@tonic-gate 		return (NULL);
12447c478bd9Sstevel@tonic-gate 	}
12457c478bd9Sstevel@tonic-gate 
12467c478bd9Sstevel@tonic-gate 	if (strcmp(sz_type, "pset") != 0) {
12477c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
12487c478bd9Sstevel@tonic-gate 		return (NULL);
12497c478bd9Sstevel@tonic-gate 	}
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 	if (!is_valid_name(name) || pool_get_resource(conf, sz_type, name) !=
12527c478bd9Sstevel@tonic-gate 	    NULL) {
12537c478bd9Sstevel@tonic-gate 		/*
12547c478bd9Sstevel@tonic-gate 		 * Resources must be unique by name+type.
12557c478bd9Sstevel@tonic-gate 		 */
12567c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
12577c478bd9Sstevel@tonic-gate 		return (NULL);
12587c478bd9Sstevel@tonic-gate 	}
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 	props[0] = &val;
12617c478bd9Sstevel@tonic-gate 
12627c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS ||
12637c478bd9Sstevel@tonic-gate 	    pool_value_set_name(props[0], c_type) != PO_SUCCESS) {
12647c478bd9Sstevel@tonic-gate 		return (NULL);
12657c478bd9Sstevel@tonic-gate 	}
12667c478bd9Sstevel@tonic-gate 
12677c478bd9Sstevel@tonic-gate 	if ((resources = pool_query_resources(conf, &nelem, props)) == NULL) {
12687c478bd9Sstevel@tonic-gate 		/*
12697c478bd9Sstevel@tonic-gate 		 * This is the first representative of this type; when it's
12707c478bd9Sstevel@tonic-gate 		 * created it should be created with 'default' = 'true'.
12717c478bd9Sstevel@tonic-gate 		 */
12727c478bd9Sstevel@tonic-gate 		is_default = 1;
12737c478bd9Sstevel@tonic-gate 	} else {
12747c478bd9Sstevel@tonic-gate 		free(resources);
12757c478bd9Sstevel@tonic-gate 	}
12767c478bd9Sstevel@tonic-gate 	/*
12777c478bd9Sstevel@tonic-gate 	 * TODO: If Additional PEC_RES_COMP types are added to
12787c478bd9Sstevel@tonic-gate 	 * pool_impl.h, this would need to be extended.
12797c478bd9Sstevel@tonic-gate 	 */
12807c478bd9Sstevel@tonic-gate 	switch (type) {
12817c478bd9Sstevel@tonic-gate 	case PREC_PSET:
12827c478bd9Sstevel@tonic-gate 		elem_class = PEC_RES_COMP;
12837c478bd9Sstevel@tonic-gate 		break;
12847c478bd9Sstevel@tonic-gate 	default:
12857c478bd9Sstevel@tonic-gate 		elem_class = PEC_RES_AGG;
12867c478bd9Sstevel@tonic-gate 		break;
12877c478bd9Sstevel@tonic-gate 	}
12887c478bd9Sstevel@tonic-gate 	if ((pe = conf->pc_prov->pc_elem_create(conf, elem_class, type,
12897c478bd9Sstevel@tonic-gate 	    PCEC_INVALID)) == NULL) {
12907c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
12917c478bd9Sstevel@tonic-gate 		return (NULL);
12927c478bd9Sstevel@tonic-gate 	}
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate 	/*
12957c478bd9Sstevel@tonic-gate 	 * The plugins contain a list of default properties and their values
12967c478bd9Sstevel@tonic-gate 	 * for resources. The resource returned, hence, is fully initialized.
12977c478bd9Sstevel@tonic-gate 	 */
12987c478bd9Sstevel@tonic-gate 	if ((default_props = provider_get_props(pe)) != NULL) {
12997c478bd9Sstevel@tonic-gate 		int i;
13007c478bd9Sstevel@tonic-gate 		for (i = 0; default_props[i].pp_pname != NULL; i++) {
13017c478bd9Sstevel@tonic-gate 			if (prop_is_init(&default_props[i]) &&
13027c478bd9Sstevel@tonic-gate 			    pool_put_any_property(pe, default_props[i].pp_pname,
13037c478bd9Sstevel@tonic-gate 			    &default_props[i].pp_value) == PO_FAIL) {
13047c478bd9Sstevel@tonic-gate 				(void) pool_resource_destroy(conf,
13057c478bd9Sstevel@tonic-gate 				    pool_elem_res(pe));
13067c478bd9Sstevel@tonic-gate 				return (NULL);
13077c478bd9Sstevel@tonic-gate 			}
13087c478bd9Sstevel@tonic-gate 		}
13097c478bd9Sstevel@tonic-gate 	}
13107c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(&val, name) != PO_SUCCESS ||
13117c478bd9Sstevel@tonic-gate 	    pool_put_ns_property(pe, "name", &val) != PO_SUCCESS) {
13127c478bd9Sstevel@tonic-gate 		(void) pool_resource_destroy(conf, pool_elem_res(pe));
13137c478bd9Sstevel@tonic-gate 		return (NULL);
13147c478bd9Sstevel@tonic-gate 	}
13157c478bd9Sstevel@tonic-gate 	if (is_default) {
13167c478bd9Sstevel@tonic-gate 		pool_value_set_bool(&val, PO_TRUE);
13177c478bd9Sstevel@tonic-gate 		if (pool_put_any_ns_property(pe, "default", &val) !=
13187c478bd9Sstevel@tonic-gate 		    PO_SUCCESS) {
13197c478bd9Sstevel@tonic-gate 			(void) pool_resource_destroy(conf, pool_elem_res(pe));
13207c478bd9Sstevel@tonic-gate 			return (NULL);
13217c478bd9Sstevel@tonic-gate 		}
13227c478bd9Sstevel@tonic-gate 	}
13230209230bSgjelinek 
13240209230bSgjelinek 	/*
13250209230bSgjelinek 	 * If we are creating a temporary pool configuration, flag the resource.
13260209230bSgjelinek 	 */
13270209230bSgjelinek 	if (conf->pc_prov->pc_oflags & PO_TEMP) {
13280209230bSgjelinek 		if (pool_set_temporary(conf, pe) != PO_SUCCESS) {
13290209230bSgjelinek 			(void) pool_resource_destroy(conf, pool_elem_res(pe));
13300209230bSgjelinek 			return (NULL);
13310209230bSgjelinek 		}
13320209230bSgjelinek 	}
13330209230bSgjelinek 
13347c478bd9Sstevel@tonic-gate 	return (pool_elem_res(pe));
13357c478bd9Sstevel@tonic-gate }
13367c478bd9Sstevel@tonic-gate 
13377c478bd9Sstevel@tonic-gate /*
13387c478bd9Sstevel@tonic-gate  * Create an element to represent a resource component.
13397c478bd9Sstevel@tonic-gate  */
13407c478bd9Sstevel@tonic-gate pool_component_t *
pool_component_create(pool_conf_t * conf,const pool_resource_t * res,int64_t sys_id)13417c478bd9Sstevel@tonic-gate pool_component_create(pool_conf_t *conf, const pool_resource_t *res,
13427c478bd9Sstevel@tonic-gate     int64_t sys_id)
13437c478bd9Sstevel@tonic-gate {
13447c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
13457c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
13467c478bd9Sstevel@tonic-gate 	const pool_prop_t *default_props;
13477c478bd9Sstevel@tonic-gate 	char refbuf[KEY_BUFFER_SIZE];
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate 	if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_COMP,
13507c478bd9Sstevel@tonic-gate 	    PREC_INVALID, PCEC_CPU)) == NULL) {
13517c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
13527c478bd9Sstevel@tonic-gate 		return (NULL);
13537c478bd9Sstevel@tonic-gate 	}
13547c478bd9Sstevel@tonic-gate 	/*
13557c478bd9Sstevel@tonic-gate 	 * TODO: If additional PEC_COMP types are added in pool_impl.h,
13567c478bd9Sstevel@tonic-gate 	 * this would need to be extended.
13577c478bd9Sstevel@tonic-gate 	 */
13587c478bd9Sstevel@tonic-gate 	pe->pe_component_class = PCEC_CPU;
13597c478bd9Sstevel@tonic-gate 	/* Now set the container for this comp */
13607c478bd9Sstevel@tonic-gate 	if (pool_set_container(TO_ELEM(res), pe) == PO_FAIL) {
13617c478bd9Sstevel@tonic-gate 		(void) pool_component_destroy(pool_elem_comp(pe));
13627c478bd9Sstevel@tonic-gate 		return (NULL);
13637c478bd9Sstevel@tonic-gate 	}
13647c478bd9Sstevel@tonic-gate 	/*
13657c478bd9Sstevel@tonic-gate 	 * The plugins contain a list of default properties and their values
13667c478bd9Sstevel@tonic-gate 	 * for resources. The resource returned, hence, is fully initialized.
13677c478bd9Sstevel@tonic-gate 	 */
13687c478bd9Sstevel@tonic-gate 	if ((default_props = provider_get_props(pe)) != NULL) {
13697c478bd9Sstevel@tonic-gate 		int i;
13707c478bd9Sstevel@tonic-gate 		for (i = 0; default_props[i].pp_pname != NULL; i++) {
13717c478bd9Sstevel@tonic-gate 			if (prop_is_init(&default_props[i]) &&
13727c478bd9Sstevel@tonic-gate 			    pool_put_any_property(pe,
13737c478bd9Sstevel@tonic-gate 			    default_props[i].pp_pname,
13747c478bd9Sstevel@tonic-gate 			    &default_props[i].pp_value) == PO_FAIL) {
13757c478bd9Sstevel@tonic-gate 				(void) pool_component_destroy(
13767c478bd9Sstevel@tonic-gate 				    pool_elem_comp(pe));
13777c478bd9Sstevel@tonic-gate 				return (NULL);
13787c478bd9Sstevel@tonic-gate 			}
13797c478bd9Sstevel@tonic-gate 		}
13807c478bd9Sstevel@tonic-gate 	}
13817c478bd9Sstevel@tonic-gate 	/*
13827c478bd9Sstevel@tonic-gate 	 * Set additional attributes/properties on component.
13837c478bd9Sstevel@tonic-gate 	 */
13847c478bd9Sstevel@tonic-gate 	pool_value_set_int64(&val, sys_id);
13857c478bd9Sstevel@tonic-gate 	if (pool_put_any_ns_property(pe, c_sys_prop, &val) != PO_SUCCESS) {
13867c478bd9Sstevel@tonic-gate 		(void) pool_component_destroy(pool_elem_comp(pe));
13877c478bd9Sstevel@tonic-gate 		return (NULL);
13887c478bd9Sstevel@tonic-gate 	}
13897c478bd9Sstevel@tonic-gate 	if (snprintf(refbuf, KEY_BUFFER_SIZE, "%s_%lld",
13907c478bd9Sstevel@tonic-gate 	    pool_elem_class_string(pe), sys_id) > KEY_BUFFER_SIZE) {
13917c478bd9Sstevel@tonic-gate 		(void) pool_component_destroy(pool_elem_comp(pe));
13927c478bd9Sstevel@tonic-gate 		return (NULL);
13937c478bd9Sstevel@tonic-gate 	}
13947c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(&val, refbuf) != PO_SUCCESS) {
13957c478bd9Sstevel@tonic-gate 		(void) pool_component_destroy(pool_elem_comp(pe));
13967c478bd9Sstevel@tonic-gate 		return (NULL);
13977c478bd9Sstevel@tonic-gate 	}
13987c478bd9Sstevel@tonic-gate 	if (pool_put_any_ns_property(pe, c_ref_id, &val) != PO_SUCCESS) {
13997c478bd9Sstevel@tonic-gate 		(void) pool_component_destroy(pool_elem_comp(pe));
14007c478bd9Sstevel@tonic-gate 		return (NULL);
14017c478bd9Sstevel@tonic-gate 	}
14027c478bd9Sstevel@tonic-gate 	return (pool_elem_comp(pe));
14037c478bd9Sstevel@tonic-gate }
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate /*
14067c478bd9Sstevel@tonic-gate  * Return the location of a configuration.
14077c478bd9Sstevel@tonic-gate  */
14087c478bd9Sstevel@tonic-gate const char *
pool_conf_location(const pool_conf_t * conf)14097c478bd9Sstevel@tonic-gate pool_conf_location(const pool_conf_t *conf)
14107c478bd9Sstevel@tonic-gate {
14117c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
14127c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
14137c478bd9Sstevel@tonic-gate 		return (NULL);
14147c478bd9Sstevel@tonic-gate 	}
14157c478bd9Sstevel@tonic-gate 	return (conf->pc_location);
14167c478bd9Sstevel@tonic-gate }
14177c478bd9Sstevel@tonic-gate /*
14187c478bd9Sstevel@tonic-gate  * Close a configuration, freeing all associated resources. Once a
14197c478bd9Sstevel@tonic-gate  * configuration is closed, it can no longer be used.
14207c478bd9Sstevel@tonic-gate  */
14217c478bd9Sstevel@tonic-gate int
pool_conf_close(pool_conf_t * conf)14227c478bd9Sstevel@tonic-gate pool_conf_close(pool_conf_t *conf)
14237c478bd9Sstevel@tonic-gate {
14247c478bd9Sstevel@tonic-gate 	int rv;
14257c478bd9Sstevel@tonic-gate 
14267c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
14277c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
14287c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
14297c478bd9Sstevel@tonic-gate 	}
14307c478bd9Sstevel@tonic-gate 	rv = conf->pc_prov->pc_close(conf);
14317c478bd9Sstevel@tonic-gate 	conf->pc_prov = NULL;
14327c478bd9Sstevel@tonic-gate 	free((void *)conf->pc_location);
14337c478bd9Sstevel@tonic-gate 	conf->pc_location = NULL;
14347c478bd9Sstevel@tonic-gate 	conf->pc_state = POF_INVALID;
14357c478bd9Sstevel@tonic-gate 	return (rv);
14367c478bd9Sstevel@tonic-gate }
14377c478bd9Sstevel@tonic-gate 
14387c478bd9Sstevel@tonic-gate /*
14397c478bd9Sstevel@tonic-gate  * Remove a configuration, freeing all associated resources. Once a
14407c478bd9Sstevel@tonic-gate  * configuration is removed, it can no longer be accessed and is forever
14417c478bd9Sstevel@tonic-gate  * gone.
14427c478bd9Sstevel@tonic-gate  */
14437c478bd9Sstevel@tonic-gate int
pool_conf_remove(pool_conf_t * conf)14447c478bd9Sstevel@tonic-gate pool_conf_remove(pool_conf_t *conf)
14457c478bd9Sstevel@tonic-gate {
14467c478bd9Sstevel@tonic-gate 	int rv;
14477c478bd9Sstevel@tonic-gate 
14487c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
14497c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
14507c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
14517c478bd9Sstevel@tonic-gate 	}
14527c478bd9Sstevel@tonic-gate 	rv = conf->pc_prov->pc_remove(conf);
14537c478bd9Sstevel@tonic-gate 	conf->pc_state = POF_INVALID;
14547c478bd9Sstevel@tonic-gate 	return (rv);
14557c478bd9Sstevel@tonic-gate }
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate /*
14587c478bd9Sstevel@tonic-gate  * pool_conf_alloc() allocate the resources to represent a configuration.
14597c478bd9Sstevel@tonic-gate  */
14607c478bd9Sstevel@tonic-gate pool_conf_t *
pool_conf_alloc(void)14617c478bd9Sstevel@tonic-gate pool_conf_alloc(void)
14627c478bd9Sstevel@tonic-gate {
14637c478bd9Sstevel@tonic-gate 	pool_conf_t *conf;
14647c478bd9Sstevel@tonic-gate 
14657c478bd9Sstevel@tonic-gate 	if ((conf = calloc(1, sizeof (pool_conf_t))) == NULL) {
14667c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
14677c478bd9Sstevel@tonic-gate 		return (NULL);
14687c478bd9Sstevel@tonic-gate 	}
14697c478bd9Sstevel@tonic-gate 	conf->pc_state = POF_INVALID;
14707c478bd9Sstevel@tonic-gate 	return (conf);
14717c478bd9Sstevel@tonic-gate }
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate /*
14747c478bd9Sstevel@tonic-gate  * pool_conf_free() frees the resources associated with a configuration.
14757c478bd9Sstevel@tonic-gate  */
14767c478bd9Sstevel@tonic-gate void
pool_conf_free(pool_conf_t * conf)14777c478bd9Sstevel@tonic-gate pool_conf_free(pool_conf_t *conf)
14787c478bd9Sstevel@tonic-gate {
14797c478bd9Sstevel@tonic-gate 	free(conf);
14807c478bd9Sstevel@tonic-gate }
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate /*
14837c478bd9Sstevel@tonic-gate  * pool_conf_open() opens a configuration, establishing all required
14847c478bd9Sstevel@tonic-gate  * connections to the data source.
14857c478bd9Sstevel@tonic-gate  */
14867c478bd9Sstevel@tonic-gate int
pool_conf_open(pool_conf_t * conf,const char * location,int oflags)14877c478bd9Sstevel@tonic-gate pool_conf_open(pool_conf_t *conf, const char *location, int oflags)
14887c478bd9Sstevel@tonic-gate {
14897c478bd9Sstevel@tonic-gate 	/*
14907c478bd9Sstevel@tonic-gate 	 * Since you can't do anything to a pool configuration without opening
14917c478bd9Sstevel@tonic-gate 	 * it, this represents a good point to intialise structures that would
14927c478bd9Sstevel@tonic-gate 	 * otherwise need to be initialised in a .init section.
14937c478bd9Sstevel@tonic-gate 	 */
14947c478bd9Sstevel@tonic-gate 	internal_init();
14957c478bd9Sstevel@tonic-gate 
14967c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) != POF_INVALID) {
14977c478bd9Sstevel@tonic-gate 		/*
14987c478bd9Sstevel@tonic-gate 		 * Already opened configuration, return PO_FAIL
14997c478bd9Sstevel@tonic-gate 		 */
15007c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
15017c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
15027c478bd9Sstevel@tonic-gate 	}
15030209230bSgjelinek 	if (oflags & ~(PO_RDONLY | PO_RDWR | PO_CREAT | PO_DISCO | PO_UPDATE |
15040209230bSgjelinek 	    PO_TEMP)) {
15057c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
15067c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
15077c478bd9Sstevel@tonic-gate 	}
15087c478bd9Sstevel@tonic-gate 
15097c478bd9Sstevel@tonic-gate 	/*
15107c478bd9Sstevel@tonic-gate 	 * Creating a configuration implies read-write access, so make
15117c478bd9Sstevel@tonic-gate 	 * sure that PO_RDWR is set in addition if PO_CREAT is set.
15127c478bd9Sstevel@tonic-gate 	 */
15137c478bd9Sstevel@tonic-gate 	if (oflags & PO_CREAT)
15147c478bd9Sstevel@tonic-gate 		oflags |= PO_RDWR;
15157c478bd9Sstevel@tonic-gate 
15160209230bSgjelinek 	/* location is ignored when creating a temporary configuration */
15170209230bSgjelinek 	if (oflags & PO_TEMP)
15180209230bSgjelinek 		location = "";
15190209230bSgjelinek 
15207c478bd9Sstevel@tonic-gate 	if ((conf->pc_location = strdup(location)) == NULL) {
15217c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
15227c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
15237c478bd9Sstevel@tonic-gate 	}
15247c478bd9Sstevel@tonic-gate 	/*
15257c478bd9Sstevel@tonic-gate 	 * This is the crossover point into the actual data provider
15267c478bd9Sstevel@tonic-gate 	 * implementation, allocate a data provider of the appropriate
15270209230bSgjelinek 	 * type for your data storage medium. In this case it's either a kernel
15280209230bSgjelinek 	 * or xml data provider. To use a different data provider, write some
15290209230bSgjelinek 	 * code to implement all the required interfaces and then change the
15300209230bSgjelinek 	 * following code to allocate a data provider which uses your new code.
15310209230bSgjelinek 	 * All data provider routines can be static, apart from the allocation
15320209230bSgjelinek 	 * routine.
15330209230bSgjelinek 	 *
15340209230bSgjelinek 	 * For temporary pools (PO_TEMP) we start with a copy of the current
15350209230bSgjelinek 	 * dynamic configuration and do all of the updates in-memory.
15367c478bd9Sstevel@tonic-gate 	 */
15370209230bSgjelinek 	if (oflags & PO_TEMP) {
15380209230bSgjelinek 		if (pool_knl_connection_alloc(conf, PO_TEMP) != PO_SUCCESS) {
15390209230bSgjelinek 			conf->pc_state = POF_INVALID;
15400209230bSgjelinek 			return (PO_FAIL);
15410209230bSgjelinek 		}
15420209230bSgjelinek 		/* set rdwr flag so we can updated the in-memory config. */
15430209230bSgjelinek 		conf->pc_prov->pc_oflags |= PO_RDWR;
15440209230bSgjelinek 
15450209230bSgjelinek 	} else if (strcmp(location, pool_dynamic_location()) == 0) {
15467c478bd9Sstevel@tonic-gate 		if (pool_knl_connection_alloc(conf, oflags) != PO_SUCCESS) {
15477c478bd9Sstevel@tonic-gate 			conf->pc_state = POF_INVALID;
15487c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
15497c478bd9Sstevel@tonic-gate 		}
15507c478bd9Sstevel@tonic-gate 	} else {
15517c478bd9Sstevel@tonic-gate 		if (pool_xml_connection_alloc(conf, oflags) != PO_SUCCESS) {
15527c478bd9Sstevel@tonic-gate 			conf->pc_state = POF_INVALID;
15537c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
15547c478bd9Sstevel@tonic-gate 		}
15557c478bd9Sstevel@tonic-gate 	}
15567c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
15577c478bd9Sstevel@tonic-gate }
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate /*
15607c478bd9Sstevel@tonic-gate  * Rollback a configuration. This will undo all changes to the configuration
15617c478bd9Sstevel@tonic-gate  * since the last time pool_conf_commit was called.
15627c478bd9Sstevel@tonic-gate  */
15637c478bd9Sstevel@tonic-gate int
pool_conf_rollback(pool_conf_t * conf)15647c478bd9Sstevel@tonic-gate pool_conf_rollback(pool_conf_t *conf)
15657c478bd9Sstevel@tonic-gate {
15667c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
15677c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
15687c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
15697c478bd9Sstevel@tonic-gate 	}
15707c478bd9Sstevel@tonic-gate 	return (conf->pc_prov->pc_rollback(conf));
15717c478bd9Sstevel@tonic-gate }
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate /*
15747c478bd9Sstevel@tonic-gate  * Commit a configuration. This will apply all changes to the
15757c478bd9Sstevel@tonic-gate  * configuration to the permanent data store. The active parameter
15767c478bd9Sstevel@tonic-gate  * indicates whether the configuration should be used to update the
15777c478bd9Sstevel@tonic-gate  * dynamic configuration from the supplied (static) configuration or
15787c478bd9Sstevel@tonic-gate  * whether it should be written back to persistent store.
15797c478bd9Sstevel@tonic-gate  */
15807c478bd9Sstevel@tonic-gate int
pool_conf_commit(pool_conf_t * conf,int active)15817c478bd9Sstevel@tonic-gate pool_conf_commit(pool_conf_t *conf, int active)
15827c478bd9Sstevel@tonic-gate {
15837c478bd9Sstevel@tonic-gate 	int retval;
15847c478bd9Sstevel@tonic-gate 
15857c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
15867c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
15877c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
15887c478bd9Sstevel@tonic-gate 	}
15897c478bd9Sstevel@tonic-gate 	if (active) {
15907c478bd9Sstevel@tonic-gate 		int oflags;
15917c478bd9Sstevel@tonic-gate 
15927c478bd9Sstevel@tonic-gate 		if (conf_is_dynamic(conf) == PO_TRUE) {
15937c478bd9Sstevel@tonic-gate 			pool_seterror(POE_BADPARAM);
15947c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
15957c478bd9Sstevel@tonic-gate 		}
15967c478bd9Sstevel@tonic-gate 		/*
15977c478bd9Sstevel@tonic-gate 		 * Pretend that the configuration was opened PO_RDWR
15987c478bd9Sstevel@tonic-gate 		 * so that a configuration which was opened PO_RDONLY
15997c478bd9Sstevel@tonic-gate 		 * can be committed. The original flags are preserved
16007c478bd9Sstevel@tonic-gate 		 * in oflags and restored after pool_conf_commit_sys()
16017c478bd9Sstevel@tonic-gate 		 * returns.
16027c478bd9Sstevel@tonic-gate 		 */
16037c478bd9Sstevel@tonic-gate 		oflags = conf->pc_prov->pc_oflags;
16047c478bd9Sstevel@tonic-gate 		conf->pc_prov->pc_oflags |= PO_RDWR;
16057c478bd9Sstevel@tonic-gate 		retval = pool_conf_commit_sys(conf, active);
16067c478bd9Sstevel@tonic-gate 		conf->pc_prov->pc_oflags = oflags;
16077c478bd9Sstevel@tonic-gate 	} else {
16087c478bd9Sstevel@tonic-gate 		/*
16097c478bd9Sstevel@tonic-gate 		 * Write the configuration back to the backing store.
16107c478bd9Sstevel@tonic-gate 		 */
16117c478bd9Sstevel@tonic-gate 		retval =  conf->pc_prov->pc_commit(conf);
16127c478bd9Sstevel@tonic-gate 	}
16137c478bd9Sstevel@tonic-gate 	return (retval);
16147c478bd9Sstevel@tonic-gate }
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate /*
16177c478bd9Sstevel@tonic-gate  * Export a configuration. This will export a configuration in the specified
16187c478bd9Sstevel@tonic-gate  * format (fmt) to the specified location.
16197c478bd9Sstevel@tonic-gate  */
16207c478bd9Sstevel@tonic-gate int
pool_conf_export(const pool_conf_t * conf,const char * location,pool_export_format_t fmt)16217c478bd9Sstevel@tonic-gate pool_conf_export(const pool_conf_t *conf, const char *location,
16227c478bd9Sstevel@tonic-gate     pool_export_format_t fmt)
16237c478bd9Sstevel@tonic-gate {
16247c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
16257c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
16267c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
16277c478bd9Sstevel@tonic-gate 	}
16287c478bd9Sstevel@tonic-gate 	return (conf->pc_prov->pc_export(conf, location, fmt));
16297c478bd9Sstevel@tonic-gate }
16307c478bd9Sstevel@tonic-gate 
16317c478bd9Sstevel@tonic-gate /*
16327c478bd9Sstevel@tonic-gate  * Validate a configuration. This will validate a configuration at the
16337c478bd9Sstevel@tonic-gate  * specified level.
16347c478bd9Sstevel@tonic-gate  */
16357c478bd9Sstevel@tonic-gate int
pool_conf_validate(const pool_conf_t * conf,pool_valid_level_t level)16367c478bd9Sstevel@tonic-gate pool_conf_validate(const pool_conf_t *conf, pool_valid_level_t level)
16377c478bd9Sstevel@tonic-gate {
16387c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
16397c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
16407c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
16417c478bd9Sstevel@tonic-gate 	}
16427c478bd9Sstevel@tonic-gate 	return (conf->pc_prov->pc_validate(conf, level));
16437c478bd9Sstevel@tonic-gate }
16447c478bd9Sstevel@tonic-gate 
16457c478bd9Sstevel@tonic-gate /*
16467c478bd9Sstevel@tonic-gate  * Update the snapshot of a configuration. This can only be used on a
16477c478bd9Sstevel@tonic-gate  * dynamic configuration.
16487c478bd9Sstevel@tonic-gate  */
16497c478bd9Sstevel@tonic-gate int
pool_conf_update(const pool_conf_t * conf,int * changed)16507c478bd9Sstevel@tonic-gate pool_conf_update(const pool_conf_t *conf, int *changed)
16517c478bd9Sstevel@tonic-gate {
16527c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID ||
16537c478bd9Sstevel@tonic-gate 	    conf_is_dynamic(conf) == PO_FALSE) {
16547c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
16557c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
16567c478bd9Sstevel@tonic-gate 	}
16577c478bd9Sstevel@tonic-gate 	/*
16587c478bd9Sstevel@tonic-gate 	 * Since this function only makes sense for dynamic
16597c478bd9Sstevel@tonic-gate 	 * configurations, just call directly into the appropriate
16607c478bd9Sstevel@tonic-gate 	 * function. This could be added into the pool_connection_t
16617c478bd9Sstevel@tonic-gate 	 * interface if it was ever required.
16627c478bd9Sstevel@tonic-gate 	 */
16637c478bd9Sstevel@tonic-gate 	if (changed)
16647c478bd9Sstevel@tonic-gate 		*changed = 0;
16657c478bd9Sstevel@tonic-gate 	return (pool_knl_update((pool_conf_t *)conf, changed));
16667c478bd9Sstevel@tonic-gate }
16677c478bd9Sstevel@tonic-gate 
16687c478bd9Sstevel@tonic-gate /*
16697c478bd9Sstevel@tonic-gate  * Walk the properties of the supplied elem, calling the user supplied
16707c478bd9Sstevel@tonic-gate  * function repeatedly as long as the user function returns
16717c478bd9Sstevel@tonic-gate  * PO_SUCCESS.
16727c478bd9Sstevel@tonic-gate  */
16737c478bd9Sstevel@tonic-gate int
pool_walk_properties(pool_conf_t * conf,pool_elem_t * elem,void * arg,int (* prop_callback)(pool_conf_t *,pool_elem_t *,const char *,pool_value_t *,void *))16747c478bd9Sstevel@tonic-gate pool_walk_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg,
16757c478bd9Sstevel@tonic-gate     int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *,
16767c478bd9Sstevel@tonic-gate 	pool_value_t *, void *))
16777c478bd9Sstevel@tonic-gate {
16787c478bd9Sstevel@tonic-gate 	return (pool_walk_any_properties(conf, elem, arg, prop_callback, 0));
16797c478bd9Sstevel@tonic-gate }
16807c478bd9Sstevel@tonic-gate 
16817c478bd9Sstevel@tonic-gate void
free_value_list(int npvals,pool_value_t ** pvals)16827c478bd9Sstevel@tonic-gate free_value_list(int npvals, pool_value_t **pvals)
16837c478bd9Sstevel@tonic-gate {
16847c478bd9Sstevel@tonic-gate 	int j;
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 	for (j = 0; j < npvals; j++) {
16877c478bd9Sstevel@tonic-gate 		if (pvals[j])
16887c478bd9Sstevel@tonic-gate 			pool_value_free(pvals[j]);
16897c478bd9Sstevel@tonic-gate 	}
16907c478bd9Sstevel@tonic-gate 	free(pvals);
16917c478bd9Sstevel@tonic-gate }
16927c478bd9Sstevel@tonic-gate 
16937c478bd9Sstevel@tonic-gate /*
16947c478bd9Sstevel@tonic-gate  * Walk the properties of the supplied elem, calling the user supplied
16957c478bd9Sstevel@tonic-gate  * function repeatedly as long as the user function returns
16967c478bd9Sstevel@tonic-gate  * PO_SUCCESS.
16977c478bd9Sstevel@tonic-gate  * The list of properties to be walked is retrieved from the element
16987c478bd9Sstevel@tonic-gate  */
16997c478bd9Sstevel@tonic-gate int
pool_walk_any_properties(pool_conf_t * conf,pool_elem_t * elem,void * arg,int (* prop_callback)(pool_conf_t *,pool_elem_t *,const char *,pool_value_t *,void *),int any)17007c478bd9Sstevel@tonic-gate pool_walk_any_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg,
17017c478bd9Sstevel@tonic-gate     int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *,
17027c478bd9Sstevel@tonic-gate 	pool_value_t *, void *), int any)
17037c478bd9Sstevel@tonic-gate {
17047c478bd9Sstevel@tonic-gate 	pool_value_t **pvals;
17057c478bd9Sstevel@tonic-gate 	int i;
17067c478bd9Sstevel@tonic-gate 	const pool_prop_t *props = provider_get_props(elem);
17077c478bd9Sstevel@tonic-gate 	uint_t npvals;
17087c478bd9Sstevel@tonic-gate 
17097c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
17107c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
17117c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
17127c478bd9Sstevel@tonic-gate 	}
17137c478bd9Sstevel@tonic-gate 
17147c478bd9Sstevel@tonic-gate 	if (props == NULL) {
17157c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
17167c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
17177c478bd9Sstevel@tonic-gate 	}
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 	if ((pvals = elem->pe_get_props(elem, &npvals)) == NULL)
17207c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate 	/*
17237c478bd9Sstevel@tonic-gate 	 * Now walk the managed properties. As we find managed
17247c478bd9Sstevel@tonic-gate 	 * properties removed them from the list of all properties to
17257c478bd9Sstevel@tonic-gate 	 * prevent duplication.
17267c478bd9Sstevel@tonic-gate 	 */
17277c478bd9Sstevel@tonic-gate 	for (i = 0;  props[i].pp_pname != NULL; i++) {
17287c478bd9Sstevel@tonic-gate 		int j;
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate 		/*
17317c478bd9Sstevel@tonic-gate 		 * Special processing for type
17327c478bd9Sstevel@tonic-gate 		 */
17337c478bd9Sstevel@tonic-gate 		if (strcmp(props[i].pp_pname, c_type) == 0) {
17347c478bd9Sstevel@tonic-gate 			pool_value_t val = POOL_VALUE_INITIALIZER;
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate 			if (pool_value_set_name(&val, props[i].pp_pname) ==
17377c478bd9Sstevel@tonic-gate 			    PO_FAIL) {
17387c478bd9Sstevel@tonic-gate 				free_value_list(npvals, pvals);
17397c478bd9Sstevel@tonic-gate 				return (PO_FAIL);
17407c478bd9Sstevel@tonic-gate 			}
17417c478bd9Sstevel@tonic-gate 			if (props[i].pp_op.ppo_get_value(elem, &val) ==
17427c478bd9Sstevel@tonic-gate 			    PO_FAIL) {
17437c478bd9Sstevel@tonic-gate 				free_value_list(npvals, pvals);
17447c478bd9Sstevel@tonic-gate 				return (PO_FAIL);
17457c478bd9Sstevel@tonic-gate 			}
17467c478bd9Sstevel@tonic-gate 			if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) {
17477c478bd9Sstevel@tonic-gate 				if (prop_callback(conf, elem, props[i].pp_pname,
17487c478bd9Sstevel@tonic-gate 				    &val, arg) != PO_SUCCESS) {
17497c478bd9Sstevel@tonic-gate 					free_value_list(npvals, pvals);
17507c478bd9Sstevel@tonic-gate 					pool_seterror(POE_BADPARAM);
17517c478bd9Sstevel@tonic-gate 					return (PO_FAIL);
17527c478bd9Sstevel@tonic-gate 				}
17537c478bd9Sstevel@tonic-gate 			}
17547c478bd9Sstevel@tonic-gate 			continue;
17557c478bd9Sstevel@tonic-gate 		}
17567c478bd9Sstevel@tonic-gate 
17577c478bd9Sstevel@tonic-gate 		for (j = 0; j < npvals; j++) {
17587c478bd9Sstevel@tonic-gate 			if (pvals[j] && strcmp(pool_value_get_name(pvals[j]),
17597c478bd9Sstevel@tonic-gate 			    props[i].pp_pname) == 0)
17607c478bd9Sstevel@tonic-gate 				break;
17617c478bd9Sstevel@tonic-gate 		}
17627c478bd9Sstevel@tonic-gate 		/*
17637c478bd9Sstevel@tonic-gate 		 * If we have found the property, then j < npvals. Process it
17647c478bd9Sstevel@tonic-gate 		 * according to our property attributes. Otherwise, it's not
17657c478bd9Sstevel@tonic-gate 		 * a managed property, so just ignore it until later.
17667c478bd9Sstevel@tonic-gate 		 */
17677c478bd9Sstevel@tonic-gate 		if (j < npvals) {
17687c478bd9Sstevel@tonic-gate 			if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) {
17697c478bd9Sstevel@tonic-gate 				if (props[i].pp_op.ppo_get_value) {
17707c478bd9Sstevel@tonic-gate 					if (pool_value_set_name(pvals[j],
17717c478bd9Sstevel@tonic-gate 					props[i].pp_pname) == PO_FAIL) {
17727c478bd9Sstevel@tonic-gate 						free_value_list(npvals, pvals);
17737c478bd9Sstevel@tonic-gate 						return (PO_FAIL);
17747c478bd9Sstevel@tonic-gate 					}
17757c478bd9Sstevel@tonic-gate 					if (props[i].pp_op.ppo_get_value(elem,
17767c478bd9Sstevel@tonic-gate 					    pvals[j]) == PO_FAIL) {
17777c478bd9Sstevel@tonic-gate 						free_value_list(npvals, pvals);
17787c478bd9Sstevel@tonic-gate 						return (PO_FAIL);
17797c478bd9Sstevel@tonic-gate 					}
17807c478bd9Sstevel@tonic-gate 				}
17817c478bd9Sstevel@tonic-gate 				if (prop_callback(conf, elem, props[i].pp_pname,
17827c478bd9Sstevel@tonic-gate 				    pvals[j], arg) != PO_SUCCESS) {
17837c478bd9Sstevel@tonic-gate 					free_value_list(npvals, pvals);
17847c478bd9Sstevel@tonic-gate 					pool_seterror(POE_BADPARAM);
17857c478bd9Sstevel@tonic-gate 					return (PO_FAIL);
17867c478bd9Sstevel@tonic-gate 				}
17877c478bd9Sstevel@tonic-gate 			}
17887c478bd9Sstevel@tonic-gate 			pool_value_free(pvals[j]);
17897c478bd9Sstevel@tonic-gate 			pvals[j] = NULL;
17907c478bd9Sstevel@tonic-gate 		}
17917c478bd9Sstevel@tonic-gate 	}
17927c478bd9Sstevel@tonic-gate 	for (i = 0;  i < npvals; i++) {
17937c478bd9Sstevel@tonic-gate 		if (pvals[i]) {
17947c478bd9Sstevel@tonic-gate 			const char *name = pool_value_get_name(pvals[i]);
17957c478bd9Sstevel@tonic-gate 			char *qname = strrchr(name, '.');
17967c478bd9Sstevel@tonic-gate 			if ((qname && qname[1] != '_') ||
17977c478bd9Sstevel@tonic-gate 			    (!qname && name[0] != '_')) {
17987c478bd9Sstevel@tonic-gate 				if (prop_callback(conf, elem, name, pvals[i],
17997c478bd9Sstevel@tonic-gate 				    arg) != PO_SUCCESS) {
18007c478bd9Sstevel@tonic-gate 					free_value_list(npvals, pvals);
18017c478bd9Sstevel@tonic-gate 					pool_seterror(POE_BADPARAM);
18027c478bd9Sstevel@tonic-gate 					return (PO_FAIL);
18037c478bd9Sstevel@tonic-gate 				}
18047c478bd9Sstevel@tonic-gate 			}
18057c478bd9Sstevel@tonic-gate 			pool_value_free(pvals[i]);
18067c478bd9Sstevel@tonic-gate 			pvals[i] = NULL;
18077c478bd9Sstevel@tonic-gate 		}
18087c478bd9Sstevel@tonic-gate 	}
18097c478bd9Sstevel@tonic-gate 	free(pvals);
18107c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
18117c478bd9Sstevel@tonic-gate }
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate /*
18147c478bd9Sstevel@tonic-gate  * Return a pool, searching the supplied configuration for a pool with the
18157c478bd9Sstevel@tonic-gate  * supplied name. The search is case sensitive.
18167c478bd9Sstevel@tonic-gate  */
18177c478bd9Sstevel@tonic-gate pool_t *
pool_get_pool(const pool_conf_t * conf,const char * name)18187c478bd9Sstevel@tonic-gate pool_get_pool(const pool_conf_t *conf, const char *name)
18197c478bd9Sstevel@tonic-gate {
18207c478bd9Sstevel@tonic-gate 	pool_value_t *props[] = { NULL, NULL };
18217c478bd9Sstevel@tonic-gate 	pool_t **rs;
18227c478bd9Sstevel@tonic-gate 	pool_t *ret;
18237c478bd9Sstevel@tonic-gate 	uint_t size = 0;
18247c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate 	props[0] = &val;
18277c478bd9Sstevel@tonic-gate 
18287c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
18297c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
18307c478bd9Sstevel@tonic-gate 		return (NULL);
18317c478bd9Sstevel@tonic-gate 	}
18327c478bd9Sstevel@tonic-gate 
18337c478bd9Sstevel@tonic-gate 	if (pool_value_set_name(props[0], "pool.name") != PO_SUCCESS ||
18347c478bd9Sstevel@tonic-gate 	    pool_value_set_string(props[0], name) != PO_SUCCESS) {
18357c478bd9Sstevel@tonic-gate 		return (NULL);
18367c478bd9Sstevel@tonic-gate 	}
18377c478bd9Sstevel@tonic-gate 	rs = pool_query_pools(conf, &size, props);
18387c478bd9Sstevel@tonic-gate 	if (rs == NULL) { /* Can't find a pool to match the name */
18397c478bd9Sstevel@tonic-gate 		return (NULL);
18407c478bd9Sstevel@tonic-gate 	}
18417c478bd9Sstevel@tonic-gate 	if (size != 1) {
18427c478bd9Sstevel@tonic-gate 		free(rs);
18437c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
18447c478bd9Sstevel@tonic-gate 		return (NULL);
18457c478bd9Sstevel@tonic-gate 	}
18467c478bd9Sstevel@tonic-gate 	ret = rs[0];
18477c478bd9Sstevel@tonic-gate 	free(rs);
18487c478bd9Sstevel@tonic-gate 	return (ret);
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate /*
18527c478bd9Sstevel@tonic-gate  * Return a result set of pools, searching the supplied configuration
18537c478bd9Sstevel@tonic-gate  * for pools which match the supplied property criteria. props is a null
18547c478bd9Sstevel@tonic-gate  * terminated list of properties which will be used to match qualifying
18557c478bd9Sstevel@tonic-gate  * pools. size is updated with the size of the pool
18567c478bd9Sstevel@tonic-gate  */
18577c478bd9Sstevel@tonic-gate pool_t **
pool_query_pools(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)18587c478bd9Sstevel@tonic-gate pool_query_pools(const pool_conf_t *conf, uint_t *size, pool_value_t **props)
18597c478bd9Sstevel@tonic-gate {
18607c478bd9Sstevel@tonic-gate 	pool_result_set_t *rs;
18617c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
18627c478bd9Sstevel@tonic-gate 	pool_t **result = NULL;
18637c478bd9Sstevel@tonic-gate 	int i = 0;
18647c478bd9Sstevel@tonic-gate 
18657c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
18667c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
18677c478bd9Sstevel@tonic-gate 		return (NULL);
18687c478bd9Sstevel@tonic-gate 	}
18697c478bd9Sstevel@tonic-gate 	rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_POOL, props);
18707c478bd9Sstevel@tonic-gate 	if (rs == NULL) {
18717c478bd9Sstevel@tonic-gate 		return (NULL);
18727c478bd9Sstevel@tonic-gate 	}
18737c478bd9Sstevel@tonic-gate 	if ((*size = pool_rs_count(rs)) == 0) {
18747c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
18757c478bd9Sstevel@tonic-gate 		return (NULL);
18767c478bd9Sstevel@tonic-gate 	}
18777c478bd9Sstevel@tonic-gate 	if ((result = malloc(sizeof (pool_t *) * (*size + 1))) == NULL) {
18787c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
18797c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
18807c478bd9Sstevel@tonic-gate 		return (NULL);
18817c478bd9Sstevel@tonic-gate 	}
18827c478bd9Sstevel@tonic-gate 	(void) memset(result, 0, sizeof (pool_t *) * (*size + 1));
18837c478bd9Sstevel@tonic-gate 	for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
18847c478bd9Sstevel@tonic-gate 		if (pool_elem_class(pe) != PEC_POOL) {
18857c478bd9Sstevel@tonic-gate 			pool_seterror(POE_INVALID_CONF);
18867c478bd9Sstevel@tonic-gate 			free(result);
18877c478bd9Sstevel@tonic-gate 			(void) pool_rs_close(rs);
18887c478bd9Sstevel@tonic-gate 			return (NULL);
18897c478bd9Sstevel@tonic-gate 		}
18907c478bd9Sstevel@tonic-gate 		result[i++] = pool_elem_pool(pe);
18917c478bd9Sstevel@tonic-gate 	}
18927c478bd9Sstevel@tonic-gate 	(void) pool_rs_close(rs);
18937c478bd9Sstevel@tonic-gate 	return (result);
18947c478bd9Sstevel@tonic-gate }
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate /*
18977c478bd9Sstevel@tonic-gate  * Return an res, searching the supplied configuration for an res with the
18987c478bd9Sstevel@tonic-gate  * supplied name. The search is case sensitive.
18997c478bd9Sstevel@tonic-gate  */
19007c478bd9Sstevel@tonic-gate pool_resource_t *
pool_get_resource(const pool_conf_t * conf,const char * sz_type,const char * name)19017c478bd9Sstevel@tonic-gate pool_get_resource(const pool_conf_t *conf, const char *sz_type,
19027c478bd9Sstevel@tonic-gate     const char *name)
19037c478bd9Sstevel@tonic-gate {
19047c478bd9Sstevel@tonic-gate 	pool_value_t *props[] = { NULL, NULL, NULL };
19057c478bd9Sstevel@tonic-gate 	pool_resource_t **rs;
19067c478bd9Sstevel@tonic-gate 	pool_resource_t *ret;
19077c478bd9Sstevel@tonic-gate 	uint_t size = 0;
19087c478bd9Sstevel@tonic-gate 	char_buf_t *cb = NULL;
19097c478bd9Sstevel@tonic-gate 	pool_value_t val0 = POOL_VALUE_INITIALIZER;
19107c478bd9Sstevel@tonic-gate 	pool_value_t val1 = POOL_VALUE_INITIALIZER;
19117c478bd9Sstevel@tonic-gate 
19127c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
19137c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
19147c478bd9Sstevel@tonic-gate 		return (NULL);
19157c478bd9Sstevel@tonic-gate 	}
19167c478bd9Sstevel@tonic-gate 
19177c478bd9Sstevel@tonic-gate 	if (sz_type == NULL) {
19187c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
19197c478bd9Sstevel@tonic-gate 		return (NULL);
19207c478bd9Sstevel@tonic-gate 	}
19217c478bd9Sstevel@tonic-gate 
19227c478bd9Sstevel@tonic-gate 	props[0] = &val0;
19237c478bd9Sstevel@tonic-gate 	props[1] = &val1;
19247c478bd9Sstevel@tonic-gate 
19257c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS ||
19267c478bd9Sstevel@tonic-gate 	    pool_value_set_name(props[0], c_type) != PO_SUCCESS)
19277c478bd9Sstevel@tonic-gate 		return (NULL);
19287c478bd9Sstevel@tonic-gate 
19297c478bd9Sstevel@tonic-gate 	if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) {
19307c478bd9Sstevel@tonic-gate 		return (NULL);
19317c478bd9Sstevel@tonic-gate 	}
19327c478bd9Sstevel@tonic-gate 	if (set_char_buf(cb, "%s.name", sz_type) != PO_SUCCESS) {
19337c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
19347c478bd9Sstevel@tonic-gate 		return (NULL);
19357c478bd9Sstevel@tonic-gate 	}
19367c478bd9Sstevel@tonic-gate 	if (pool_value_set_name(props[1], cb->cb_buf) != PO_SUCCESS) {
19377c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
19387c478bd9Sstevel@tonic-gate 		return (NULL);
19397c478bd9Sstevel@tonic-gate 	}
19407c478bd9Sstevel@tonic-gate 	if (pool_value_set_string(props[1], name) != PO_SUCCESS) {
19417c478bd9Sstevel@tonic-gate 		free_char_buf(cb);
19427c478bd9Sstevel@tonic-gate 		return (NULL);
19437c478bd9Sstevel@tonic-gate 	}
19447c478bd9Sstevel@tonic-gate 	free_char_buf(cb);
19457c478bd9Sstevel@tonic-gate 	rs = pool_query_resources(conf, &size, props);
19467c478bd9Sstevel@tonic-gate 	if (rs == NULL) {
19477c478bd9Sstevel@tonic-gate 		return (NULL);
19487c478bd9Sstevel@tonic-gate 	}
19497c478bd9Sstevel@tonic-gate 	if (size != 1) {
19507c478bd9Sstevel@tonic-gate 		free(rs);
19517c478bd9Sstevel@tonic-gate 		pool_seterror(POE_INVALID_CONF);
19527c478bd9Sstevel@tonic-gate 		return (NULL);
19537c478bd9Sstevel@tonic-gate 	}
19547c478bd9Sstevel@tonic-gate 	ret = rs[0];
19557c478bd9Sstevel@tonic-gate 	free(rs);
19567c478bd9Sstevel@tonic-gate 	return (ret);
19577c478bd9Sstevel@tonic-gate }
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate /*
19607c478bd9Sstevel@tonic-gate  * Return a result set of res (actually as pool_elem_ts), searching the
19617c478bd9Sstevel@tonic-gate  * supplied configuration for res which match the supplied property
19627c478bd9Sstevel@tonic-gate  * criteria. props is a null terminated list of properties which will be used
19637c478bd9Sstevel@tonic-gate  * to match qualifying res.
19647c478bd9Sstevel@tonic-gate  */
19657c478bd9Sstevel@tonic-gate pool_resource_t **
pool_query_resources(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)19667c478bd9Sstevel@tonic-gate pool_query_resources(const pool_conf_t *conf, uint_t *size,
19677c478bd9Sstevel@tonic-gate     pool_value_t **props)
19687c478bd9Sstevel@tonic-gate {
19697c478bd9Sstevel@tonic-gate 	pool_result_set_t *rs;
19707c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
19717c478bd9Sstevel@tonic-gate 	pool_resource_t **result = NULL;
19727c478bd9Sstevel@tonic-gate 	int i = 0;
19737c478bd9Sstevel@tonic-gate 
19747c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
19757c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
19767c478bd9Sstevel@tonic-gate 		return (NULL);
19777c478bd9Sstevel@tonic-gate 	}
19787c478bd9Sstevel@tonic-gate 
19797c478bd9Sstevel@tonic-gate 	*size = 0;
19807c478bd9Sstevel@tonic-gate 
19817c478bd9Sstevel@tonic-gate 	rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_RES, props);
19827c478bd9Sstevel@tonic-gate 	if (rs == NULL) {
19837c478bd9Sstevel@tonic-gate 		return (NULL);
19847c478bd9Sstevel@tonic-gate 	}
19857c478bd9Sstevel@tonic-gate 	if ((*size = pool_rs_count(rs)) == 0) {
19867c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
19877c478bd9Sstevel@tonic-gate 		return (NULL);
19887c478bd9Sstevel@tonic-gate 	}
19897c478bd9Sstevel@tonic-gate 	if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1)))
19907c478bd9Sstevel@tonic-gate 	    == NULL) {
19917c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
19927c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
19937c478bd9Sstevel@tonic-gate 		return (NULL);
19947c478bd9Sstevel@tonic-gate 	}
19957c478bd9Sstevel@tonic-gate 	(void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1));
19967c478bd9Sstevel@tonic-gate 	for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
19977c478bd9Sstevel@tonic-gate 		if (pool_elem_class(pe) != PEC_RES_COMP &&
19987c478bd9Sstevel@tonic-gate 		    pool_elem_class(pe) != PEC_RES_AGG) {
19997c478bd9Sstevel@tonic-gate 			pool_seterror(POE_INVALID_CONF);
20007c478bd9Sstevel@tonic-gate 			free(result);
20017c478bd9Sstevel@tonic-gate 			(void) pool_rs_close(rs);
20027c478bd9Sstevel@tonic-gate 			return (NULL);
20037c478bd9Sstevel@tonic-gate 		}
20047c478bd9Sstevel@tonic-gate 		result[i++] = pool_elem_res(pe);
20057c478bd9Sstevel@tonic-gate 	}
20067c478bd9Sstevel@tonic-gate 	(void) pool_rs_close(rs);
20077c478bd9Sstevel@tonic-gate 	return (result);
20087c478bd9Sstevel@tonic-gate }
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate /*
20117c478bd9Sstevel@tonic-gate  * Return a result set of comp (actually as pool_elem_ts), searching the
20127c478bd9Sstevel@tonic-gate  * supplied configuration for comp which match the supplied property
20137c478bd9Sstevel@tonic-gate  * criteria. props is a null terminated list of properties which will be used
20147c478bd9Sstevel@tonic-gate  * to match qualifying comp.
20157c478bd9Sstevel@tonic-gate  */
20167c478bd9Sstevel@tonic-gate pool_component_t **
pool_query_components(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)20177c478bd9Sstevel@tonic-gate pool_query_components(const pool_conf_t *conf, uint_t *size,
20187c478bd9Sstevel@tonic-gate     pool_value_t **props)
20197c478bd9Sstevel@tonic-gate {
20207c478bd9Sstevel@tonic-gate 	return (pool_query_resource_components(conf, NULL, size, props));
20217c478bd9Sstevel@tonic-gate }
20227c478bd9Sstevel@tonic-gate 
20237c478bd9Sstevel@tonic-gate /*
20247c478bd9Sstevel@tonic-gate  * Destroy a pool. If the pool cannot be found or removed an error is
20257c478bd9Sstevel@tonic-gate  * returned. This is basically a wrapper around pool_elem_remove to ensure
20267c478bd9Sstevel@tonic-gate  * some type safety for the pool subtype.
20277c478bd9Sstevel@tonic-gate  */
20287c478bd9Sstevel@tonic-gate int
pool_destroy(pool_conf_t * conf,pool_t * pp)20297c478bd9Sstevel@tonic-gate pool_destroy(pool_conf_t *conf, pool_t *pp)
20307c478bd9Sstevel@tonic-gate {
20317c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
20327c478bd9Sstevel@tonic-gate 
20337c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
20347c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
20357c478bd9Sstevel@tonic-gate 
20367c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(pp);
20377c478bd9Sstevel@tonic-gate 
20387c478bd9Sstevel@tonic-gate 	/*
20397c478bd9Sstevel@tonic-gate 	 * Cannot destroy the default pool.
20407c478bd9Sstevel@tonic-gate 	 */
20417c478bd9Sstevel@tonic-gate 	if (elem_is_default(pe) == PO_TRUE) {
20427c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
20437c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
20447c478bd9Sstevel@tonic-gate 	}
20457c478bd9Sstevel@tonic-gate 	if (pool_elem_remove(pe) != PO_SUCCESS)
20467c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
20477c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
20487c478bd9Sstevel@tonic-gate }
20497c478bd9Sstevel@tonic-gate 
20507c478bd9Sstevel@tonic-gate /*
20517c478bd9Sstevel@tonic-gate  * Destroy an res. If the res cannot be found or removed an error is
20527c478bd9Sstevel@tonic-gate  * returned. This is basically a wrapper around pool_elem_remove to ensure
20537c478bd9Sstevel@tonic-gate  * some type safety for the res subtype.
20547c478bd9Sstevel@tonic-gate  */
20557c478bd9Sstevel@tonic-gate int
pool_resource_destroy(pool_conf_t * conf,pool_resource_t * prs)20567c478bd9Sstevel@tonic-gate pool_resource_destroy(pool_conf_t *conf, pool_resource_t *prs)
20577c478bd9Sstevel@tonic-gate {
20587c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
20597c478bd9Sstevel@tonic-gate 	pool_component_t **rl;
20607c478bd9Sstevel@tonic-gate 	uint_t res_size;
20617c478bd9Sstevel@tonic-gate 	pool_t **pl;
20627c478bd9Sstevel@tonic-gate 	uint_t npool;
20637c478bd9Sstevel@tonic-gate 	int i;
20647c478bd9Sstevel@tonic-gate 
20657c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
20667c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
20677c478bd9Sstevel@tonic-gate 
20687c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(prs);
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 	if (resource_is_system(prs) == PO_TRUE) {
20717c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
20727c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
20737c478bd9Sstevel@tonic-gate 	}
20747c478bd9Sstevel@tonic-gate 	/*
20757c478bd9Sstevel@tonic-gate 	 * Walk all the pools and dissociate any pools which are using
20767c478bd9Sstevel@tonic-gate 	 * this resource.
20777c478bd9Sstevel@tonic-gate 	 */
20787c478bd9Sstevel@tonic-gate 	if ((pl = pool_query_pools(conf, &npool, NULL)) != NULL) {
20797c478bd9Sstevel@tonic-gate 		for (i = 0; i < npool; i++) {
20807c478bd9Sstevel@tonic-gate 			pool_resource_t **rl;
20817c478bd9Sstevel@tonic-gate 			uint_t nres;
20827c478bd9Sstevel@tonic-gate 			int j;
20837c478bd9Sstevel@tonic-gate 
20847c478bd9Sstevel@tonic-gate 			if ((rl = pool_query_pool_resources(conf, pl[i], &nres,
20857c478bd9Sstevel@tonic-gate 			    NULL)) != NULL) {
20867c478bd9Sstevel@tonic-gate 				for (j = 0; j < nres; j++) {
20877c478bd9Sstevel@tonic-gate 					if (rl[j] == prs) {
20887c478bd9Sstevel@tonic-gate 						if (pool_dissociate(conf, pl[i],
20897c478bd9Sstevel@tonic-gate 						    rl[j]) != PO_SUCCESS) {
20907c478bd9Sstevel@tonic-gate 							free(rl);
20917c478bd9Sstevel@tonic-gate 							free(pl);
20927c478bd9Sstevel@tonic-gate 							return (PO_FAIL);
20937c478bd9Sstevel@tonic-gate 						}
20947c478bd9Sstevel@tonic-gate 						break;
20957c478bd9Sstevel@tonic-gate 					}
20967c478bd9Sstevel@tonic-gate 				}
20977c478bd9Sstevel@tonic-gate 			free(rl);
20987c478bd9Sstevel@tonic-gate 			}
20997c478bd9Sstevel@tonic-gate 		}
21007c478bd9Sstevel@tonic-gate 		free(pl);
21017c478bd9Sstevel@tonic-gate 	}
21027c478bd9Sstevel@tonic-gate 	if (pe->pe_class == PEC_RES_COMP) {
21037c478bd9Sstevel@tonic-gate 		pool_resource_t *default_set_res;
21047c478bd9Sstevel@tonic-gate 
21057c478bd9Sstevel@tonic-gate 		/*
21067c478bd9Sstevel@tonic-gate 		 * Use the xtransfer option to move comp around
21077c478bd9Sstevel@tonic-gate 		 */
21087c478bd9Sstevel@tonic-gate 		default_set_res = (pool_resource_t *)get_default_resource(prs);
21097c478bd9Sstevel@tonic-gate 
21107c478bd9Sstevel@tonic-gate 		if ((rl = pool_query_resource_components(conf, prs, &res_size,
21117c478bd9Sstevel@tonic-gate 		    NULL)) != NULL) {
21127c478bd9Sstevel@tonic-gate 			int ostate = conf->pc_state;
21137c478bd9Sstevel@tonic-gate 			conf->pc_state = POF_DESTROY;
21147c478bd9Sstevel@tonic-gate 			if (pool_resource_xtransfer(conf, prs, default_set_res,
21157c478bd9Sstevel@tonic-gate 			    rl) == PO_FAIL) {
21167c478bd9Sstevel@tonic-gate 				free(rl);
21177c478bd9Sstevel@tonic-gate 				conf->pc_state = ostate;
21187c478bd9Sstevel@tonic-gate 				return (PO_FAIL);
21197c478bd9Sstevel@tonic-gate 			}
21207c478bd9Sstevel@tonic-gate 			conf->pc_state = ostate;
21217c478bd9Sstevel@tonic-gate 			free(rl);
21227c478bd9Sstevel@tonic-gate 		}
21237c478bd9Sstevel@tonic-gate 	}
21247c478bd9Sstevel@tonic-gate 	if (pool_elem_remove(pe) != PO_SUCCESS)
21257c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
21267c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
21277c478bd9Sstevel@tonic-gate }
21287c478bd9Sstevel@tonic-gate 
21297c478bd9Sstevel@tonic-gate /*
21307c478bd9Sstevel@tonic-gate  * Destroy a comp. If the comp cannot be found or removed an error is
21317c478bd9Sstevel@tonic-gate  * returned. This is basically a wrapper around pool_elem_remove to ensure
21327c478bd9Sstevel@tonic-gate  * some type safety for the comp subtype.
21337c478bd9Sstevel@tonic-gate  */
21347c478bd9Sstevel@tonic-gate int
pool_component_destroy(pool_component_t * pr)21357c478bd9Sstevel@tonic-gate pool_component_destroy(pool_component_t *pr)
21367c478bd9Sstevel@tonic-gate {
21377c478bd9Sstevel@tonic-gate 	pool_elem_t *pe = TO_ELEM(pr);
21387c478bd9Sstevel@tonic-gate 
21397c478bd9Sstevel@tonic-gate 	if (pool_elem_remove(pe) != PO_SUCCESS)
21407c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
21417c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
21427c478bd9Sstevel@tonic-gate }
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate /*
21457c478bd9Sstevel@tonic-gate  * Remove a pool_elem_t from a configuration. This has been "hidden" away as
21467c478bd9Sstevel@tonic-gate  * a static routine since the only elements which are currently being removed
21477c478bd9Sstevel@tonic-gate  * are pools, res & comp and the wrapper functions above provide type-safe
21487c478bd9Sstevel@tonic-gate  * access. However, if there is a need to remove other types of elements
21497c478bd9Sstevel@tonic-gate  * then this could be promoted to pool_impl.h or more wrappers could
21507c478bd9Sstevel@tonic-gate  * be added to pool_impl.h.
21517c478bd9Sstevel@tonic-gate  */
21527c478bd9Sstevel@tonic-gate int
pool_elem_remove(pool_elem_t * pe)21537c478bd9Sstevel@tonic-gate pool_elem_remove(pool_elem_t *pe)
21547c478bd9Sstevel@tonic-gate {
21557c478bd9Sstevel@tonic-gate 	return (pe->pe_remove(pe));
21567c478bd9Sstevel@tonic-gate }
21577c478bd9Sstevel@tonic-gate 
21587c478bd9Sstevel@tonic-gate /*
21597c478bd9Sstevel@tonic-gate  * Execute a query to search for a qualifying set of elements.
21607c478bd9Sstevel@tonic-gate  */
21617c478bd9Sstevel@tonic-gate pool_result_set_t *
pool_exec_query(const pool_conf_t * conf,const pool_elem_t * src,const char * src_attr,pool_elem_class_t classes,pool_value_t ** props)21627c478bd9Sstevel@tonic-gate pool_exec_query(const pool_conf_t *conf, const pool_elem_t *src,
21637c478bd9Sstevel@tonic-gate     const char *src_attr, pool_elem_class_t classes, pool_value_t **props)
21647c478bd9Sstevel@tonic-gate {
21657c478bd9Sstevel@tonic-gate 	return (conf->pc_prov->pc_exec_query(conf, src, src_attr, classes,
21667c478bd9Sstevel@tonic-gate 	    props));
21677c478bd9Sstevel@tonic-gate }
21687c478bd9Sstevel@tonic-gate 
21697c478bd9Sstevel@tonic-gate /*
21707c478bd9Sstevel@tonic-gate  * Get the next result from a result set of elements.
21717c478bd9Sstevel@tonic-gate  */
21727c478bd9Sstevel@tonic-gate pool_elem_t *
pool_rs_next(pool_result_set_t * set)21737c478bd9Sstevel@tonic-gate pool_rs_next(pool_result_set_t *set)
21747c478bd9Sstevel@tonic-gate {
21757c478bd9Sstevel@tonic-gate 	return (set->prs_next(set));
21767c478bd9Sstevel@tonic-gate }
21777c478bd9Sstevel@tonic-gate 
21787c478bd9Sstevel@tonic-gate /*
21797c478bd9Sstevel@tonic-gate  * Get the previous result from a result set of elements.
21807c478bd9Sstevel@tonic-gate  */
21817c478bd9Sstevel@tonic-gate pool_elem_t *
pool_rs_prev(pool_result_set_t * set)21827c478bd9Sstevel@tonic-gate pool_rs_prev(pool_result_set_t *set)
21837c478bd9Sstevel@tonic-gate {
21847c478bd9Sstevel@tonic-gate 	return (set->prs_prev(set));
21857c478bd9Sstevel@tonic-gate }
21867c478bd9Sstevel@tonic-gate 
21877c478bd9Sstevel@tonic-gate /*
21887c478bd9Sstevel@tonic-gate  * Get the first result from a result set of elements.
21897c478bd9Sstevel@tonic-gate  */
21907c478bd9Sstevel@tonic-gate pool_elem_t *
pool_rs_first(pool_result_set_t * set)21917c478bd9Sstevel@tonic-gate pool_rs_first(pool_result_set_t *set)
21927c478bd9Sstevel@tonic-gate {
21937c478bd9Sstevel@tonic-gate 	return (set->prs_first(set));
21947c478bd9Sstevel@tonic-gate }
21957c478bd9Sstevel@tonic-gate 
21967c478bd9Sstevel@tonic-gate /*
21977c478bd9Sstevel@tonic-gate  * Get the last result from a result set of elements.
21987c478bd9Sstevel@tonic-gate  */
21997c478bd9Sstevel@tonic-gate pool_elem_t *
pool_rs_last(pool_result_set_t * set)22007c478bd9Sstevel@tonic-gate pool_rs_last(pool_result_set_t *set)
22017c478bd9Sstevel@tonic-gate {
22027c478bd9Sstevel@tonic-gate 	return (set->prs_last(set));
22037c478bd9Sstevel@tonic-gate }
22047c478bd9Sstevel@tonic-gate 
22057c478bd9Sstevel@tonic-gate 
22067c478bd9Sstevel@tonic-gate /*
22077c478bd9Sstevel@tonic-gate  * Get the count for a result set of elements.
22087c478bd9Sstevel@tonic-gate  */
22097c478bd9Sstevel@tonic-gate int
pool_rs_count(pool_result_set_t * set)22107c478bd9Sstevel@tonic-gate pool_rs_count(pool_result_set_t *set)
22117c478bd9Sstevel@tonic-gate {
22127c478bd9Sstevel@tonic-gate 	return (set->prs_count(set));
22137c478bd9Sstevel@tonic-gate }
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate /*
22167c478bd9Sstevel@tonic-gate  * Get the index for a result set of elements.
22177c478bd9Sstevel@tonic-gate  */
22187c478bd9Sstevel@tonic-gate int
pool_rs_get_index(pool_result_set_t * set)22197c478bd9Sstevel@tonic-gate pool_rs_get_index(pool_result_set_t *set)
22207c478bd9Sstevel@tonic-gate {
22217c478bd9Sstevel@tonic-gate 	return (set->prs_get_index(set));
22227c478bd9Sstevel@tonic-gate }
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate /*
22257c478bd9Sstevel@tonic-gate  * Set the index for a result set of elements.
22267c478bd9Sstevel@tonic-gate  */
22277c478bd9Sstevel@tonic-gate int
pool_rs_set_index(pool_result_set_t * set,int index)22287c478bd9Sstevel@tonic-gate pool_rs_set_index(pool_result_set_t *set, int index)
22297c478bd9Sstevel@tonic-gate {
22307c478bd9Sstevel@tonic-gate 	return (set->prs_set_index(set, index));
22317c478bd9Sstevel@tonic-gate }
22327c478bd9Sstevel@tonic-gate 
22337c478bd9Sstevel@tonic-gate /*
22347c478bd9Sstevel@tonic-gate  * Close a result set of elements, freeing all associated resources.
22357c478bd9Sstevel@tonic-gate  */
22367c478bd9Sstevel@tonic-gate int
pool_rs_close(pool_result_set_t * set)22377c478bd9Sstevel@tonic-gate pool_rs_close(pool_result_set_t *set)
22387c478bd9Sstevel@tonic-gate {
22397c478bd9Sstevel@tonic-gate 	return (set->prs_close(set));
22407c478bd9Sstevel@tonic-gate }
22417c478bd9Sstevel@tonic-gate 
22427c478bd9Sstevel@tonic-gate /*
22437c478bd9Sstevel@tonic-gate  * When transferring resource components using pool_resource_transfer,
22447c478bd9Sstevel@tonic-gate  * this function is invoked to choose which actual components will be
22457c478bd9Sstevel@tonic-gate  * transferred.
22467c478bd9Sstevel@tonic-gate  */
22477c478bd9Sstevel@tonic-gate int
choose_components(pool_resource_t * src,pool_resource_t * dst,uint64_t size)22487c478bd9Sstevel@tonic-gate choose_components(pool_resource_t *src, pool_resource_t *dst, uint64_t size)
22497c478bd9Sstevel@tonic-gate {
22507c478bd9Sstevel@tonic-gate 	pool_component_t **components = NULL, *moved[] = { NULL, NULL };
22517c478bd9Sstevel@tonic-gate 	int i;
22527c478bd9Sstevel@tonic-gate 	uint_t ncomponent;
22537c478bd9Sstevel@tonic-gate 	pool_conf_t *conf = TO_CONF(TO_ELEM(src));
22547c478bd9Sstevel@tonic-gate 
22557c478bd9Sstevel@tonic-gate 	if (size == 0)
22567c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS);
22577c478bd9Sstevel@tonic-gate 	/*
22587c478bd9Sstevel@tonic-gate 	 * Get the component list from our src component.
22597c478bd9Sstevel@tonic-gate 	 */
22607c478bd9Sstevel@tonic-gate 	if ((components = pool_query_resource_components(conf, src, &ncomponent,
22617c478bd9Sstevel@tonic-gate 	    NULL)) == NULL) {
22627c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
22637c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
22647c478bd9Sstevel@tonic-gate 	}
22657c478bd9Sstevel@tonic-gate 	qsort(components, ncomponent, sizeof (pool_elem_t *),
22667c478bd9Sstevel@tonic-gate 	    qsort_elem_compare);
22677c478bd9Sstevel@tonic-gate 	/*
22687c478bd9Sstevel@tonic-gate 	 * Components that aren't specifically requested by the resource
22697c478bd9Sstevel@tonic-gate 	 * should be transferred out first.
22707c478bd9Sstevel@tonic-gate 	 */
22717c478bd9Sstevel@tonic-gate 	for (i = 0; size > 0 && components[i] != NULL; i++) {
22727c478bd9Sstevel@tonic-gate 		if (!cpu_is_requested(components[i])) {
22737c478bd9Sstevel@tonic-gate 			moved[0] = components[i];
22747c478bd9Sstevel@tonic-gate 			if (pool_resource_xtransfer(conf, src, dst, moved) ==
22757c478bd9Sstevel@tonic-gate 			    PO_SUCCESS) {
22767c478bd9Sstevel@tonic-gate 				size--;
22777c478bd9Sstevel@tonic-gate 			}
22787c478bd9Sstevel@tonic-gate 		}
22797c478bd9Sstevel@tonic-gate 	}
22807c478bd9Sstevel@tonic-gate 
22817c478bd9Sstevel@tonic-gate 	/*
22827c478bd9Sstevel@tonic-gate 	 * If we couldn't find enough "un-requested" components, select random
22837c478bd9Sstevel@tonic-gate 	 * requested components.
22847c478bd9Sstevel@tonic-gate 	 */
22857c478bd9Sstevel@tonic-gate 	for (i = 0; size > 0 && components[i] != NULL; i++) {
22867c478bd9Sstevel@tonic-gate 		if (cpu_is_requested(components[i])) {
22877c478bd9Sstevel@tonic-gate 			moved[0] = components[i];
22887c478bd9Sstevel@tonic-gate 			if (pool_resource_xtransfer(conf, src, dst, moved) ==
22897c478bd9Sstevel@tonic-gate 			    PO_SUCCESS) {
22907c478bd9Sstevel@tonic-gate 				size--;
22917c478bd9Sstevel@tonic-gate 			}
22927c478bd9Sstevel@tonic-gate 		}
22937c478bd9Sstevel@tonic-gate 	}
22947c478bd9Sstevel@tonic-gate 
22957c478bd9Sstevel@tonic-gate 	free(components);
22967c478bd9Sstevel@tonic-gate 	/*
22977c478bd9Sstevel@tonic-gate 	 * If we couldn't transfer out all the resources we asked for, then
22987c478bd9Sstevel@tonic-gate 	 * return error.
22997c478bd9Sstevel@tonic-gate 	 */
23007c478bd9Sstevel@tonic-gate 	return (size == 0 ? PO_SUCCESS : PO_FAIL);
23017c478bd9Sstevel@tonic-gate }
23027c478bd9Sstevel@tonic-gate 
23037c478bd9Sstevel@tonic-gate /*
23047c478bd9Sstevel@tonic-gate  * Common processing for a resource transfer (xfer or xxfer).
23057c478bd9Sstevel@tonic-gate  *
23067c478bd9Sstevel@tonic-gate  * - Return XFER_CONTINUE if the transfer should proceeed
23077c478bd9Sstevel@tonic-gate  * - Return XFER_FAIL if the transfer should be stopped in failure
23087c478bd9Sstevel@tonic-gate  * - Return XFER_SUCCESS if the transfer should be stopped in success
23097c478bd9Sstevel@tonic-gate  */
23107c478bd9Sstevel@tonic-gate int
setup_transfer(pool_conf_t * conf,pool_resource_t * src,pool_resource_t * tgt,uint64_t size,uint64_t * src_size,uint64_t * tgt_size)23117c478bd9Sstevel@tonic-gate setup_transfer(pool_conf_t *conf, pool_resource_t *src, pool_resource_t *tgt,
23127c478bd9Sstevel@tonic-gate     uint64_t size, uint64_t *src_size, uint64_t *tgt_size)
23137c478bd9Sstevel@tonic-gate {
23147c478bd9Sstevel@tonic-gate 	uint64_t src_min;
23157c478bd9Sstevel@tonic-gate 	uint64_t tgt_max;
23167c478bd9Sstevel@tonic-gate 
23177c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
23187c478bd9Sstevel@tonic-gate 		return (XFER_FAIL);
23197c478bd9Sstevel@tonic-gate 
23207c478bd9Sstevel@tonic-gate 	/*
23217c478bd9Sstevel@tonic-gate 	 * Makes sure the two resources are of the same type
23227c478bd9Sstevel@tonic-gate 	 */
23237c478bd9Sstevel@tonic-gate 	if (pool_resource_elem_class(TO_ELEM(src)) !=
23247c478bd9Sstevel@tonic-gate 	    pool_resource_elem_class(TO_ELEM(tgt))) {
23257c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
23267c478bd9Sstevel@tonic-gate 		return (XFER_FAIL);
23277c478bd9Sstevel@tonic-gate 	}
23287c478bd9Sstevel@tonic-gate 
23297c478bd9Sstevel@tonic-gate 	/*
23307c478bd9Sstevel@tonic-gate 	 * Transferring to yourself is a no-op
23317c478bd9Sstevel@tonic-gate 	 */
23327c478bd9Sstevel@tonic-gate 	if (src == tgt)
23337c478bd9Sstevel@tonic-gate 		return (XFER_SUCCESS);
23347c478bd9Sstevel@tonic-gate 
23357c478bd9Sstevel@tonic-gate 	/*
23367c478bd9Sstevel@tonic-gate 	 * Transferring nothing is a no-op
23377c478bd9Sstevel@tonic-gate 	 */
23387c478bd9Sstevel@tonic-gate 	if (size == 0)
23397c478bd9Sstevel@tonic-gate 		return (XFER_SUCCESS);
23407c478bd9Sstevel@tonic-gate 
23417c478bd9Sstevel@tonic-gate 	if (resource_get_min(src, &src_min) != PO_SUCCESS ||
23427c478bd9Sstevel@tonic-gate 	    resource_get_size(src, src_size) != PO_SUCCESS ||
23437c478bd9Sstevel@tonic-gate 	    resource_get_max(tgt, &tgt_max) != PO_SUCCESS ||
23447c478bd9Sstevel@tonic-gate 	    resource_get_size(tgt, tgt_size) != PO_SUCCESS) {
23457c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
23467c478bd9Sstevel@tonic-gate 		return (XFER_FAIL);
23477c478bd9Sstevel@tonic-gate 	}
23487c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) != POF_DESTROY) {
23497c478bd9Sstevel@tonic-gate 		/*
23507c478bd9Sstevel@tonic-gate 		 * src_size - donating >= src.min
23517c478bd9Sstevel@tonic-gate 		 * size + receiving <= tgt.max (except for default)
23527c478bd9Sstevel@tonic-gate 		 */
23537c478bd9Sstevel@tonic-gate #ifdef DEBUG
23547c478bd9Sstevel@tonic-gate 		dprintf("conf is %s\n", pool_conf_location(conf));
23557c478bd9Sstevel@tonic-gate 		dprintf("setup_transfer: src_size %llu\n", *src_size);
23567c478bd9Sstevel@tonic-gate 		pool_elem_dprintf(TO_ELEM(src));
23577c478bd9Sstevel@tonic-gate 		dprintf("setup_transfer: tgt_size %llu\n", *tgt_size);
23587c478bd9Sstevel@tonic-gate 		pool_elem_dprintf(TO_ELEM(tgt));
23597c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
23607c478bd9Sstevel@tonic-gate 		if (*src_size - size < src_min ||
23617c478bd9Sstevel@tonic-gate 		    (resource_is_default(tgt) == PO_FALSE &&
23627c478bd9Sstevel@tonic-gate 			*tgt_size + size > tgt_max)) {
23637c478bd9Sstevel@tonic-gate 			pool_seterror(POE_INVALID_CONF);
23647c478bd9Sstevel@tonic-gate 			return (XFER_FAIL);
23657c478bd9Sstevel@tonic-gate 		}
23667c478bd9Sstevel@tonic-gate 	}
23677c478bd9Sstevel@tonic-gate 	return (XFER_CONTINUE);
23687c478bd9Sstevel@tonic-gate }
23697c478bd9Sstevel@tonic-gate 
23707c478bd9Sstevel@tonic-gate /*
23717c478bd9Sstevel@tonic-gate  * Transfer resource quantities from one resource set to another.
23727c478bd9Sstevel@tonic-gate  */
23737c478bd9Sstevel@tonic-gate int
pool_resource_transfer(pool_conf_t * conf,pool_resource_t * src,pool_resource_t * tgt,uint64_t size)23747c478bd9Sstevel@tonic-gate pool_resource_transfer(pool_conf_t *conf, pool_resource_t *src,
23757c478bd9Sstevel@tonic-gate     pool_resource_t *tgt, uint64_t size)
23767c478bd9Sstevel@tonic-gate {
23777c478bd9Sstevel@tonic-gate 	uint64_t src_size;
23787c478bd9Sstevel@tonic-gate 	uint64_t tgt_size;
23797c478bd9Sstevel@tonic-gate 	int ret;
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate 	if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size))
23827c478bd9Sstevel@tonic-gate 	    != XFER_CONTINUE)
23837c478bd9Sstevel@tonic-gate 		return (ret);
23847c478bd9Sstevel@tonic-gate 	/*
23857c478bd9Sstevel@tonic-gate 	 * If this resource is a res_comp we must call move components
23867c478bd9Sstevel@tonic-gate 	 */
23877c478bd9Sstevel@tonic-gate 	if (pool_elem_class(TO_ELEM(src)) == PEC_RES_COMP)
23887c478bd9Sstevel@tonic-gate 		return (choose_components(src, tgt, size));
23897c478bd9Sstevel@tonic-gate 	/*
23907c478bd9Sstevel@tonic-gate 	 * Now do the transfer.
23917c478bd9Sstevel@tonic-gate 	 */
23927c478bd9Sstevel@tonic-gate 	ret = conf->pc_prov->pc_res_xfer(src, tgt, size);
23937c478bd9Sstevel@tonic-gate 	/*
23947c478bd9Sstevel@tonic-gate 	 * Modify the sizes of the resource sets if the process was
23957c478bd9Sstevel@tonic-gate 	 * successful
23967c478bd9Sstevel@tonic-gate 	 */
23977c478bd9Sstevel@tonic-gate 	if (ret == PO_SUCCESS) {
23987c478bd9Sstevel@tonic-gate 		pool_value_t val = POOL_VALUE_INITIALIZER;
23997c478bd9Sstevel@tonic-gate 
24007c478bd9Sstevel@tonic-gate 		src_size -= size;
24017c478bd9Sstevel@tonic-gate 		tgt_size += size;
24027c478bd9Sstevel@tonic-gate 		pool_value_set_uint64(&val, src_size);
24037c478bd9Sstevel@tonic-gate 		(void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop,
24047c478bd9Sstevel@tonic-gate 		    &val);
24057c478bd9Sstevel@tonic-gate 		pool_value_set_uint64(&val, tgt_size);
24067c478bd9Sstevel@tonic-gate 		(void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop,
24077c478bd9Sstevel@tonic-gate 		    &val);
24087c478bd9Sstevel@tonic-gate 	}
24097c478bd9Sstevel@tonic-gate 	return (ret);
24107c478bd9Sstevel@tonic-gate }
24117c478bd9Sstevel@tonic-gate 
24127c478bd9Sstevel@tonic-gate /*
24137c478bd9Sstevel@tonic-gate  * Transfer resource components from one resource set to another.
24147c478bd9Sstevel@tonic-gate  */
24157c478bd9Sstevel@tonic-gate int
pool_resource_xtransfer(pool_conf_t * conf,pool_resource_t * src,pool_resource_t * tgt,pool_component_t ** rl)24167c478bd9Sstevel@tonic-gate pool_resource_xtransfer(pool_conf_t *conf, pool_resource_t *src,
24177c478bd9Sstevel@tonic-gate     pool_resource_t *tgt,
24187c478bd9Sstevel@tonic-gate     pool_component_t **rl)
24197c478bd9Sstevel@tonic-gate {
24207c478bd9Sstevel@tonic-gate 	int i;
24217c478bd9Sstevel@tonic-gate 	uint64_t src_size;
24227c478bd9Sstevel@tonic-gate 	uint64_t tgt_size;
24237c478bd9Sstevel@tonic-gate 	uint64_t size;
24247c478bd9Sstevel@tonic-gate 	int ret;
24257c478bd9Sstevel@tonic-gate 
24267c478bd9Sstevel@tonic-gate 	/*
24277c478bd9Sstevel@tonic-gate 	 * Make sure the components are all contained in 'src'. This
24287c478bd9Sstevel@tonic-gate 	 * processing must be done before setup_transfer so that size
24297c478bd9Sstevel@tonic-gate 	 * is known.
24307c478bd9Sstevel@tonic-gate 	 */
24317c478bd9Sstevel@tonic-gate 	for (i = 0; rl[i] != NULL; i++) {
24327c478bd9Sstevel@tonic-gate #ifdef DEBUG
24337c478bd9Sstevel@tonic-gate 		dprintf("resource xtransfer\n");
24347c478bd9Sstevel@tonic-gate 		dprintf("in conf %s\n", pool_conf_location(conf));
24357c478bd9Sstevel@tonic-gate 		dprintf("transferring component\n");
24367c478bd9Sstevel@tonic-gate 		pool_elem_dprintf(TO_ELEM(rl[i]));
24377c478bd9Sstevel@tonic-gate 		dprintf("from\n");
24387c478bd9Sstevel@tonic-gate 		pool_elem_dprintf(TO_ELEM(src));
24397c478bd9Sstevel@tonic-gate 		dprintf("to\n");
24407c478bd9Sstevel@tonic-gate 		pool_elem_dprintf(TO_ELEM(tgt));
24417c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 		if (pool_get_owning_resource(conf, rl[i]) != src) {
24447c478bd9Sstevel@tonic-gate 			pool_seterror(POE_BADPARAM);
24457c478bd9Sstevel@tonic-gate 			return (PO_FAIL);
24467c478bd9Sstevel@tonic-gate 		}
24477c478bd9Sstevel@tonic-gate 	}
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate 	size = (uint64_t)i;
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate 	if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size))
24527c478bd9Sstevel@tonic-gate 	    != XFER_CONTINUE)
24537c478bd9Sstevel@tonic-gate 		return (ret);
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate 	ret = conf->pc_prov->pc_res_xxfer(src, tgt, rl);
24567c478bd9Sstevel@tonic-gate 	/*
24577c478bd9Sstevel@tonic-gate 	 * Modify the sizes of the resource sets if the process was
24587c478bd9Sstevel@tonic-gate 	 * successful
24597c478bd9Sstevel@tonic-gate 	 */
24607c478bd9Sstevel@tonic-gate 	if (ret == PO_SUCCESS) {
24617c478bd9Sstevel@tonic-gate 		pool_value_t val = POOL_VALUE_INITIALIZER;
24627c478bd9Sstevel@tonic-gate 
24637c478bd9Sstevel@tonic-gate #ifdef DEBUG
24647c478bd9Sstevel@tonic-gate 		dprintf("src_size %llu\n", src_size);
24657c478bd9Sstevel@tonic-gate 		dprintf("tgt_size %llu\n", tgt_size);
24667c478bd9Sstevel@tonic-gate 		dprintf("size %llu\n", size);
24677c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
24687c478bd9Sstevel@tonic-gate 		src_size -= size;
24697c478bd9Sstevel@tonic-gate 		tgt_size += size;
24707c478bd9Sstevel@tonic-gate 		pool_value_set_uint64(&val, src_size);
24717c478bd9Sstevel@tonic-gate 		(void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop,
24727c478bd9Sstevel@tonic-gate 		    &val);
24737c478bd9Sstevel@tonic-gate 		pool_value_set_uint64(&val, tgt_size);
24747c478bd9Sstevel@tonic-gate 		(void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop,
24757c478bd9Sstevel@tonic-gate 		    &val);
24767c478bd9Sstevel@tonic-gate 	}
24777c478bd9Sstevel@tonic-gate 	return (ret);
24787c478bd9Sstevel@tonic-gate }
24797c478bd9Sstevel@tonic-gate 
24807c478bd9Sstevel@tonic-gate /*
24817c478bd9Sstevel@tonic-gate  * Find the owning resource for a resource component.
24827c478bd9Sstevel@tonic-gate  */
24837c478bd9Sstevel@tonic-gate pool_resource_t *
pool_get_owning_resource(const pool_conf_t * conf,const pool_component_t * comp)24847c478bd9Sstevel@tonic-gate pool_get_owning_resource(const pool_conf_t *conf, const pool_component_t *comp)
24857c478bd9Sstevel@tonic-gate {
24867c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
24877c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
24887c478bd9Sstevel@tonic-gate 		return (NULL);
24897c478bd9Sstevel@tonic-gate 	}
24907c478bd9Sstevel@tonic-gate 	return (pool_elem_res(pool_get_container(TO_ELEM(comp))));
24917c478bd9Sstevel@tonic-gate }
24927c478bd9Sstevel@tonic-gate 
24937c478bd9Sstevel@tonic-gate /*
24947c478bd9Sstevel@tonic-gate  * pool_get_container() returns the container of pc.
24957c478bd9Sstevel@tonic-gate  */
24967c478bd9Sstevel@tonic-gate pool_elem_t *
pool_get_container(const pool_elem_t * pc)24977c478bd9Sstevel@tonic-gate pool_get_container(const pool_elem_t *pc)
24987c478bd9Sstevel@tonic-gate {
24997c478bd9Sstevel@tonic-gate 	return (pc->pe_get_container(pc));
25007c478bd9Sstevel@tonic-gate }
25017c478bd9Sstevel@tonic-gate 
25027c478bd9Sstevel@tonic-gate /*
25037c478bd9Sstevel@tonic-gate  * pool_set_container() moves pc so that it is contained by pp.
25047c478bd9Sstevel@tonic-gate  *
25057c478bd9Sstevel@tonic-gate  * Returns PO_SUCCESS/PO_FAIL
25067c478bd9Sstevel@tonic-gate  */
25077c478bd9Sstevel@tonic-gate int
pool_set_container(pool_elem_t * pp,pool_elem_t * pc)25087c478bd9Sstevel@tonic-gate pool_set_container(pool_elem_t *pp, pool_elem_t *pc)
25097c478bd9Sstevel@tonic-gate {
25107c478bd9Sstevel@tonic-gate 	return (pc->pe_set_container(pp, pc));
25117c478bd9Sstevel@tonic-gate }
25127c478bd9Sstevel@tonic-gate 
25137c478bd9Sstevel@tonic-gate /*
25147c478bd9Sstevel@tonic-gate  * Conversion routines for converting to and from elem and it's various
25157c478bd9Sstevel@tonic-gate  * subtypes of system, pool, res and comp.
25167c478bd9Sstevel@tonic-gate  */
25177c478bd9Sstevel@tonic-gate pool_elem_t *
pool_system_elem(const pool_system_t * ph)25187c478bd9Sstevel@tonic-gate pool_system_elem(const pool_system_t *ph)
25197c478bd9Sstevel@tonic-gate {
25207c478bd9Sstevel@tonic-gate 	return ((pool_elem_t *)ph);
25217c478bd9Sstevel@tonic-gate }
25227c478bd9Sstevel@tonic-gate 
25237c478bd9Sstevel@tonic-gate pool_elem_t *
pool_conf_to_elem(const pool_conf_t * conf)25247c478bd9Sstevel@tonic-gate pool_conf_to_elem(const pool_conf_t *conf)
25257c478bd9Sstevel@tonic-gate {
25267c478bd9Sstevel@tonic-gate 	pool_system_t *sys;
25277c478bd9Sstevel@tonic-gate 
25287c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
25297c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25307c478bd9Sstevel@tonic-gate 		return (NULL);
25317c478bd9Sstevel@tonic-gate 	}
25327c478bd9Sstevel@tonic-gate 	if ((sys = pool_conf_system(conf)) == NULL) {
25337c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25347c478bd9Sstevel@tonic-gate 		return (NULL);
25357c478bd9Sstevel@tonic-gate 	}
25367c478bd9Sstevel@tonic-gate 	return (pool_system_elem(sys));
25377c478bd9Sstevel@tonic-gate }
25387c478bd9Sstevel@tonic-gate 
25397c478bd9Sstevel@tonic-gate pool_elem_t *
pool_to_elem(const pool_conf_t * conf,const pool_t * pp)25407c478bd9Sstevel@tonic-gate pool_to_elem(const pool_conf_t *conf, const pool_t *pp)
25417c478bd9Sstevel@tonic-gate {
25427c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
25437c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25447c478bd9Sstevel@tonic-gate 		return (NULL);
25457c478bd9Sstevel@tonic-gate 	}
25467c478bd9Sstevel@tonic-gate 	return ((pool_elem_t *)pp);
25477c478bd9Sstevel@tonic-gate }
25487c478bd9Sstevel@tonic-gate 
25497c478bd9Sstevel@tonic-gate pool_elem_t *
pool_resource_to_elem(const pool_conf_t * conf,const pool_resource_t * prs)25507c478bd9Sstevel@tonic-gate pool_resource_to_elem(const pool_conf_t *conf, const pool_resource_t *prs)
25517c478bd9Sstevel@tonic-gate {
25527c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
25537c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25547c478bd9Sstevel@tonic-gate 		return (NULL);
25557c478bd9Sstevel@tonic-gate 	}
25567c478bd9Sstevel@tonic-gate 	return ((pool_elem_t *)prs);
25577c478bd9Sstevel@tonic-gate }
25587c478bd9Sstevel@tonic-gate 
25597c478bd9Sstevel@tonic-gate pool_elem_t *
pool_component_to_elem(const pool_conf_t * conf,const pool_component_t * pr)25607c478bd9Sstevel@tonic-gate pool_component_to_elem(const pool_conf_t *conf, const pool_component_t *pr)
25617c478bd9Sstevel@tonic-gate {
25627c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
25637c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25647c478bd9Sstevel@tonic-gate 		return (NULL);
25657c478bd9Sstevel@tonic-gate 	}
25667c478bd9Sstevel@tonic-gate 	return ((pool_elem_t *)pr);
25677c478bd9Sstevel@tonic-gate }
25687c478bd9Sstevel@tonic-gate 
25697c478bd9Sstevel@tonic-gate /*
25707c478bd9Sstevel@tonic-gate  * Walk all the pools of the configuration calling the user supplied function
25717c478bd9Sstevel@tonic-gate  * as long as the user function continues to return PO_TRUE
25727c478bd9Sstevel@tonic-gate  */
25737c478bd9Sstevel@tonic-gate int
pool_walk_pools(pool_conf_t * conf,void * arg,int (* callback)(pool_conf_t * conf,pool_t * pool,void * arg))25747c478bd9Sstevel@tonic-gate pool_walk_pools(pool_conf_t *conf, void *arg,
25757c478bd9Sstevel@tonic-gate     int (*callback)(pool_conf_t *conf, pool_t *pool, void *arg))
25767c478bd9Sstevel@tonic-gate {
25777c478bd9Sstevel@tonic-gate 	pool_t **rs;
25787c478bd9Sstevel@tonic-gate 	int i;
25797c478bd9Sstevel@tonic-gate 	uint_t size;
25807c478bd9Sstevel@tonic-gate 	int error = PO_SUCCESS;
25817c478bd9Sstevel@tonic-gate 
25827c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
25837c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
25847c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
25857c478bd9Sstevel@tonic-gate 	}
25867c478bd9Sstevel@tonic-gate 
25877c478bd9Sstevel@tonic-gate 	if ((rs = pool_query_pools(conf, &size, NULL)) == NULL) /* None */
25887c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS);
25897c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++)
25907c478bd9Sstevel@tonic-gate 		if (callback(conf, rs[i], arg) != PO_SUCCESS) {
25917c478bd9Sstevel@tonic-gate 			error = PO_FAIL;
25927c478bd9Sstevel@tonic-gate 			break;
25937c478bd9Sstevel@tonic-gate 		}
25947c478bd9Sstevel@tonic-gate 	free(rs);
25957c478bd9Sstevel@tonic-gate 	return (error);
25967c478bd9Sstevel@tonic-gate }
25977c478bd9Sstevel@tonic-gate 
25987c478bd9Sstevel@tonic-gate /*
25997c478bd9Sstevel@tonic-gate  * Walk all the comp of the res calling the user supplied function
26007c478bd9Sstevel@tonic-gate  * as long as the user function continues to return PO_TRUE
26017c478bd9Sstevel@tonic-gate  */
26027c478bd9Sstevel@tonic-gate int
pool_walk_components(pool_conf_t * conf,pool_resource_t * prs,void * arg,int (* callback)(pool_conf_t * conf,pool_component_t * pr,void * arg))26037c478bd9Sstevel@tonic-gate pool_walk_components(pool_conf_t *conf, pool_resource_t *prs, void *arg,
26047c478bd9Sstevel@tonic-gate     int (*callback)(pool_conf_t *conf, pool_component_t *pr, void *arg))
26057c478bd9Sstevel@tonic-gate {
26067c478bd9Sstevel@tonic-gate 	pool_component_t **rs;
26077c478bd9Sstevel@tonic-gate 	int i;
26087c478bd9Sstevel@tonic-gate 	uint_t size;
26097c478bd9Sstevel@tonic-gate 	int error = PO_SUCCESS;
26107c478bd9Sstevel@tonic-gate 
26117c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
26127c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
26137c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
26147c478bd9Sstevel@tonic-gate 	}
26157c478bd9Sstevel@tonic-gate 
26167c478bd9Sstevel@tonic-gate 	if ((rs = pool_query_resource_components(conf, prs, &size, NULL)) ==
26177c478bd9Sstevel@tonic-gate 	    NULL)
26187c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS); /* None */
26197c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++)
26207c478bd9Sstevel@tonic-gate 		if (callback(conf, rs[i], arg) != PO_SUCCESS) {
26217c478bd9Sstevel@tonic-gate 			error = PO_FAIL;
26227c478bd9Sstevel@tonic-gate 			break;
26237c478bd9Sstevel@tonic-gate 		}
26247c478bd9Sstevel@tonic-gate 	free(rs);
26257c478bd9Sstevel@tonic-gate 	return (error);
26267c478bd9Sstevel@tonic-gate }
26277c478bd9Sstevel@tonic-gate 
26287c478bd9Sstevel@tonic-gate /*
26297c478bd9Sstevel@tonic-gate  * Return an array of all matching res for the supplied pool.
26307c478bd9Sstevel@tonic-gate  */
26317c478bd9Sstevel@tonic-gate pool_resource_t **
pool_query_pool_resources(const pool_conf_t * conf,const pool_t * pp,uint_t * size,pool_value_t ** props)26327c478bd9Sstevel@tonic-gate pool_query_pool_resources(const pool_conf_t *conf, const pool_t *pp,
26337c478bd9Sstevel@tonic-gate     uint_t *size, pool_value_t **props)
26347c478bd9Sstevel@tonic-gate {
26357c478bd9Sstevel@tonic-gate 	pool_result_set_t *rs;
26367c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
26377c478bd9Sstevel@tonic-gate 	pool_resource_t **result = NULL;
26387c478bd9Sstevel@tonic-gate 	int i = 0;
26397c478bd9Sstevel@tonic-gate 
26407c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
26417c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
26427c478bd9Sstevel@tonic-gate 		return (NULL);
26437c478bd9Sstevel@tonic-gate 	}
26447c478bd9Sstevel@tonic-gate 
26457c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(pp);
26467c478bd9Sstevel@tonic-gate 
26477c478bd9Sstevel@tonic-gate 	rs = pool_exec_query(conf, pe, "res", PEC_QRY_RES, props);
26487c478bd9Sstevel@tonic-gate 	if (rs == NULL) {
26497c478bd9Sstevel@tonic-gate 		return (NULL);
26507c478bd9Sstevel@tonic-gate 	}
26517c478bd9Sstevel@tonic-gate 	if ((*size = pool_rs_count(rs)) == 0) {
26527c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
26537c478bd9Sstevel@tonic-gate 		return (NULL);
26547c478bd9Sstevel@tonic-gate 	}
26557c478bd9Sstevel@tonic-gate 	if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1)))
26567c478bd9Sstevel@tonic-gate 	    == NULL) {
26577c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
26587c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
26597c478bd9Sstevel@tonic-gate 		return (NULL);
26607c478bd9Sstevel@tonic-gate 	}
26617c478bd9Sstevel@tonic-gate 	(void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1));
26627c478bd9Sstevel@tonic-gate 	for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
26637c478bd9Sstevel@tonic-gate 		if (pool_elem_class(pe) != PEC_RES_COMP &&
26647c478bd9Sstevel@tonic-gate 		    pool_elem_class(pe) != PEC_RES_AGG) {
26657c478bd9Sstevel@tonic-gate 			pool_seterror(POE_INVALID_CONF);
26667c478bd9Sstevel@tonic-gate 			free(result);
26677c478bd9Sstevel@tonic-gate 			(void) pool_rs_close(rs);
26687c478bd9Sstevel@tonic-gate 			return (NULL);
26697c478bd9Sstevel@tonic-gate 		}
26707c478bd9Sstevel@tonic-gate 		result[i++] = pool_elem_res(pe);
26717c478bd9Sstevel@tonic-gate 	}
26727c478bd9Sstevel@tonic-gate 	(void) pool_rs_close(rs);
26737c478bd9Sstevel@tonic-gate 	return (result);
26747c478bd9Sstevel@tonic-gate }
26757c478bd9Sstevel@tonic-gate 
26767c478bd9Sstevel@tonic-gate /*
26777c478bd9Sstevel@tonic-gate  * Walk all the res of the pool calling the user supplied function
26787c478bd9Sstevel@tonic-gate  * as long as the user function continues to return PO_TRUE
26797c478bd9Sstevel@tonic-gate  */
26807c478bd9Sstevel@tonic-gate int
pool_walk_resources(pool_conf_t * conf,pool_t * pp,void * arg,int (* callback)(pool_conf_t *,pool_resource_t *,void *))26817c478bd9Sstevel@tonic-gate pool_walk_resources(pool_conf_t *conf, pool_t *pp, void *arg,
26827c478bd9Sstevel@tonic-gate     int (*callback)(pool_conf_t *, pool_resource_t *, void *))
26837c478bd9Sstevel@tonic-gate {
26847c478bd9Sstevel@tonic-gate 	pool_resource_t **rs;
26857c478bd9Sstevel@tonic-gate 	int i;
26867c478bd9Sstevel@tonic-gate 	uint_t size;
26877c478bd9Sstevel@tonic-gate 	int error = PO_SUCCESS;
26887c478bd9Sstevel@tonic-gate 
26897c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
26907c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
26917c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
26927c478bd9Sstevel@tonic-gate 	}
26937c478bd9Sstevel@tonic-gate 	if ((rs = pool_query_pool_resources(conf, pp, &size, NULL)) == NULL)
26947c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS); /* None */
26957c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++)
26967c478bd9Sstevel@tonic-gate 		if (callback(conf, rs[i], arg) != PO_SUCCESS) {
26977c478bd9Sstevel@tonic-gate 			error = PO_FAIL;
26987c478bd9Sstevel@tonic-gate 			break;
26997c478bd9Sstevel@tonic-gate 		}
27007c478bd9Sstevel@tonic-gate 	free(rs);
27017c478bd9Sstevel@tonic-gate 	return (error);
27027c478bd9Sstevel@tonic-gate }
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate /*
27057c478bd9Sstevel@tonic-gate  * Return a result set of all comp for the supplied res.
27067c478bd9Sstevel@tonic-gate  */
27077c478bd9Sstevel@tonic-gate pool_component_t **
pool_query_resource_components(const pool_conf_t * conf,const pool_resource_t * prs,uint_t * size,pool_value_t ** props)27087c478bd9Sstevel@tonic-gate pool_query_resource_components(const pool_conf_t *conf,
27097c478bd9Sstevel@tonic-gate     const pool_resource_t *prs, uint_t *size, pool_value_t **props)
27107c478bd9Sstevel@tonic-gate {
27117c478bd9Sstevel@tonic-gate 	pool_result_set_t *rs;
27127c478bd9Sstevel@tonic-gate 	pool_elem_t *pe;
27137c478bd9Sstevel@tonic-gate 	pool_component_t **result = NULL;
27147c478bd9Sstevel@tonic-gate 	int i = 0;
27157c478bd9Sstevel@tonic-gate 
27167c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
27177c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
27187c478bd9Sstevel@tonic-gate 		return (NULL);
27197c478bd9Sstevel@tonic-gate 	}
27207c478bd9Sstevel@tonic-gate 	pe = TO_ELEM(prs);
27217c478bd9Sstevel@tonic-gate 
27227c478bd9Sstevel@tonic-gate 	rs = pool_exec_query(conf, pe, NULL, PEC_QRY_COMP, props);
27237c478bd9Sstevel@tonic-gate 	if (rs == NULL) {
27247c478bd9Sstevel@tonic-gate 		return (NULL);
27257c478bd9Sstevel@tonic-gate 	}
27267c478bd9Sstevel@tonic-gate 	if ((*size = pool_rs_count(rs)) == 0) {
27277c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
27287c478bd9Sstevel@tonic-gate 		return (NULL);
27297c478bd9Sstevel@tonic-gate 	}
27307c478bd9Sstevel@tonic-gate 	if ((result = malloc(sizeof (pool_component_t *) * (*size + 1)))
27317c478bd9Sstevel@tonic-gate 	    == NULL) {
27327c478bd9Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
27337c478bd9Sstevel@tonic-gate 		(void) pool_rs_close(rs);
27347c478bd9Sstevel@tonic-gate 		return (NULL);
27357c478bd9Sstevel@tonic-gate 	}
27367c478bd9Sstevel@tonic-gate 	(void) memset(result, 0, sizeof (pool_component_t *) * (*size + 1));
27377c478bd9Sstevel@tonic-gate 	for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
27387c478bd9Sstevel@tonic-gate 		if (pool_elem_class(pe) != PEC_COMP) {
27397c478bd9Sstevel@tonic-gate 			pool_seterror(POE_INVALID_CONF);
27407c478bd9Sstevel@tonic-gate 			free(result);
27417c478bd9Sstevel@tonic-gate 			(void) pool_rs_close(rs);
27427c478bd9Sstevel@tonic-gate 			return (NULL);
27437c478bd9Sstevel@tonic-gate 		}
27447c478bd9Sstevel@tonic-gate 		result[i++] = pool_elem_comp(pe);
27457c478bd9Sstevel@tonic-gate 	}
27467c478bd9Sstevel@tonic-gate 	(void) pool_rs_close(rs);
27477c478bd9Sstevel@tonic-gate 	return (result);
27487c478bd9Sstevel@tonic-gate }
27497c478bd9Sstevel@tonic-gate 
27507c478bd9Sstevel@tonic-gate /*
27517c478bd9Sstevel@tonic-gate  * pool_version() returns the version of this library, depending on the supplied
27527c478bd9Sstevel@tonic-gate  * parameter.
27537c478bd9Sstevel@tonic-gate  *
27547c478bd9Sstevel@tonic-gate  * Returns: library version depening on the supplied ver parameter.
27557c478bd9Sstevel@tonic-gate  */
27567c478bd9Sstevel@tonic-gate uint_t
pool_version(uint_t ver)27577c478bd9Sstevel@tonic-gate pool_version(uint_t ver)
27587c478bd9Sstevel@tonic-gate {
27597c478bd9Sstevel@tonic-gate 	switch (ver) {
27607c478bd9Sstevel@tonic-gate 	case POOL_VER_NONE:
27617c478bd9Sstevel@tonic-gate 		break;
27627c478bd9Sstevel@tonic-gate 	case POOL_VER_CURRENT:
27637c478bd9Sstevel@tonic-gate 		pool_workver = ver;
27647c478bd9Sstevel@tonic-gate 		break;
27657c478bd9Sstevel@tonic-gate 	default:
27667c478bd9Sstevel@tonic-gate 		return (POOL_VER_NONE);
27677c478bd9Sstevel@tonic-gate 	}
27687c478bd9Sstevel@tonic-gate 	return (pool_workver);
27697c478bd9Sstevel@tonic-gate }
27707c478bd9Sstevel@tonic-gate 
27717c478bd9Sstevel@tonic-gate /*
27727c478bd9Sstevel@tonic-gate  * pool_associate() associates the supplied resource to the supplied pool.
27737c478bd9Sstevel@tonic-gate  *
27747c478bd9Sstevel@tonic-gate  * Returns: PO_SUCCESS/PO_FAIL
27757c478bd9Sstevel@tonic-gate  */
27767c478bd9Sstevel@tonic-gate int
pool_associate(pool_conf_t * conf,pool_t * pool,const pool_resource_t * res)27777c478bd9Sstevel@tonic-gate pool_associate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res)
27787c478bd9Sstevel@tonic-gate {
27797c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
27807c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
27817c478bd9Sstevel@tonic-gate 
27827c478bd9Sstevel@tonic-gate 	return (pool->pp_associate(pool, res));
27837c478bd9Sstevel@tonic-gate }
27847c478bd9Sstevel@tonic-gate 
27857c478bd9Sstevel@tonic-gate /*
27867c478bd9Sstevel@tonic-gate  * pool_dissociate() dissociates the supplied resource from the supplied pool.
27877c478bd9Sstevel@tonic-gate  *
27887c478bd9Sstevel@tonic-gate  * Returns: PO_SUCCESS/PO_FAIL
27897c478bd9Sstevel@tonic-gate  */
27907c478bd9Sstevel@tonic-gate int
pool_dissociate(pool_conf_t * conf,pool_t * pool,const pool_resource_t * res)27917c478bd9Sstevel@tonic-gate pool_dissociate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res)
27927c478bd9Sstevel@tonic-gate {
27937c478bd9Sstevel@tonic-gate 	if (pool_conf_check(conf) != PO_SUCCESS)
27947c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
27957c478bd9Sstevel@tonic-gate 
27967c478bd9Sstevel@tonic-gate 	if (elem_is_default(TO_ELEM(res)))
27977c478bd9Sstevel@tonic-gate 		return (PO_SUCCESS);
27987c478bd9Sstevel@tonic-gate 	return (pool->pp_dissociate(pool, res));
27997c478bd9Sstevel@tonic-gate }
28007c478bd9Sstevel@tonic-gate 
28017c478bd9Sstevel@tonic-gate /*
28027c478bd9Sstevel@tonic-gate  * Compare two elements for purposes of ordering.
28037c478bd9Sstevel@tonic-gate  * Return:
28047c478bd9Sstevel@tonic-gate  *	< 0 if e1 is "before" e2
28057c478bd9Sstevel@tonic-gate  *	0 if e1 "equals" e2
28067c478bd9Sstevel@tonic-gate  *	> 0 if e1 comes after e2
28077c478bd9Sstevel@tonic-gate  */
28087c478bd9Sstevel@tonic-gate int
pool_elem_compare_name(const pool_elem_t * e1,const pool_elem_t * e2)28097c478bd9Sstevel@tonic-gate pool_elem_compare_name(const pool_elem_t *e1, const pool_elem_t *e2)
28107c478bd9Sstevel@tonic-gate {
28117c478bd9Sstevel@tonic-gate 	char *name1, *name2;
28127c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
28137c478bd9Sstevel@tonic-gate 	int retval;
28147c478bd9Sstevel@tonic-gate 
28157c478bd9Sstevel@tonic-gate 	/*
28167c478bd9Sstevel@tonic-gate 	 * We may be asked to compare two elements from different classes.
28177c478bd9Sstevel@tonic-gate 	 * They are different so return (1).
28187c478bd9Sstevel@tonic-gate 	 */
28197c478bd9Sstevel@tonic-gate 	if (pool_elem_same_class(e1, e2) != PO_TRUE)
28207c478bd9Sstevel@tonic-gate 		return (1);
28217c478bd9Sstevel@tonic-gate 
28227c478bd9Sstevel@tonic-gate 	/*
28237c478bd9Sstevel@tonic-gate 	 * If the class is PEC_SYSTEM, always match them
28247c478bd9Sstevel@tonic-gate 	 */
28257c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) == PEC_SYSTEM)
28267c478bd9Sstevel@tonic-gate 		return (0);
28277c478bd9Sstevel@tonic-gate 
28287c478bd9Sstevel@tonic-gate 	/*
28297c478bd9Sstevel@tonic-gate 	 * If we are going to compare components, then use sys_id
28307c478bd9Sstevel@tonic-gate 	 */
28317c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) == PEC_COMP) {
28327c478bd9Sstevel@tonic-gate 		int64_t sys_id1, sys_id2;
28337c478bd9Sstevel@tonic-gate 
28347c478bd9Sstevel@tonic-gate 		if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) {
28357c478bd9Sstevel@tonic-gate 			return (-1);
28367c478bd9Sstevel@tonic-gate 		}
28377c478bd9Sstevel@tonic-gate 		(void) pool_value_get_int64(&val, &sys_id1);
28387c478bd9Sstevel@tonic-gate 		if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) {
28397c478bd9Sstevel@tonic-gate 			return (-1);
28407c478bd9Sstevel@tonic-gate 		}
28417c478bd9Sstevel@tonic-gate 		(void) pool_value_get_int64(&val, &sys_id2);
28427c478bd9Sstevel@tonic-gate 		retval = (sys_id1 - sys_id2);
28437c478bd9Sstevel@tonic-gate 	} else {
28447c478bd9Sstevel@tonic-gate 		if (pool_get_ns_property(e1, "name", &val) == POC_INVAL) {
28457c478bd9Sstevel@tonic-gate 			return (-1);
28467c478bd9Sstevel@tonic-gate 		}
28477c478bd9Sstevel@tonic-gate 		(void) pool_value_get_string(&val, (const char **)&name1);
28487c478bd9Sstevel@tonic-gate 		if ((name1 = strdup(name1)) == NULL) {
28497c478bd9Sstevel@tonic-gate 			return (-1);
28507c478bd9Sstevel@tonic-gate 		}
28517c478bd9Sstevel@tonic-gate 
28527c478bd9Sstevel@tonic-gate 		if (pool_get_ns_property(e2, "name", &val) == POC_INVAL) {
28537c478bd9Sstevel@tonic-gate 			return (-1);
28547c478bd9Sstevel@tonic-gate 		}
28557c478bd9Sstevel@tonic-gate 
28567c478bd9Sstevel@tonic-gate 		(void) pool_value_get_string(&val, (const char **)&name2);
28577c478bd9Sstevel@tonic-gate 		retval = strcmp(name1, name2);
28587c478bd9Sstevel@tonic-gate 		free(name1);
28597c478bd9Sstevel@tonic-gate 	}
28607c478bd9Sstevel@tonic-gate 	return (retval);
28617c478bd9Sstevel@tonic-gate }
28627c478bd9Sstevel@tonic-gate 
28637c478bd9Sstevel@tonic-gate /*
28647c478bd9Sstevel@tonic-gate  * Compare two elements for purposes of ordering.
28657c478bd9Sstevel@tonic-gate  * Return:
28667c478bd9Sstevel@tonic-gate  *	< 0 if e1 is "before" e2
28677c478bd9Sstevel@tonic-gate  *	0 if e1 "equals" e2
28687c478bd9Sstevel@tonic-gate  *	> 0 if e1 comes after e2
28697c478bd9Sstevel@tonic-gate  */
28707c478bd9Sstevel@tonic-gate int
pool_elem_compare(const pool_elem_t * e1,const pool_elem_t * e2)28717c478bd9Sstevel@tonic-gate pool_elem_compare(const pool_elem_t *e1, const pool_elem_t *e2)
28727c478bd9Sstevel@tonic-gate {
28737c478bd9Sstevel@tonic-gate 	pool_value_t val = POOL_VALUE_INITIALIZER;
28747c478bd9Sstevel@tonic-gate 	int64_t sys_id1, sys_id2;
28757c478bd9Sstevel@tonic-gate 
28767c478bd9Sstevel@tonic-gate 	/*
28777c478bd9Sstevel@tonic-gate 	 * We may be asked to compare two elements from different classes.
28787c478bd9Sstevel@tonic-gate 	 * They are different so return the difference in their classes
28797c478bd9Sstevel@tonic-gate 	 */
28807c478bd9Sstevel@tonic-gate 	if (pool_elem_same_class(e1, e2) != PO_TRUE)
28817c478bd9Sstevel@tonic-gate 		return (1);
28827c478bd9Sstevel@tonic-gate 
28837c478bd9Sstevel@tonic-gate 	/*
28847c478bd9Sstevel@tonic-gate 	 * If the class is PEC_SYSTEM, always match them
28857c478bd9Sstevel@tonic-gate 	 */
28867c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) == PEC_SYSTEM)
28877c478bd9Sstevel@tonic-gate 		return (0);
28887c478bd9Sstevel@tonic-gate 
28897c478bd9Sstevel@tonic-gate 	/*
28907c478bd9Sstevel@tonic-gate 	 * Compare with sys_id
28917c478bd9Sstevel@tonic-gate 	 */
28927c478bd9Sstevel@tonic-gate 	if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) {
28937c478bd9Sstevel@tonic-gate 		assert(!"no sys_id on e1\n");
28947c478bd9Sstevel@tonic-gate 	}
28957c478bd9Sstevel@tonic-gate 	(void) pool_value_get_int64(&val, &sys_id1);
28967c478bd9Sstevel@tonic-gate 	if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) {
28977c478bd9Sstevel@tonic-gate 		assert(!"no sys_id on e2\n");
28987c478bd9Sstevel@tonic-gate 	}
28997c478bd9Sstevel@tonic-gate 	(void) pool_value_get_int64(&val, &sys_id2);
29007c478bd9Sstevel@tonic-gate 	return (sys_id1 - sys_id2);
29017c478bd9Sstevel@tonic-gate }
29027c478bd9Sstevel@tonic-gate 
29037c478bd9Sstevel@tonic-gate /*
29047c478bd9Sstevel@tonic-gate  * Return PO_TRUE if the supplied elems are of the same class.
29057c478bd9Sstevel@tonic-gate  */
29067c478bd9Sstevel@tonic-gate int
pool_elem_same_class(const pool_elem_t * e1,const pool_elem_t * e2)29077c478bd9Sstevel@tonic-gate pool_elem_same_class(const pool_elem_t *e1, const pool_elem_t *e2)
29087c478bd9Sstevel@tonic-gate {
29097c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) != pool_elem_class(e2))
29107c478bd9Sstevel@tonic-gate 		return (PO_FALSE);
29117c478bd9Sstevel@tonic-gate 
29127c478bd9Sstevel@tonic-gate 	/*
29137c478bd9Sstevel@tonic-gate 	 * Check to make sure the fundamental class of the elements match
29147c478bd9Sstevel@tonic-gate 	 */
29157c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) == PEC_RES_COMP ||
29167c478bd9Sstevel@tonic-gate 	    pool_elem_class(e1) == PEC_RES_AGG)
29177c478bd9Sstevel@tonic-gate 		if (pool_resource_elem_class(e1) !=
29187c478bd9Sstevel@tonic-gate 		    pool_resource_elem_class(e2))
29197c478bd9Sstevel@tonic-gate 			return (PO_FALSE);
29207c478bd9Sstevel@tonic-gate 	if (pool_elem_class(e1) == PEC_COMP)
29217c478bd9Sstevel@tonic-gate 		if (pool_component_elem_class(e1) !=
29227c478bd9Sstevel@tonic-gate 		    pool_component_elem_class(e2))
29237c478bd9Sstevel@tonic-gate 			return (PO_FALSE);
29247c478bd9Sstevel@tonic-gate 	return (PO_TRUE);
29257c478bd9Sstevel@tonic-gate }
29267c478bd9Sstevel@tonic-gate 
29277c478bd9Sstevel@tonic-gate /*
29287c478bd9Sstevel@tonic-gate  * pool_conf_check() checks that the configuration state isn't invalid
29297c478bd9Sstevel@tonic-gate  * and that the configuration was opened for modification.
29307c478bd9Sstevel@tonic-gate  */
29317c478bd9Sstevel@tonic-gate int
pool_conf_check(const pool_conf_t * conf)29327c478bd9Sstevel@tonic-gate pool_conf_check(const pool_conf_t *conf)
29337c478bd9Sstevel@tonic-gate {
29347c478bd9Sstevel@tonic-gate 	if (pool_conf_status(conf) == POF_INVALID) {
29357c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
29367c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
29377c478bd9Sstevel@tonic-gate 	}
29387c478bd9Sstevel@tonic-gate 
29397c478bd9Sstevel@tonic-gate 	if ((conf->pc_prov->pc_oflags & PO_RDWR) == 0) {
29407c478bd9Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
29417c478bd9Sstevel@tonic-gate 		return (PO_FAIL);
29427c478bd9Sstevel@tonic-gate 	}
29437c478bd9Sstevel@tonic-gate 	return (PO_SUCCESS);
29447c478bd9Sstevel@tonic-gate }
2945