10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51823Sgarypen * Common Development and Distribution License (the "License").
61823Sgarypen * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
211823Sgarypen
220Sstevel@tonic-gate /*
23*3864Sraf * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <assert.h>
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <stdlib.h>
320Sstevel@tonic-gate #include <string.h>
330Sstevel@tonic-gate #include <thread.h>
34*3864Sraf #include <pthread.h>
350Sstevel@tonic-gate #include <synch.h>
360Sstevel@tonic-gate #include <unistd.h>
370Sstevel@tonic-gate #include <stropts.h>
380Sstevel@tonic-gate #include <fcntl.h>
390Sstevel@tonic-gate #include <note.h>
400Sstevel@tonic-gate #include <errno.h>
410Sstevel@tonic-gate #include <ctype.h>
420Sstevel@tonic-gate #include <libintl.h>
433251Ssl108498 #include <libscf.h>
440Sstevel@tonic-gate #include <pool.h>
450Sstevel@tonic-gate #include <signal.h>
460Sstevel@tonic-gate
470Sstevel@tonic-gate #include <sys/pool.h>
480Sstevel@tonic-gate #include <sys/priocntl.h>
490Sstevel@tonic-gate #include <sys/types.h>
500Sstevel@tonic-gate #include <sys/stat.h>
510Sstevel@tonic-gate #include <sys/wait.h>
520Sstevel@tonic-gate
530Sstevel@tonic-gate #include "pool_internal.h"
540Sstevel@tonic-gate #include "pool_impl.h"
550Sstevel@tonic-gate
560Sstevel@tonic-gate /*
570Sstevel@tonic-gate * libpool Interface Routines
580Sstevel@tonic-gate *
590Sstevel@tonic-gate * pool.c implements (most of) the external interface to libpool
600Sstevel@tonic-gate * users. Some of the interface is implemented in pool_internal.c for
610Sstevel@tonic-gate * reasons of internal code organisation. The core requirements for
620Sstevel@tonic-gate * pool.c are:
630Sstevel@tonic-gate *
640Sstevel@tonic-gate * Data Abstraction
650Sstevel@tonic-gate *
660Sstevel@tonic-gate * The abstraction of the actual datastore so that no details of the
670Sstevel@tonic-gate * underlying data representation mechanism are revealed to users of
680Sstevel@tonic-gate * the library. For instance, the fact that we use the kernel or files
690Sstevel@tonic-gate * to store our configurations is completely abstracted via the
700Sstevel@tonic-gate * various libpool APIs.
710Sstevel@tonic-gate *
720Sstevel@tonic-gate * External Interaction
730Sstevel@tonic-gate *
740Sstevel@tonic-gate * libpool users manipulate configuration components via the API
750Sstevel@tonic-gate * defined in pool.h. Most functions in this file act as interceptors,
760Sstevel@tonic-gate * validating parameters before redirecting the request into a
770Sstevel@tonic-gate * specific datastore implementation for the actual work to be done.
780Sstevel@tonic-gate *
790Sstevel@tonic-gate * These main sets of requirements have driven the design so that it
800Sstevel@tonic-gate * is possible to replace the entire datastore type without having to
810Sstevel@tonic-gate * modify the external (or internal provider) APIs. It is possible to
820Sstevel@tonic-gate * modify the storage technology used by libpool by implementing a new
830Sstevel@tonic-gate * set of datastore provider operations. Simply modify the
840Sstevel@tonic-gate * pool_conf_open() routine to establish a new datastore as the
850Sstevel@tonic-gate * provider for a configuration.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * The key components in a libpool configuration are :
880Sstevel@tonic-gate * pool_conf_t - This represents a complete configuration instance
890Sstevel@tonic-gate * pool_t - A pool inside a configuration
900Sstevel@tonic-gate * pool_resource_t - A resource inside a configuration
910Sstevel@tonic-gate * pool_component_t - A component of a resource
920Sstevel@tonic-gate *
930Sstevel@tonic-gate */
940Sstevel@tonic-gate
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate * Used to control transfer setup.
970Sstevel@tonic-gate */
980Sstevel@tonic-gate #define XFER_FAIL PO_FAIL
990Sstevel@tonic-gate #define XFER_SUCCESS PO_SUCCESS
1000Sstevel@tonic-gate #define XFER_CONTINUE 1
1010Sstevel@tonic-gate
1021042Sgarypen #define SMF_SVC_INSTANCE "svc:/system/pools:default"
1030Sstevel@tonic-gate #define E_ERROR 1 /* Exit status for error */
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate #ifndef TEXT_DOMAIN
1060Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
1070Sstevel@tonic-gate #endif /* TEXT_DOMAIN */
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate const char pool_info_location[] = "/dev/pool";
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate /*
1120Sstevel@tonic-gate * Static data
1130Sstevel@tonic-gate */
1140Sstevel@tonic-gate static const char static_location[] = "/etc/pooladm.conf";
1150Sstevel@tonic-gate static const char dynamic_location[] = "/dev/poolctl";
116*3864Sraf static thread_key_t errkey = THR_ONCE_KEY;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate /*
1190Sstevel@tonic-gate * libpool error code
1200Sstevel@tonic-gate */
1210Sstevel@tonic-gate static int pool_errval = POE_OK;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate * libpool version
1250Sstevel@tonic-gate */
1260Sstevel@tonic-gate static uint_t pool_workver = POOL_VER_CURRENT;
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate static const char *data_type_tags[] = {
1290Sstevel@tonic-gate "uint",
1300Sstevel@tonic-gate "int",
1310Sstevel@tonic-gate "float",
1320Sstevel@tonic-gate "boolean",
1330Sstevel@tonic-gate "string"
1340Sstevel@tonic-gate };
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate /*
1370Sstevel@tonic-gate * static functions
1380Sstevel@tonic-gate */
1390Sstevel@tonic-gate static int pool_elem_remove(pool_elem_t *);
1400Sstevel@tonic-gate static int is_valid_prop_name(const char *);
1410Sstevel@tonic-gate static int prop_buf_build_cb(pool_conf_t *, pool_elem_t *, const char *,
1420Sstevel@tonic-gate pool_value_t *, void *);
1430Sstevel@tonic-gate static char *pool_base_info(const pool_elem_t *, char_buf_t *, int);
1440Sstevel@tonic-gate static int choose_components(pool_resource_t *, pool_resource_t *, uint64_t);
1450Sstevel@tonic-gate static int pool_conf_check(const pool_conf_t *);
1460Sstevel@tonic-gate static void free_value_list(int, pool_value_t **);
1470Sstevel@tonic-gate static int setup_transfer(pool_conf_t *, pool_resource_t *, pool_resource_t *,
1480Sstevel@tonic-gate uint64_t, uint64_t *, uint64_t *);
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate * Return the "static" location string for libpool.
1520Sstevel@tonic-gate */
1530Sstevel@tonic-gate const char *
pool_static_location(void)1540Sstevel@tonic-gate pool_static_location(void)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate return (static_location);
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate
1590Sstevel@tonic-gate /*
1600Sstevel@tonic-gate * Return the "dynamic" location string for libpool.
1610Sstevel@tonic-gate */
1620Sstevel@tonic-gate const char *
pool_dynamic_location(void)1630Sstevel@tonic-gate pool_dynamic_location(void)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate return (dynamic_location);
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate * Return the status for a configuration. If the configuration has
1700Sstevel@tonic-gate * been successfully opened, then the status will be POF_VALID or
1710Sstevel@tonic-gate * POF_DESTROY. If the configuration failed to open properly or has
1720Sstevel@tonic-gate * been closed or removed, then the status will be POF_INVALID.
1730Sstevel@tonic-gate */
1740Sstevel@tonic-gate pool_conf_state_t
pool_conf_status(const pool_conf_t * conf)1750Sstevel@tonic-gate pool_conf_status(const pool_conf_t *conf)
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate return (conf->pc_state);
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate /*
1810Sstevel@tonic-gate * Bind idtype id to the pool name.
1820Sstevel@tonic-gate */
1830Sstevel@tonic-gate int
pool_set_binding(const char * pool_name,idtype_t idtype,id_t id)1840Sstevel@tonic-gate pool_set_binding(const char *pool_name, idtype_t idtype, id_t id)
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate pool_conf_t *conf;
1870Sstevel@tonic-gate int result;
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate if ((conf = pool_conf_alloc()) == NULL)
1900Sstevel@tonic-gate return (PO_FAIL);
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) < 0) {
1930Sstevel@tonic-gate pool_conf_free(conf);
1940Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
1950Sstevel@tonic-gate return (PO_FAIL);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate result = conf->pc_prov->pc_set_binding(conf, pool_name, idtype, id);
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate (void) pool_conf_close(conf);
2010Sstevel@tonic-gate pool_conf_free(conf);
2020Sstevel@tonic-gate return (result);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate /*
2060Sstevel@tonic-gate * pool_get_resource_binding() returns the binding for a pid to the supplied
2070Sstevel@tonic-gate * type of resource. If a binding cannot be determined, NULL is returned.
2080Sstevel@tonic-gate */
2090Sstevel@tonic-gate char *
pool_get_resource_binding(const char * sz_type,pid_t pid)2100Sstevel@tonic-gate pool_get_resource_binding(const char *sz_type, pid_t pid)
2110Sstevel@tonic-gate {
2120Sstevel@tonic-gate pool_conf_t *conf;
2130Sstevel@tonic-gate char *result;
2140Sstevel@tonic-gate pool_resource_elem_class_t type;
2150Sstevel@tonic-gate
2160Sstevel@tonic-gate if ((type = pool_resource_elem_class_from_string(sz_type)) ==
2170Sstevel@tonic-gate PREC_INVALID) {
2180Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
2190Sstevel@tonic-gate return (NULL);
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate if ((conf = pool_conf_alloc()) == NULL)
2230Sstevel@tonic-gate return (NULL);
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
2260Sstevel@tonic-gate != PO_SUCCESS) {
2270Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
2280Sstevel@tonic-gate pool_conf_free(conf);
2290Sstevel@tonic-gate return (NULL);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate result = conf->pc_prov->pc_get_resource_binding(conf, type, pid);
2320Sstevel@tonic-gate (void) pool_conf_close(conf);
2330Sstevel@tonic-gate pool_conf_free(conf);
2340Sstevel@tonic-gate return (result);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate * pool_get_binding() returns the binding for a pid to a pool. If a
2390Sstevel@tonic-gate * binding cannot be determined, NULL is returned.
2400Sstevel@tonic-gate */
2410Sstevel@tonic-gate char *
pool_get_binding(pid_t pid)2420Sstevel@tonic-gate pool_get_binding(pid_t pid)
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate pool_conf_t *conf;
2450Sstevel@tonic-gate char *result;
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate if ((conf = pool_conf_alloc()) == NULL)
2480Sstevel@tonic-gate return (NULL);
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
2510Sstevel@tonic-gate != PO_SUCCESS) {
2520Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
2530Sstevel@tonic-gate pool_conf_free(conf);
2540Sstevel@tonic-gate return (NULL);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate result = conf->pc_prov->pc_get_binding(conf, pid);
2570Sstevel@tonic-gate (void) pool_conf_close(conf);
2580Sstevel@tonic-gate pool_conf_free(conf);
2590Sstevel@tonic-gate return (result);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate /*ARGSUSED*/
2630Sstevel@tonic-gate int
prop_buf_build_cb(pool_conf_t * UNUSED,pool_elem_t * pe,const char * name,pool_value_t * pval,void * user)2640Sstevel@tonic-gate prop_buf_build_cb(pool_conf_t *UNUSED, pool_elem_t *pe, const char *name,
2650Sstevel@tonic-gate pool_value_t *pval, void *user)
2660Sstevel@tonic-gate {
2670Sstevel@tonic-gate uint64_t u;
2680Sstevel@tonic-gate int64_t i;
2690Sstevel@tonic-gate uchar_t bool;
2700Sstevel@tonic-gate const char *str;
2710Sstevel@tonic-gate double d;
2720Sstevel@tonic-gate char_buf_t *cb = (char_buf_t *)user;
2730Sstevel@tonic-gate int type = pool_value_get_type(pval);
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate /*
2760Sstevel@tonic-gate * Ignore "type" and "<type>.name" properties as these are not
2770Sstevel@tonic-gate * to be displayed by this function
2780Sstevel@tonic-gate */
2790Sstevel@tonic-gate if (strcmp(name, c_type) == 0 ||
2800Sstevel@tonic-gate strcmp(property_name_minus_ns(pe, name), c_name) == 0)
2810Sstevel@tonic-gate return (PO_SUCCESS);
2820Sstevel@tonic-gate if (append_char_buf(cb, "\n%s\t%s\t%s ", cb->cb_tab_buf,
2830Sstevel@tonic-gate data_type_tags[type], name) == PO_FAIL)
2840Sstevel@tonic-gate return (PO_FAIL);
2850Sstevel@tonic-gate switch (type) {
2860Sstevel@tonic-gate case POC_UINT:
2870Sstevel@tonic-gate (void) pool_value_get_uint64(pval, &u);
2880Sstevel@tonic-gate if (append_char_buf(cb, "%llu", (u_longlong_t)u) == PO_FAIL)
2890Sstevel@tonic-gate return (PO_FAIL);
2900Sstevel@tonic-gate break;
2910Sstevel@tonic-gate case POC_INT:
2920Sstevel@tonic-gate (void) pool_value_get_int64(pval, &i);
2930Sstevel@tonic-gate if (append_char_buf(cb, "%lld", (longlong_t)i) == PO_FAIL)
2940Sstevel@tonic-gate return (PO_FAIL);
2950Sstevel@tonic-gate break;
2960Sstevel@tonic-gate case POC_STRING:
2970Sstevel@tonic-gate (void) pool_value_get_string(pval, &str);
2980Sstevel@tonic-gate if (append_char_buf(cb, "%s", str) == PO_FAIL)
2990Sstevel@tonic-gate return (PO_FAIL);
3000Sstevel@tonic-gate break;
3010Sstevel@tonic-gate case POC_BOOL:
3020Sstevel@tonic-gate (void) pool_value_get_bool(pval, &bool);
3030Sstevel@tonic-gate if (bool == 0) {
3040Sstevel@tonic-gate if (append_char_buf(cb, "%s", "false") == PO_FAIL)
3050Sstevel@tonic-gate return (PO_FAIL);
3060Sstevel@tonic-gate } else {
3070Sstevel@tonic-gate if (append_char_buf(cb, "%s", "true") == PO_FAIL)
3080Sstevel@tonic-gate return (PO_FAIL);
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate break;
3110Sstevel@tonic-gate case POC_DOUBLE:
3120Sstevel@tonic-gate (void) pool_value_get_double(pval, &d);
3130Sstevel@tonic-gate if (append_char_buf(cb, "%g", d) == PO_FAIL)
3140Sstevel@tonic-gate return (PO_FAIL);
3150Sstevel@tonic-gate break;
3160Sstevel@tonic-gate case POC_INVAL: /* Do nothing */
3170Sstevel@tonic-gate break;
3180Sstevel@tonic-gate default:
3190Sstevel@tonic-gate return (PO_FAIL);
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate return (PO_SUCCESS);
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate /*
3250Sstevel@tonic-gate * Return a buffer which describes the element
3260Sstevel@tonic-gate * pe is a pointer to the element
3270Sstevel@tonic-gate * deep is PO_TRUE/PO_FALSE to indicate whether children should be included
3280Sstevel@tonic-gate */
3290Sstevel@tonic-gate char *
pool_base_info(const pool_elem_t * pe,char_buf_t * cb,int deep)3300Sstevel@tonic-gate pool_base_info(const pool_elem_t *pe, char_buf_t *cb, int deep)
3310Sstevel@tonic-gate {
3320Sstevel@tonic-gate const char *sres;
3330Sstevel@tonic-gate uint_t i;
3340Sstevel@tonic-gate uint_t nelem;
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
3370Sstevel@tonic-gate pool_resource_t **rs;
3380Sstevel@tonic-gate pool_elem_t *elem;
3390Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(pe);
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate if (cb == NULL) {
3420Sstevel@tonic-gate char *ret = NULL;
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
3450Sstevel@tonic-gate return (NULL);
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate /*
3480Sstevel@tonic-gate * Populate the buffer with element details
3490Sstevel@tonic-gate */
3500Sstevel@tonic-gate (void) pool_base_info(pe, cb, deep);
3510Sstevel@tonic-gate if (cb->cb_buf)
3520Sstevel@tonic-gate ret = strdup(cb->cb_buf);
3530Sstevel@tonic-gate free_char_buf(cb);
3540Sstevel@tonic-gate return (ret);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate if (append_char_buf(cb, "\n%s%s", cb->cb_tab_buf,
3580Sstevel@tonic-gate pool_elem_class_string(pe)) == PO_FAIL) {
3590Sstevel@tonic-gate return (NULL);
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate if (pool_get_ns_property(pe, c_name, &val) == POC_STRING) {
3630Sstevel@tonic-gate (void) pool_value_get_string(&val, &sres);
3640Sstevel@tonic-gate if (append_char_buf(cb, " %s", sres) == PO_FAIL) {
3650Sstevel@tonic-gate return (NULL);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate /*
3700Sstevel@tonic-gate * Add in some details about the element
3710Sstevel@tonic-gate */
3720Sstevel@tonic-gate if (pool_walk_properties(conf, (pool_elem_t *)pe, cb,
3730Sstevel@tonic-gate prop_buf_build_cb) == PO_FAIL) {
3740Sstevel@tonic-gate (void) append_char_buf(cb, "\n%s%s\n", cb->cb_tab_buf,
3750Sstevel@tonic-gate "Cannot access the properties of this element.");
3760Sstevel@tonic-gate return (NULL);
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate if (append_char_buf(cb, "%s", "\n") == PO_FAIL)
3790Sstevel@tonic-gate return (NULL);
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate if (pe->pe_class == PEC_POOL) {
3820Sstevel@tonic-gate /*
3830Sstevel@tonic-gate * A shallow display of a pool only lists the resources by name
3840Sstevel@tonic-gate */
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate if ((rs = pool_query_pool_resources(conf, pool_elem_pool(pe),
3870Sstevel@tonic-gate &nelem, NULL)) == NULL) {
3880Sstevel@tonic-gate return (NULL);
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate for (i = 0; i < nelem; i++) {
3920Sstevel@tonic-gate const char *str;
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate elem = TO_ELEM(rs[i]);
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate if (append_char_buf(cb, "\t%s%s", cb->cb_tab_buf,
3970Sstevel@tonic-gate pool_elem_class_string(elem)) == PO_FAIL) {
3980Sstevel@tonic-gate free(rs);
3990Sstevel@tonic-gate return (NULL);
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate if (pool_get_ns_property(elem, c_name, &val) !=
4030Sstevel@tonic-gate POC_STRING) {
4040Sstevel@tonic-gate free(rs);
4050Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
4060Sstevel@tonic-gate return (NULL);
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate (void) pool_value_get_string(&val, &str);
4090Sstevel@tonic-gate if (append_char_buf(cb, "\t%s\n", str) == PO_FAIL) {
4100Sstevel@tonic-gate free(rs);
4110Sstevel@tonic-gate return (NULL);
4120Sstevel@tonic-gate }
4130Sstevel@tonic-gate }
4140Sstevel@tonic-gate free(rs);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate if (deep == PO_TRUE) {
4170Sstevel@tonic-gate pool_t **ps;
4180Sstevel@tonic-gate pool_component_t **cs;
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate if (strlcat(cb->cb_tab_buf, "\t", CB_TAB_BUF_SIZE)
4210Sstevel@tonic-gate >= CB_TAB_BUF_SIZE) {
4220Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
4230Sstevel@tonic-gate return (NULL);
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate switch (pe->pe_class) {
4260Sstevel@tonic-gate case PEC_SYSTEM:
4270Sstevel@tonic-gate if ((ps = pool_query_pools(conf, &nelem, NULL)) !=
4280Sstevel@tonic-gate NULL) { /* process the pools */
4290Sstevel@tonic-gate for (i = 0; i < nelem; i++) {
4300Sstevel@tonic-gate elem = TO_ELEM(ps[i]);
4310Sstevel@tonic-gate if (pool_base_info(elem, cb,
4320Sstevel@tonic-gate PO_FALSE) == NULL) {
4330Sstevel@tonic-gate free(ps);
4340Sstevel@tonic-gate return (NULL);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate free(ps);
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate if ((rs = pool_query_resources(conf, &nelem, NULL)) !=
4400Sstevel@tonic-gate NULL) {
4410Sstevel@tonic-gate for (i = 0; i < nelem; i++) {
4420Sstevel@tonic-gate elem = TO_ELEM(rs[i]);
4430Sstevel@tonic-gate if (pool_base_info(elem, cb,
4440Sstevel@tonic-gate PO_TRUE) == NULL) {
4450Sstevel@tonic-gate free(rs);
4460Sstevel@tonic-gate return (NULL);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate free(rs);
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate break;
4520Sstevel@tonic-gate case PEC_POOL:
4530Sstevel@tonic-gate if ((rs = pool_query_pool_resources(conf,
4540Sstevel@tonic-gate pool_elem_pool(pe), &nelem, NULL)) == NULL)
4550Sstevel@tonic-gate return (NULL);
4560Sstevel@tonic-gate for (i = 0; i < nelem; i++) {
4570Sstevel@tonic-gate elem = TO_ELEM(rs[i]);
4580Sstevel@tonic-gate if (pool_base_info(elem, cb, PO_TRUE) == NULL) {
4590Sstevel@tonic-gate free(rs);
4600Sstevel@tonic-gate return (NULL);
4610Sstevel@tonic-gate }
4620Sstevel@tonic-gate }
4630Sstevel@tonic-gate free(rs);
4640Sstevel@tonic-gate break;
4650Sstevel@tonic-gate case PEC_RES_COMP:
4660Sstevel@tonic-gate if ((cs = pool_query_resource_components(conf,
4670Sstevel@tonic-gate pool_elem_res(pe), &nelem, NULL)) != NULL) {
4680Sstevel@tonic-gate for (i = 0; i < nelem; i++) {
4690Sstevel@tonic-gate elem = TO_ELEM(cs[i]);
4700Sstevel@tonic-gate if (pool_base_info(elem, cb,
4710Sstevel@tonic-gate PO_FALSE) == NULL) {
4720Sstevel@tonic-gate free(cs);
4730Sstevel@tonic-gate return (NULL);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate free(cs);
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate break;
4790Sstevel@tonic-gate case PEC_RES_AGG:
4800Sstevel@tonic-gate case PEC_COMP:
4810Sstevel@tonic-gate break;
4820Sstevel@tonic-gate default:
4830Sstevel@tonic-gate /*NOTREACHED*/
4840Sstevel@tonic-gate break;
4850Sstevel@tonic-gate }
4860Sstevel@tonic-gate if (cb->cb_tab_buf[0] != 0)
4870Sstevel@tonic-gate cb->cb_tab_buf[strlen(cb->cb_tab_buf) - 1] = 0;
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate return (cb->cb_buf);
4900Sstevel@tonic-gate }
4910Sstevel@tonic-gate
4920Sstevel@tonic-gate /*
4930Sstevel@tonic-gate * Returns The information on the specified pool or NULL.
4940Sstevel@tonic-gate *
4950Sstevel@tonic-gate * Errors If the status of the conf is INVALID or the supplied
4960Sstevel@tonic-gate * value of deep is illegal, POE_BADPARAM.
4970Sstevel@tonic-gate *
4980Sstevel@tonic-gate * The caller is responsible for free(3c)ing the string returned.
4990Sstevel@tonic-gate */
5000Sstevel@tonic-gate char *
pool_info(const pool_conf_t * conf,const pool_t * pool,int deep)5010Sstevel@tonic-gate pool_info(const pool_conf_t *conf, const pool_t *pool, int deep)
5020Sstevel@tonic-gate {
5030Sstevel@tonic-gate pool_elem_t *pe;
5040Sstevel@tonic-gate
5050Sstevel@tonic-gate pe = TO_ELEM(pool);
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate if (TO_CONF(pe) != conf) {
5080Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5090Sstevel@tonic-gate return (NULL);
5100Sstevel@tonic-gate }
5110Sstevel@tonic-gate
5120Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5130Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5140Sstevel@tonic-gate return (NULL);
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate return (pool_base_info(pe, NULL, deep));
5180Sstevel@tonic-gate }
5190Sstevel@tonic-gate
5200Sstevel@tonic-gate /*
5210Sstevel@tonic-gate * Returns The information on the specified resource or NULL.
5220Sstevel@tonic-gate *
5230Sstevel@tonic-gate * Errors If the status of the conf is INVALID or the supplied
5240Sstevel@tonic-gate * value of deep is illegal, POE_BADPARAM.
5250Sstevel@tonic-gate *
5260Sstevel@tonic-gate * The caller is responsible for free(3c)ing the string returned.
5270Sstevel@tonic-gate */
5280Sstevel@tonic-gate char *
pool_resource_info(const pool_conf_t * conf,const pool_resource_t * res,int deep)5290Sstevel@tonic-gate pool_resource_info(const pool_conf_t *conf, const pool_resource_t *res,
5300Sstevel@tonic-gate int deep)
5310Sstevel@tonic-gate {
5320Sstevel@tonic-gate pool_elem_t *pe;
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate pe = TO_ELEM(res);
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate if (TO_CONF(pe) != conf) {
5370Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5380Sstevel@tonic-gate return (NULL);
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5420Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5430Sstevel@tonic-gate return (NULL);
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate return (pool_base_info(pe, NULL, deep));
5470Sstevel@tonic-gate }
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate /*
5500Sstevel@tonic-gate * Returns The information on the specified component or NULL.
5510Sstevel@tonic-gate *
5520Sstevel@tonic-gate * Errors If the status of the conf is INVALID or the supplied
5530Sstevel@tonic-gate * value of deep is illegal, POE_BADPARAM.
5540Sstevel@tonic-gate *
5550Sstevel@tonic-gate * The caller is responsible for free(3c)ing the string returned.
5560Sstevel@tonic-gate */
5570Sstevel@tonic-gate char *
pool_component_info(const pool_conf_t * conf,const pool_component_t * comp,int deep)5580Sstevel@tonic-gate pool_component_info(const pool_conf_t *conf, const pool_component_t *comp,
5590Sstevel@tonic-gate int deep)
5600Sstevel@tonic-gate {
5610Sstevel@tonic-gate pool_elem_t *pe;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate pe = TO_ELEM(comp);
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate if (TO_CONF(pe) != conf) {
5660Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5670Sstevel@tonic-gate return (NULL);
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5710Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5720Sstevel@tonic-gate return (NULL);
5730Sstevel@tonic-gate }
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate return (pool_base_info(pe, NULL, deep));
5760Sstevel@tonic-gate }
5770Sstevel@tonic-gate
5780Sstevel@tonic-gate /*
5790Sstevel@tonic-gate * Returns The information on the specified conf or NULL.
5800Sstevel@tonic-gate *
5810Sstevel@tonic-gate * Errors If the status of the conf is INVALID or the supplied
5820Sstevel@tonic-gate * value of deep is illegal, POE_BADPARAM.
5830Sstevel@tonic-gate *
5840Sstevel@tonic-gate * The caller is responsible for free(3c)ing the string returned.
5850Sstevel@tonic-gate */
5860Sstevel@tonic-gate char *
pool_conf_info(const pool_conf_t * conf,int deep)5870Sstevel@tonic-gate pool_conf_info(const pool_conf_t *conf, int deep)
5880Sstevel@tonic-gate {
5890Sstevel@tonic-gate pool_elem_t *pe;
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID || (deep & ~1)) {
5920Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5930Sstevel@tonic-gate return (NULL);
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate if ((pe = pool_conf_to_elem(conf)) == NULL) {
5960Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
5970Sstevel@tonic-gate return (NULL);
5980Sstevel@tonic-gate }
5990Sstevel@tonic-gate return (pool_base_info(pe, NULL, deep));
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate /*
6040Sstevel@tonic-gate * Set the thread specific error value.
6050Sstevel@tonic-gate */
6060Sstevel@tonic-gate void
pool_seterror(int errval)6070Sstevel@tonic-gate pool_seterror(int errval)
6080Sstevel@tonic-gate {
6090Sstevel@tonic-gate if (thr_main()) {
6100Sstevel@tonic-gate pool_errval = errval;
6110Sstevel@tonic-gate return;
6120Sstevel@tonic-gate }
613*3864Sraf (void) thr_keycreate_once(&errkey, 0);
6140Sstevel@tonic-gate (void) thr_setspecific(errkey, (void *)(intptr_t)errval);
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate /*
6180Sstevel@tonic-gate * Return the current value of the error code.
6190Sstevel@tonic-gate * Returns: int error code
6200Sstevel@tonic-gate */
6210Sstevel@tonic-gate int
pool_error(void)6220Sstevel@tonic-gate pool_error(void)
6230Sstevel@tonic-gate {
6240Sstevel@tonic-gate if (thr_main())
6250Sstevel@tonic-gate return (pool_errval);
626*3864Sraf if (errkey == THR_ONCE_KEY)
6270Sstevel@tonic-gate return (POE_OK);
628*3864Sraf return ((uintptr_t)pthread_getspecific(errkey));
6290Sstevel@tonic-gate }
6300Sstevel@tonic-gate
6310Sstevel@tonic-gate /*
6320Sstevel@tonic-gate * Return the text represenation for the current value of the error code.
6330Sstevel@tonic-gate * Returns: const char * error string
6340Sstevel@tonic-gate */
6350Sstevel@tonic-gate const char *
pool_strerror(int error)6360Sstevel@tonic-gate pool_strerror(int error)
6370Sstevel@tonic-gate {
6380Sstevel@tonic-gate char *str;
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate switch (error) {
6410Sstevel@tonic-gate case POE_OK:
6420Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Operation successful");
6430Sstevel@tonic-gate break;
6440Sstevel@tonic-gate case POE_BAD_PROP_TYPE:
6450Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN,
6460Sstevel@tonic-gate "Attempted to retrieve the wrong property type");
6470Sstevel@tonic-gate break;
6480Sstevel@tonic-gate case POE_INVALID_CONF:
6490Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Invalid configuration");
6500Sstevel@tonic-gate break;
6510Sstevel@tonic-gate case POE_NOTSUP:
6520Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Operation is not supported");
6530Sstevel@tonic-gate break;
6540Sstevel@tonic-gate case POE_INVALID_SEARCH:
6550Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Invalid search");
6560Sstevel@tonic-gate break;
6570Sstevel@tonic-gate case POE_BADPARAM:
6580Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Bad parameter supplied");
6590Sstevel@tonic-gate break;
6600Sstevel@tonic-gate case POE_PUTPROP:
6610Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Error putting property");
6620Sstevel@tonic-gate break;
6630Sstevel@tonic-gate case POE_DATASTORE:
6640Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Pools repository error");
6650Sstevel@tonic-gate break;
6660Sstevel@tonic-gate case POE_SYSTEM:
6670Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "System error");
6680Sstevel@tonic-gate break;
6690Sstevel@tonic-gate case POE_ACCESS:
6700Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Permission denied");
6710Sstevel@tonic-gate break;
6720Sstevel@tonic-gate default:
6730Sstevel@tonic-gate errno = ESRCH;
6740Sstevel@tonic-gate str = NULL;
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate return (str);
6770Sstevel@tonic-gate }
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate int
pool_get_status(int * state)6800Sstevel@tonic-gate pool_get_status(int *state)
6810Sstevel@tonic-gate {
6820Sstevel@tonic-gate int fd;
6830Sstevel@tonic-gate pool_status_t status;
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate if ((fd = open(pool_info_location, O_RDONLY)) < 0) {
6860Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
6870Sstevel@tonic-gate return (PO_FAIL);
6880Sstevel@tonic-gate }
6890Sstevel@tonic-gate if (ioctl(fd, POOL_STATUSQ, &status) < 0) {
6900Sstevel@tonic-gate (void) close(fd);
6910Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
6920Sstevel@tonic-gate return (PO_FAIL);
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate (void) close(fd);
6950Sstevel@tonic-gate
6960Sstevel@tonic-gate *state = status.ps_io_state;
6970Sstevel@tonic-gate
6980Sstevel@tonic-gate return (PO_SUCCESS);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate int
pool_set_status(int state)7020Sstevel@tonic-gate pool_set_status(int state)
7030Sstevel@tonic-gate {
7040Sstevel@tonic-gate int old_state;
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate if (pool_get_status(&old_state) != PO_SUCCESS) {
7070Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
7080Sstevel@tonic-gate return (PO_FAIL);
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate if (old_state != state) {
7120Sstevel@tonic-gate int fd;
7130Sstevel@tonic-gate pool_status_t status;
7143251Ssl108498 char *fmri;
7150Sstevel@tonic-gate
7161042Sgarypen /*
7171042Sgarypen * Changing the status of pools is performed by enabling
7181042Sgarypen * or disabling the pools service instance. If this
7191042Sgarypen * function has not been invoked by startd then we simply
7201042Sgarypen * enable/disable the service and return success.
7211042Sgarypen *
7221042Sgarypen * There is no way to specify that state changes must be
7231042Sgarypen * synchronous using the library API as yet, so we use
7241042Sgarypen * the -s option provided by svcadm.
7251042Sgarypen */
7263251Ssl108498 fmri = getenv("SMF_FMRI");
7273251Ssl108498 if (fmri == NULL) {
7281042Sgarypen FILE *p;
7292706Sgarypen char *cmd;
7302706Sgarypen
7313251Ssl108498 if (state != 0) {
7322706Sgarypen cmd = "/usr/sbin/svcadm enable -s " \
7331042Sgarypen SMF_SVC_INSTANCE;
7341042Sgarypen } else {
7352706Sgarypen cmd = "/usr/sbin/svcadm disable -s " \
7361042Sgarypen SMF_SVC_INSTANCE;
7372706Sgarypen }
7382706Sgarypen if ((p = popen(cmd, "wF")) == NULL || pclose(p) != 0) {
7392706Sgarypen pool_seterror(POE_SYSTEM);
7402706Sgarypen return (PO_FAIL);
7410Sstevel@tonic-gate }
7421042Sgarypen return (PO_SUCCESS);
7430Sstevel@tonic-gate }
7440Sstevel@tonic-gate
7450Sstevel@tonic-gate if ((fd = open(pool_dynamic_location(), O_RDWR | O_EXCL)) < 0) {
7460Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
7470Sstevel@tonic-gate return (PO_FAIL);
7480Sstevel@tonic-gate }
7490Sstevel@tonic-gate
7503251Ssl108498 /*
7513251Ssl108498 * If pools are being enabled/disabled by another smf service,
7523251Ssl108498 * enable the smf service instance. This must be done
7533251Ssl108498 * asynchronously as one service cannot synchronously
7543251Ssl108498 * enable/disable another.
7553251Ssl108498 */
7563251Ssl108498 if (strcmp(fmri, SMF_SVC_INSTANCE) != 0) {
7573251Ssl108498 int res;
7583251Ssl108498
7593251Ssl108498 if (state != 0)
7603251Ssl108498 res = smf_enable_instance(SMF_SVC_INSTANCE, 0);
7613251Ssl108498 else
7623251Ssl108498 res = smf_disable_instance(SMF_SVC_INSTANCE, 0);
7633251Ssl108498
7643251Ssl108498 if (res != 0) {
7653251Ssl108498 (void) close(fd);
7663251Ssl108498 pool_seterror(POE_SYSTEM);
7673251Ssl108498 return (PO_FAIL);
7683251Ssl108498 }
7693251Ssl108498 }
7700Sstevel@tonic-gate status.ps_io_state = state;
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate if (ioctl(fd, POOL_STATUS, &status) < 0) {
7730Sstevel@tonic-gate (void) close(fd);
7740Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
7750Sstevel@tonic-gate return (PO_FAIL);
7760Sstevel@tonic-gate }
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate (void) close(fd);
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate }
7810Sstevel@tonic-gate return (PO_SUCCESS);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate /*
7850Sstevel@tonic-gate * General Data Provider Independent Access Methods
7860Sstevel@tonic-gate */
7870Sstevel@tonic-gate
7880Sstevel@tonic-gate /*
7890Sstevel@tonic-gate * Property manipulation code.
7900Sstevel@tonic-gate *
7910Sstevel@tonic-gate * The pool_(get|rm|set)_property() functions consult the plugins before
7920Sstevel@tonic-gate * looking at the actual configuration. This allows plugins to provide
7930Sstevel@tonic-gate * "virtual" properties that may not exist in the configuration file per se,
7940Sstevel@tonic-gate * but behave like regular properties. This also allows plugins to reserve
7950Sstevel@tonic-gate * certain properties as read-only, non-removable, etc.
7960Sstevel@tonic-gate *
7970Sstevel@tonic-gate * A negative value returned from the plugin denotes error, 0 means that the
7980Sstevel@tonic-gate * property request should be forwarded to the backend, and 1 means the request
7990Sstevel@tonic-gate * was satisfied by the plugin and should not be processed further.
8000Sstevel@tonic-gate *
8010Sstevel@tonic-gate * The (get|rm|set)_property() functions bypass the plugin layer completely,
8020Sstevel@tonic-gate * and hence should not be generally used.
8030Sstevel@tonic-gate */
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate /*
8060Sstevel@tonic-gate * Return true if the string passed in matches the pattern
8070Sstevel@tonic-gate * [A-Za-z][A-Za-z0-9,._-]*
8080Sstevel@tonic-gate */
8090Sstevel@tonic-gate int
is_valid_name(const char * name)8100Sstevel@tonic-gate is_valid_name(const char *name)
8110Sstevel@tonic-gate {
8120Sstevel@tonic-gate int i;
8130Sstevel@tonic-gate char c;
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate if (name == NULL)
8160Sstevel@tonic-gate return (PO_FALSE);
8170Sstevel@tonic-gate if (!isalpha(name[0]))
8180Sstevel@tonic-gate return (PO_FALSE);
8190Sstevel@tonic-gate for (i = 1; (c = name[i]) != '\0'; i++) {
8200Sstevel@tonic-gate if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-')
8210Sstevel@tonic-gate return (PO_FALSE);
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate return (PO_TRUE);
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate /*
8270Sstevel@tonic-gate * Return true if the string passed in matches the pattern
8280Sstevel@tonic-gate * [A-Za-z_][A-Za-z0-9,._-]*
8290Sstevel@tonic-gate * A property name starting with a '_' is an "invisible" property that does not
8300Sstevel@tonic-gate * show up in a property walk.
8310Sstevel@tonic-gate */
8320Sstevel@tonic-gate int
is_valid_prop_name(const char * prop_name)8330Sstevel@tonic-gate is_valid_prop_name(const char *prop_name)
8340Sstevel@tonic-gate {
8350Sstevel@tonic-gate int i;
8360Sstevel@tonic-gate char c;
8370Sstevel@tonic-gate
8380Sstevel@tonic-gate if (prop_name == NULL)
8390Sstevel@tonic-gate return (PO_FALSE);
8400Sstevel@tonic-gate if (!isalpha(prop_name[0]) && prop_name[0] != '_')
8410Sstevel@tonic-gate return (PO_FALSE);
8420Sstevel@tonic-gate for (i = 1; (c = prop_name[i]) != '\0'; i++) {
8430Sstevel@tonic-gate if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-')
8440Sstevel@tonic-gate return (PO_FALSE);
8450Sstevel@tonic-gate }
8460Sstevel@tonic-gate return (PO_TRUE);
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate /*
8500Sstevel@tonic-gate * Return the specified property value.
8510Sstevel@tonic-gate *
8520Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated
8530Sstevel@tonic-gate * to indicate the cause of the error.
8540Sstevel@tonic-gate */
8550Sstevel@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)8560Sstevel@tonic-gate pool_get_property(const pool_conf_t *conf, const pool_elem_t *pe,
8570Sstevel@tonic-gate const char *name, pool_value_t *val)
8580Sstevel@tonic-gate {
8590Sstevel@tonic-gate const pool_prop_t *prop_info;
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
8620Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
8630Sstevel@tonic-gate return (POC_INVAL);
8640Sstevel@tonic-gate }
8650Sstevel@tonic-gate if (pool_value_set_name(val, name) != PO_SUCCESS) {
8660Sstevel@tonic-gate return (POC_INVAL);
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate /*
8690Sstevel@tonic-gate * Check to see if this is a property we are managing. If it
8700Sstevel@tonic-gate * is and it has an interceptor installed for property
8710Sstevel@tonic-gate * retrieval, use it.
8720Sstevel@tonic-gate */
8730Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL &&
8740Sstevel@tonic-gate prop_info->pp_op.ppo_get_value != NULL) {
8750Sstevel@tonic-gate if (prop_info->pp_op.ppo_get_value(pe, val) == PO_FAIL)
8760Sstevel@tonic-gate return (POC_INVAL);
8770Sstevel@tonic-gate else
8780Sstevel@tonic-gate return (pool_value_get_type(val));
8790Sstevel@tonic-gate }
8800Sstevel@tonic-gate return (pe->pe_get_prop(pe, name, val));
8810Sstevel@tonic-gate }
8820Sstevel@tonic-gate
8830Sstevel@tonic-gate /*
8840Sstevel@tonic-gate * Return the specified property value with the namespace prepended.
8850Sstevel@tonic-gate * e.g. If this function is used to get the property "name" on a pool, it will
8860Sstevel@tonic-gate * attempt to retrieve "pool.name".
8870Sstevel@tonic-gate *
8880Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated
8890Sstevel@tonic-gate * to indicate the cause of the error.
8900Sstevel@tonic-gate */
8910Sstevel@tonic-gate pool_value_class_t
pool_get_ns_property(const pool_elem_t * pe,const char * name,pool_value_t * val)8920Sstevel@tonic-gate pool_get_ns_property(const pool_elem_t *pe, const char *name, pool_value_t *val)
8930Sstevel@tonic-gate {
8940Sstevel@tonic-gate int ret;
8950Sstevel@tonic-gate char_buf_t *cb;
8960Sstevel@tonic-gate
8970Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
8980Sstevel@tonic-gate return (POC_INVAL);
8990Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
9000Sstevel@tonic-gate PO_FAIL) {
9010Sstevel@tonic-gate free_char_buf(cb);
9020Sstevel@tonic-gate return (POC_INVAL);
9030Sstevel@tonic-gate }
9040Sstevel@tonic-gate ret = pool_get_property(TO_CONF(pe), pe, cb->cb_buf, val);
9050Sstevel@tonic-gate free_char_buf(cb);
9060Sstevel@tonic-gate return (ret);
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate
9090Sstevel@tonic-gate /*
9100Sstevel@tonic-gate * Update the specified property value.
9110Sstevel@tonic-gate *
9120Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated
9130Sstevel@tonic-gate * to indicate the cause of the error.
9140Sstevel@tonic-gate */
9150Sstevel@tonic-gate int
pool_put_property(pool_conf_t * conf,pool_elem_t * pe,const char * name,const pool_value_t * val)9160Sstevel@tonic-gate pool_put_property(pool_conf_t *conf, pool_elem_t *pe, const char *name,
9170Sstevel@tonic-gate const pool_value_t *val)
9180Sstevel@tonic-gate {
9190Sstevel@tonic-gate const pool_prop_t *prop_info;
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
9220Sstevel@tonic-gate return (PO_FAIL);
9230Sstevel@tonic-gate
9240Sstevel@tonic-gate if (TO_CONF(pe) != conf) {
9250Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
9260Sstevel@tonic-gate return (NULL);
9270Sstevel@tonic-gate }
9280Sstevel@tonic-gate
9293247Sgjelinek /* Don't allow (re)setting of the "temporary" property */
9303247Sgjelinek if (!is_valid_prop_name(name) || strstr(name, ".temporary") != NULL) {
9310Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
9320Sstevel@tonic-gate return (PO_FAIL);
9330Sstevel@tonic-gate }
9343247Sgjelinek
9353247Sgjelinek /* Don't allow rename of temporary pools/resources */
9363247Sgjelinek if (strstr(name, ".name") != NULL && elem_is_tmp(pe)) {
9373247Sgjelinek boolean_t rename = B_TRUE;
9383247Sgjelinek pool_value_t *pv = pool_value_alloc();
9393247Sgjelinek
9403247Sgjelinek if (pe->pe_get_prop(pe, name, pv) != POC_INVAL) {
9413247Sgjelinek const char *s1 = NULL;
9423247Sgjelinek const char *s2 = NULL;
9433247Sgjelinek
9443247Sgjelinek (void) pool_value_get_string(pv, &s1);
9453247Sgjelinek (void) pool_value_get_string(val, &s2);
9463247Sgjelinek if (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0)
9473247Sgjelinek rename = B_FALSE;
9483247Sgjelinek }
9493247Sgjelinek pool_value_free(pv);
9503247Sgjelinek
9513247Sgjelinek if (rename) {
9523247Sgjelinek pool_seterror(POE_BADPARAM);
9533247Sgjelinek return (PO_FAIL);
9543247Sgjelinek }
9553247Sgjelinek }
9563247Sgjelinek
9570Sstevel@tonic-gate /*
9580Sstevel@tonic-gate * Check to see if this is a property we are managing. If it is,
9590Sstevel@tonic-gate * ensure that we are happy with what the user is doing.
9600Sstevel@tonic-gate */
9610Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL) {
9620Sstevel@tonic-gate if (prop_is_readonly(prop_info) == PO_TRUE) {
9630Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
9640Sstevel@tonic-gate return (PO_FAIL);
9650Sstevel@tonic-gate }
9660Sstevel@tonic-gate if (prop_info->pp_op.ppo_set_value &&
9670Sstevel@tonic-gate prop_info->pp_op.ppo_set_value(pe, val) == PO_FAIL)
9680Sstevel@tonic-gate return (PO_FAIL);
9690Sstevel@tonic-gate }
9700Sstevel@tonic-gate
9710Sstevel@tonic-gate return (pe->pe_put_prop(pe, name, val));
9720Sstevel@tonic-gate }
9730Sstevel@tonic-gate
9740Sstevel@tonic-gate /*
9753247Sgjelinek * Set temporary property to flag as a temporary element.
9763247Sgjelinek *
9773247Sgjelinek * PO_FAIL is returned if an error is detected and the error code is updated
9783247Sgjelinek * to indicate the cause of the error.
9793247Sgjelinek */
9803247Sgjelinek int
pool_set_temporary(pool_conf_t * conf,pool_elem_t * pe)9813247Sgjelinek pool_set_temporary(pool_conf_t *conf, pool_elem_t *pe)
9823247Sgjelinek {
9833247Sgjelinek int res;
9843247Sgjelinek char name[128];
9853247Sgjelinek pool_value_t *val;
9863247Sgjelinek
9873247Sgjelinek if (pool_conf_check(conf) != PO_SUCCESS)
9883247Sgjelinek return (PO_FAIL);
9893247Sgjelinek
9903247Sgjelinek if (TO_CONF(pe) != conf) {
9913247Sgjelinek pool_seterror(POE_BADPARAM);
9923247Sgjelinek return (PO_FAIL);
9933247Sgjelinek }
9943247Sgjelinek
9953247Sgjelinek /* create property name based on element type */
9963247Sgjelinek if (snprintf(name, sizeof (name), "%s.temporary",
9973247Sgjelinek pool_elem_class_string(pe)) > sizeof (name)) {
9983247Sgjelinek pool_seterror(POE_SYSTEM);
9993247Sgjelinek return (PO_FAIL);
10003247Sgjelinek }
10013247Sgjelinek
10023247Sgjelinek if ((val = pool_value_alloc()) == NULL)
10033247Sgjelinek return (PO_FAIL);
10043247Sgjelinek
10053247Sgjelinek pool_value_set_bool(val, (uchar_t)1);
10063247Sgjelinek
10073247Sgjelinek res = pe->pe_put_prop(pe, name, val);
10083247Sgjelinek
10093247Sgjelinek pool_value_free(val);
10103247Sgjelinek
10113247Sgjelinek return (res);
10123247Sgjelinek }
10133247Sgjelinek
10143247Sgjelinek /*
10150Sstevel@tonic-gate * Update the specified property value with the namespace prepended.
10160Sstevel@tonic-gate * e.g. If this function is used to update the property "name" on a pool, it
10170Sstevel@tonic-gate * will attempt to update "pool.name".
10180Sstevel@tonic-gate *
10190Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated
10200Sstevel@tonic-gate * to indicate the cause of the error.
10210Sstevel@tonic-gate */
10220Sstevel@tonic-gate int
pool_put_ns_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10230Sstevel@tonic-gate pool_put_ns_property(pool_elem_t *pe, const char *name,
10240Sstevel@tonic-gate const pool_value_t *val)
10250Sstevel@tonic-gate {
10260Sstevel@tonic-gate char_buf_t *cb;
10270Sstevel@tonic-gate int ret;
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
10300Sstevel@tonic-gate return (PO_FAIL);
10310Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
10320Sstevel@tonic-gate PO_FAIL) {
10330Sstevel@tonic-gate free_char_buf(cb);
10340Sstevel@tonic-gate return (PO_FAIL);
10350Sstevel@tonic-gate }
10360Sstevel@tonic-gate ret = pool_put_property(TO_CONF(pe), pe, cb->cb_buf, val);
10370Sstevel@tonic-gate free_char_buf(cb);
10380Sstevel@tonic-gate return (ret);
10390Sstevel@tonic-gate }
10400Sstevel@tonic-gate
10410Sstevel@tonic-gate /*
10420Sstevel@tonic-gate * Update the specified property value. Do not use the property
10430Sstevel@tonic-gate * protection mechanism. This function should only be used for cases
10440Sstevel@tonic-gate * where the library must bypass the normal property protection
10450Sstevel@tonic-gate * mechanism. The only known use is to update properties in the static
10460Sstevel@tonic-gate * configuration when performing a commit.
10470Sstevel@tonic-gate *
10480Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is
10490Sstevel@tonic-gate * updated to indicate the cause of the error.
10500Sstevel@tonic-gate */
10510Sstevel@tonic-gate int
pool_put_any_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10520Sstevel@tonic-gate pool_put_any_property(pool_elem_t *pe, const char *name,
10530Sstevel@tonic-gate const pool_value_t *val)
10540Sstevel@tonic-gate {
10550Sstevel@tonic-gate if (!is_valid_prop_name(name)) {
10560Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
10570Sstevel@tonic-gate return (PO_FAIL);
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate
10600Sstevel@tonic-gate return (pe->pe_put_prop(pe, name, val));
10610Sstevel@tonic-gate }
10620Sstevel@tonic-gate
10630Sstevel@tonic-gate /*
10640Sstevel@tonic-gate * Update the specified property value with the namespace prepended.
10650Sstevel@tonic-gate * e.g. If this function is used to update the property "name" on a pool, it
10660Sstevel@tonic-gate * will attempt to update "pool.name".
10670Sstevel@tonic-gate *
10680Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated
10690Sstevel@tonic-gate * to indicate the cause of the error.
10700Sstevel@tonic-gate */
10710Sstevel@tonic-gate int
pool_put_any_ns_property(pool_elem_t * pe,const char * name,const pool_value_t * val)10720Sstevel@tonic-gate pool_put_any_ns_property(pool_elem_t *pe, const char *name,
10730Sstevel@tonic-gate const pool_value_t *val)
10740Sstevel@tonic-gate {
10750Sstevel@tonic-gate char_buf_t *cb;
10760Sstevel@tonic-gate int ret;
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL)
10790Sstevel@tonic-gate return (PO_FAIL);
10800Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) ==
10810Sstevel@tonic-gate PO_FAIL) {
10820Sstevel@tonic-gate free_char_buf(cb);
10830Sstevel@tonic-gate return (PO_FAIL);
10840Sstevel@tonic-gate }
10850Sstevel@tonic-gate ret = pool_put_any_property(pe, cb->cb_buf, val);
10860Sstevel@tonic-gate free_char_buf(cb);
10870Sstevel@tonic-gate return (ret);
10880Sstevel@tonic-gate }
10890Sstevel@tonic-gate
10900Sstevel@tonic-gate /*
10910Sstevel@tonic-gate * Remove the specified property value. Note that some properties are
10920Sstevel@tonic-gate * mandatory and thus failure to remove these properties is inevitable.
10930Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated
10940Sstevel@tonic-gate * to indicate the cause of the error.
10950Sstevel@tonic-gate */
10960Sstevel@tonic-gate int
pool_rm_property(pool_conf_t * conf,pool_elem_t * pe,const char * name)10970Sstevel@tonic-gate pool_rm_property(pool_conf_t *conf, pool_elem_t *pe, const char *name)
10980Sstevel@tonic-gate {
10990Sstevel@tonic-gate const pool_prop_t *prop_info;
11000Sstevel@tonic-gate
11010Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
11020Sstevel@tonic-gate return (PO_FAIL);
11030Sstevel@tonic-gate
11040Sstevel@tonic-gate if (TO_CONF(pe) != conf) {
11050Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
11060Sstevel@tonic-gate return (NULL);
11070Sstevel@tonic-gate }
11080Sstevel@tonic-gate
11093247Sgjelinek /* Don't allow removal of the "temporary" property */
11103247Sgjelinek if (strstr(name, ".temporary") != NULL) {
11113247Sgjelinek pool_seterror(POE_BADPARAM);
11123247Sgjelinek return (PO_FAIL);
11133247Sgjelinek }
11143247Sgjelinek
11150Sstevel@tonic-gate /*
11160Sstevel@tonic-gate * Check to see if this is a property we are managing. If it is,
11170Sstevel@tonic-gate * ensure that we are happy with what the user is doing.
11180Sstevel@tonic-gate */
11190Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL) {
11200Sstevel@tonic-gate if (prop_is_optional(prop_info) == PO_FALSE) {
11210Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
11220Sstevel@tonic-gate return (PO_FAIL);
11230Sstevel@tonic-gate }
11240Sstevel@tonic-gate }
11250Sstevel@tonic-gate return (pe->pe_rm_prop(pe, name));
11260Sstevel@tonic-gate }
11270Sstevel@tonic-gate
11280Sstevel@tonic-gate /*
11290Sstevel@tonic-gate * Check if the supplied name is a namespace protected property for the supplied
11300Sstevel@tonic-gate * element, pe. If it is, return the prefix, otherwise just return NULL.
11310Sstevel@tonic-gate */
11320Sstevel@tonic-gate const char *
is_ns_property(const pool_elem_t * pe,const char * name)11330Sstevel@tonic-gate is_ns_property(const pool_elem_t *pe, const char *name)
11340Sstevel@tonic-gate {
11350Sstevel@tonic-gate const char *prefix;
11360Sstevel@tonic-gate
11370Sstevel@tonic-gate if ((prefix = pool_elem_class_string(pe)) != NULL) {
11380Sstevel@tonic-gate if (strncmp(name, prefix, strlen(prefix)) == 0)
11390Sstevel@tonic-gate return (prefix);
11400Sstevel@tonic-gate }
11410Sstevel@tonic-gate return (NULL);
11420Sstevel@tonic-gate }
11430Sstevel@tonic-gate
11440Sstevel@tonic-gate /*
11450Sstevel@tonic-gate * Check if the supplied name is a namespace protected property for the supplied
11460Sstevel@tonic-gate * element, pe. If it is, return the property name with the namespace stripped,
11470Sstevel@tonic-gate * otherwise just return the name.
11480Sstevel@tonic-gate */
11490Sstevel@tonic-gate const char *
property_name_minus_ns(const pool_elem_t * pe,const char * name)11500Sstevel@tonic-gate property_name_minus_ns(const pool_elem_t *pe, const char *name)
11510Sstevel@tonic-gate {
11520Sstevel@tonic-gate const char *prefix;
11530Sstevel@tonic-gate if ((prefix = is_ns_property(pe, name)) != NULL) {
11540Sstevel@tonic-gate return (name + strlen(prefix) + 1);
11550Sstevel@tonic-gate }
11560Sstevel@tonic-gate return (name);
11570Sstevel@tonic-gate }
11580Sstevel@tonic-gate
11590Sstevel@tonic-gate /*
11600Sstevel@tonic-gate * Create an element to represent a pool and add it to the supplied
11610Sstevel@tonic-gate * configuration.
11620Sstevel@tonic-gate */
11630Sstevel@tonic-gate pool_t *
pool_create(pool_conf_t * conf,const char * name)11640Sstevel@tonic-gate pool_create(pool_conf_t *conf, const char *name)
11650Sstevel@tonic-gate {
11660Sstevel@tonic-gate pool_elem_t *pe;
11670Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
11680Sstevel@tonic-gate const pool_prop_t *default_props;
11690Sstevel@tonic-gate
11700Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
11710Sstevel@tonic-gate return (NULL);
11720Sstevel@tonic-gate
11730Sstevel@tonic-gate if (!is_valid_name(name) || pool_get_pool(conf, name) != NULL) {
11740Sstevel@tonic-gate /*
11750Sstevel@tonic-gate * A pool with the same name exists. Reject.
11760Sstevel@tonic-gate */
11770Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
11780Sstevel@tonic-gate return (NULL);
11790Sstevel@tonic-gate }
11800Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_POOL, PREC_INVALID,
11810Sstevel@tonic-gate PCEC_INVALID)) == NULL) {
11820Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
11830Sstevel@tonic-gate return (NULL);
11840Sstevel@tonic-gate }
11850Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) {
11860Sstevel@tonic-gate int i;
11870Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) {
11880Sstevel@tonic-gate if (prop_is_init(&default_props[i]) &&
11890Sstevel@tonic-gate (pool_put_any_property(pe,
11900Sstevel@tonic-gate default_props[i].pp_pname,
11910Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL)) {
11920Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe));
11930Sstevel@tonic-gate return (NULL);
11940Sstevel@tonic-gate }
11950Sstevel@tonic-gate }
11960Sstevel@tonic-gate }
11970Sstevel@tonic-gate if (pool_value_set_string(&val, name) != PO_SUCCESS) {
11980Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe));
11990Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
12000Sstevel@tonic-gate return (NULL);
12010Sstevel@tonic-gate }
12020Sstevel@tonic-gate if (pool_put_property(conf, pe, "pool.name", &val) == PO_FAIL) {
12030Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe));
12040Sstevel@tonic-gate pool_seterror(POE_PUTPROP);
12050Sstevel@tonic-gate return (NULL);
12060Sstevel@tonic-gate }
12073247Sgjelinek
12083247Sgjelinek /*
12093247Sgjelinek * If we are creating a temporary pool configuration, flag the pool.
12103247Sgjelinek */
12113247Sgjelinek if (conf->pc_prov->pc_oflags & PO_TEMP) {
12123247Sgjelinek if (pool_set_temporary(conf, pe) == PO_FAIL) {
12133247Sgjelinek (void) pool_destroy(conf, pool_elem_pool(pe));
12143247Sgjelinek return (NULL);
12153247Sgjelinek }
12163247Sgjelinek }
12173247Sgjelinek
12180Sstevel@tonic-gate return (pool_elem_pool(pe));
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate /*
12220Sstevel@tonic-gate * Create an element to represent a res.
12230Sstevel@tonic-gate */
12240Sstevel@tonic-gate pool_resource_t *
pool_resource_create(pool_conf_t * conf,const char * sz_type,const char * name)12250Sstevel@tonic-gate pool_resource_create(pool_conf_t *conf, const char *sz_type, const char *name)
12260Sstevel@tonic-gate {
12270Sstevel@tonic-gate pool_elem_t *pe;
12280Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
12290Sstevel@tonic-gate const pool_prop_t *default_props;
12300Sstevel@tonic-gate pool_resource_t **resources;
12310Sstevel@tonic-gate int is_default = 0;
12320Sstevel@tonic-gate uint_t nelem;
12330Sstevel@tonic-gate pool_elem_class_t elem_class;
12340Sstevel@tonic-gate pool_resource_elem_class_t type;
12350Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL };
12360Sstevel@tonic-gate
12370Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
12380Sstevel@tonic-gate return (NULL);
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate if ((type = pool_resource_elem_class_from_string(sz_type)) ==
12410Sstevel@tonic-gate PREC_INVALID) {
12420Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
12430Sstevel@tonic-gate return (NULL);
12440Sstevel@tonic-gate }
12450Sstevel@tonic-gate
12460Sstevel@tonic-gate if (strcmp(sz_type, "pset") != 0) {
12470Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
12480Sstevel@tonic-gate return (NULL);
12490Sstevel@tonic-gate }
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate if (!is_valid_name(name) || pool_get_resource(conf, sz_type, name) !=
12520Sstevel@tonic-gate NULL) {
12530Sstevel@tonic-gate /*
12540Sstevel@tonic-gate * Resources must be unique by name+type.
12550Sstevel@tonic-gate */
12560Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
12570Sstevel@tonic-gate return (NULL);
12580Sstevel@tonic-gate }
12590Sstevel@tonic-gate
12600Sstevel@tonic-gate props[0] = &val;
12610Sstevel@tonic-gate
12620Sstevel@tonic-gate if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS ||
12630Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS) {
12640Sstevel@tonic-gate return (NULL);
12650Sstevel@tonic-gate }
12660Sstevel@tonic-gate
12670Sstevel@tonic-gate if ((resources = pool_query_resources(conf, &nelem, props)) == NULL) {
12680Sstevel@tonic-gate /*
12690Sstevel@tonic-gate * This is the first representative of this type; when it's
12700Sstevel@tonic-gate * created it should be created with 'default' = 'true'.
12710Sstevel@tonic-gate */
12720Sstevel@tonic-gate is_default = 1;
12730Sstevel@tonic-gate } else {
12740Sstevel@tonic-gate free(resources);
12750Sstevel@tonic-gate }
12760Sstevel@tonic-gate /*
12770Sstevel@tonic-gate * TODO: If Additional PEC_RES_COMP types are added to
12780Sstevel@tonic-gate * pool_impl.h, this would need to be extended.
12790Sstevel@tonic-gate */
12800Sstevel@tonic-gate switch (type) {
12810Sstevel@tonic-gate case PREC_PSET:
12820Sstevel@tonic-gate elem_class = PEC_RES_COMP;
12830Sstevel@tonic-gate break;
12840Sstevel@tonic-gate default:
12850Sstevel@tonic-gate elem_class = PEC_RES_AGG;
12860Sstevel@tonic-gate break;
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, elem_class, type,
12890Sstevel@tonic-gate PCEC_INVALID)) == NULL) {
12900Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
12910Sstevel@tonic-gate return (NULL);
12920Sstevel@tonic-gate }
12930Sstevel@tonic-gate
12940Sstevel@tonic-gate /*
12950Sstevel@tonic-gate * The plugins contain a list of default properties and their values
12960Sstevel@tonic-gate * for resources. The resource returned, hence, is fully initialized.
12970Sstevel@tonic-gate */
12980Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) {
12990Sstevel@tonic-gate int i;
13000Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) {
13010Sstevel@tonic-gate if (prop_is_init(&default_props[i]) &&
13020Sstevel@tonic-gate pool_put_any_property(pe, default_props[i].pp_pname,
13030Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL) {
13040Sstevel@tonic-gate (void) pool_resource_destroy(conf,
13050Sstevel@tonic-gate pool_elem_res(pe));
13060Sstevel@tonic-gate return (NULL);
13070Sstevel@tonic-gate }
13080Sstevel@tonic-gate }
13090Sstevel@tonic-gate }
13100Sstevel@tonic-gate if (pool_value_set_string(&val, name) != PO_SUCCESS ||
13110Sstevel@tonic-gate pool_put_ns_property(pe, "name", &val) != PO_SUCCESS) {
13120Sstevel@tonic-gate (void) pool_resource_destroy(conf, pool_elem_res(pe));
13130Sstevel@tonic-gate return (NULL);
13140Sstevel@tonic-gate }
13150Sstevel@tonic-gate if (is_default) {
13160Sstevel@tonic-gate pool_value_set_bool(&val, PO_TRUE);
13170Sstevel@tonic-gate if (pool_put_any_ns_property(pe, "default", &val) !=
13180Sstevel@tonic-gate PO_SUCCESS) {
13190Sstevel@tonic-gate (void) pool_resource_destroy(conf, pool_elem_res(pe));
13200Sstevel@tonic-gate return (NULL);
13210Sstevel@tonic-gate }
13220Sstevel@tonic-gate }
13233247Sgjelinek
13243247Sgjelinek /*
13253247Sgjelinek * If we are creating a temporary pool configuration, flag the resource.
13263247Sgjelinek */
13273247Sgjelinek if (conf->pc_prov->pc_oflags & PO_TEMP) {
13283247Sgjelinek if (pool_set_temporary(conf, pe) != PO_SUCCESS) {
13293247Sgjelinek (void) pool_resource_destroy(conf, pool_elem_res(pe));
13303247Sgjelinek return (NULL);
13313247Sgjelinek }
13323247Sgjelinek }
13333247Sgjelinek
13340Sstevel@tonic-gate return (pool_elem_res(pe));
13350Sstevel@tonic-gate }
13360Sstevel@tonic-gate
13370Sstevel@tonic-gate /*
13380Sstevel@tonic-gate * Create an element to represent a resource component.
13390Sstevel@tonic-gate */
13400Sstevel@tonic-gate pool_component_t *
pool_component_create(pool_conf_t * conf,const pool_resource_t * res,int64_t sys_id)13410Sstevel@tonic-gate pool_component_create(pool_conf_t *conf, const pool_resource_t *res,
13420Sstevel@tonic-gate int64_t sys_id)
13430Sstevel@tonic-gate {
13440Sstevel@tonic-gate pool_elem_t *pe;
13450Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
13460Sstevel@tonic-gate const pool_prop_t *default_props;
13470Sstevel@tonic-gate char refbuf[KEY_BUFFER_SIZE];
13480Sstevel@tonic-gate
13490Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_COMP,
13500Sstevel@tonic-gate PREC_INVALID, PCEC_CPU)) == NULL) {
13510Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
13520Sstevel@tonic-gate return (NULL);
13530Sstevel@tonic-gate }
13540Sstevel@tonic-gate /*
13550Sstevel@tonic-gate * TODO: If additional PEC_COMP types are added in pool_impl.h,
13560Sstevel@tonic-gate * this would need to be extended.
13570Sstevel@tonic-gate */
13580Sstevel@tonic-gate pe->pe_component_class = PCEC_CPU;
13590Sstevel@tonic-gate /* Now set the container for this comp */
13600Sstevel@tonic-gate if (pool_set_container(TO_ELEM(res), pe) == PO_FAIL) {
13610Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe));
13620Sstevel@tonic-gate return (NULL);
13630Sstevel@tonic-gate }
13640Sstevel@tonic-gate /*
13650Sstevel@tonic-gate * The plugins contain a list of default properties and their values
13660Sstevel@tonic-gate * for resources. The resource returned, hence, is fully initialized.
13670Sstevel@tonic-gate */
13680Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) {
13690Sstevel@tonic-gate int i;
13700Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) {
13710Sstevel@tonic-gate if (prop_is_init(&default_props[i]) &&
13720Sstevel@tonic-gate pool_put_any_property(pe,
13730Sstevel@tonic-gate default_props[i].pp_pname,
13740Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL) {
13750Sstevel@tonic-gate (void) pool_component_destroy(
13760Sstevel@tonic-gate pool_elem_comp(pe));
13770Sstevel@tonic-gate return (NULL);
13780Sstevel@tonic-gate }
13790Sstevel@tonic-gate }
13800Sstevel@tonic-gate }
13810Sstevel@tonic-gate /*
13820Sstevel@tonic-gate * Set additional attributes/properties on component.
13830Sstevel@tonic-gate */
13840Sstevel@tonic-gate pool_value_set_int64(&val, sys_id);
13850Sstevel@tonic-gate if (pool_put_any_ns_property(pe, c_sys_prop, &val) != PO_SUCCESS) {
13860Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe));
13870Sstevel@tonic-gate return (NULL);
13880Sstevel@tonic-gate }
13890Sstevel@tonic-gate if (snprintf(refbuf, KEY_BUFFER_SIZE, "%s_%lld",
13900Sstevel@tonic-gate pool_elem_class_string(pe), sys_id) > KEY_BUFFER_SIZE) {
13910Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe));
13920Sstevel@tonic-gate return (NULL);
13930Sstevel@tonic-gate }
13940Sstevel@tonic-gate if (pool_value_set_string(&val, refbuf) != PO_SUCCESS) {
13950Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe));
13960Sstevel@tonic-gate return (NULL);
13970Sstevel@tonic-gate }
13980Sstevel@tonic-gate if (pool_put_any_ns_property(pe, c_ref_id, &val) != PO_SUCCESS) {
13990Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe));
14000Sstevel@tonic-gate return (NULL);
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate return (pool_elem_comp(pe));
14030Sstevel@tonic-gate }
14040Sstevel@tonic-gate
14050Sstevel@tonic-gate /*
14060Sstevel@tonic-gate * Return the location of a configuration.
14070Sstevel@tonic-gate */
14080Sstevel@tonic-gate const char *
pool_conf_location(const pool_conf_t * conf)14090Sstevel@tonic-gate pool_conf_location(const pool_conf_t *conf)
14100Sstevel@tonic-gate {
14110Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
14120Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
14130Sstevel@tonic-gate return (NULL);
14140Sstevel@tonic-gate }
14150Sstevel@tonic-gate return (conf->pc_location);
14160Sstevel@tonic-gate }
14170Sstevel@tonic-gate /*
14180Sstevel@tonic-gate * Close a configuration, freeing all associated resources. Once a
14190Sstevel@tonic-gate * configuration is closed, it can no longer be used.
14200Sstevel@tonic-gate */
14210Sstevel@tonic-gate int
pool_conf_close(pool_conf_t * conf)14220Sstevel@tonic-gate pool_conf_close(pool_conf_t *conf)
14230Sstevel@tonic-gate {
14240Sstevel@tonic-gate int rv;
14250Sstevel@tonic-gate
14260Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
14270Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
14280Sstevel@tonic-gate return (PO_FAIL);
14290Sstevel@tonic-gate }
14300Sstevel@tonic-gate rv = conf->pc_prov->pc_close(conf);
14310Sstevel@tonic-gate conf->pc_prov = NULL;
14320Sstevel@tonic-gate free((void *)conf->pc_location);
14330Sstevel@tonic-gate conf->pc_location = NULL;
14340Sstevel@tonic-gate conf->pc_state = POF_INVALID;
14350Sstevel@tonic-gate return (rv);
14360Sstevel@tonic-gate }
14370Sstevel@tonic-gate
14380Sstevel@tonic-gate /*
14390Sstevel@tonic-gate * Remove a configuration, freeing all associated resources. Once a
14400Sstevel@tonic-gate * configuration is removed, it can no longer be accessed and is forever
14410Sstevel@tonic-gate * gone.
14420Sstevel@tonic-gate */
14430Sstevel@tonic-gate int
pool_conf_remove(pool_conf_t * conf)14440Sstevel@tonic-gate pool_conf_remove(pool_conf_t *conf)
14450Sstevel@tonic-gate {
14460Sstevel@tonic-gate int rv;
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
14490Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
14500Sstevel@tonic-gate return (PO_FAIL);
14510Sstevel@tonic-gate }
14520Sstevel@tonic-gate rv = conf->pc_prov->pc_remove(conf);
14530Sstevel@tonic-gate conf->pc_state = POF_INVALID;
14540Sstevel@tonic-gate return (rv);
14550Sstevel@tonic-gate }
14560Sstevel@tonic-gate
14570Sstevel@tonic-gate /*
14580Sstevel@tonic-gate * pool_conf_alloc() allocate the resources to represent a configuration.
14590Sstevel@tonic-gate */
14600Sstevel@tonic-gate pool_conf_t *
pool_conf_alloc(void)14610Sstevel@tonic-gate pool_conf_alloc(void)
14620Sstevel@tonic-gate {
14630Sstevel@tonic-gate pool_conf_t *conf;
14640Sstevel@tonic-gate
14650Sstevel@tonic-gate if ((conf = calloc(1, sizeof (pool_conf_t))) == NULL) {
14660Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
14670Sstevel@tonic-gate return (NULL);
14680Sstevel@tonic-gate }
14690Sstevel@tonic-gate conf->pc_state = POF_INVALID;
14700Sstevel@tonic-gate return (conf);
14710Sstevel@tonic-gate }
14720Sstevel@tonic-gate
14730Sstevel@tonic-gate /*
14740Sstevel@tonic-gate * pool_conf_free() frees the resources associated with a configuration.
14750Sstevel@tonic-gate */
14760Sstevel@tonic-gate void
pool_conf_free(pool_conf_t * conf)14770Sstevel@tonic-gate pool_conf_free(pool_conf_t *conf)
14780Sstevel@tonic-gate {
14790Sstevel@tonic-gate free(conf);
14800Sstevel@tonic-gate }
14810Sstevel@tonic-gate
14820Sstevel@tonic-gate /*
14830Sstevel@tonic-gate * pool_conf_open() opens a configuration, establishing all required
14840Sstevel@tonic-gate * connections to the data source.
14850Sstevel@tonic-gate */
14860Sstevel@tonic-gate int
pool_conf_open(pool_conf_t * conf,const char * location,int oflags)14870Sstevel@tonic-gate pool_conf_open(pool_conf_t *conf, const char *location, int oflags)
14880Sstevel@tonic-gate {
14890Sstevel@tonic-gate /*
14900Sstevel@tonic-gate * Since you can't do anything to a pool configuration without opening
14910Sstevel@tonic-gate * it, this represents a good point to intialise structures that would
14920Sstevel@tonic-gate * otherwise need to be initialised in a .init section.
14930Sstevel@tonic-gate */
14940Sstevel@tonic-gate internal_init();
14950Sstevel@tonic-gate
14960Sstevel@tonic-gate if (pool_conf_status(conf) != POF_INVALID) {
14970Sstevel@tonic-gate /*
14980Sstevel@tonic-gate * Already opened configuration, return PO_FAIL
14990Sstevel@tonic-gate */
15000Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
15010Sstevel@tonic-gate return (PO_FAIL);
15020Sstevel@tonic-gate }
15033247Sgjelinek if (oflags & ~(PO_RDONLY | PO_RDWR | PO_CREAT | PO_DISCO | PO_UPDATE |
15043247Sgjelinek PO_TEMP)) {
15050Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
15060Sstevel@tonic-gate return (PO_FAIL);
15070Sstevel@tonic-gate }
15080Sstevel@tonic-gate
15090Sstevel@tonic-gate /*
15100Sstevel@tonic-gate * Creating a configuration implies read-write access, so make
15110Sstevel@tonic-gate * sure that PO_RDWR is set in addition if PO_CREAT is set.
15120Sstevel@tonic-gate */
15130Sstevel@tonic-gate if (oflags & PO_CREAT)
15140Sstevel@tonic-gate oflags |= PO_RDWR;
15150Sstevel@tonic-gate
15163247Sgjelinek /* location is ignored when creating a temporary configuration */
15173247Sgjelinek if (oflags & PO_TEMP)
15183247Sgjelinek location = "";
15193247Sgjelinek
15200Sstevel@tonic-gate if ((conf->pc_location = strdup(location)) == NULL) {
15210Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
15220Sstevel@tonic-gate return (PO_FAIL);
15230Sstevel@tonic-gate }
15240Sstevel@tonic-gate /*
15250Sstevel@tonic-gate * This is the crossover point into the actual data provider
15260Sstevel@tonic-gate * implementation, allocate a data provider of the appropriate
15273247Sgjelinek * type for your data storage medium. In this case it's either a kernel
15283247Sgjelinek * or xml data provider. To use a different data provider, write some
15293247Sgjelinek * code to implement all the required interfaces and then change the
15303247Sgjelinek * following code to allocate a data provider which uses your new code.
15313247Sgjelinek * All data provider routines can be static, apart from the allocation
15323247Sgjelinek * routine.
15333247Sgjelinek *
15343247Sgjelinek * For temporary pools (PO_TEMP) we start with a copy of the current
15353247Sgjelinek * dynamic configuration and do all of the updates in-memory.
15360Sstevel@tonic-gate */
15373247Sgjelinek if (oflags & PO_TEMP) {
15383247Sgjelinek if (pool_knl_connection_alloc(conf, PO_TEMP) != PO_SUCCESS) {
15393247Sgjelinek conf->pc_state = POF_INVALID;
15403247Sgjelinek return (PO_FAIL);
15413247Sgjelinek }
15423247Sgjelinek /* set rdwr flag so we can updated the in-memory config. */
15433247Sgjelinek conf->pc_prov->pc_oflags |= PO_RDWR;
15443247Sgjelinek
15453247Sgjelinek } else if (strcmp(location, pool_dynamic_location()) == 0) {
15460Sstevel@tonic-gate if (pool_knl_connection_alloc(conf, oflags) != PO_SUCCESS) {
15470Sstevel@tonic-gate conf->pc_state = POF_INVALID;
15480Sstevel@tonic-gate return (PO_FAIL);
15490Sstevel@tonic-gate }
15500Sstevel@tonic-gate } else {
15510Sstevel@tonic-gate if (pool_xml_connection_alloc(conf, oflags) != PO_SUCCESS) {
15520Sstevel@tonic-gate conf->pc_state = POF_INVALID;
15530Sstevel@tonic-gate return (PO_FAIL);
15540Sstevel@tonic-gate }
15550Sstevel@tonic-gate }
15560Sstevel@tonic-gate return (PO_SUCCESS);
15570Sstevel@tonic-gate }
15580Sstevel@tonic-gate
15590Sstevel@tonic-gate /*
15600Sstevel@tonic-gate * Rollback a configuration. This will undo all changes to the configuration
15610Sstevel@tonic-gate * since the last time pool_conf_commit was called.
15620Sstevel@tonic-gate */
15630Sstevel@tonic-gate int
pool_conf_rollback(pool_conf_t * conf)15640Sstevel@tonic-gate pool_conf_rollback(pool_conf_t *conf)
15650Sstevel@tonic-gate {
15660Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
15670Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
15680Sstevel@tonic-gate return (PO_FAIL);
15690Sstevel@tonic-gate }
15700Sstevel@tonic-gate return (conf->pc_prov->pc_rollback(conf));
15710Sstevel@tonic-gate }
15720Sstevel@tonic-gate
15730Sstevel@tonic-gate /*
15740Sstevel@tonic-gate * Commit a configuration. This will apply all changes to the
15750Sstevel@tonic-gate * configuration to the permanent data store. The active parameter
15760Sstevel@tonic-gate * indicates whether the configuration should be used to update the
15770Sstevel@tonic-gate * dynamic configuration from the supplied (static) configuration or
15780Sstevel@tonic-gate * whether it should be written back to persistent store.
15790Sstevel@tonic-gate */
15800Sstevel@tonic-gate int
pool_conf_commit(pool_conf_t * conf,int active)15810Sstevel@tonic-gate pool_conf_commit(pool_conf_t *conf, int active)
15820Sstevel@tonic-gate {
15830Sstevel@tonic-gate int retval;
15840Sstevel@tonic-gate
15850Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
15860Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
15870Sstevel@tonic-gate return (PO_FAIL);
15880Sstevel@tonic-gate }
15890Sstevel@tonic-gate if (active) {
15900Sstevel@tonic-gate int oflags;
15910Sstevel@tonic-gate
15920Sstevel@tonic-gate if (conf_is_dynamic(conf) == PO_TRUE) {
15930Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
15940Sstevel@tonic-gate return (PO_FAIL);
15950Sstevel@tonic-gate }
15960Sstevel@tonic-gate /*
15970Sstevel@tonic-gate * Pretend that the configuration was opened PO_RDWR
15980Sstevel@tonic-gate * so that a configuration which was opened PO_RDONLY
15990Sstevel@tonic-gate * can be committed. The original flags are preserved
16000Sstevel@tonic-gate * in oflags and restored after pool_conf_commit_sys()
16010Sstevel@tonic-gate * returns.
16020Sstevel@tonic-gate */
16030Sstevel@tonic-gate oflags = conf->pc_prov->pc_oflags;
16040Sstevel@tonic-gate conf->pc_prov->pc_oflags |= PO_RDWR;
16050Sstevel@tonic-gate retval = pool_conf_commit_sys(conf, active);
16060Sstevel@tonic-gate conf->pc_prov->pc_oflags = oflags;
16070Sstevel@tonic-gate } else {
16080Sstevel@tonic-gate /*
16090Sstevel@tonic-gate * Write the configuration back to the backing store.
16100Sstevel@tonic-gate */
16110Sstevel@tonic-gate retval = conf->pc_prov->pc_commit(conf);
16120Sstevel@tonic-gate }
16130Sstevel@tonic-gate return (retval);
16140Sstevel@tonic-gate }
16150Sstevel@tonic-gate
16160Sstevel@tonic-gate /*
16170Sstevel@tonic-gate * Export a configuration. This will export a configuration in the specified
16180Sstevel@tonic-gate * format (fmt) to the specified location.
16190Sstevel@tonic-gate */
16200Sstevel@tonic-gate int
pool_conf_export(const pool_conf_t * conf,const char * location,pool_export_format_t fmt)16210Sstevel@tonic-gate pool_conf_export(const pool_conf_t *conf, const char *location,
16220Sstevel@tonic-gate pool_export_format_t fmt)
16230Sstevel@tonic-gate {
16240Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
16250Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
16260Sstevel@tonic-gate return (PO_FAIL);
16270Sstevel@tonic-gate }
16280Sstevel@tonic-gate return (conf->pc_prov->pc_export(conf, location, fmt));
16290Sstevel@tonic-gate }
16300Sstevel@tonic-gate
16310Sstevel@tonic-gate /*
16320Sstevel@tonic-gate * Validate a configuration. This will validate a configuration at the
16330Sstevel@tonic-gate * specified level.
16340Sstevel@tonic-gate */
16350Sstevel@tonic-gate int
pool_conf_validate(const pool_conf_t * conf,pool_valid_level_t level)16360Sstevel@tonic-gate pool_conf_validate(const pool_conf_t *conf, pool_valid_level_t level)
16370Sstevel@tonic-gate {
16380Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
16390Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
16400Sstevel@tonic-gate return (PO_FAIL);
16410Sstevel@tonic-gate }
16420Sstevel@tonic-gate return (conf->pc_prov->pc_validate(conf, level));
16430Sstevel@tonic-gate }
16440Sstevel@tonic-gate
16450Sstevel@tonic-gate /*
16460Sstevel@tonic-gate * Update the snapshot of a configuration. This can only be used on a
16470Sstevel@tonic-gate * dynamic configuration.
16480Sstevel@tonic-gate */
16490Sstevel@tonic-gate int
pool_conf_update(const pool_conf_t * conf,int * changed)16500Sstevel@tonic-gate pool_conf_update(const pool_conf_t *conf, int *changed)
16510Sstevel@tonic-gate {
16520Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID ||
16530Sstevel@tonic-gate conf_is_dynamic(conf) == PO_FALSE) {
16540Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
16550Sstevel@tonic-gate return (PO_FAIL);
16560Sstevel@tonic-gate }
16570Sstevel@tonic-gate /*
16580Sstevel@tonic-gate * Since this function only makes sense for dynamic
16590Sstevel@tonic-gate * configurations, just call directly into the appropriate
16600Sstevel@tonic-gate * function. This could be added into the pool_connection_t
16610Sstevel@tonic-gate * interface if it was ever required.
16620Sstevel@tonic-gate */
16630Sstevel@tonic-gate if (changed)
16640Sstevel@tonic-gate *changed = 0;
16650Sstevel@tonic-gate return (pool_knl_update((pool_conf_t *)conf, changed));
16660Sstevel@tonic-gate }
16670Sstevel@tonic-gate
16680Sstevel@tonic-gate /*
16690Sstevel@tonic-gate * Walk the properties of the supplied elem, calling the user supplied
16700Sstevel@tonic-gate * function repeatedly as long as the user function returns
16710Sstevel@tonic-gate * PO_SUCCESS.
16720Sstevel@tonic-gate */
16730Sstevel@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 *))16740Sstevel@tonic-gate pool_walk_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg,
16750Sstevel@tonic-gate int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *,
16760Sstevel@tonic-gate pool_value_t *, void *))
16770Sstevel@tonic-gate {
16780Sstevel@tonic-gate return (pool_walk_any_properties(conf, elem, arg, prop_callback, 0));
16790Sstevel@tonic-gate }
16800Sstevel@tonic-gate
16810Sstevel@tonic-gate void
free_value_list(int npvals,pool_value_t ** pvals)16820Sstevel@tonic-gate free_value_list(int npvals, pool_value_t **pvals)
16830Sstevel@tonic-gate {
16840Sstevel@tonic-gate int j;
16850Sstevel@tonic-gate
16860Sstevel@tonic-gate for (j = 0; j < npvals; j++) {
16870Sstevel@tonic-gate if (pvals[j])
16880Sstevel@tonic-gate pool_value_free(pvals[j]);
16890Sstevel@tonic-gate }
16900Sstevel@tonic-gate free(pvals);
16910Sstevel@tonic-gate }
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate /*
16940Sstevel@tonic-gate * Walk the properties of the supplied elem, calling the user supplied
16950Sstevel@tonic-gate * function repeatedly as long as the user function returns
16960Sstevel@tonic-gate * PO_SUCCESS.
16970Sstevel@tonic-gate * The list of properties to be walked is retrieved from the element
16980Sstevel@tonic-gate */
16990Sstevel@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)17000Sstevel@tonic-gate pool_walk_any_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg,
17010Sstevel@tonic-gate int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *,
17020Sstevel@tonic-gate pool_value_t *, void *), int any)
17030Sstevel@tonic-gate {
17040Sstevel@tonic-gate pool_value_t **pvals;
17050Sstevel@tonic-gate int i;
17060Sstevel@tonic-gate const pool_prop_t *props = provider_get_props(elem);
17070Sstevel@tonic-gate uint_t npvals;
17080Sstevel@tonic-gate
17090Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
17100Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
17110Sstevel@tonic-gate return (PO_FAIL);
17120Sstevel@tonic-gate }
17130Sstevel@tonic-gate
17140Sstevel@tonic-gate if (props == NULL) {
17150Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
17160Sstevel@tonic-gate return (PO_FAIL);
17170Sstevel@tonic-gate }
17180Sstevel@tonic-gate
17190Sstevel@tonic-gate if ((pvals = elem->pe_get_props(elem, &npvals)) == NULL)
17200Sstevel@tonic-gate return (PO_FAIL);
17210Sstevel@tonic-gate
17220Sstevel@tonic-gate /*
17230Sstevel@tonic-gate * Now walk the managed properties. As we find managed
17240Sstevel@tonic-gate * properties removed them from the list of all properties to
17250Sstevel@tonic-gate * prevent duplication.
17260Sstevel@tonic-gate */
17270Sstevel@tonic-gate for (i = 0; props[i].pp_pname != NULL; i++) {
17280Sstevel@tonic-gate int j;
17290Sstevel@tonic-gate
17300Sstevel@tonic-gate /*
17310Sstevel@tonic-gate * Special processing for type
17320Sstevel@tonic-gate */
17330Sstevel@tonic-gate if (strcmp(props[i].pp_pname, c_type) == 0) {
17340Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
17350Sstevel@tonic-gate
17360Sstevel@tonic-gate if (pool_value_set_name(&val, props[i].pp_pname) ==
17370Sstevel@tonic-gate PO_FAIL) {
17380Sstevel@tonic-gate free_value_list(npvals, pvals);
17390Sstevel@tonic-gate return (PO_FAIL);
17400Sstevel@tonic-gate }
17410Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value(elem, &val) ==
17420Sstevel@tonic-gate PO_FAIL) {
17430Sstevel@tonic-gate free_value_list(npvals, pvals);
17440Sstevel@tonic-gate return (PO_FAIL);
17450Sstevel@tonic-gate }
17460Sstevel@tonic-gate if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) {
17470Sstevel@tonic-gate if (prop_callback(conf, elem, props[i].pp_pname,
17480Sstevel@tonic-gate &val, arg) != PO_SUCCESS) {
17490Sstevel@tonic-gate free_value_list(npvals, pvals);
17500Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
17510Sstevel@tonic-gate return (PO_FAIL);
17520Sstevel@tonic-gate }
17530Sstevel@tonic-gate }
17540Sstevel@tonic-gate continue;
17550Sstevel@tonic-gate }
17560Sstevel@tonic-gate
17570Sstevel@tonic-gate for (j = 0; j < npvals; j++) {
17580Sstevel@tonic-gate if (pvals[j] && strcmp(pool_value_get_name(pvals[j]),
17590Sstevel@tonic-gate props[i].pp_pname) == 0)
17600Sstevel@tonic-gate break;
17610Sstevel@tonic-gate }
17620Sstevel@tonic-gate /*
17630Sstevel@tonic-gate * If we have found the property, then j < npvals. Process it
17640Sstevel@tonic-gate * according to our property attributes. Otherwise, it's not
17650Sstevel@tonic-gate * a managed property, so just ignore it until later.
17660Sstevel@tonic-gate */
17670Sstevel@tonic-gate if (j < npvals) {
17680Sstevel@tonic-gate if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) {
17690Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value) {
17700Sstevel@tonic-gate if (pool_value_set_name(pvals[j],
17710Sstevel@tonic-gate props[i].pp_pname) == PO_FAIL) {
17720Sstevel@tonic-gate free_value_list(npvals, pvals);
17730Sstevel@tonic-gate return (PO_FAIL);
17740Sstevel@tonic-gate }
17750Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value(elem,
17760Sstevel@tonic-gate pvals[j]) == PO_FAIL) {
17770Sstevel@tonic-gate free_value_list(npvals, pvals);
17780Sstevel@tonic-gate return (PO_FAIL);
17790Sstevel@tonic-gate }
17800Sstevel@tonic-gate }
17810Sstevel@tonic-gate if (prop_callback(conf, elem, props[i].pp_pname,
17820Sstevel@tonic-gate pvals[j], arg) != PO_SUCCESS) {
17830Sstevel@tonic-gate free_value_list(npvals, pvals);
17840Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
17850Sstevel@tonic-gate return (PO_FAIL);
17860Sstevel@tonic-gate }
17870Sstevel@tonic-gate }
17880Sstevel@tonic-gate pool_value_free(pvals[j]);
17890Sstevel@tonic-gate pvals[j] = NULL;
17900Sstevel@tonic-gate }
17910Sstevel@tonic-gate }
17920Sstevel@tonic-gate for (i = 0; i < npvals; i++) {
17930Sstevel@tonic-gate if (pvals[i]) {
17940Sstevel@tonic-gate const char *name = pool_value_get_name(pvals[i]);
17950Sstevel@tonic-gate char *qname = strrchr(name, '.');
17960Sstevel@tonic-gate if ((qname && qname[1] != '_') ||
17970Sstevel@tonic-gate (!qname && name[0] != '_')) {
17980Sstevel@tonic-gate if (prop_callback(conf, elem, name, pvals[i],
17990Sstevel@tonic-gate arg) != PO_SUCCESS) {
18000Sstevel@tonic-gate free_value_list(npvals, pvals);
18010Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
18020Sstevel@tonic-gate return (PO_FAIL);
18030Sstevel@tonic-gate }
18040Sstevel@tonic-gate }
18050Sstevel@tonic-gate pool_value_free(pvals[i]);
18060Sstevel@tonic-gate pvals[i] = NULL;
18070Sstevel@tonic-gate }
18080Sstevel@tonic-gate }
18090Sstevel@tonic-gate free(pvals);
18100Sstevel@tonic-gate return (PO_SUCCESS);
18110Sstevel@tonic-gate }
18120Sstevel@tonic-gate
18130Sstevel@tonic-gate /*
18140Sstevel@tonic-gate * Return a pool, searching the supplied configuration for a pool with the
18150Sstevel@tonic-gate * supplied name. The search is case sensitive.
18160Sstevel@tonic-gate */
18170Sstevel@tonic-gate pool_t *
pool_get_pool(const pool_conf_t * conf,const char * name)18180Sstevel@tonic-gate pool_get_pool(const pool_conf_t *conf, const char *name)
18190Sstevel@tonic-gate {
18200Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL };
18210Sstevel@tonic-gate pool_t **rs;
18220Sstevel@tonic-gate pool_t *ret;
18230Sstevel@tonic-gate uint_t size = 0;
18240Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
18250Sstevel@tonic-gate
18260Sstevel@tonic-gate props[0] = &val;
18270Sstevel@tonic-gate
18280Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
18290Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
18300Sstevel@tonic-gate return (NULL);
18310Sstevel@tonic-gate }
18320Sstevel@tonic-gate
18330Sstevel@tonic-gate if (pool_value_set_name(props[0], "pool.name") != PO_SUCCESS ||
18340Sstevel@tonic-gate pool_value_set_string(props[0], name) != PO_SUCCESS) {
18350Sstevel@tonic-gate return (NULL);
18360Sstevel@tonic-gate }
18370Sstevel@tonic-gate rs = pool_query_pools(conf, &size, props);
18380Sstevel@tonic-gate if (rs == NULL) { /* Can't find a pool to match the name */
18390Sstevel@tonic-gate return (NULL);
18400Sstevel@tonic-gate }
18410Sstevel@tonic-gate if (size != 1) {
18420Sstevel@tonic-gate free(rs);
18430Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
18440Sstevel@tonic-gate return (NULL);
18450Sstevel@tonic-gate }
18460Sstevel@tonic-gate ret = rs[0];
18470Sstevel@tonic-gate free(rs);
18480Sstevel@tonic-gate return (ret);
18490Sstevel@tonic-gate }
18500Sstevel@tonic-gate
18510Sstevel@tonic-gate /*
18520Sstevel@tonic-gate * Return a result set of pools, searching the supplied configuration
18530Sstevel@tonic-gate * for pools which match the supplied property criteria. props is a null
18540Sstevel@tonic-gate * terminated list of properties which will be used to match qualifying
18550Sstevel@tonic-gate * pools. size is updated with the size of the pool
18560Sstevel@tonic-gate */
18570Sstevel@tonic-gate pool_t **
pool_query_pools(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)18580Sstevel@tonic-gate pool_query_pools(const pool_conf_t *conf, uint_t *size, pool_value_t **props)
18590Sstevel@tonic-gate {
18600Sstevel@tonic-gate pool_result_set_t *rs;
18610Sstevel@tonic-gate pool_elem_t *pe;
18620Sstevel@tonic-gate pool_t **result = NULL;
18630Sstevel@tonic-gate int i = 0;
18640Sstevel@tonic-gate
18650Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
18660Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
18670Sstevel@tonic-gate return (NULL);
18680Sstevel@tonic-gate }
18690Sstevel@tonic-gate rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_POOL, props);
18700Sstevel@tonic-gate if (rs == NULL) {
18710Sstevel@tonic-gate return (NULL);
18720Sstevel@tonic-gate }
18730Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) {
18740Sstevel@tonic-gate (void) pool_rs_close(rs);
18750Sstevel@tonic-gate return (NULL);
18760Sstevel@tonic-gate }
18770Sstevel@tonic-gate if ((result = malloc(sizeof (pool_t *) * (*size + 1))) == NULL) {
18780Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
18790Sstevel@tonic-gate (void) pool_rs_close(rs);
18800Sstevel@tonic-gate return (NULL);
18810Sstevel@tonic-gate }
18820Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_t *) * (*size + 1));
18830Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
18840Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_POOL) {
18850Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
18860Sstevel@tonic-gate free(result);
18870Sstevel@tonic-gate (void) pool_rs_close(rs);
18880Sstevel@tonic-gate return (NULL);
18890Sstevel@tonic-gate }
18900Sstevel@tonic-gate result[i++] = pool_elem_pool(pe);
18910Sstevel@tonic-gate }
18920Sstevel@tonic-gate (void) pool_rs_close(rs);
18930Sstevel@tonic-gate return (result);
18940Sstevel@tonic-gate }
18950Sstevel@tonic-gate
18960Sstevel@tonic-gate /*
18970Sstevel@tonic-gate * Return an res, searching the supplied configuration for an res with the
18980Sstevel@tonic-gate * supplied name. The search is case sensitive.
18990Sstevel@tonic-gate */
19000Sstevel@tonic-gate pool_resource_t *
pool_get_resource(const pool_conf_t * conf,const char * sz_type,const char * name)19010Sstevel@tonic-gate pool_get_resource(const pool_conf_t *conf, const char *sz_type,
19020Sstevel@tonic-gate const char *name)
19030Sstevel@tonic-gate {
19040Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL, NULL };
19050Sstevel@tonic-gate pool_resource_t **rs;
19060Sstevel@tonic-gate pool_resource_t *ret;
19070Sstevel@tonic-gate uint_t size = 0;
19080Sstevel@tonic-gate char_buf_t *cb = NULL;
19090Sstevel@tonic-gate pool_value_t val0 = POOL_VALUE_INITIALIZER;
19100Sstevel@tonic-gate pool_value_t val1 = POOL_VALUE_INITIALIZER;
19110Sstevel@tonic-gate
19120Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
19130Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
19140Sstevel@tonic-gate return (NULL);
19150Sstevel@tonic-gate }
19160Sstevel@tonic-gate
19170Sstevel@tonic-gate if (sz_type == NULL) {
19180Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
19190Sstevel@tonic-gate return (NULL);
19200Sstevel@tonic-gate }
19210Sstevel@tonic-gate
19220Sstevel@tonic-gate props[0] = &val0;
19230Sstevel@tonic-gate props[1] = &val1;
19240Sstevel@tonic-gate
19250Sstevel@tonic-gate if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS ||
19260Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS)
19270Sstevel@tonic-gate return (NULL);
19280Sstevel@tonic-gate
19290Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) {
19300Sstevel@tonic-gate return (NULL);
19310Sstevel@tonic-gate }
19320Sstevel@tonic-gate if (set_char_buf(cb, "%s.name", sz_type) != PO_SUCCESS) {
19330Sstevel@tonic-gate free_char_buf(cb);
19340Sstevel@tonic-gate return (NULL);
19350Sstevel@tonic-gate }
19360Sstevel@tonic-gate if (pool_value_set_name(props[1], cb->cb_buf) != PO_SUCCESS) {
19370Sstevel@tonic-gate free_char_buf(cb);
19380Sstevel@tonic-gate return (NULL);
19390Sstevel@tonic-gate }
19400Sstevel@tonic-gate if (pool_value_set_string(props[1], name) != PO_SUCCESS) {
19410Sstevel@tonic-gate free_char_buf(cb);
19420Sstevel@tonic-gate return (NULL);
19430Sstevel@tonic-gate }
19440Sstevel@tonic-gate free_char_buf(cb);
19450Sstevel@tonic-gate rs = pool_query_resources(conf, &size, props);
19460Sstevel@tonic-gate if (rs == NULL) {
19470Sstevel@tonic-gate return (NULL);
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate if (size != 1) {
19500Sstevel@tonic-gate free(rs);
19510Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
19520Sstevel@tonic-gate return (NULL);
19530Sstevel@tonic-gate }
19540Sstevel@tonic-gate ret = rs[0];
19550Sstevel@tonic-gate free(rs);
19560Sstevel@tonic-gate return (ret);
19570Sstevel@tonic-gate }
19580Sstevel@tonic-gate
19590Sstevel@tonic-gate /*
19600Sstevel@tonic-gate * Return a result set of res (actually as pool_elem_ts), searching the
19610Sstevel@tonic-gate * supplied configuration for res which match the supplied property
19620Sstevel@tonic-gate * criteria. props is a null terminated list of properties which will be used
19630Sstevel@tonic-gate * to match qualifying res.
19640Sstevel@tonic-gate */
19650Sstevel@tonic-gate pool_resource_t **
pool_query_resources(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)19660Sstevel@tonic-gate pool_query_resources(const pool_conf_t *conf, uint_t *size,
19670Sstevel@tonic-gate pool_value_t **props)
19680Sstevel@tonic-gate {
19690Sstevel@tonic-gate pool_result_set_t *rs;
19700Sstevel@tonic-gate pool_elem_t *pe;
19710Sstevel@tonic-gate pool_resource_t **result = NULL;
19720Sstevel@tonic-gate int i = 0;
19730Sstevel@tonic-gate
19740Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
19750Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
19760Sstevel@tonic-gate return (NULL);
19770Sstevel@tonic-gate }
19780Sstevel@tonic-gate
19790Sstevel@tonic-gate *size = 0;
19800Sstevel@tonic-gate
19810Sstevel@tonic-gate rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_RES, props);
19820Sstevel@tonic-gate if (rs == NULL) {
19830Sstevel@tonic-gate return (NULL);
19840Sstevel@tonic-gate }
19850Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) {
19860Sstevel@tonic-gate (void) pool_rs_close(rs);
19870Sstevel@tonic-gate return (NULL);
19880Sstevel@tonic-gate }
19890Sstevel@tonic-gate if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1)))
19900Sstevel@tonic-gate == NULL) {
19910Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
19920Sstevel@tonic-gate (void) pool_rs_close(rs);
19930Sstevel@tonic-gate return (NULL);
19940Sstevel@tonic-gate }
19950Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1));
19960Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
19970Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_RES_COMP &&
19980Sstevel@tonic-gate pool_elem_class(pe) != PEC_RES_AGG) {
19990Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
20000Sstevel@tonic-gate free(result);
20010Sstevel@tonic-gate (void) pool_rs_close(rs);
20020Sstevel@tonic-gate return (NULL);
20030Sstevel@tonic-gate }
20040Sstevel@tonic-gate result[i++] = pool_elem_res(pe);
20050Sstevel@tonic-gate }
20060Sstevel@tonic-gate (void) pool_rs_close(rs);
20070Sstevel@tonic-gate return (result);
20080Sstevel@tonic-gate }
20090Sstevel@tonic-gate
20100Sstevel@tonic-gate /*
20110Sstevel@tonic-gate * Return a result set of comp (actually as pool_elem_ts), searching the
20120Sstevel@tonic-gate * supplied configuration for comp which match the supplied property
20130Sstevel@tonic-gate * criteria. props is a null terminated list of properties which will be used
20140Sstevel@tonic-gate * to match qualifying comp.
20150Sstevel@tonic-gate */
20160Sstevel@tonic-gate pool_component_t **
pool_query_components(const pool_conf_t * conf,uint_t * size,pool_value_t ** props)20170Sstevel@tonic-gate pool_query_components(const pool_conf_t *conf, uint_t *size,
20180Sstevel@tonic-gate pool_value_t **props)
20190Sstevel@tonic-gate {
20200Sstevel@tonic-gate return (pool_query_resource_components(conf, NULL, size, props));
20210Sstevel@tonic-gate }
20220Sstevel@tonic-gate
20230Sstevel@tonic-gate /*
20240Sstevel@tonic-gate * Destroy a pool. If the pool cannot be found or removed an error is
20250Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure
20260Sstevel@tonic-gate * some type safety for the pool subtype.
20270Sstevel@tonic-gate */
20280Sstevel@tonic-gate int
pool_destroy(pool_conf_t * conf,pool_t * pp)20290Sstevel@tonic-gate pool_destroy(pool_conf_t *conf, pool_t *pp)
20300Sstevel@tonic-gate {
20310Sstevel@tonic-gate pool_elem_t *pe;
20320Sstevel@tonic-gate
20330Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
20340Sstevel@tonic-gate return (PO_FAIL);
20350Sstevel@tonic-gate
20360Sstevel@tonic-gate pe = TO_ELEM(pp);
20370Sstevel@tonic-gate
20380Sstevel@tonic-gate /*
20390Sstevel@tonic-gate * Cannot destroy the default pool.
20400Sstevel@tonic-gate */
20410Sstevel@tonic-gate if (elem_is_default(pe) == PO_TRUE) {
20420Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
20430Sstevel@tonic-gate return (PO_FAIL);
20440Sstevel@tonic-gate }
20450Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS)
20460Sstevel@tonic-gate return (PO_FAIL);
20470Sstevel@tonic-gate return (PO_SUCCESS);
20480Sstevel@tonic-gate }
20490Sstevel@tonic-gate
20500Sstevel@tonic-gate /*
20510Sstevel@tonic-gate * Destroy an res. If the res cannot be found or removed an error is
20520Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure
20530Sstevel@tonic-gate * some type safety for the res subtype.
20540Sstevel@tonic-gate */
20550Sstevel@tonic-gate int
pool_resource_destroy(pool_conf_t * conf,pool_resource_t * prs)20560Sstevel@tonic-gate pool_resource_destroy(pool_conf_t *conf, pool_resource_t *prs)
20570Sstevel@tonic-gate {
20580Sstevel@tonic-gate pool_elem_t *pe;
20590Sstevel@tonic-gate pool_component_t **rl;
20600Sstevel@tonic-gate uint_t res_size;
20610Sstevel@tonic-gate pool_t **pl;
20620Sstevel@tonic-gate uint_t npool;
20630Sstevel@tonic-gate int i;
20640Sstevel@tonic-gate
20650Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
20660Sstevel@tonic-gate return (PO_FAIL);
20670Sstevel@tonic-gate
20680Sstevel@tonic-gate pe = TO_ELEM(prs);
20690Sstevel@tonic-gate
20700Sstevel@tonic-gate if (resource_is_system(prs) == PO_TRUE) {
20710Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
20720Sstevel@tonic-gate return (PO_FAIL);
20730Sstevel@tonic-gate }
20740Sstevel@tonic-gate /*
20750Sstevel@tonic-gate * Walk all the pools and dissociate any pools which are using
20760Sstevel@tonic-gate * this resource.
20770Sstevel@tonic-gate */
20780Sstevel@tonic-gate if ((pl = pool_query_pools(conf, &npool, NULL)) != NULL) {
20790Sstevel@tonic-gate for (i = 0; i < npool; i++) {
20800Sstevel@tonic-gate pool_resource_t **rl;
20810Sstevel@tonic-gate uint_t nres;
20820Sstevel@tonic-gate int j;
20830Sstevel@tonic-gate
20840Sstevel@tonic-gate if ((rl = pool_query_pool_resources(conf, pl[i], &nres,
20850Sstevel@tonic-gate NULL)) != NULL) {
20860Sstevel@tonic-gate for (j = 0; j < nres; j++) {
20870Sstevel@tonic-gate if (rl[j] == prs) {
20880Sstevel@tonic-gate if (pool_dissociate(conf, pl[i],
20890Sstevel@tonic-gate rl[j]) != PO_SUCCESS) {
20900Sstevel@tonic-gate free(rl);
20910Sstevel@tonic-gate free(pl);
20920Sstevel@tonic-gate return (PO_FAIL);
20930Sstevel@tonic-gate }
20940Sstevel@tonic-gate break;
20950Sstevel@tonic-gate }
20960Sstevel@tonic-gate }
20970Sstevel@tonic-gate free(rl);
20980Sstevel@tonic-gate }
20990Sstevel@tonic-gate }
21000Sstevel@tonic-gate free(pl);
21010Sstevel@tonic-gate }
21020Sstevel@tonic-gate if (pe->pe_class == PEC_RES_COMP) {
21030Sstevel@tonic-gate pool_resource_t *default_set_res;
21040Sstevel@tonic-gate
21050Sstevel@tonic-gate /*
21060Sstevel@tonic-gate * Use the xtransfer option to move comp around
21070Sstevel@tonic-gate */
21080Sstevel@tonic-gate default_set_res = (pool_resource_t *)get_default_resource(prs);
21090Sstevel@tonic-gate
21100Sstevel@tonic-gate if ((rl = pool_query_resource_components(conf, prs, &res_size,
21110Sstevel@tonic-gate NULL)) != NULL) {
21120Sstevel@tonic-gate int ostate = conf->pc_state;
21130Sstevel@tonic-gate conf->pc_state = POF_DESTROY;
21140Sstevel@tonic-gate if (pool_resource_xtransfer(conf, prs, default_set_res,
21150Sstevel@tonic-gate rl) == PO_FAIL) {
21160Sstevel@tonic-gate free(rl);
21170Sstevel@tonic-gate conf->pc_state = ostate;
21180Sstevel@tonic-gate return (PO_FAIL);
21190Sstevel@tonic-gate }
21200Sstevel@tonic-gate conf->pc_state = ostate;
21210Sstevel@tonic-gate free(rl);
21220Sstevel@tonic-gate }
21230Sstevel@tonic-gate }
21240Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS)
21250Sstevel@tonic-gate return (PO_FAIL);
21260Sstevel@tonic-gate return (PO_SUCCESS);
21270Sstevel@tonic-gate }
21280Sstevel@tonic-gate
21290Sstevel@tonic-gate /*
21300Sstevel@tonic-gate * Destroy a comp. If the comp cannot be found or removed an error is
21310Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure
21320Sstevel@tonic-gate * some type safety for the comp subtype.
21330Sstevel@tonic-gate */
21340Sstevel@tonic-gate int
pool_component_destroy(pool_component_t * pr)21350Sstevel@tonic-gate pool_component_destroy(pool_component_t *pr)
21360Sstevel@tonic-gate {
21370Sstevel@tonic-gate pool_elem_t *pe = TO_ELEM(pr);
21380Sstevel@tonic-gate
21390Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS)
21400Sstevel@tonic-gate return (PO_FAIL);
21410Sstevel@tonic-gate return (PO_SUCCESS);
21420Sstevel@tonic-gate }
21430Sstevel@tonic-gate
21440Sstevel@tonic-gate /*
21450Sstevel@tonic-gate * Remove a pool_elem_t from a configuration. This has been "hidden" away as
21460Sstevel@tonic-gate * a static routine since the only elements which are currently being removed
21470Sstevel@tonic-gate * are pools, res & comp and the wrapper functions above provide type-safe
21480Sstevel@tonic-gate * access. However, if there is a need to remove other types of elements
21490Sstevel@tonic-gate * then this could be promoted to pool_impl.h or more wrappers could
21500Sstevel@tonic-gate * be added to pool_impl.h.
21510Sstevel@tonic-gate */
21520Sstevel@tonic-gate int
pool_elem_remove(pool_elem_t * pe)21530Sstevel@tonic-gate pool_elem_remove(pool_elem_t *pe)
21540Sstevel@tonic-gate {
21550Sstevel@tonic-gate return (pe->pe_remove(pe));
21560Sstevel@tonic-gate }
21570Sstevel@tonic-gate
21580Sstevel@tonic-gate /*
21590Sstevel@tonic-gate * Execute a query to search for a qualifying set of elements.
21600Sstevel@tonic-gate */
21610Sstevel@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)21620Sstevel@tonic-gate pool_exec_query(const pool_conf_t *conf, const pool_elem_t *src,
21630Sstevel@tonic-gate const char *src_attr, pool_elem_class_t classes, pool_value_t **props)
21640Sstevel@tonic-gate {
21650Sstevel@tonic-gate return (conf->pc_prov->pc_exec_query(conf, src, src_attr, classes,
21660Sstevel@tonic-gate props));
21670Sstevel@tonic-gate }
21680Sstevel@tonic-gate
21690Sstevel@tonic-gate /*
21700Sstevel@tonic-gate * Get the next result from a result set of elements.
21710Sstevel@tonic-gate */
21720Sstevel@tonic-gate pool_elem_t *
pool_rs_next(pool_result_set_t * set)21730Sstevel@tonic-gate pool_rs_next(pool_result_set_t *set)
21740Sstevel@tonic-gate {
21750Sstevel@tonic-gate return (set->prs_next(set));
21760Sstevel@tonic-gate }
21770Sstevel@tonic-gate
21780Sstevel@tonic-gate /*
21790Sstevel@tonic-gate * Get the previous result from a result set of elements.
21800Sstevel@tonic-gate */
21810Sstevel@tonic-gate pool_elem_t *
pool_rs_prev(pool_result_set_t * set)21820Sstevel@tonic-gate pool_rs_prev(pool_result_set_t *set)
21830Sstevel@tonic-gate {
21840Sstevel@tonic-gate return (set->prs_prev(set));
21850Sstevel@tonic-gate }
21860Sstevel@tonic-gate
21870Sstevel@tonic-gate /*
21880Sstevel@tonic-gate * Get the first result from a result set of elements.
21890Sstevel@tonic-gate */
21900Sstevel@tonic-gate pool_elem_t *
pool_rs_first(pool_result_set_t * set)21910Sstevel@tonic-gate pool_rs_first(pool_result_set_t *set)
21920Sstevel@tonic-gate {
21930Sstevel@tonic-gate return (set->prs_first(set));
21940Sstevel@tonic-gate }
21950Sstevel@tonic-gate
21960Sstevel@tonic-gate /*
21970Sstevel@tonic-gate * Get the last result from a result set of elements.
21980Sstevel@tonic-gate */
21990Sstevel@tonic-gate pool_elem_t *
pool_rs_last(pool_result_set_t * set)22000Sstevel@tonic-gate pool_rs_last(pool_result_set_t *set)
22010Sstevel@tonic-gate {
22020Sstevel@tonic-gate return (set->prs_last(set));
22030Sstevel@tonic-gate }
22040Sstevel@tonic-gate
22050Sstevel@tonic-gate
22060Sstevel@tonic-gate /*
22070Sstevel@tonic-gate * Get the count for a result set of elements.
22080Sstevel@tonic-gate */
22090Sstevel@tonic-gate int
pool_rs_count(pool_result_set_t * set)22100Sstevel@tonic-gate pool_rs_count(pool_result_set_t *set)
22110Sstevel@tonic-gate {
22120Sstevel@tonic-gate return (set->prs_count(set));
22130Sstevel@tonic-gate }
22140Sstevel@tonic-gate
22150Sstevel@tonic-gate /*
22160Sstevel@tonic-gate * Get the index for a result set of elements.
22170Sstevel@tonic-gate */
22180Sstevel@tonic-gate int
pool_rs_get_index(pool_result_set_t * set)22190Sstevel@tonic-gate pool_rs_get_index(pool_result_set_t *set)
22200Sstevel@tonic-gate {
22210Sstevel@tonic-gate return (set->prs_get_index(set));
22220Sstevel@tonic-gate }
22230Sstevel@tonic-gate
22240Sstevel@tonic-gate /*
22250Sstevel@tonic-gate * Set the index for a result set of elements.
22260Sstevel@tonic-gate */
22270Sstevel@tonic-gate int
pool_rs_set_index(pool_result_set_t * set,int index)22280Sstevel@tonic-gate pool_rs_set_index(pool_result_set_t *set, int index)
22290Sstevel@tonic-gate {
22300Sstevel@tonic-gate return (set->prs_set_index(set, index));
22310Sstevel@tonic-gate }
22320Sstevel@tonic-gate
22330Sstevel@tonic-gate /*
22340Sstevel@tonic-gate * Close a result set of elements, freeing all associated resources.
22350Sstevel@tonic-gate */
22360Sstevel@tonic-gate int
pool_rs_close(pool_result_set_t * set)22370Sstevel@tonic-gate pool_rs_close(pool_result_set_t *set)
22380Sstevel@tonic-gate {
22390Sstevel@tonic-gate return (set->prs_close(set));
22400Sstevel@tonic-gate }
22410Sstevel@tonic-gate
22420Sstevel@tonic-gate /*
22430Sstevel@tonic-gate * When transferring resource components using pool_resource_transfer,
22440Sstevel@tonic-gate * this function is invoked to choose which actual components will be
22450Sstevel@tonic-gate * transferred.
22460Sstevel@tonic-gate */
22470Sstevel@tonic-gate int
choose_components(pool_resource_t * src,pool_resource_t * dst,uint64_t size)22480Sstevel@tonic-gate choose_components(pool_resource_t *src, pool_resource_t *dst, uint64_t size)
22490Sstevel@tonic-gate {
22500Sstevel@tonic-gate pool_component_t **components = NULL, *moved[] = { NULL, NULL };
22510Sstevel@tonic-gate int i;
22520Sstevel@tonic-gate uint_t ncomponent;
22530Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(TO_ELEM(src));
22540Sstevel@tonic-gate
22550Sstevel@tonic-gate if (size == 0)
22560Sstevel@tonic-gate return (PO_SUCCESS);
22570Sstevel@tonic-gate /*
22580Sstevel@tonic-gate * Get the component list from our src component.
22590Sstevel@tonic-gate */
22600Sstevel@tonic-gate if ((components = pool_query_resource_components(conf, src, &ncomponent,
22610Sstevel@tonic-gate NULL)) == NULL) {
22620Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
22630Sstevel@tonic-gate return (PO_FAIL);
22640Sstevel@tonic-gate }
22650Sstevel@tonic-gate qsort(components, ncomponent, sizeof (pool_elem_t *),
22660Sstevel@tonic-gate qsort_elem_compare);
22670Sstevel@tonic-gate /*
22680Sstevel@tonic-gate * Components that aren't specifically requested by the resource
22690Sstevel@tonic-gate * should be transferred out first.
22700Sstevel@tonic-gate */
22710Sstevel@tonic-gate for (i = 0; size > 0 && components[i] != NULL; i++) {
22720Sstevel@tonic-gate if (!cpu_is_requested(components[i])) {
22730Sstevel@tonic-gate moved[0] = components[i];
22740Sstevel@tonic-gate if (pool_resource_xtransfer(conf, src, dst, moved) ==
22750Sstevel@tonic-gate PO_SUCCESS) {
22760Sstevel@tonic-gate size--;
22770Sstevel@tonic-gate }
22780Sstevel@tonic-gate }
22790Sstevel@tonic-gate }
22800Sstevel@tonic-gate
22810Sstevel@tonic-gate /*
22820Sstevel@tonic-gate * If we couldn't find enough "un-requested" components, select random
22830Sstevel@tonic-gate * requested components.
22840Sstevel@tonic-gate */
22850Sstevel@tonic-gate for (i = 0; size > 0 && components[i] != NULL; i++) {
22860Sstevel@tonic-gate if (cpu_is_requested(components[i])) {
22870Sstevel@tonic-gate moved[0] = components[i];
22880Sstevel@tonic-gate if (pool_resource_xtransfer(conf, src, dst, moved) ==
22890Sstevel@tonic-gate PO_SUCCESS) {
22900Sstevel@tonic-gate size--;
22910Sstevel@tonic-gate }
22920Sstevel@tonic-gate }
22930Sstevel@tonic-gate }
22940Sstevel@tonic-gate
22950Sstevel@tonic-gate free(components);
22960Sstevel@tonic-gate /*
22970Sstevel@tonic-gate * If we couldn't transfer out all the resources we asked for, then
22980Sstevel@tonic-gate * return error.
22990Sstevel@tonic-gate */
23000Sstevel@tonic-gate return (size == 0 ? PO_SUCCESS : PO_FAIL);
23010Sstevel@tonic-gate }
23020Sstevel@tonic-gate
23030Sstevel@tonic-gate /*
23040Sstevel@tonic-gate * Common processing for a resource transfer (xfer or xxfer).
23050Sstevel@tonic-gate *
23060Sstevel@tonic-gate * - Return XFER_CONTINUE if the transfer should proceeed
23070Sstevel@tonic-gate * - Return XFER_FAIL if the transfer should be stopped in failure
23080Sstevel@tonic-gate * - Return XFER_SUCCESS if the transfer should be stopped in success
23090Sstevel@tonic-gate */
23100Sstevel@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)23110Sstevel@tonic-gate setup_transfer(pool_conf_t *conf, pool_resource_t *src, pool_resource_t *tgt,
23120Sstevel@tonic-gate uint64_t size, uint64_t *src_size, uint64_t *tgt_size)
23130Sstevel@tonic-gate {
23140Sstevel@tonic-gate uint64_t src_min;
23150Sstevel@tonic-gate uint64_t tgt_max;
23160Sstevel@tonic-gate
23170Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
23180Sstevel@tonic-gate return (XFER_FAIL);
23190Sstevel@tonic-gate
23200Sstevel@tonic-gate /*
23210Sstevel@tonic-gate * Makes sure the two resources are of the same type
23220Sstevel@tonic-gate */
23230Sstevel@tonic-gate if (pool_resource_elem_class(TO_ELEM(src)) !=
23240Sstevel@tonic-gate pool_resource_elem_class(TO_ELEM(tgt))) {
23250Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
23260Sstevel@tonic-gate return (XFER_FAIL);
23270Sstevel@tonic-gate }
23280Sstevel@tonic-gate
23290Sstevel@tonic-gate /*
23300Sstevel@tonic-gate * Transferring to yourself is a no-op
23310Sstevel@tonic-gate */
23320Sstevel@tonic-gate if (src == tgt)
23330Sstevel@tonic-gate return (XFER_SUCCESS);
23340Sstevel@tonic-gate
23350Sstevel@tonic-gate /*
23360Sstevel@tonic-gate * Transferring nothing is a no-op
23370Sstevel@tonic-gate */
23380Sstevel@tonic-gate if (size == 0)
23390Sstevel@tonic-gate return (XFER_SUCCESS);
23400Sstevel@tonic-gate
23410Sstevel@tonic-gate if (resource_get_min(src, &src_min) != PO_SUCCESS ||
23420Sstevel@tonic-gate resource_get_size(src, src_size) != PO_SUCCESS ||
23430Sstevel@tonic-gate resource_get_max(tgt, &tgt_max) != PO_SUCCESS ||
23440Sstevel@tonic-gate resource_get_size(tgt, tgt_size) != PO_SUCCESS) {
23450Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
23460Sstevel@tonic-gate return (XFER_FAIL);
23470Sstevel@tonic-gate }
23480Sstevel@tonic-gate if (pool_conf_status(conf) != POF_DESTROY) {
23490Sstevel@tonic-gate /*
23500Sstevel@tonic-gate * src_size - donating >= src.min
23510Sstevel@tonic-gate * size + receiving <= tgt.max (except for default)
23520Sstevel@tonic-gate */
23530Sstevel@tonic-gate #ifdef DEBUG
23540Sstevel@tonic-gate dprintf("conf is %s\n", pool_conf_location(conf));
23550Sstevel@tonic-gate dprintf("setup_transfer: src_size %llu\n", *src_size);
23560Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(src));
23570Sstevel@tonic-gate dprintf("setup_transfer: tgt_size %llu\n", *tgt_size);
23580Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(tgt));
23590Sstevel@tonic-gate #endif /* DEBUG */
23600Sstevel@tonic-gate if (*src_size - size < src_min ||
23610Sstevel@tonic-gate (resource_is_default(tgt) == PO_FALSE &&
23620Sstevel@tonic-gate *tgt_size + size > tgt_max)) {
23630Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
23640Sstevel@tonic-gate return (XFER_FAIL);
23650Sstevel@tonic-gate }
23660Sstevel@tonic-gate }
23670Sstevel@tonic-gate return (XFER_CONTINUE);
23680Sstevel@tonic-gate }
23690Sstevel@tonic-gate
23700Sstevel@tonic-gate /*
23710Sstevel@tonic-gate * Transfer resource quantities from one resource set to another.
23720Sstevel@tonic-gate */
23730Sstevel@tonic-gate int
pool_resource_transfer(pool_conf_t * conf,pool_resource_t * src,pool_resource_t * tgt,uint64_t size)23740Sstevel@tonic-gate pool_resource_transfer(pool_conf_t *conf, pool_resource_t *src,
23750Sstevel@tonic-gate pool_resource_t *tgt, uint64_t size)
23760Sstevel@tonic-gate {
23770Sstevel@tonic-gate uint64_t src_size;
23780Sstevel@tonic-gate uint64_t tgt_size;
23790Sstevel@tonic-gate int ret;
23800Sstevel@tonic-gate
23810Sstevel@tonic-gate if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size))
23820Sstevel@tonic-gate != XFER_CONTINUE)
23830Sstevel@tonic-gate return (ret);
23840Sstevel@tonic-gate /*
23850Sstevel@tonic-gate * If this resource is a res_comp we must call move components
23860Sstevel@tonic-gate */
23870Sstevel@tonic-gate if (pool_elem_class(TO_ELEM(src)) == PEC_RES_COMP)
23880Sstevel@tonic-gate return (choose_components(src, tgt, size));
23890Sstevel@tonic-gate /*
23900Sstevel@tonic-gate * Now do the transfer.
23910Sstevel@tonic-gate */
23920Sstevel@tonic-gate ret = conf->pc_prov->pc_res_xfer(src, tgt, size);
23930Sstevel@tonic-gate /*
23940Sstevel@tonic-gate * Modify the sizes of the resource sets if the process was
23950Sstevel@tonic-gate * successful
23960Sstevel@tonic-gate */
23970Sstevel@tonic-gate if (ret == PO_SUCCESS) {
23980Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
23990Sstevel@tonic-gate
24000Sstevel@tonic-gate src_size -= size;
24010Sstevel@tonic-gate tgt_size += size;
24020Sstevel@tonic-gate pool_value_set_uint64(&val, src_size);
24030Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop,
24040Sstevel@tonic-gate &val);
24050Sstevel@tonic-gate pool_value_set_uint64(&val, tgt_size);
24060Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop,
24070Sstevel@tonic-gate &val);
24080Sstevel@tonic-gate }
24090Sstevel@tonic-gate return (ret);
24100Sstevel@tonic-gate }
24110Sstevel@tonic-gate
24120Sstevel@tonic-gate /*
24130Sstevel@tonic-gate * Transfer resource components from one resource set to another.
24140Sstevel@tonic-gate */
24150Sstevel@tonic-gate int
pool_resource_xtransfer(pool_conf_t * conf,pool_resource_t * src,pool_resource_t * tgt,pool_component_t ** rl)24160Sstevel@tonic-gate pool_resource_xtransfer(pool_conf_t *conf, pool_resource_t *src,
24170Sstevel@tonic-gate pool_resource_t *tgt,
24180Sstevel@tonic-gate pool_component_t **rl)
24190Sstevel@tonic-gate {
24200Sstevel@tonic-gate int i;
24210Sstevel@tonic-gate uint64_t src_size;
24220Sstevel@tonic-gate uint64_t tgt_size;
24230Sstevel@tonic-gate uint64_t size;
24240Sstevel@tonic-gate int ret;
24250Sstevel@tonic-gate
24260Sstevel@tonic-gate /*
24270Sstevel@tonic-gate * Make sure the components are all contained in 'src'. This
24280Sstevel@tonic-gate * processing must be done before setup_transfer so that size
24290Sstevel@tonic-gate * is known.
24300Sstevel@tonic-gate */
24310Sstevel@tonic-gate for (i = 0; rl[i] != NULL; i++) {
24320Sstevel@tonic-gate #ifdef DEBUG
24330Sstevel@tonic-gate dprintf("resource xtransfer\n");
24340Sstevel@tonic-gate dprintf("in conf %s\n", pool_conf_location(conf));
24350Sstevel@tonic-gate dprintf("transferring component\n");
24360Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(rl[i]));
24370Sstevel@tonic-gate dprintf("from\n");
24380Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(src));
24390Sstevel@tonic-gate dprintf("to\n");
24400Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(tgt));
24410Sstevel@tonic-gate #endif /* DEBUG */
24420Sstevel@tonic-gate
24430Sstevel@tonic-gate if (pool_get_owning_resource(conf, rl[i]) != src) {
24440Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
24450Sstevel@tonic-gate return (PO_FAIL);
24460Sstevel@tonic-gate }
24470Sstevel@tonic-gate }
24480Sstevel@tonic-gate
24490Sstevel@tonic-gate size = (uint64_t)i;
24500Sstevel@tonic-gate
24510Sstevel@tonic-gate if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size))
24520Sstevel@tonic-gate != XFER_CONTINUE)
24530Sstevel@tonic-gate return (ret);
24540Sstevel@tonic-gate
24550Sstevel@tonic-gate ret = conf->pc_prov->pc_res_xxfer(src, tgt, rl);
24560Sstevel@tonic-gate /*
24570Sstevel@tonic-gate * Modify the sizes of the resource sets if the process was
24580Sstevel@tonic-gate * successful
24590Sstevel@tonic-gate */
24600Sstevel@tonic-gate if (ret == PO_SUCCESS) {
24610Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
24620Sstevel@tonic-gate
24630Sstevel@tonic-gate #ifdef DEBUG
24640Sstevel@tonic-gate dprintf("src_size %llu\n", src_size);
24650Sstevel@tonic-gate dprintf("tgt_size %llu\n", tgt_size);
24660Sstevel@tonic-gate dprintf("size %llu\n", size);
24670Sstevel@tonic-gate #endif /* DEBUG */
24680Sstevel@tonic-gate src_size -= size;
24690Sstevel@tonic-gate tgt_size += size;
24700Sstevel@tonic-gate pool_value_set_uint64(&val, src_size);
24710Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop,
24720Sstevel@tonic-gate &val);
24730Sstevel@tonic-gate pool_value_set_uint64(&val, tgt_size);
24740Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop,
24750Sstevel@tonic-gate &val);
24760Sstevel@tonic-gate }
24770Sstevel@tonic-gate return (ret);
24780Sstevel@tonic-gate }
24790Sstevel@tonic-gate
24800Sstevel@tonic-gate /*
24810Sstevel@tonic-gate * Find the owning resource for a resource component.
24820Sstevel@tonic-gate */
24830Sstevel@tonic-gate pool_resource_t *
pool_get_owning_resource(const pool_conf_t * conf,const pool_component_t * comp)24840Sstevel@tonic-gate pool_get_owning_resource(const pool_conf_t *conf, const pool_component_t *comp)
24850Sstevel@tonic-gate {
24860Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
24870Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
24880Sstevel@tonic-gate return (NULL);
24890Sstevel@tonic-gate }
24900Sstevel@tonic-gate return (pool_elem_res(pool_get_container(TO_ELEM(comp))));
24910Sstevel@tonic-gate }
24920Sstevel@tonic-gate
24930Sstevel@tonic-gate /*
24940Sstevel@tonic-gate * pool_get_container() returns the container of pc.
24950Sstevel@tonic-gate */
24960Sstevel@tonic-gate pool_elem_t *
pool_get_container(const pool_elem_t * pc)24970Sstevel@tonic-gate pool_get_container(const pool_elem_t *pc)
24980Sstevel@tonic-gate {
24990Sstevel@tonic-gate return (pc->pe_get_container(pc));
25000Sstevel@tonic-gate }
25010Sstevel@tonic-gate
25020Sstevel@tonic-gate /*
25030Sstevel@tonic-gate * pool_set_container() moves pc so that it is contained by pp.
25040Sstevel@tonic-gate *
25050Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL
25060Sstevel@tonic-gate */
25070Sstevel@tonic-gate int
pool_set_container(pool_elem_t * pp,pool_elem_t * pc)25080Sstevel@tonic-gate pool_set_container(pool_elem_t *pp, pool_elem_t *pc)
25090Sstevel@tonic-gate {
25100Sstevel@tonic-gate return (pc->pe_set_container(pp, pc));
25110Sstevel@tonic-gate }
25120Sstevel@tonic-gate
25130Sstevel@tonic-gate /*
25140Sstevel@tonic-gate * Conversion routines for converting to and from elem and it's various
25150Sstevel@tonic-gate * subtypes of system, pool, res and comp.
25160Sstevel@tonic-gate */
25170Sstevel@tonic-gate pool_elem_t *
pool_system_elem(const pool_system_t * ph)25180Sstevel@tonic-gate pool_system_elem(const pool_system_t *ph)
25190Sstevel@tonic-gate {
25200Sstevel@tonic-gate return ((pool_elem_t *)ph);
25210Sstevel@tonic-gate }
25220Sstevel@tonic-gate
25230Sstevel@tonic-gate pool_elem_t *
pool_conf_to_elem(const pool_conf_t * conf)25240Sstevel@tonic-gate pool_conf_to_elem(const pool_conf_t *conf)
25250Sstevel@tonic-gate {
25260Sstevel@tonic-gate pool_system_t *sys;
25270Sstevel@tonic-gate
25280Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
25290Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25300Sstevel@tonic-gate return (NULL);
25310Sstevel@tonic-gate }
25320Sstevel@tonic-gate if ((sys = pool_conf_system(conf)) == NULL) {
25330Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25340Sstevel@tonic-gate return (NULL);
25350Sstevel@tonic-gate }
25360Sstevel@tonic-gate return (pool_system_elem(sys));
25370Sstevel@tonic-gate }
25380Sstevel@tonic-gate
25390Sstevel@tonic-gate pool_elem_t *
pool_to_elem(const pool_conf_t * conf,const pool_t * pp)25400Sstevel@tonic-gate pool_to_elem(const pool_conf_t *conf, const pool_t *pp)
25410Sstevel@tonic-gate {
25420Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
25430Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25440Sstevel@tonic-gate return (NULL);
25450Sstevel@tonic-gate }
25460Sstevel@tonic-gate return ((pool_elem_t *)pp);
25470Sstevel@tonic-gate }
25480Sstevel@tonic-gate
25490Sstevel@tonic-gate pool_elem_t *
pool_resource_to_elem(const pool_conf_t * conf,const pool_resource_t * prs)25500Sstevel@tonic-gate pool_resource_to_elem(const pool_conf_t *conf, const pool_resource_t *prs)
25510Sstevel@tonic-gate {
25520Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
25530Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25540Sstevel@tonic-gate return (NULL);
25550Sstevel@tonic-gate }
25560Sstevel@tonic-gate return ((pool_elem_t *)prs);
25570Sstevel@tonic-gate }
25580Sstevel@tonic-gate
25590Sstevel@tonic-gate pool_elem_t *
pool_component_to_elem(const pool_conf_t * conf,const pool_component_t * pr)25600Sstevel@tonic-gate pool_component_to_elem(const pool_conf_t *conf, const pool_component_t *pr)
25610Sstevel@tonic-gate {
25620Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
25630Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25640Sstevel@tonic-gate return (NULL);
25650Sstevel@tonic-gate }
25660Sstevel@tonic-gate return ((pool_elem_t *)pr);
25670Sstevel@tonic-gate }
25680Sstevel@tonic-gate
25690Sstevel@tonic-gate /*
25700Sstevel@tonic-gate * Walk all the pools of the configuration calling the user supplied function
25710Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE
25720Sstevel@tonic-gate */
25730Sstevel@tonic-gate int
pool_walk_pools(pool_conf_t * conf,void * arg,int (* callback)(pool_conf_t * conf,pool_t * pool,void * arg))25740Sstevel@tonic-gate pool_walk_pools(pool_conf_t *conf, void *arg,
25750Sstevel@tonic-gate int (*callback)(pool_conf_t *conf, pool_t *pool, void *arg))
25760Sstevel@tonic-gate {
25770Sstevel@tonic-gate pool_t **rs;
25780Sstevel@tonic-gate int i;
25790Sstevel@tonic-gate uint_t size;
25800Sstevel@tonic-gate int error = PO_SUCCESS;
25810Sstevel@tonic-gate
25820Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
25830Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
25840Sstevel@tonic-gate return (PO_FAIL);
25850Sstevel@tonic-gate }
25860Sstevel@tonic-gate
25870Sstevel@tonic-gate if ((rs = pool_query_pools(conf, &size, NULL)) == NULL) /* None */
25880Sstevel@tonic-gate return (PO_SUCCESS);
25890Sstevel@tonic-gate for (i = 0; i < size; i++)
25900Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) {
25910Sstevel@tonic-gate error = PO_FAIL;
25920Sstevel@tonic-gate break;
25930Sstevel@tonic-gate }
25940Sstevel@tonic-gate free(rs);
25950Sstevel@tonic-gate return (error);
25960Sstevel@tonic-gate }
25970Sstevel@tonic-gate
25980Sstevel@tonic-gate /*
25990Sstevel@tonic-gate * Walk all the comp of the res calling the user supplied function
26000Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE
26010Sstevel@tonic-gate */
26020Sstevel@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))26030Sstevel@tonic-gate pool_walk_components(pool_conf_t *conf, pool_resource_t *prs, void *arg,
26040Sstevel@tonic-gate int (*callback)(pool_conf_t *conf, pool_component_t *pr, void *arg))
26050Sstevel@tonic-gate {
26060Sstevel@tonic-gate pool_component_t **rs;
26070Sstevel@tonic-gate int i;
26080Sstevel@tonic-gate uint_t size;
26090Sstevel@tonic-gate int error = PO_SUCCESS;
26100Sstevel@tonic-gate
26110Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
26120Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
26130Sstevel@tonic-gate return (PO_FAIL);
26140Sstevel@tonic-gate }
26150Sstevel@tonic-gate
26160Sstevel@tonic-gate if ((rs = pool_query_resource_components(conf, prs, &size, NULL)) ==
26170Sstevel@tonic-gate NULL)
26180Sstevel@tonic-gate return (PO_SUCCESS); /* None */
26190Sstevel@tonic-gate for (i = 0; i < size; i++)
26200Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) {
26210Sstevel@tonic-gate error = PO_FAIL;
26220Sstevel@tonic-gate break;
26230Sstevel@tonic-gate }
26240Sstevel@tonic-gate free(rs);
26250Sstevel@tonic-gate return (error);
26260Sstevel@tonic-gate }
26270Sstevel@tonic-gate
26280Sstevel@tonic-gate /*
26290Sstevel@tonic-gate * Return an array of all matching res for the supplied pool.
26300Sstevel@tonic-gate */
26310Sstevel@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)26320Sstevel@tonic-gate pool_query_pool_resources(const pool_conf_t *conf, const pool_t *pp,
26330Sstevel@tonic-gate uint_t *size, pool_value_t **props)
26340Sstevel@tonic-gate {
26350Sstevel@tonic-gate pool_result_set_t *rs;
26360Sstevel@tonic-gate pool_elem_t *pe;
26370Sstevel@tonic-gate pool_resource_t **result = NULL;
26380Sstevel@tonic-gate int i = 0;
26390Sstevel@tonic-gate
26400Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
26410Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
26420Sstevel@tonic-gate return (NULL);
26430Sstevel@tonic-gate }
26440Sstevel@tonic-gate
26450Sstevel@tonic-gate pe = TO_ELEM(pp);
26460Sstevel@tonic-gate
26470Sstevel@tonic-gate rs = pool_exec_query(conf, pe, "res", PEC_QRY_RES, props);
26480Sstevel@tonic-gate if (rs == NULL) {
26490Sstevel@tonic-gate return (NULL);
26500Sstevel@tonic-gate }
26510Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) {
26520Sstevel@tonic-gate (void) pool_rs_close(rs);
26530Sstevel@tonic-gate return (NULL);
26540Sstevel@tonic-gate }
26550Sstevel@tonic-gate if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1)))
26560Sstevel@tonic-gate == NULL) {
26570Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
26580Sstevel@tonic-gate (void) pool_rs_close(rs);
26590Sstevel@tonic-gate return (NULL);
26600Sstevel@tonic-gate }
26610Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1));
26620Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
26630Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_RES_COMP &&
26640Sstevel@tonic-gate pool_elem_class(pe) != PEC_RES_AGG) {
26650Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
26660Sstevel@tonic-gate free(result);
26670Sstevel@tonic-gate (void) pool_rs_close(rs);
26680Sstevel@tonic-gate return (NULL);
26690Sstevel@tonic-gate }
26700Sstevel@tonic-gate result[i++] = pool_elem_res(pe);
26710Sstevel@tonic-gate }
26720Sstevel@tonic-gate (void) pool_rs_close(rs);
26730Sstevel@tonic-gate return (result);
26740Sstevel@tonic-gate }
26750Sstevel@tonic-gate
26760Sstevel@tonic-gate /*
26770Sstevel@tonic-gate * Walk all the res of the pool calling the user supplied function
26780Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE
26790Sstevel@tonic-gate */
26800Sstevel@tonic-gate int
pool_walk_resources(pool_conf_t * conf,pool_t * pp,void * arg,int (* callback)(pool_conf_t *,pool_resource_t *,void *))26810Sstevel@tonic-gate pool_walk_resources(pool_conf_t *conf, pool_t *pp, void *arg,
26820Sstevel@tonic-gate int (*callback)(pool_conf_t *, pool_resource_t *, void *))
26830Sstevel@tonic-gate {
26840Sstevel@tonic-gate pool_resource_t **rs;
26850Sstevel@tonic-gate int i;
26860Sstevel@tonic-gate uint_t size;
26870Sstevel@tonic-gate int error = PO_SUCCESS;
26880Sstevel@tonic-gate
26890Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
26900Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
26910Sstevel@tonic-gate return (PO_FAIL);
26920Sstevel@tonic-gate }
26930Sstevel@tonic-gate if ((rs = pool_query_pool_resources(conf, pp, &size, NULL)) == NULL)
26940Sstevel@tonic-gate return (PO_SUCCESS); /* None */
26950Sstevel@tonic-gate for (i = 0; i < size; i++)
26960Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) {
26970Sstevel@tonic-gate error = PO_FAIL;
26980Sstevel@tonic-gate break;
26990Sstevel@tonic-gate }
27000Sstevel@tonic-gate free(rs);
27010Sstevel@tonic-gate return (error);
27020Sstevel@tonic-gate }
27030Sstevel@tonic-gate
27040Sstevel@tonic-gate /*
27050Sstevel@tonic-gate * Return a result set of all comp for the supplied res.
27060Sstevel@tonic-gate */
27070Sstevel@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)27080Sstevel@tonic-gate pool_query_resource_components(const pool_conf_t *conf,
27090Sstevel@tonic-gate const pool_resource_t *prs, uint_t *size, pool_value_t **props)
27100Sstevel@tonic-gate {
27110Sstevel@tonic-gate pool_result_set_t *rs;
27120Sstevel@tonic-gate pool_elem_t *pe;
27130Sstevel@tonic-gate pool_component_t **result = NULL;
27140Sstevel@tonic-gate int i = 0;
27150Sstevel@tonic-gate
27160Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
27170Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
27180Sstevel@tonic-gate return (NULL);
27190Sstevel@tonic-gate }
27200Sstevel@tonic-gate pe = TO_ELEM(prs);
27210Sstevel@tonic-gate
27220Sstevel@tonic-gate rs = pool_exec_query(conf, pe, NULL, PEC_QRY_COMP, props);
27230Sstevel@tonic-gate if (rs == NULL) {
27240Sstevel@tonic-gate return (NULL);
27250Sstevel@tonic-gate }
27260Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) {
27270Sstevel@tonic-gate (void) pool_rs_close(rs);
27280Sstevel@tonic-gate return (NULL);
27290Sstevel@tonic-gate }
27300Sstevel@tonic-gate if ((result = malloc(sizeof (pool_component_t *) * (*size + 1)))
27310Sstevel@tonic-gate == NULL) {
27320Sstevel@tonic-gate pool_seterror(POE_SYSTEM);
27330Sstevel@tonic-gate (void) pool_rs_close(rs);
27340Sstevel@tonic-gate return (NULL);
27350Sstevel@tonic-gate }
27360Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_component_t *) * (*size + 1));
27370Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) {
27380Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_COMP) {
27390Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF);
27400Sstevel@tonic-gate free(result);
27410Sstevel@tonic-gate (void) pool_rs_close(rs);
27420Sstevel@tonic-gate return (NULL);
27430Sstevel@tonic-gate }
27440Sstevel@tonic-gate result[i++] = pool_elem_comp(pe);
27450Sstevel@tonic-gate }
27460Sstevel@tonic-gate (void) pool_rs_close(rs);
27470Sstevel@tonic-gate return (result);
27480Sstevel@tonic-gate }
27490Sstevel@tonic-gate
27500Sstevel@tonic-gate /*
27510Sstevel@tonic-gate * pool_version() returns the version of this library, depending on the supplied
27520Sstevel@tonic-gate * parameter.
27530Sstevel@tonic-gate *
27540Sstevel@tonic-gate * Returns: library version depening on the supplied ver parameter.
27550Sstevel@tonic-gate */
27560Sstevel@tonic-gate uint_t
pool_version(uint_t ver)27570Sstevel@tonic-gate pool_version(uint_t ver)
27580Sstevel@tonic-gate {
27590Sstevel@tonic-gate switch (ver) {
27600Sstevel@tonic-gate case POOL_VER_NONE:
27610Sstevel@tonic-gate break;
27620Sstevel@tonic-gate case POOL_VER_CURRENT:
27630Sstevel@tonic-gate pool_workver = ver;
27640Sstevel@tonic-gate break;
27650Sstevel@tonic-gate default:
27660Sstevel@tonic-gate return (POOL_VER_NONE);
27670Sstevel@tonic-gate }
27680Sstevel@tonic-gate return (pool_workver);
27690Sstevel@tonic-gate }
27700Sstevel@tonic-gate
27710Sstevel@tonic-gate /*
27720Sstevel@tonic-gate * pool_associate() associates the supplied resource to the supplied pool.
27730Sstevel@tonic-gate *
27740Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL
27750Sstevel@tonic-gate */
27760Sstevel@tonic-gate int
pool_associate(pool_conf_t * conf,pool_t * pool,const pool_resource_t * res)27770Sstevel@tonic-gate pool_associate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res)
27780Sstevel@tonic-gate {
27790Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
27800Sstevel@tonic-gate return (PO_FAIL);
27810Sstevel@tonic-gate
27820Sstevel@tonic-gate return (pool->pp_associate(pool, res));
27830Sstevel@tonic-gate }
27840Sstevel@tonic-gate
27850Sstevel@tonic-gate /*
27860Sstevel@tonic-gate * pool_dissociate() dissociates the supplied resource from the supplied pool.
27870Sstevel@tonic-gate *
27880Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL
27890Sstevel@tonic-gate */
27900Sstevel@tonic-gate int
pool_dissociate(pool_conf_t * conf,pool_t * pool,const pool_resource_t * res)27910Sstevel@tonic-gate pool_dissociate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res)
27920Sstevel@tonic-gate {
27930Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS)
27940Sstevel@tonic-gate return (PO_FAIL);
27950Sstevel@tonic-gate
27960Sstevel@tonic-gate if (elem_is_default(TO_ELEM(res)))
27970Sstevel@tonic-gate return (PO_SUCCESS);
27980Sstevel@tonic-gate return (pool->pp_dissociate(pool, res));
27990Sstevel@tonic-gate }
28000Sstevel@tonic-gate
28010Sstevel@tonic-gate /*
28020Sstevel@tonic-gate * Compare two elements for purposes of ordering.
28030Sstevel@tonic-gate * Return:
28040Sstevel@tonic-gate * < 0 if e1 is "before" e2
28050Sstevel@tonic-gate * 0 if e1 "equals" e2
28060Sstevel@tonic-gate * > 0 if e1 comes after e2
28070Sstevel@tonic-gate */
28080Sstevel@tonic-gate int
pool_elem_compare_name(const pool_elem_t * e1,const pool_elem_t * e2)28090Sstevel@tonic-gate pool_elem_compare_name(const pool_elem_t *e1, const pool_elem_t *e2)
28100Sstevel@tonic-gate {
28110Sstevel@tonic-gate char *name1, *name2;
28120Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
28130Sstevel@tonic-gate int retval;
28140Sstevel@tonic-gate
28150Sstevel@tonic-gate /*
28160Sstevel@tonic-gate * We may be asked to compare two elements from different classes.
28170Sstevel@tonic-gate * They are different so return (1).
28180Sstevel@tonic-gate */
28190Sstevel@tonic-gate if (pool_elem_same_class(e1, e2) != PO_TRUE)
28200Sstevel@tonic-gate return (1);
28210Sstevel@tonic-gate
28220Sstevel@tonic-gate /*
28230Sstevel@tonic-gate * If the class is PEC_SYSTEM, always match them
28240Sstevel@tonic-gate */
28250Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_SYSTEM)
28260Sstevel@tonic-gate return (0);
28270Sstevel@tonic-gate
28280Sstevel@tonic-gate /*
28290Sstevel@tonic-gate * If we are going to compare components, then use sys_id
28300Sstevel@tonic-gate */
28310Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_COMP) {
28320Sstevel@tonic-gate int64_t sys_id1, sys_id2;
28330Sstevel@tonic-gate
28340Sstevel@tonic-gate if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) {
28350Sstevel@tonic-gate return (-1);
28360Sstevel@tonic-gate }
28370Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id1);
28380Sstevel@tonic-gate if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) {
28390Sstevel@tonic-gate return (-1);
28400Sstevel@tonic-gate }
28410Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id2);
28420Sstevel@tonic-gate retval = (sys_id1 - sys_id2);
28430Sstevel@tonic-gate } else {
28440Sstevel@tonic-gate if (pool_get_ns_property(e1, "name", &val) == POC_INVAL) {
28450Sstevel@tonic-gate return (-1);
28460Sstevel@tonic-gate }
28470Sstevel@tonic-gate (void) pool_value_get_string(&val, (const char **)&name1);
28480Sstevel@tonic-gate if ((name1 = strdup(name1)) == NULL) {
28490Sstevel@tonic-gate return (-1);
28500Sstevel@tonic-gate }
28510Sstevel@tonic-gate
28520Sstevel@tonic-gate if (pool_get_ns_property(e2, "name", &val) == POC_INVAL) {
28530Sstevel@tonic-gate return (-1);
28540Sstevel@tonic-gate }
28550Sstevel@tonic-gate
28560Sstevel@tonic-gate (void) pool_value_get_string(&val, (const char **)&name2);
28570Sstevel@tonic-gate retval = strcmp(name1, name2);
28580Sstevel@tonic-gate free(name1);
28590Sstevel@tonic-gate }
28600Sstevel@tonic-gate return (retval);
28610Sstevel@tonic-gate }
28620Sstevel@tonic-gate
28630Sstevel@tonic-gate /*
28640Sstevel@tonic-gate * Compare two elements for purposes of ordering.
28650Sstevel@tonic-gate * Return:
28660Sstevel@tonic-gate * < 0 if e1 is "before" e2
28670Sstevel@tonic-gate * 0 if e1 "equals" e2
28680Sstevel@tonic-gate * > 0 if e1 comes after e2
28690Sstevel@tonic-gate */
28700Sstevel@tonic-gate int
pool_elem_compare(const pool_elem_t * e1,const pool_elem_t * e2)28710Sstevel@tonic-gate pool_elem_compare(const pool_elem_t *e1, const pool_elem_t *e2)
28720Sstevel@tonic-gate {
28730Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER;
28740Sstevel@tonic-gate int64_t sys_id1, sys_id2;
28750Sstevel@tonic-gate
28760Sstevel@tonic-gate /*
28770Sstevel@tonic-gate * We may be asked to compare two elements from different classes.
28780Sstevel@tonic-gate * They are different so return the difference in their classes
28790Sstevel@tonic-gate */
28800Sstevel@tonic-gate if (pool_elem_same_class(e1, e2) != PO_TRUE)
28810Sstevel@tonic-gate return (1);
28820Sstevel@tonic-gate
28830Sstevel@tonic-gate /*
28840Sstevel@tonic-gate * If the class is PEC_SYSTEM, always match them
28850Sstevel@tonic-gate */
28860Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_SYSTEM)
28870Sstevel@tonic-gate return (0);
28880Sstevel@tonic-gate
28890Sstevel@tonic-gate /*
28900Sstevel@tonic-gate * Compare with sys_id
28910Sstevel@tonic-gate */
28920Sstevel@tonic-gate if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) {
28930Sstevel@tonic-gate assert(!"no sys_id on e1\n");
28940Sstevel@tonic-gate }
28950Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id1);
28960Sstevel@tonic-gate if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) {
28970Sstevel@tonic-gate assert(!"no sys_id on e2\n");
28980Sstevel@tonic-gate }
28990Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id2);
29000Sstevel@tonic-gate return (sys_id1 - sys_id2);
29010Sstevel@tonic-gate }
29020Sstevel@tonic-gate
29030Sstevel@tonic-gate /*
29040Sstevel@tonic-gate * Return PO_TRUE if the supplied elems are of the same class.
29050Sstevel@tonic-gate */
29060Sstevel@tonic-gate int
pool_elem_same_class(const pool_elem_t * e1,const pool_elem_t * e2)29070Sstevel@tonic-gate pool_elem_same_class(const pool_elem_t *e1, const pool_elem_t *e2)
29080Sstevel@tonic-gate {
29090Sstevel@tonic-gate if (pool_elem_class(e1) != pool_elem_class(e2))
29100Sstevel@tonic-gate return (PO_FALSE);
29110Sstevel@tonic-gate
29120Sstevel@tonic-gate /*
29130Sstevel@tonic-gate * Check to make sure the fundamental class of the elements match
29140Sstevel@tonic-gate */
29150Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_RES_COMP ||
29160Sstevel@tonic-gate pool_elem_class(e1) == PEC_RES_AGG)
29170Sstevel@tonic-gate if (pool_resource_elem_class(e1) !=
29180Sstevel@tonic-gate pool_resource_elem_class(e2))
29190Sstevel@tonic-gate return (PO_FALSE);
29200Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_COMP)
29210Sstevel@tonic-gate if (pool_component_elem_class(e1) !=
29220Sstevel@tonic-gate pool_component_elem_class(e2))
29230Sstevel@tonic-gate return (PO_FALSE);
29240Sstevel@tonic-gate return (PO_TRUE);
29250Sstevel@tonic-gate }
29260Sstevel@tonic-gate
29270Sstevel@tonic-gate /*
29280Sstevel@tonic-gate * pool_conf_check() checks that the configuration state isn't invalid
29290Sstevel@tonic-gate * and that the configuration was opened for modification.
29300Sstevel@tonic-gate */
29310Sstevel@tonic-gate int
pool_conf_check(const pool_conf_t * conf)29320Sstevel@tonic-gate pool_conf_check(const pool_conf_t *conf)
29330Sstevel@tonic-gate {
29340Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) {
29350Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
29360Sstevel@tonic-gate return (PO_FAIL);
29370Sstevel@tonic-gate }
29380Sstevel@tonic-gate
29390Sstevel@tonic-gate if ((conf->pc_prov->pc_oflags & PO_RDWR) == 0) {
29400Sstevel@tonic-gate pool_seterror(POE_BADPARAM);
29410Sstevel@tonic-gate return (PO_FAIL);
29420Sstevel@tonic-gate }
29430Sstevel@tonic-gate return (PO_SUCCESS);
29440Sstevel@tonic-gate }
2945