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 /* 231823Sgarypen * Copyright 2006 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> 340Sstevel@tonic-gate #include <synch.h> 350Sstevel@tonic-gate #include <unistd.h> 360Sstevel@tonic-gate #include <stropts.h> 370Sstevel@tonic-gate #include <fcntl.h> 380Sstevel@tonic-gate #include <note.h> 390Sstevel@tonic-gate #include <errno.h> 400Sstevel@tonic-gate #include <ctype.h> 410Sstevel@tonic-gate #include <libintl.h> 420Sstevel@tonic-gate #include <pool.h> 430Sstevel@tonic-gate #include <signal.h> 440Sstevel@tonic-gate 450Sstevel@tonic-gate #include <sys/pool.h> 460Sstevel@tonic-gate #include <sys/priocntl.h> 470Sstevel@tonic-gate #include <sys/types.h> 480Sstevel@tonic-gate #include <sys/stat.h> 490Sstevel@tonic-gate #include <sys/wait.h> 500Sstevel@tonic-gate 510Sstevel@tonic-gate #include "pool_internal.h" 520Sstevel@tonic-gate #include "pool_impl.h" 530Sstevel@tonic-gate 540Sstevel@tonic-gate /* 550Sstevel@tonic-gate * libpool Interface Routines 560Sstevel@tonic-gate * 570Sstevel@tonic-gate * pool.c implements (most of) the external interface to libpool 580Sstevel@tonic-gate * users. Some of the interface is implemented in pool_internal.c for 590Sstevel@tonic-gate * reasons of internal code organisation. The core requirements for 600Sstevel@tonic-gate * pool.c are: 610Sstevel@tonic-gate * 620Sstevel@tonic-gate * Data Abstraction 630Sstevel@tonic-gate * 640Sstevel@tonic-gate * The abstraction of the actual datastore so that no details of the 650Sstevel@tonic-gate * underlying data representation mechanism are revealed to users of 660Sstevel@tonic-gate * the library. For instance, the fact that we use the kernel or files 670Sstevel@tonic-gate * to store our configurations is completely abstracted via the 680Sstevel@tonic-gate * various libpool APIs. 690Sstevel@tonic-gate * 700Sstevel@tonic-gate * External Interaction 710Sstevel@tonic-gate * 720Sstevel@tonic-gate * libpool users manipulate configuration components via the API 730Sstevel@tonic-gate * defined in pool.h. Most functions in this file act as interceptors, 740Sstevel@tonic-gate * validating parameters before redirecting the request into a 750Sstevel@tonic-gate * specific datastore implementation for the actual work to be done. 760Sstevel@tonic-gate * 770Sstevel@tonic-gate * These main sets of requirements have driven the design so that it 780Sstevel@tonic-gate * is possible to replace the entire datastore type without having to 790Sstevel@tonic-gate * modify the external (or internal provider) APIs. It is possible to 800Sstevel@tonic-gate * modify the storage technology used by libpool by implementing a new 810Sstevel@tonic-gate * set of datastore provider operations. Simply modify the 820Sstevel@tonic-gate * pool_conf_open() routine to establish a new datastore as the 830Sstevel@tonic-gate * provider for a configuration. 840Sstevel@tonic-gate * 850Sstevel@tonic-gate * The key components in a libpool configuration are : 860Sstevel@tonic-gate * pool_conf_t - This represents a complete configuration instance 870Sstevel@tonic-gate * pool_t - A pool inside a configuration 880Sstevel@tonic-gate * pool_resource_t - A resource inside a configuration 890Sstevel@tonic-gate * pool_component_t - A component of a resource 900Sstevel@tonic-gate * 910Sstevel@tonic-gate */ 920Sstevel@tonic-gate 930Sstevel@tonic-gate /* 940Sstevel@tonic-gate * Used to control transfer setup. 950Sstevel@tonic-gate */ 960Sstevel@tonic-gate #define XFER_FAIL PO_FAIL 970Sstevel@tonic-gate #define XFER_SUCCESS PO_SUCCESS 980Sstevel@tonic-gate #define XFER_CONTINUE 1 990Sstevel@tonic-gate 1001042Sgarypen #define SMF_SVC_INSTANCE "svc:/system/pools:default" 1010Sstevel@tonic-gate #define E_ERROR 1 /* Exit status for error */ 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate #ifndef TEXT_DOMAIN 1040Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1050Sstevel@tonic-gate #endif /* TEXT_DOMAIN */ 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate const char pool_info_location[] = "/dev/pool"; 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate /* 1100Sstevel@tonic-gate * Static data 1110Sstevel@tonic-gate */ 1120Sstevel@tonic-gate static const char static_location[] = "/etc/pooladm.conf"; 1130Sstevel@tonic-gate static const char dynamic_location[] = "/dev/poolctl"; 1140Sstevel@tonic-gate static mutex_t keylock; 1150Sstevel@tonic-gate static thread_key_t errkey; 1160Sstevel@tonic-gate static int keyonce = 0; 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 * 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 * 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 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 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 * 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 * 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 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 * 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 * 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 * 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 * 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 * 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 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 } 6130Sstevel@tonic-gate if (keyonce == 0) { 6140Sstevel@tonic-gate (void) mutex_lock(&keylock); 6150Sstevel@tonic-gate if (keyonce == 0) { 6160Sstevel@tonic-gate (void) thr_keycreate(&errkey, 0); 6170Sstevel@tonic-gate keyonce++; 6180Sstevel@tonic-gate } 6190Sstevel@tonic-gate (void) mutex_unlock(&keylock); 6200Sstevel@tonic-gate } 6210Sstevel@tonic-gate (void) thr_setspecific(errkey, (void *)(intptr_t)errval); 6220Sstevel@tonic-gate } 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate /* 6250Sstevel@tonic-gate * Return the current value of the error code. 6260Sstevel@tonic-gate * Returns: int error code 6270Sstevel@tonic-gate */ 6280Sstevel@tonic-gate int 6290Sstevel@tonic-gate pool_error(void) 6300Sstevel@tonic-gate { 6310Sstevel@tonic-gate void *errval; 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate if (thr_main()) 6340Sstevel@tonic-gate return (pool_errval); 6350Sstevel@tonic-gate if (keyonce == 0) 6360Sstevel@tonic-gate return (POE_OK); 6370Sstevel@tonic-gate (void) thr_getspecific(errkey, &errval); 6380Sstevel@tonic-gate return ((intptr_t)errval); 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate /* 6420Sstevel@tonic-gate * Return the text represenation for the current value of the error code. 6430Sstevel@tonic-gate * Returns: const char * error string 6440Sstevel@tonic-gate */ 6450Sstevel@tonic-gate const char * 6460Sstevel@tonic-gate pool_strerror(int error) 6470Sstevel@tonic-gate { 6480Sstevel@tonic-gate char *str; 6490Sstevel@tonic-gate 6500Sstevel@tonic-gate switch (error) { 6510Sstevel@tonic-gate case POE_OK: 6520Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Operation successful"); 6530Sstevel@tonic-gate break; 6540Sstevel@tonic-gate case POE_BAD_PROP_TYPE: 6550Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, 6560Sstevel@tonic-gate "Attempted to retrieve the wrong property type"); 6570Sstevel@tonic-gate break; 6580Sstevel@tonic-gate case POE_INVALID_CONF: 6590Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Invalid configuration"); 6600Sstevel@tonic-gate break; 6610Sstevel@tonic-gate case POE_NOTSUP: 6620Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Operation is not supported"); 6630Sstevel@tonic-gate break; 6640Sstevel@tonic-gate case POE_INVALID_SEARCH: 6650Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Invalid search"); 6660Sstevel@tonic-gate break; 6670Sstevel@tonic-gate case POE_BADPARAM: 6680Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Bad parameter supplied"); 6690Sstevel@tonic-gate break; 6700Sstevel@tonic-gate case POE_PUTPROP: 6710Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Error putting property"); 6720Sstevel@tonic-gate break; 6730Sstevel@tonic-gate case POE_DATASTORE: 6740Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Pools repository error"); 6750Sstevel@tonic-gate break; 6760Sstevel@tonic-gate case POE_SYSTEM: 6770Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "System error"); 6780Sstevel@tonic-gate break; 6790Sstevel@tonic-gate case POE_ACCESS: 6800Sstevel@tonic-gate str = dgettext(TEXT_DOMAIN, "Permission denied"); 6810Sstevel@tonic-gate break; 6820Sstevel@tonic-gate default: 6830Sstevel@tonic-gate errno = ESRCH; 6840Sstevel@tonic-gate str = NULL; 6850Sstevel@tonic-gate } 6860Sstevel@tonic-gate return (str); 6870Sstevel@tonic-gate } 6880Sstevel@tonic-gate 6890Sstevel@tonic-gate int 6900Sstevel@tonic-gate pool_get_status(int *state) 6910Sstevel@tonic-gate { 6920Sstevel@tonic-gate int fd; 6930Sstevel@tonic-gate pool_status_t status; 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate if ((fd = open(pool_info_location, O_RDONLY)) < 0) { 6960Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 6970Sstevel@tonic-gate return (PO_FAIL); 6980Sstevel@tonic-gate } 6990Sstevel@tonic-gate if (ioctl(fd, POOL_STATUSQ, &status) < 0) { 7000Sstevel@tonic-gate (void) close(fd); 7010Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7020Sstevel@tonic-gate return (PO_FAIL); 7030Sstevel@tonic-gate } 7040Sstevel@tonic-gate (void) close(fd); 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate *state = status.ps_io_state; 7070Sstevel@tonic-gate 7080Sstevel@tonic-gate return (PO_SUCCESS); 7090Sstevel@tonic-gate } 7100Sstevel@tonic-gate 7110Sstevel@tonic-gate int 7120Sstevel@tonic-gate pool_set_status(int state) 7130Sstevel@tonic-gate { 7140Sstevel@tonic-gate int old_state; 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate if (pool_get_status(&old_state) != PO_SUCCESS) { 7170Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7180Sstevel@tonic-gate return (PO_FAIL); 7190Sstevel@tonic-gate } 7200Sstevel@tonic-gate 7210Sstevel@tonic-gate if (old_state != state) { 7220Sstevel@tonic-gate int fd; 7230Sstevel@tonic-gate pool_status_t status; 7240Sstevel@tonic-gate 7251042Sgarypen /* 7261042Sgarypen * Changing the status of pools is performed by enabling 7271042Sgarypen * or disabling the pools service instance. If this 7281042Sgarypen * function has not been invoked by startd then we simply 7291042Sgarypen * enable/disable the service and return success. 7301042Sgarypen * 7311042Sgarypen * There is no way to specify that state changes must be 7321042Sgarypen * synchronous using the library API as yet, so we use 7331042Sgarypen * the -s option provided by svcadm. 7341042Sgarypen */ 7351042Sgarypen if (getenv("SMF_FMRI") == NULL) { 7361042Sgarypen FILE *p; 7372706Sgarypen char *cmd; 7382706Sgarypen 7391042Sgarypen if (state) { 7402706Sgarypen cmd = "/usr/sbin/svcadm enable -s " \ 7411042Sgarypen SMF_SVC_INSTANCE; 7421042Sgarypen } else { 7432706Sgarypen cmd = "/usr/sbin/svcadm disable -s " \ 7441042Sgarypen SMF_SVC_INSTANCE; 7452706Sgarypen } 7462706Sgarypen if ((p = popen(cmd, "wF")) == NULL || pclose(p) != 0) { 7472706Sgarypen pool_seterror(POE_SYSTEM); 7482706Sgarypen return (PO_FAIL); 7490Sstevel@tonic-gate } 7501042Sgarypen return (PO_SUCCESS); 7510Sstevel@tonic-gate } 7520Sstevel@tonic-gate 7530Sstevel@tonic-gate if ((fd = open(pool_dynamic_location(), O_RDWR | O_EXCL)) < 0) { 7540Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7550Sstevel@tonic-gate return (PO_FAIL); 7560Sstevel@tonic-gate } 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate status.ps_io_state = state; 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate if (ioctl(fd, POOL_STATUS, &status) < 0) { 7610Sstevel@tonic-gate (void) close(fd); 7620Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7630Sstevel@tonic-gate return (PO_FAIL); 7640Sstevel@tonic-gate } 7650Sstevel@tonic-gate 7660Sstevel@tonic-gate (void) close(fd); 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate } 7690Sstevel@tonic-gate return (PO_SUCCESS); 7700Sstevel@tonic-gate } 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate /* 7730Sstevel@tonic-gate * General Data Provider Independent Access Methods 7740Sstevel@tonic-gate */ 7750Sstevel@tonic-gate 7760Sstevel@tonic-gate /* 7770Sstevel@tonic-gate * Property manipulation code. 7780Sstevel@tonic-gate * 7790Sstevel@tonic-gate * The pool_(get|rm|set)_property() functions consult the plugins before 7800Sstevel@tonic-gate * looking at the actual configuration. This allows plugins to provide 7810Sstevel@tonic-gate * "virtual" properties that may not exist in the configuration file per se, 7820Sstevel@tonic-gate * but behave like regular properties. This also allows plugins to reserve 7830Sstevel@tonic-gate * certain properties as read-only, non-removable, etc. 7840Sstevel@tonic-gate * 7850Sstevel@tonic-gate * A negative value returned from the plugin denotes error, 0 means that the 7860Sstevel@tonic-gate * property request should be forwarded to the backend, and 1 means the request 7870Sstevel@tonic-gate * was satisfied by the plugin and should not be processed further. 7880Sstevel@tonic-gate * 7890Sstevel@tonic-gate * The (get|rm|set)_property() functions bypass the plugin layer completely, 7900Sstevel@tonic-gate * and hence should not be generally used. 7910Sstevel@tonic-gate */ 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate /* 7940Sstevel@tonic-gate * Return true if the string passed in matches the pattern 7950Sstevel@tonic-gate * [A-Za-z][A-Za-z0-9,._-]* 7960Sstevel@tonic-gate */ 7970Sstevel@tonic-gate int 7980Sstevel@tonic-gate is_valid_name(const char *name) 7990Sstevel@tonic-gate { 8000Sstevel@tonic-gate int i; 8010Sstevel@tonic-gate char c; 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate if (name == NULL) 8040Sstevel@tonic-gate return (PO_FALSE); 8050Sstevel@tonic-gate if (!isalpha(name[0])) 8060Sstevel@tonic-gate return (PO_FALSE); 8070Sstevel@tonic-gate for (i = 1; (c = name[i]) != '\0'; i++) { 8080Sstevel@tonic-gate if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-') 8090Sstevel@tonic-gate return (PO_FALSE); 8100Sstevel@tonic-gate } 8110Sstevel@tonic-gate return (PO_TRUE); 8120Sstevel@tonic-gate } 8130Sstevel@tonic-gate 8140Sstevel@tonic-gate /* 8150Sstevel@tonic-gate * Return true if the string passed in matches the pattern 8160Sstevel@tonic-gate * [A-Za-z_][A-Za-z0-9,._-]* 8170Sstevel@tonic-gate * A property name starting with a '_' is an "invisible" property that does not 8180Sstevel@tonic-gate * show up in a property walk. 8190Sstevel@tonic-gate */ 8200Sstevel@tonic-gate int 8210Sstevel@tonic-gate is_valid_prop_name(const char *prop_name) 8220Sstevel@tonic-gate { 8230Sstevel@tonic-gate int i; 8240Sstevel@tonic-gate char c; 8250Sstevel@tonic-gate 8260Sstevel@tonic-gate if (prop_name == NULL) 8270Sstevel@tonic-gate return (PO_FALSE); 8280Sstevel@tonic-gate if (!isalpha(prop_name[0]) && prop_name[0] != '_') 8290Sstevel@tonic-gate return (PO_FALSE); 8300Sstevel@tonic-gate for (i = 1; (c = prop_name[i]) != '\0'; i++) { 8310Sstevel@tonic-gate if (!isalnum(c) && c != ',' && c != '.' && c != '_' && c != '-') 8320Sstevel@tonic-gate return (PO_FALSE); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate return (PO_TRUE); 8350Sstevel@tonic-gate } 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate /* 8380Sstevel@tonic-gate * Return the specified property value. 8390Sstevel@tonic-gate * 8400Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated 8410Sstevel@tonic-gate * to indicate the cause of the error. 8420Sstevel@tonic-gate */ 8430Sstevel@tonic-gate pool_value_class_t 8440Sstevel@tonic-gate pool_get_property(const pool_conf_t *conf, const pool_elem_t *pe, 8450Sstevel@tonic-gate const char *name, pool_value_t *val) 8460Sstevel@tonic-gate { 8470Sstevel@tonic-gate const pool_prop_t *prop_info; 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 8500Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 8510Sstevel@tonic-gate return (POC_INVAL); 8520Sstevel@tonic-gate } 8530Sstevel@tonic-gate if (pool_value_set_name(val, name) != PO_SUCCESS) { 8540Sstevel@tonic-gate return (POC_INVAL); 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate /* 8570Sstevel@tonic-gate * Check to see if this is a property we are managing. If it 8580Sstevel@tonic-gate * is and it has an interceptor installed for property 8590Sstevel@tonic-gate * retrieval, use it. 8600Sstevel@tonic-gate */ 8610Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL && 8620Sstevel@tonic-gate prop_info->pp_op.ppo_get_value != NULL) { 8630Sstevel@tonic-gate if (prop_info->pp_op.ppo_get_value(pe, val) == PO_FAIL) 8640Sstevel@tonic-gate return (POC_INVAL); 8650Sstevel@tonic-gate else 8660Sstevel@tonic-gate return (pool_value_get_type(val)); 8670Sstevel@tonic-gate } 8680Sstevel@tonic-gate return (pe->pe_get_prop(pe, name, val)); 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate /* 8720Sstevel@tonic-gate * Return the specified property value with the namespace prepended. 8730Sstevel@tonic-gate * e.g. If this function is used to get the property "name" on a pool, it will 8740Sstevel@tonic-gate * attempt to retrieve "pool.name". 8750Sstevel@tonic-gate * 8760Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated 8770Sstevel@tonic-gate * to indicate the cause of the error. 8780Sstevel@tonic-gate */ 8790Sstevel@tonic-gate pool_value_class_t 8800Sstevel@tonic-gate pool_get_ns_property(const pool_elem_t *pe, const char *name, pool_value_t *val) 8810Sstevel@tonic-gate { 8820Sstevel@tonic-gate int ret; 8830Sstevel@tonic-gate char_buf_t *cb; 8840Sstevel@tonic-gate 8850Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) 8860Sstevel@tonic-gate return (POC_INVAL); 8870Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) == 8880Sstevel@tonic-gate PO_FAIL) { 8890Sstevel@tonic-gate free_char_buf(cb); 8900Sstevel@tonic-gate return (POC_INVAL); 8910Sstevel@tonic-gate } 8920Sstevel@tonic-gate ret = pool_get_property(TO_CONF(pe), pe, cb->cb_buf, val); 8930Sstevel@tonic-gate free_char_buf(cb); 8940Sstevel@tonic-gate return (ret); 8950Sstevel@tonic-gate } 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate /* 8980Sstevel@tonic-gate * Update the specified property value. 8990Sstevel@tonic-gate * 9000Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated 9010Sstevel@tonic-gate * to indicate the cause of the error. 9020Sstevel@tonic-gate */ 9030Sstevel@tonic-gate int 9040Sstevel@tonic-gate pool_put_property(pool_conf_t *conf, pool_elem_t *pe, const char *name, 9050Sstevel@tonic-gate const pool_value_t *val) 9060Sstevel@tonic-gate { 9070Sstevel@tonic-gate const pool_prop_t *prop_info; 9080Sstevel@tonic-gate 9090Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 9100Sstevel@tonic-gate return (PO_FAIL); 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate if (TO_CONF(pe) != conf) { 9130Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 9140Sstevel@tonic-gate return (NULL); 9150Sstevel@tonic-gate } 9160Sstevel@tonic-gate 917*3247Sgjelinek /* Don't allow (re)setting of the "temporary" property */ 918*3247Sgjelinek if (!is_valid_prop_name(name) || strstr(name, ".temporary") != NULL) { 9190Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 9200Sstevel@tonic-gate return (PO_FAIL); 9210Sstevel@tonic-gate } 922*3247Sgjelinek 923*3247Sgjelinek /* Don't allow rename of temporary pools/resources */ 924*3247Sgjelinek if (strstr(name, ".name") != NULL && elem_is_tmp(pe)) { 925*3247Sgjelinek boolean_t rename = B_TRUE; 926*3247Sgjelinek pool_value_t *pv = pool_value_alloc(); 927*3247Sgjelinek 928*3247Sgjelinek if (pe->pe_get_prop(pe, name, pv) != POC_INVAL) { 929*3247Sgjelinek const char *s1 = NULL; 930*3247Sgjelinek const char *s2 = NULL; 931*3247Sgjelinek 932*3247Sgjelinek (void) pool_value_get_string(pv, &s1); 933*3247Sgjelinek (void) pool_value_get_string(val, &s2); 934*3247Sgjelinek if (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0) 935*3247Sgjelinek rename = B_FALSE; 936*3247Sgjelinek } 937*3247Sgjelinek pool_value_free(pv); 938*3247Sgjelinek 939*3247Sgjelinek if (rename) { 940*3247Sgjelinek pool_seterror(POE_BADPARAM); 941*3247Sgjelinek return (PO_FAIL); 942*3247Sgjelinek } 943*3247Sgjelinek } 944*3247Sgjelinek 9450Sstevel@tonic-gate /* 9460Sstevel@tonic-gate * Check to see if this is a property we are managing. If it is, 9470Sstevel@tonic-gate * ensure that we are happy with what the user is doing. 9480Sstevel@tonic-gate */ 9490Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL) { 9500Sstevel@tonic-gate if (prop_is_readonly(prop_info) == PO_TRUE) { 9510Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 9520Sstevel@tonic-gate return (PO_FAIL); 9530Sstevel@tonic-gate } 9540Sstevel@tonic-gate if (prop_info->pp_op.ppo_set_value && 9550Sstevel@tonic-gate prop_info->pp_op.ppo_set_value(pe, val) == PO_FAIL) 9560Sstevel@tonic-gate return (PO_FAIL); 9570Sstevel@tonic-gate } 9580Sstevel@tonic-gate 9590Sstevel@tonic-gate return (pe->pe_put_prop(pe, name, val)); 9600Sstevel@tonic-gate } 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate /* 963*3247Sgjelinek * Set temporary property to flag as a temporary element. 964*3247Sgjelinek * 965*3247Sgjelinek * PO_FAIL is returned if an error is detected and the error code is updated 966*3247Sgjelinek * to indicate the cause of the error. 967*3247Sgjelinek */ 968*3247Sgjelinek int 969*3247Sgjelinek pool_set_temporary(pool_conf_t *conf, pool_elem_t *pe) 970*3247Sgjelinek { 971*3247Sgjelinek int res; 972*3247Sgjelinek char name[128]; 973*3247Sgjelinek pool_value_t *val; 974*3247Sgjelinek 975*3247Sgjelinek if (pool_conf_check(conf) != PO_SUCCESS) 976*3247Sgjelinek return (PO_FAIL); 977*3247Sgjelinek 978*3247Sgjelinek if (TO_CONF(pe) != conf) { 979*3247Sgjelinek pool_seterror(POE_BADPARAM); 980*3247Sgjelinek return (PO_FAIL); 981*3247Sgjelinek } 982*3247Sgjelinek 983*3247Sgjelinek /* create property name based on element type */ 984*3247Sgjelinek if (snprintf(name, sizeof (name), "%s.temporary", 985*3247Sgjelinek pool_elem_class_string(pe)) > sizeof (name)) { 986*3247Sgjelinek pool_seterror(POE_SYSTEM); 987*3247Sgjelinek return (PO_FAIL); 988*3247Sgjelinek } 989*3247Sgjelinek 990*3247Sgjelinek if ((val = pool_value_alloc()) == NULL) 991*3247Sgjelinek return (PO_FAIL); 992*3247Sgjelinek 993*3247Sgjelinek pool_value_set_bool(val, (uchar_t)1); 994*3247Sgjelinek 995*3247Sgjelinek res = pe->pe_put_prop(pe, name, val); 996*3247Sgjelinek 997*3247Sgjelinek pool_value_free(val); 998*3247Sgjelinek 999*3247Sgjelinek return (res); 1000*3247Sgjelinek } 1001*3247Sgjelinek 1002*3247Sgjelinek /* 10030Sstevel@tonic-gate * Update the specified property value with the namespace prepended. 10040Sstevel@tonic-gate * e.g. If this function is used to update the property "name" on a pool, it 10050Sstevel@tonic-gate * will attempt to update "pool.name". 10060Sstevel@tonic-gate * 10070Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated 10080Sstevel@tonic-gate * to indicate the cause of the error. 10090Sstevel@tonic-gate */ 10100Sstevel@tonic-gate int 10110Sstevel@tonic-gate pool_put_ns_property(pool_elem_t *pe, const char *name, 10120Sstevel@tonic-gate const pool_value_t *val) 10130Sstevel@tonic-gate { 10140Sstevel@tonic-gate char_buf_t *cb; 10150Sstevel@tonic-gate int ret; 10160Sstevel@tonic-gate 10170Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) 10180Sstevel@tonic-gate return (PO_FAIL); 10190Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) == 10200Sstevel@tonic-gate PO_FAIL) { 10210Sstevel@tonic-gate free_char_buf(cb); 10220Sstevel@tonic-gate return (PO_FAIL); 10230Sstevel@tonic-gate } 10240Sstevel@tonic-gate ret = pool_put_property(TO_CONF(pe), pe, cb->cb_buf, val); 10250Sstevel@tonic-gate free_char_buf(cb); 10260Sstevel@tonic-gate return (ret); 10270Sstevel@tonic-gate } 10280Sstevel@tonic-gate 10290Sstevel@tonic-gate /* 10300Sstevel@tonic-gate * Update the specified property value. Do not use the property 10310Sstevel@tonic-gate * protection mechanism. This function should only be used for cases 10320Sstevel@tonic-gate * where the library must bypass the normal property protection 10330Sstevel@tonic-gate * mechanism. The only known use is to update properties in the static 10340Sstevel@tonic-gate * configuration when performing a commit. 10350Sstevel@tonic-gate * 10360Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is 10370Sstevel@tonic-gate * updated to indicate the cause of the error. 10380Sstevel@tonic-gate */ 10390Sstevel@tonic-gate int 10400Sstevel@tonic-gate pool_put_any_property(pool_elem_t *pe, const char *name, 10410Sstevel@tonic-gate const pool_value_t *val) 10420Sstevel@tonic-gate { 10430Sstevel@tonic-gate if (!is_valid_prop_name(name)) { 10440Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 10450Sstevel@tonic-gate return (PO_FAIL); 10460Sstevel@tonic-gate } 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate return (pe->pe_put_prop(pe, name, val)); 10490Sstevel@tonic-gate } 10500Sstevel@tonic-gate 10510Sstevel@tonic-gate /* 10520Sstevel@tonic-gate * Update the specified property value with the namespace prepended. 10530Sstevel@tonic-gate * e.g. If this function is used to update the property "name" on a pool, it 10540Sstevel@tonic-gate * will attempt to update "pool.name". 10550Sstevel@tonic-gate * 10560Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated 10570Sstevel@tonic-gate * to indicate the cause of the error. 10580Sstevel@tonic-gate */ 10590Sstevel@tonic-gate int 10600Sstevel@tonic-gate pool_put_any_ns_property(pool_elem_t *pe, const char *name, 10610Sstevel@tonic-gate const pool_value_t *val) 10620Sstevel@tonic-gate { 10630Sstevel@tonic-gate char_buf_t *cb; 10640Sstevel@tonic-gate int ret; 10650Sstevel@tonic-gate 10660Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) 10670Sstevel@tonic-gate return (PO_FAIL); 10680Sstevel@tonic-gate if (set_char_buf(cb, "%s.%s", pool_elem_class_string(pe), name) == 10690Sstevel@tonic-gate PO_FAIL) { 10700Sstevel@tonic-gate free_char_buf(cb); 10710Sstevel@tonic-gate return (PO_FAIL); 10720Sstevel@tonic-gate } 10730Sstevel@tonic-gate ret = pool_put_any_property(pe, cb->cb_buf, val); 10740Sstevel@tonic-gate free_char_buf(cb); 10750Sstevel@tonic-gate return (ret); 10760Sstevel@tonic-gate } 10770Sstevel@tonic-gate 10780Sstevel@tonic-gate /* 10790Sstevel@tonic-gate * Remove the specified property value. Note that some properties are 10800Sstevel@tonic-gate * mandatory and thus failure to remove these properties is inevitable. 10810Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated 10820Sstevel@tonic-gate * to indicate the cause of the error. 10830Sstevel@tonic-gate */ 10840Sstevel@tonic-gate int 10850Sstevel@tonic-gate pool_rm_property(pool_conf_t *conf, pool_elem_t *pe, const char *name) 10860Sstevel@tonic-gate { 10870Sstevel@tonic-gate const pool_prop_t *prop_info; 10880Sstevel@tonic-gate 10890Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 10900Sstevel@tonic-gate return (PO_FAIL); 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate if (TO_CONF(pe) != conf) { 10930Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 10940Sstevel@tonic-gate return (NULL); 10950Sstevel@tonic-gate } 10960Sstevel@tonic-gate 1097*3247Sgjelinek /* Don't allow removal of the "temporary" property */ 1098*3247Sgjelinek if (strstr(name, ".temporary") != NULL) { 1099*3247Sgjelinek pool_seterror(POE_BADPARAM); 1100*3247Sgjelinek return (PO_FAIL); 1101*3247Sgjelinek } 1102*3247Sgjelinek 11030Sstevel@tonic-gate /* 11040Sstevel@tonic-gate * Check to see if this is a property we are managing. If it is, 11050Sstevel@tonic-gate * ensure that we are happy with what the user is doing. 11060Sstevel@tonic-gate */ 11070Sstevel@tonic-gate if ((prop_info = provider_get_prop(pe, name)) != NULL) { 11080Sstevel@tonic-gate if (prop_is_optional(prop_info) == PO_FALSE) { 11090Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 11100Sstevel@tonic-gate return (PO_FAIL); 11110Sstevel@tonic-gate } 11120Sstevel@tonic-gate } 11130Sstevel@tonic-gate return (pe->pe_rm_prop(pe, name)); 11140Sstevel@tonic-gate } 11150Sstevel@tonic-gate 11160Sstevel@tonic-gate /* 11170Sstevel@tonic-gate * Check if the supplied name is a namespace protected property for the supplied 11180Sstevel@tonic-gate * element, pe. If it is, return the prefix, otherwise just return NULL. 11190Sstevel@tonic-gate */ 11200Sstevel@tonic-gate const char * 11210Sstevel@tonic-gate is_ns_property(const pool_elem_t *pe, const char *name) 11220Sstevel@tonic-gate { 11230Sstevel@tonic-gate const char *prefix; 11240Sstevel@tonic-gate 11250Sstevel@tonic-gate if ((prefix = pool_elem_class_string(pe)) != NULL) { 11260Sstevel@tonic-gate if (strncmp(name, prefix, strlen(prefix)) == 0) 11270Sstevel@tonic-gate return (prefix); 11280Sstevel@tonic-gate } 11290Sstevel@tonic-gate return (NULL); 11300Sstevel@tonic-gate } 11310Sstevel@tonic-gate 11320Sstevel@tonic-gate /* 11330Sstevel@tonic-gate * Check if the supplied name is a namespace protected property for the supplied 11340Sstevel@tonic-gate * element, pe. If it is, return the property name with the namespace stripped, 11350Sstevel@tonic-gate * otherwise just return the name. 11360Sstevel@tonic-gate */ 11370Sstevel@tonic-gate const char * 11380Sstevel@tonic-gate property_name_minus_ns(const pool_elem_t *pe, const char *name) 11390Sstevel@tonic-gate { 11400Sstevel@tonic-gate const char *prefix; 11410Sstevel@tonic-gate if ((prefix = is_ns_property(pe, name)) != NULL) { 11420Sstevel@tonic-gate return (name + strlen(prefix) + 1); 11430Sstevel@tonic-gate } 11440Sstevel@tonic-gate return (name); 11450Sstevel@tonic-gate } 11460Sstevel@tonic-gate 11470Sstevel@tonic-gate /* 11480Sstevel@tonic-gate * Create an element to represent a pool and add it to the supplied 11490Sstevel@tonic-gate * configuration. 11500Sstevel@tonic-gate */ 11510Sstevel@tonic-gate pool_t * 11520Sstevel@tonic-gate pool_create(pool_conf_t *conf, const char *name) 11530Sstevel@tonic-gate { 11540Sstevel@tonic-gate pool_elem_t *pe; 11550Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 11560Sstevel@tonic-gate const pool_prop_t *default_props; 11570Sstevel@tonic-gate 11580Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 11590Sstevel@tonic-gate return (NULL); 11600Sstevel@tonic-gate 11610Sstevel@tonic-gate if (!is_valid_name(name) || pool_get_pool(conf, name) != NULL) { 11620Sstevel@tonic-gate /* 11630Sstevel@tonic-gate * A pool with the same name exists. Reject. 11640Sstevel@tonic-gate */ 11650Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 11660Sstevel@tonic-gate return (NULL); 11670Sstevel@tonic-gate } 11680Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_POOL, PREC_INVALID, 11690Sstevel@tonic-gate PCEC_INVALID)) == NULL) { 11700Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 11710Sstevel@tonic-gate return (NULL); 11720Sstevel@tonic-gate } 11730Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) { 11740Sstevel@tonic-gate int i; 11750Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) { 11760Sstevel@tonic-gate if (prop_is_init(&default_props[i]) && 11770Sstevel@tonic-gate (pool_put_any_property(pe, 11780Sstevel@tonic-gate default_props[i].pp_pname, 11790Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL)) { 11800Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe)); 11810Sstevel@tonic-gate return (NULL); 11820Sstevel@tonic-gate } 11830Sstevel@tonic-gate } 11840Sstevel@tonic-gate } 11850Sstevel@tonic-gate if (pool_value_set_string(&val, name) != PO_SUCCESS) { 11860Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe)); 11870Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 11880Sstevel@tonic-gate return (NULL); 11890Sstevel@tonic-gate } 11900Sstevel@tonic-gate if (pool_put_property(conf, pe, "pool.name", &val) == PO_FAIL) { 11910Sstevel@tonic-gate (void) pool_destroy(conf, pool_elem_pool(pe)); 11920Sstevel@tonic-gate pool_seterror(POE_PUTPROP); 11930Sstevel@tonic-gate return (NULL); 11940Sstevel@tonic-gate } 1195*3247Sgjelinek 1196*3247Sgjelinek /* 1197*3247Sgjelinek * If we are creating a temporary pool configuration, flag the pool. 1198*3247Sgjelinek */ 1199*3247Sgjelinek if (conf->pc_prov->pc_oflags & PO_TEMP) { 1200*3247Sgjelinek if (pool_set_temporary(conf, pe) == PO_FAIL) { 1201*3247Sgjelinek (void) pool_destroy(conf, pool_elem_pool(pe)); 1202*3247Sgjelinek return (NULL); 1203*3247Sgjelinek } 1204*3247Sgjelinek } 1205*3247Sgjelinek 12060Sstevel@tonic-gate return (pool_elem_pool(pe)); 12070Sstevel@tonic-gate } 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate /* 12100Sstevel@tonic-gate * Create an element to represent a res. 12110Sstevel@tonic-gate */ 12120Sstevel@tonic-gate pool_resource_t * 12130Sstevel@tonic-gate pool_resource_create(pool_conf_t *conf, const char *sz_type, const char *name) 12140Sstevel@tonic-gate { 12150Sstevel@tonic-gate pool_elem_t *pe; 12160Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 12170Sstevel@tonic-gate const pool_prop_t *default_props; 12180Sstevel@tonic-gate pool_resource_t **resources; 12190Sstevel@tonic-gate int is_default = 0; 12200Sstevel@tonic-gate uint_t nelem; 12210Sstevel@tonic-gate pool_elem_class_t elem_class; 12220Sstevel@tonic-gate pool_resource_elem_class_t type; 12230Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL }; 12240Sstevel@tonic-gate 12250Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 12260Sstevel@tonic-gate return (NULL); 12270Sstevel@tonic-gate 12280Sstevel@tonic-gate if ((type = pool_resource_elem_class_from_string(sz_type)) == 12290Sstevel@tonic-gate PREC_INVALID) { 12300Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 12310Sstevel@tonic-gate return (NULL); 12320Sstevel@tonic-gate } 12330Sstevel@tonic-gate 12340Sstevel@tonic-gate if (strcmp(sz_type, "pset") != 0) { 12350Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 12360Sstevel@tonic-gate return (NULL); 12370Sstevel@tonic-gate } 12380Sstevel@tonic-gate 12390Sstevel@tonic-gate if (!is_valid_name(name) || pool_get_resource(conf, sz_type, name) != 12400Sstevel@tonic-gate NULL) { 12410Sstevel@tonic-gate /* 12420Sstevel@tonic-gate * Resources must be unique by name+type. 12430Sstevel@tonic-gate */ 12440Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 12450Sstevel@tonic-gate return (NULL); 12460Sstevel@tonic-gate } 12470Sstevel@tonic-gate 12480Sstevel@tonic-gate props[0] = &val; 12490Sstevel@tonic-gate 12500Sstevel@tonic-gate if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS || 12510Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS) { 12520Sstevel@tonic-gate return (NULL); 12530Sstevel@tonic-gate } 12540Sstevel@tonic-gate 12550Sstevel@tonic-gate if ((resources = pool_query_resources(conf, &nelem, props)) == NULL) { 12560Sstevel@tonic-gate /* 12570Sstevel@tonic-gate * This is the first representative of this type; when it's 12580Sstevel@tonic-gate * created it should be created with 'default' = 'true'. 12590Sstevel@tonic-gate */ 12600Sstevel@tonic-gate is_default = 1; 12610Sstevel@tonic-gate } else { 12620Sstevel@tonic-gate free(resources); 12630Sstevel@tonic-gate } 12640Sstevel@tonic-gate /* 12650Sstevel@tonic-gate * TODO: If Additional PEC_RES_COMP types are added to 12660Sstevel@tonic-gate * pool_impl.h, this would need to be extended. 12670Sstevel@tonic-gate */ 12680Sstevel@tonic-gate switch (type) { 12690Sstevel@tonic-gate case PREC_PSET: 12700Sstevel@tonic-gate elem_class = PEC_RES_COMP; 12710Sstevel@tonic-gate break; 12720Sstevel@tonic-gate default: 12730Sstevel@tonic-gate elem_class = PEC_RES_AGG; 12740Sstevel@tonic-gate break; 12750Sstevel@tonic-gate } 12760Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, elem_class, type, 12770Sstevel@tonic-gate PCEC_INVALID)) == NULL) { 12780Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 12790Sstevel@tonic-gate return (NULL); 12800Sstevel@tonic-gate } 12810Sstevel@tonic-gate 12820Sstevel@tonic-gate /* 12830Sstevel@tonic-gate * The plugins contain a list of default properties and their values 12840Sstevel@tonic-gate * for resources. The resource returned, hence, is fully initialized. 12850Sstevel@tonic-gate */ 12860Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) { 12870Sstevel@tonic-gate int i; 12880Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) { 12890Sstevel@tonic-gate if (prop_is_init(&default_props[i]) && 12900Sstevel@tonic-gate pool_put_any_property(pe, default_props[i].pp_pname, 12910Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL) { 12920Sstevel@tonic-gate (void) pool_resource_destroy(conf, 12930Sstevel@tonic-gate pool_elem_res(pe)); 12940Sstevel@tonic-gate return (NULL); 12950Sstevel@tonic-gate } 12960Sstevel@tonic-gate } 12970Sstevel@tonic-gate } 12980Sstevel@tonic-gate if (pool_value_set_string(&val, name) != PO_SUCCESS || 12990Sstevel@tonic-gate pool_put_ns_property(pe, "name", &val) != PO_SUCCESS) { 13000Sstevel@tonic-gate (void) pool_resource_destroy(conf, pool_elem_res(pe)); 13010Sstevel@tonic-gate return (NULL); 13020Sstevel@tonic-gate } 13030Sstevel@tonic-gate if (is_default) { 13040Sstevel@tonic-gate pool_value_set_bool(&val, PO_TRUE); 13050Sstevel@tonic-gate if (pool_put_any_ns_property(pe, "default", &val) != 13060Sstevel@tonic-gate PO_SUCCESS) { 13070Sstevel@tonic-gate (void) pool_resource_destroy(conf, pool_elem_res(pe)); 13080Sstevel@tonic-gate return (NULL); 13090Sstevel@tonic-gate } 13100Sstevel@tonic-gate } 1311*3247Sgjelinek 1312*3247Sgjelinek /* 1313*3247Sgjelinek * If we are creating a temporary pool configuration, flag the resource. 1314*3247Sgjelinek */ 1315*3247Sgjelinek if (conf->pc_prov->pc_oflags & PO_TEMP) { 1316*3247Sgjelinek if (pool_set_temporary(conf, pe) != PO_SUCCESS) { 1317*3247Sgjelinek (void) pool_resource_destroy(conf, pool_elem_res(pe)); 1318*3247Sgjelinek return (NULL); 1319*3247Sgjelinek } 1320*3247Sgjelinek } 1321*3247Sgjelinek 13220Sstevel@tonic-gate return (pool_elem_res(pe)); 13230Sstevel@tonic-gate } 13240Sstevel@tonic-gate 13250Sstevel@tonic-gate /* 13260Sstevel@tonic-gate * Create an element to represent a resource component. 13270Sstevel@tonic-gate */ 13280Sstevel@tonic-gate pool_component_t * 13290Sstevel@tonic-gate pool_component_create(pool_conf_t *conf, const pool_resource_t *res, 13300Sstevel@tonic-gate int64_t sys_id) 13310Sstevel@tonic-gate { 13320Sstevel@tonic-gate pool_elem_t *pe; 13330Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 13340Sstevel@tonic-gate const pool_prop_t *default_props; 13350Sstevel@tonic-gate char refbuf[KEY_BUFFER_SIZE]; 13360Sstevel@tonic-gate 13370Sstevel@tonic-gate if ((pe = conf->pc_prov->pc_elem_create(conf, PEC_COMP, 13380Sstevel@tonic-gate PREC_INVALID, PCEC_CPU)) == NULL) { 13390Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 13400Sstevel@tonic-gate return (NULL); 13410Sstevel@tonic-gate } 13420Sstevel@tonic-gate /* 13430Sstevel@tonic-gate * TODO: If additional PEC_COMP types are added in pool_impl.h, 13440Sstevel@tonic-gate * this would need to be extended. 13450Sstevel@tonic-gate */ 13460Sstevel@tonic-gate pe->pe_component_class = PCEC_CPU; 13470Sstevel@tonic-gate /* Now set the container for this comp */ 13480Sstevel@tonic-gate if (pool_set_container(TO_ELEM(res), pe) == PO_FAIL) { 13490Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe)); 13500Sstevel@tonic-gate return (NULL); 13510Sstevel@tonic-gate } 13520Sstevel@tonic-gate /* 13530Sstevel@tonic-gate * The plugins contain a list of default properties and their values 13540Sstevel@tonic-gate * for resources. The resource returned, hence, is fully initialized. 13550Sstevel@tonic-gate */ 13560Sstevel@tonic-gate if ((default_props = provider_get_props(pe)) != NULL) { 13570Sstevel@tonic-gate int i; 13580Sstevel@tonic-gate for (i = 0; default_props[i].pp_pname != NULL; i++) { 13590Sstevel@tonic-gate if (prop_is_init(&default_props[i]) && 13600Sstevel@tonic-gate pool_put_any_property(pe, 13610Sstevel@tonic-gate default_props[i].pp_pname, 13620Sstevel@tonic-gate &default_props[i].pp_value) == PO_FAIL) { 13630Sstevel@tonic-gate (void) pool_component_destroy( 13640Sstevel@tonic-gate pool_elem_comp(pe)); 13650Sstevel@tonic-gate return (NULL); 13660Sstevel@tonic-gate } 13670Sstevel@tonic-gate } 13680Sstevel@tonic-gate } 13690Sstevel@tonic-gate /* 13700Sstevel@tonic-gate * Set additional attributes/properties on component. 13710Sstevel@tonic-gate */ 13720Sstevel@tonic-gate pool_value_set_int64(&val, sys_id); 13730Sstevel@tonic-gate if (pool_put_any_ns_property(pe, c_sys_prop, &val) != PO_SUCCESS) { 13740Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe)); 13750Sstevel@tonic-gate return (NULL); 13760Sstevel@tonic-gate } 13770Sstevel@tonic-gate if (snprintf(refbuf, KEY_BUFFER_SIZE, "%s_%lld", 13780Sstevel@tonic-gate pool_elem_class_string(pe), sys_id) > KEY_BUFFER_SIZE) { 13790Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe)); 13800Sstevel@tonic-gate return (NULL); 13810Sstevel@tonic-gate } 13820Sstevel@tonic-gate if (pool_value_set_string(&val, refbuf) != PO_SUCCESS) { 13830Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe)); 13840Sstevel@tonic-gate return (NULL); 13850Sstevel@tonic-gate } 13860Sstevel@tonic-gate if (pool_put_any_ns_property(pe, c_ref_id, &val) != PO_SUCCESS) { 13870Sstevel@tonic-gate (void) pool_component_destroy(pool_elem_comp(pe)); 13880Sstevel@tonic-gate return (NULL); 13890Sstevel@tonic-gate } 13900Sstevel@tonic-gate return (pool_elem_comp(pe)); 13910Sstevel@tonic-gate } 13920Sstevel@tonic-gate 13930Sstevel@tonic-gate /* 13940Sstevel@tonic-gate * Return the location of a configuration. 13950Sstevel@tonic-gate */ 13960Sstevel@tonic-gate const char * 13970Sstevel@tonic-gate pool_conf_location(const pool_conf_t *conf) 13980Sstevel@tonic-gate { 13990Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 14000Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14010Sstevel@tonic-gate return (NULL); 14020Sstevel@tonic-gate } 14030Sstevel@tonic-gate return (conf->pc_location); 14040Sstevel@tonic-gate } 14050Sstevel@tonic-gate /* 14060Sstevel@tonic-gate * Close a configuration, freeing all associated resources. Once a 14070Sstevel@tonic-gate * configuration is closed, it can no longer be used. 14080Sstevel@tonic-gate */ 14090Sstevel@tonic-gate int 14100Sstevel@tonic-gate pool_conf_close(pool_conf_t *conf) 14110Sstevel@tonic-gate { 14120Sstevel@tonic-gate int rv; 14130Sstevel@tonic-gate 14140Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 14150Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14160Sstevel@tonic-gate return (PO_FAIL); 14170Sstevel@tonic-gate } 14180Sstevel@tonic-gate rv = conf->pc_prov->pc_close(conf); 14190Sstevel@tonic-gate conf->pc_prov = NULL; 14200Sstevel@tonic-gate free((void *)conf->pc_location); 14210Sstevel@tonic-gate conf->pc_location = NULL; 14220Sstevel@tonic-gate conf->pc_state = POF_INVALID; 14230Sstevel@tonic-gate return (rv); 14240Sstevel@tonic-gate } 14250Sstevel@tonic-gate 14260Sstevel@tonic-gate /* 14270Sstevel@tonic-gate * Remove a configuration, freeing all associated resources. Once a 14280Sstevel@tonic-gate * configuration is removed, it can no longer be accessed and is forever 14290Sstevel@tonic-gate * gone. 14300Sstevel@tonic-gate */ 14310Sstevel@tonic-gate int 14320Sstevel@tonic-gate pool_conf_remove(pool_conf_t *conf) 14330Sstevel@tonic-gate { 14340Sstevel@tonic-gate int rv; 14350Sstevel@tonic-gate 14360Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 14370Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14380Sstevel@tonic-gate return (PO_FAIL); 14390Sstevel@tonic-gate } 14400Sstevel@tonic-gate rv = conf->pc_prov->pc_remove(conf); 14410Sstevel@tonic-gate conf->pc_state = POF_INVALID; 14420Sstevel@tonic-gate return (rv); 14430Sstevel@tonic-gate } 14440Sstevel@tonic-gate 14450Sstevel@tonic-gate /* 14460Sstevel@tonic-gate * pool_conf_alloc() allocate the resources to represent a configuration. 14470Sstevel@tonic-gate */ 14480Sstevel@tonic-gate pool_conf_t * 14490Sstevel@tonic-gate pool_conf_alloc(void) 14500Sstevel@tonic-gate { 14510Sstevel@tonic-gate pool_conf_t *conf; 14520Sstevel@tonic-gate 14530Sstevel@tonic-gate if ((conf = calloc(1, sizeof (pool_conf_t))) == NULL) { 14540Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 14550Sstevel@tonic-gate return (NULL); 14560Sstevel@tonic-gate } 14570Sstevel@tonic-gate conf->pc_state = POF_INVALID; 14580Sstevel@tonic-gate return (conf); 14590Sstevel@tonic-gate } 14600Sstevel@tonic-gate 14610Sstevel@tonic-gate /* 14620Sstevel@tonic-gate * pool_conf_free() frees the resources associated with a configuration. 14630Sstevel@tonic-gate */ 14640Sstevel@tonic-gate void 14650Sstevel@tonic-gate pool_conf_free(pool_conf_t *conf) 14660Sstevel@tonic-gate { 14670Sstevel@tonic-gate free(conf); 14680Sstevel@tonic-gate } 14690Sstevel@tonic-gate 14700Sstevel@tonic-gate /* 14710Sstevel@tonic-gate * pool_conf_open() opens a configuration, establishing all required 14720Sstevel@tonic-gate * connections to the data source. 14730Sstevel@tonic-gate */ 14740Sstevel@tonic-gate int 14750Sstevel@tonic-gate pool_conf_open(pool_conf_t *conf, const char *location, int oflags) 14760Sstevel@tonic-gate { 14770Sstevel@tonic-gate /* 14780Sstevel@tonic-gate * Since you can't do anything to a pool configuration without opening 14790Sstevel@tonic-gate * it, this represents a good point to intialise structures that would 14800Sstevel@tonic-gate * otherwise need to be initialised in a .init section. 14810Sstevel@tonic-gate */ 14820Sstevel@tonic-gate internal_init(); 14830Sstevel@tonic-gate 14840Sstevel@tonic-gate if (pool_conf_status(conf) != POF_INVALID) { 14850Sstevel@tonic-gate /* 14860Sstevel@tonic-gate * Already opened configuration, return PO_FAIL 14870Sstevel@tonic-gate */ 14880Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14890Sstevel@tonic-gate return (PO_FAIL); 14900Sstevel@tonic-gate } 1491*3247Sgjelinek if (oflags & ~(PO_RDONLY | PO_RDWR | PO_CREAT | PO_DISCO | PO_UPDATE | 1492*3247Sgjelinek PO_TEMP)) { 14930Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14940Sstevel@tonic-gate return (PO_FAIL); 14950Sstevel@tonic-gate } 14960Sstevel@tonic-gate 14970Sstevel@tonic-gate /* 14980Sstevel@tonic-gate * Creating a configuration implies read-write access, so make 14990Sstevel@tonic-gate * sure that PO_RDWR is set in addition if PO_CREAT is set. 15000Sstevel@tonic-gate */ 15010Sstevel@tonic-gate if (oflags & PO_CREAT) 15020Sstevel@tonic-gate oflags |= PO_RDWR; 15030Sstevel@tonic-gate 1504*3247Sgjelinek /* location is ignored when creating a temporary configuration */ 1505*3247Sgjelinek if (oflags & PO_TEMP) 1506*3247Sgjelinek location = ""; 1507*3247Sgjelinek 15080Sstevel@tonic-gate if ((conf->pc_location = strdup(location)) == NULL) { 15090Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 15100Sstevel@tonic-gate return (PO_FAIL); 15110Sstevel@tonic-gate } 15120Sstevel@tonic-gate /* 15130Sstevel@tonic-gate * This is the crossover point into the actual data provider 15140Sstevel@tonic-gate * implementation, allocate a data provider of the appropriate 1515*3247Sgjelinek * type for your data storage medium. In this case it's either a kernel 1516*3247Sgjelinek * or xml data provider. To use a different data provider, write some 1517*3247Sgjelinek * code to implement all the required interfaces and then change the 1518*3247Sgjelinek * following code to allocate a data provider which uses your new code. 1519*3247Sgjelinek * All data provider routines can be static, apart from the allocation 1520*3247Sgjelinek * routine. 1521*3247Sgjelinek * 1522*3247Sgjelinek * For temporary pools (PO_TEMP) we start with a copy of the current 1523*3247Sgjelinek * dynamic configuration and do all of the updates in-memory. 15240Sstevel@tonic-gate */ 1525*3247Sgjelinek if (oflags & PO_TEMP) { 1526*3247Sgjelinek if (pool_knl_connection_alloc(conf, PO_TEMP) != PO_SUCCESS) { 1527*3247Sgjelinek conf->pc_state = POF_INVALID; 1528*3247Sgjelinek return (PO_FAIL); 1529*3247Sgjelinek } 1530*3247Sgjelinek /* set rdwr flag so we can updated the in-memory config. */ 1531*3247Sgjelinek conf->pc_prov->pc_oflags |= PO_RDWR; 1532*3247Sgjelinek 1533*3247Sgjelinek } else if (strcmp(location, pool_dynamic_location()) == 0) { 15340Sstevel@tonic-gate if (pool_knl_connection_alloc(conf, oflags) != PO_SUCCESS) { 15350Sstevel@tonic-gate conf->pc_state = POF_INVALID; 15360Sstevel@tonic-gate return (PO_FAIL); 15370Sstevel@tonic-gate } 15380Sstevel@tonic-gate } else { 15390Sstevel@tonic-gate if (pool_xml_connection_alloc(conf, oflags) != PO_SUCCESS) { 15400Sstevel@tonic-gate conf->pc_state = POF_INVALID; 15410Sstevel@tonic-gate return (PO_FAIL); 15420Sstevel@tonic-gate } 15430Sstevel@tonic-gate } 15440Sstevel@tonic-gate return (PO_SUCCESS); 15450Sstevel@tonic-gate } 15460Sstevel@tonic-gate 15470Sstevel@tonic-gate /* 15480Sstevel@tonic-gate * Rollback a configuration. This will undo all changes to the configuration 15490Sstevel@tonic-gate * since the last time pool_conf_commit was called. 15500Sstevel@tonic-gate */ 15510Sstevel@tonic-gate int 15520Sstevel@tonic-gate pool_conf_rollback(pool_conf_t *conf) 15530Sstevel@tonic-gate { 15540Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 15550Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 15560Sstevel@tonic-gate return (PO_FAIL); 15570Sstevel@tonic-gate } 15580Sstevel@tonic-gate return (conf->pc_prov->pc_rollback(conf)); 15590Sstevel@tonic-gate } 15600Sstevel@tonic-gate 15610Sstevel@tonic-gate /* 15620Sstevel@tonic-gate * Commit a configuration. This will apply all changes to the 15630Sstevel@tonic-gate * configuration to the permanent data store. The active parameter 15640Sstevel@tonic-gate * indicates whether the configuration should be used to update the 15650Sstevel@tonic-gate * dynamic configuration from the supplied (static) configuration or 15660Sstevel@tonic-gate * whether it should be written back to persistent store. 15670Sstevel@tonic-gate */ 15680Sstevel@tonic-gate int 15690Sstevel@tonic-gate pool_conf_commit(pool_conf_t *conf, int active) 15700Sstevel@tonic-gate { 15710Sstevel@tonic-gate int retval; 15720Sstevel@tonic-gate 15730Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 15740Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 15750Sstevel@tonic-gate return (PO_FAIL); 15760Sstevel@tonic-gate } 15770Sstevel@tonic-gate if (active) { 15780Sstevel@tonic-gate int oflags; 15790Sstevel@tonic-gate 15800Sstevel@tonic-gate if (conf_is_dynamic(conf) == PO_TRUE) { 15810Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 15820Sstevel@tonic-gate return (PO_FAIL); 15830Sstevel@tonic-gate } 15840Sstevel@tonic-gate /* 15850Sstevel@tonic-gate * Pretend that the configuration was opened PO_RDWR 15860Sstevel@tonic-gate * so that a configuration which was opened PO_RDONLY 15870Sstevel@tonic-gate * can be committed. The original flags are preserved 15880Sstevel@tonic-gate * in oflags and restored after pool_conf_commit_sys() 15890Sstevel@tonic-gate * returns. 15900Sstevel@tonic-gate */ 15910Sstevel@tonic-gate oflags = conf->pc_prov->pc_oflags; 15920Sstevel@tonic-gate conf->pc_prov->pc_oflags |= PO_RDWR; 15930Sstevel@tonic-gate retval = pool_conf_commit_sys(conf, active); 15940Sstevel@tonic-gate conf->pc_prov->pc_oflags = oflags; 15950Sstevel@tonic-gate } else { 15960Sstevel@tonic-gate /* 15970Sstevel@tonic-gate * Write the configuration back to the backing store. 15980Sstevel@tonic-gate */ 15990Sstevel@tonic-gate retval = conf->pc_prov->pc_commit(conf); 16000Sstevel@tonic-gate } 16010Sstevel@tonic-gate return (retval); 16020Sstevel@tonic-gate } 16030Sstevel@tonic-gate 16040Sstevel@tonic-gate /* 16050Sstevel@tonic-gate * Export a configuration. This will export a configuration in the specified 16060Sstevel@tonic-gate * format (fmt) to the specified location. 16070Sstevel@tonic-gate */ 16080Sstevel@tonic-gate int 16090Sstevel@tonic-gate pool_conf_export(const pool_conf_t *conf, const char *location, 16100Sstevel@tonic-gate pool_export_format_t fmt) 16110Sstevel@tonic-gate { 16120Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 16130Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 16140Sstevel@tonic-gate return (PO_FAIL); 16150Sstevel@tonic-gate } 16160Sstevel@tonic-gate return (conf->pc_prov->pc_export(conf, location, fmt)); 16170Sstevel@tonic-gate } 16180Sstevel@tonic-gate 16190Sstevel@tonic-gate /* 16200Sstevel@tonic-gate * Validate a configuration. This will validate a configuration at the 16210Sstevel@tonic-gate * specified level. 16220Sstevel@tonic-gate */ 16230Sstevel@tonic-gate int 16240Sstevel@tonic-gate pool_conf_validate(const pool_conf_t *conf, pool_valid_level_t level) 16250Sstevel@tonic-gate { 16260Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 16270Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 16280Sstevel@tonic-gate return (PO_FAIL); 16290Sstevel@tonic-gate } 16300Sstevel@tonic-gate return (conf->pc_prov->pc_validate(conf, level)); 16310Sstevel@tonic-gate } 16320Sstevel@tonic-gate 16330Sstevel@tonic-gate /* 16340Sstevel@tonic-gate * Update the snapshot of a configuration. This can only be used on a 16350Sstevel@tonic-gate * dynamic configuration. 16360Sstevel@tonic-gate */ 16370Sstevel@tonic-gate int 16380Sstevel@tonic-gate pool_conf_update(const pool_conf_t *conf, int *changed) 16390Sstevel@tonic-gate { 16400Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID || 16410Sstevel@tonic-gate conf_is_dynamic(conf) == PO_FALSE) { 16420Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 16430Sstevel@tonic-gate return (PO_FAIL); 16440Sstevel@tonic-gate } 16450Sstevel@tonic-gate /* 16460Sstevel@tonic-gate * Since this function only makes sense for dynamic 16470Sstevel@tonic-gate * configurations, just call directly into the appropriate 16480Sstevel@tonic-gate * function. This could be added into the pool_connection_t 16490Sstevel@tonic-gate * interface if it was ever required. 16500Sstevel@tonic-gate */ 16510Sstevel@tonic-gate if (changed) 16520Sstevel@tonic-gate *changed = 0; 16530Sstevel@tonic-gate return (pool_knl_update((pool_conf_t *)conf, changed)); 16540Sstevel@tonic-gate } 16550Sstevel@tonic-gate 16560Sstevel@tonic-gate /* 16570Sstevel@tonic-gate * Walk the properties of the supplied elem, calling the user supplied 16580Sstevel@tonic-gate * function repeatedly as long as the user function returns 16590Sstevel@tonic-gate * PO_SUCCESS. 16600Sstevel@tonic-gate */ 16610Sstevel@tonic-gate int 16620Sstevel@tonic-gate pool_walk_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg, 16630Sstevel@tonic-gate int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *, 16640Sstevel@tonic-gate pool_value_t *, void *)) 16650Sstevel@tonic-gate { 16660Sstevel@tonic-gate return (pool_walk_any_properties(conf, elem, arg, prop_callback, 0)); 16670Sstevel@tonic-gate } 16680Sstevel@tonic-gate 16690Sstevel@tonic-gate void 16700Sstevel@tonic-gate free_value_list(int npvals, pool_value_t **pvals) 16710Sstevel@tonic-gate { 16720Sstevel@tonic-gate int j; 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate for (j = 0; j < npvals; j++) { 16750Sstevel@tonic-gate if (pvals[j]) 16760Sstevel@tonic-gate pool_value_free(pvals[j]); 16770Sstevel@tonic-gate } 16780Sstevel@tonic-gate free(pvals); 16790Sstevel@tonic-gate } 16800Sstevel@tonic-gate 16810Sstevel@tonic-gate /* 16820Sstevel@tonic-gate * Walk the properties of the supplied elem, calling the user supplied 16830Sstevel@tonic-gate * function repeatedly as long as the user function returns 16840Sstevel@tonic-gate * PO_SUCCESS. 16850Sstevel@tonic-gate * The list of properties to be walked is retrieved from the element 16860Sstevel@tonic-gate */ 16870Sstevel@tonic-gate int 16880Sstevel@tonic-gate pool_walk_any_properties(pool_conf_t *conf, pool_elem_t *elem, void *arg, 16890Sstevel@tonic-gate int (*prop_callback)(pool_conf_t *, pool_elem_t *, const char *, 16900Sstevel@tonic-gate pool_value_t *, void *), int any) 16910Sstevel@tonic-gate { 16920Sstevel@tonic-gate pool_value_t **pvals; 16930Sstevel@tonic-gate int i; 16940Sstevel@tonic-gate const pool_prop_t *props = provider_get_props(elem); 16950Sstevel@tonic-gate uint_t npvals; 16960Sstevel@tonic-gate 16970Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 16980Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 16990Sstevel@tonic-gate return (PO_FAIL); 17000Sstevel@tonic-gate } 17010Sstevel@tonic-gate 17020Sstevel@tonic-gate if (props == NULL) { 17030Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 17040Sstevel@tonic-gate return (PO_FAIL); 17050Sstevel@tonic-gate } 17060Sstevel@tonic-gate 17070Sstevel@tonic-gate if ((pvals = elem->pe_get_props(elem, &npvals)) == NULL) 17080Sstevel@tonic-gate return (PO_FAIL); 17090Sstevel@tonic-gate 17100Sstevel@tonic-gate /* 17110Sstevel@tonic-gate * Now walk the managed properties. As we find managed 17120Sstevel@tonic-gate * properties removed them from the list of all properties to 17130Sstevel@tonic-gate * prevent duplication. 17140Sstevel@tonic-gate */ 17150Sstevel@tonic-gate for (i = 0; props[i].pp_pname != NULL; i++) { 17160Sstevel@tonic-gate int j; 17170Sstevel@tonic-gate 17180Sstevel@tonic-gate /* 17190Sstevel@tonic-gate * Special processing for type 17200Sstevel@tonic-gate */ 17210Sstevel@tonic-gate if (strcmp(props[i].pp_pname, c_type) == 0) { 17220Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 17230Sstevel@tonic-gate 17240Sstevel@tonic-gate if (pool_value_set_name(&val, props[i].pp_pname) == 17250Sstevel@tonic-gate PO_FAIL) { 17260Sstevel@tonic-gate free_value_list(npvals, pvals); 17270Sstevel@tonic-gate return (PO_FAIL); 17280Sstevel@tonic-gate } 17290Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value(elem, &val) == 17300Sstevel@tonic-gate PO_FAIL) { 17310Sstevel@tonic-gate free_value_list(npvals, pvals); 17320Sstevel@tonic-gate return (PO_FAIL); 17330Sstevel@tonic-gate } 17340Sstevel@tonic-gate if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) { 17350Sstevel@tonic-gate if (prop_callback(conf, elem, props[i].pp_pname, 17360Sstevel@tonic-gate &val, arg) != PO_SUCCESS) { 17370Sstevel@tonic-gate free_value_list(npvals, pvals); 17380Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 17390Sstevel@tonic-gate return (PO_FAIL); 17400Sstevel@tonic-gate } 17410Sstevel@tonic-gate } 17420Sstevel@tonic-gate continue; 17430Sstevel@tonic-gate } 17440Sstevel@tonic-gate 17450Sstevel@tonic-gate for (j = 0; j < npvals; j++) { 17460Sstevel@tonic-gate if (pvals[j] && strcmp(pool_value_get_name(pvals[j]), 17470Sstevel@tonic-gate props[i].pp_pname) == 0) 17480Sstevel@tonic-gate break; 17490Sstevel@tonic-gate } 17500Sstevel@tonic-gate /* 17510Sstevel@tonic-gate * If we have found the property, then j < npvals. Process it 17520Sstevel@tonic-gate * according to our property attributes. Otherwise, it's not 17530Sstevel@tonic-gate * a managed property, so just ignore it until later. 17540Sstevel@tonic-gate */ 17550Sstevel@tonic-gate if (j < npvals) { 17560Sstevel@tonic-gate if (any == 1 || prop_is_hidden(&props[i]) == PO_FALSE) { 17570Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value) { 17580Sstevel@tonic-gate if (pool_value_set_name(pvals[j], 17590Sstevel@tonic-gate props[i].pp_pname) == PO_FAIL) { 17600Sstevel@tonic-gate free_value_list(npvals, pvals); 17610Sstevel@tonic-gate return (PO_FAIL); 17620Sstevel@tonic-gate } 17630Sstevel@tonic-gate if (props[i].pp_op.ppo_get_value(elem, 17640Sstevel@tonic-gate pvals[j]) == PO_FAIL) { 17650Sstevel@tonic-gate free_value_list(npvals, pvals); 17660Sstevel@tonic-gate return (PO_FAIL); 17670Sstevel@tonic-gate } 17680Sstevel@tonic-gate } 17690Sstevel@tonic-gate if (prop_callback(conf, elem, props[i].pp_pname, 17700Sstevel@tonic-gate pvals[j], arg) != PO_SUCCESS) { 17710Sstevel@tonic-gate free_value_list(npvals, pvals); 17720Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 17730Sstevel@tonic-gate return (PO_FAIL); 17740Sstevel@tonic-gate } 17750Sstevel@tonic-gate } 17760Sstevel@tonic-gate pool_value_free(pvals[j]); 17770Sstevel@tonic-gate pvals[j] = NULL; 17780Sstevel@tonic-gate } 17790Sstevel@tonic-gate } 17800Sstevel@tonic-gate for (i = 0; i < npvals; i++) { 17810Sstevel@tonic-gate if (pvals[i]) { 17820Sstevel@tonic-gate const char *name = pool_value_get_name(pvals[i]); 17830Sstevel@tonic-gate char *qname = strrchr(name, '.'); 17840Sstevel@tonic-gate if ((qname && qname[1] != '_') || 17850Sstevel@tonic-gate (!qname && name[0] != '_')) { 17860Sstevel@tonic-gate if (prop_callback(conf, elem, name, pvals[i], 17870Sstevel@tonic-gate arg) != PO_SUCCESS) { 17880Sstevel@tonic-gate free_value_list(npvals, pvals); 17890Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 17900Sstevel@tonic-gate return (PO_FAIL); 17910Sstevel@tonic-gate } 17920Sstevel@tonic-gate } 17930Sstevel@tonic-gate pool_value_free(pvals[i]); 17940Sstevel@tonic-gate pvals[i] = NULL; 17950Sstevel@tonic-gate } 17960Sstevel@tonic-gate } 17970Sstevel@tonic-gate free(pvals); 17980Sstevel@tonic-gate return (PO_SUCCESS); 17990Sstevel@tonic-gate } 18000Sstevel@tonic-gate 18010Sstevel@tonic-gate /* 18020Sstevel@tonic-gate * Return a pool, searching the supplied configuration for a pool with the 18030Sstevel@tonic-gate * supplied name. The search is case sensitive. 18040Sstevel@tonic-gate */ 18050Sstevel@tonic-gate pool_t * 18060Sstevel@tonic-gate pool_get_pool(const pool_conf_t *conf, const char *name) 18070Sstevel@tonic-gate { 18080Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL }; 18090Sstevel@tonic-gate pool_t **rs; 18100Sstevel@tonic-gate pool_t *ret; 18110Sstevel@tonic-gate uint_t size = 0; 18120Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 18130Sstevel@tonic-gate 18140Sstevel@tonic-gate props[0] = &val; 18150Sstevel@tonic-gate 18160Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 18170Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 18180Sstevel@tonic-gate return (NULL); 18190Sstevel@tonic-gate } 18200Sstevel@tonic-gate 18210Sstevel@tonic-gate if (pool_value_set_name(props[0], "pool.name") != PO_SUCCESS || 18220Sstevel@tonic-gate pool_value_set_string(props[0], name) != PO_SUCCESS) { 18230Sstevel@tonic-gate return (NULL); 18240Sstevel@tonic-gate } 18250Sstevel@tonic-gate rs = pool_query_pools(conf, &size, props); 18260Sstevel@tonic-gate if (rs == NULL) { /* Can't find a pool to match the name */ 18270Sstevel@tonic-gate return (NULL); 18280Sstevel@tonic-gate } 18290Sstevel@tonic-gate if (size != 1) { 18300Sstevel@tonic-gate free(rs); 18310Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 18320Sstevel@tonic-gate return (NULL); 18330Sstevel@tonic-gate } 18340Sstevel@tonic-gate ret = rs[0]; 18350Sstevel@tonic-gate free(rs); 18360Sstevel@tonic-gate return (ret); 18370Sstevel@tonic-gate } 18380Sstevel@tonic-gate 18390Sstevel@tonic-gate /* 18400Sstevel@tonic-gate * Return a result set of pools, searching the supplied configuration 18410Sstevel@tonic-gate * for pools which match the supplied property criteria. props is a null 18420Sstevel@tonic-gate * terminated list of properties which will be used to match qualifying 18430Sstevel@tonic-gate * pools. size is updated with the size of the pool 18440Sstevel@tonic-gate */ 18450Sstevel@tonic-gate pool_t ** 18460Sstevel@tonic-gate pool_query_pools(const pool_conf_t *conf, uint_t *size, pool_value_t **props) 18470Sstevel@tonic-gate { 18480Sstevel@tonic-gate pool_result_set_t *rs; 18490Sstevel@tonic-gate pool_elem_t *pe; 18500Sstevel@tonic-gate pool_t **result = NULL; 18510Sstevel@tonic-gate int i = 0; 18520Sstevel@tonic-gate 18530Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 18540Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 18550Sstevel@tonic-gate return (NULL); 18560Sstevel@tonic-gate } 18570Sstevel@tonic-gate rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_POOL, props); 18580Sstevel@tonic-gate if (rs == NULL) { 18590Sstevel@tonic-gate return (NULL); 18600Sstevel@tonic-gate } 18610Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) { 18620Sstevel@tonic-gate (void) pool_rs_close(rs); 18630Sstevel@tonic-gate return (NULL); 18640Sstevel@tonic-gate } 18650Sstevel@tonic-gate if ((result = malloc(sizeof (pool_t *) * (*size + 1))) == NULL) { 18660Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 18670Sstevel@tonic-gate (void) pool_rs_close(rs); 18680Sstevel@tonic-gate return (NULL); 18690Sstevel@tonic-gate } 18700Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_t *) * (*size + 1)); 18710Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) { 18720Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_POOL) { 18730Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 18740Sstevel@tonic-gate free(result); 18750Sstevel@tonic-gate (void) pool_rs_close(rs); 18760Sstevel@tonic-gate return (NULL); 18770Sstevel@tonic-gate } 18780Sstevel@tonic-gate result[i++] = pool_elem_pool(pe); 18790Sstevel@tonic-gate } 18800Sstevel@tonic-gate (void) pool_rs_close(rs); 18810Sstevel@tonic-gate return (result); 18820Sstevel@tonic-gate } 18830Sstevel@tonic-gate 18840Sstevel@tonic-gate /* 18850Sstevel@tonic-gate * Return an res, searching the supplied configuration for an res with the 18860Sstevel@tonic-gate * supplied name. The search is case sensitive. 18870Sstevel@tonic-gate */ 18880Sstevel@tonic-gate pool_resource_t * 18890Sstevel@tonic-gate pool_get_resource(const pool_conf_t *conf, const char *sz_type, 18900Sstevel@tonic-gate const char *name) 18910Sstevel@tonic-gate { 18920Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL, NULL }; 18930Sstevel@tonic-gate pool_resource_t **rs; 18940Sstevel@tonic-gate pool_resource_t *ret; 18950Sstevel@tonic-gate uint_t size = 0; 18960Sstevel@tonic-gate char_buf_t *cb = NULL; 18970Sstevel@tonic-gate pool_value_t val0 = POOL_VALUE_INITIALIZER; 18980Sstevel@tonic-gate pool_value_t val1 = POOL_VALUE_INITIALIZER; 18990Sstevel@tonic-gate 19000Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 19010Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 19020Sstevel@tonic-gate return (NULL); 19030Sstevel@tonic-gate } 19040Sstevel@tonic-gate 19050Sstevel@tonic-gate if (sz_type == NULL) { 19060Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 19070Sstevel@tonic-gate return (NULL); 19080Sstevel@tonic-gate } 19090Sstevel@tonic-gate 19100Sstevel@tonic-gate props[0] = &val0; 19110Sstevel@tonic-gate props[1] = &val1; 19120Sstevel@tonic-gate 19130Sstevel@tonic-gate if (pool_value_set_string(props[0], sz_type) != PO_SUCCESS || 19140Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS) 19150Sstevel@tonic-gate return (NULL); 19160Sstevel@tonic-gate 19170Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) { 19180Sstevel@tonic-gate return (NULL); 19190Sstevel@tonic-gate } 19200Sstevel@tonic-gate if (set_char_buf(cb, "%s.name", sz_type) != PO_SUCCESS) { 19210Sstevel@tonic-gate free_char_buf(cb); 19220Sstevel@tonic-gate return (NULL); 19230Sstevel@tonic-gate } 19240Sstevel@tonic-gate if (pool_value_set_name(props[1], cb->cb_buf) != PO_SUCCESS) { 19250Sstevel@tonic-gate free_char_buf(cb); 19260Sstevel@tonic-gate return (NULL); 19270Sstevel@tonic-gate } 19280Sstevel@tonic-gate if (pool_value_set_string(props[1], name) != PO_SUCCESS) { 19290Sstevel@tonic-gate free_char_buf(cb); 19300Sstevel@tonic-gate return (NULL); 19310Sstevel@tonic-gate } 19320Sstevel@tonic-gate free_char_buf(cb); 19330Sstevel@tonic-gate rs = pool_query_resources(conf, &size, props); 19340Sstevel@tonic-gate if (rs == NULL) { 19350Sstevel@tonic-gate return (NULL); 19360Sstevel@tonic-gate } 19370Sstevel@tonic-gate if (size != 1) { 19380Sstevel@tonic-gate free(rs); 19390Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 19400Sstevel@tonic-gate return (NULL); 19410Sstevel@tonic-gate } 19420Sstevel@tonic-gate ret = rs[0]; 19430Sstevel@tonic-gate free(rs); 19440Sstevel@tonic-gate return (ret); 19450Sstevel@tonic-gate } 19460Sstevel@tonic-gate 19470Sstevel@tonic-gate /* 19480Sstevel@tonic-gate * Return a result set of res (actually as pool_elem_ts), searching the 19490Sstevel@tonic-gate * supplied configuration for res which match the supplied property 19500Sstevel@tonic-gate * criteria. props is a null terminated list of properties which will be used 19510Sstevel@tonic-gate * to match qualifying res. 19520Sstevel@tonic-gate */ 19530Sstevel@tonic-gate pool_resource_t ** 19540Sstevel@tonic-gate pool_query_resources(const pool_conf_t *conf, uint_t *size, 19550Sstevel@tonic-gate pool_value_t **props) 19560Sstevel@tonic-gate { 19570Sstevel@tonic-gate pool_result_set_t *rs; 19580Sstevel@tonic-gate pool_elem_t *pe; 19590Sstevel@tonic-gate pool_resource_t **result = NULL; 19600Sstevel@tonic-gate int i = 0; 19610Sstevel@tonic-gate 19620Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 19630Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 19640Sstevel@tonic-gate return (NULL); 19650Sstevel@tonic-gate } 19660Sstevel@tonic-gate 19670Sstevel@tonic-gate *size = 0; 19680Sstevel@tonic-gate 19690Sstevel@tonic-gate rs = pool_exec_query(conf, NULL, NULL, PEC_QRY_RES, props); 19700Sstevel@tonic-gate if (rs == NULL) { 19710Sstevel@tonic-gate return (NULL); 19720Sstevel@tonic-gate } 19730Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) { 19740Sstevel@tonic-gate (void) pool_rs_close(rs); 19750Sstevel@tonic-gate return (NULL); 19760Sstevel@tonic-gate } 19770Sstevel@tonic-gate if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1))) 19780Sstevel@tonic-gate == NULL) { 19790Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 19800Sstevel@tonic-gate (void) pool_rs_close(rs); 19810Sstevel@tonic-gate return (NULL); 19820Sstevel@tonic-gate } 19830Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1)); 19840Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) { 19850Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_RES_COMP && 19860Sstevel@tonic-gate pool_elem_class(pe) != PEC_RES_AGG) { 19870Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 19880Sstevel@tonic-gate free(result); 19890Sstevel@tonic-gate (void) pool_rs_close(rs); 19900Sstevel@tonic-gate return (NULL); 19910Sstevel@tonic-gate } 19920Sstevel@tonic-gate result[i++] = pool_elem_res(pe); 19930Sstevel@tonic-gate } 19940Sstevel@tonic-gate (void) pool_rs_close(rs); 19950Sstevel@tonic-gate return (result); 19960Sstevel@tonic-gate } 19970Sstevel@tonic-gate 19980Sstevel@tonic-gate /* 19990Sstevel@tonic-gate * Return a result set of comp (actually as pool_elem_ts), searching the 20000Sstevel@tonic-gate * supplied configuration for comp which match the supplied property 20010Sstevel@tonic-gate * criteria. props is a null terminated list of properties which will be used 20020Sstevel@tonic-gate * to match qualifying comp. 20030Sstevel@tonic-gate */ 20040Sstevel@tonic-gate pool_component_t ** 20050Sstevel@tonic-gate pool_query_components(const pool_conf_t *conf, uint_t *size, 20060Sstevel@tonic-gate pool_value_t **props) 20070Sstevel@tonic-gate { 20080Sstevel@tonic-gate return (pool_query_resource_components(conf, NULL, size, props)); 20090Sstevel@tonic-gate } 20100Sstevel@tonic-gate 20110Sstevel@tonic-gate /* 20120Sstevel@tonic-gate * Destroy a pool. If the pool cannot be found or removed an error is 20130Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure 20140Sstevel@tonic-gate * some type safety for the pool subtype. 20150Sstevel@tonic-gate */ 20160Sstevel@tonic-gate int 20170Sstevel@tonic-gate pool_destroy(pool_conf_t *conf, pool_t *pp) 20180Sstevel@tonic-gate { 20190Sstevel@tonic-gate pool_elem_t *pe; 20200Sstevel@tonic-gate 20210Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 20220Sstevel@tonic-gate return (PO_FAIL); 20230Sstevel@tonic-gate 20240Sstevel@tonic-gate pe = TO_ELEM(pp); 20250Sstevel@tonic-gate 20260Sstevel@tonic-gate /* 20270Sstevel@tonic-gate * Cannot destroy the default pool. 20280Sstevel@tonic-gate */ 20290Sstevel@tonic-gate if (elem_is_default(pe) == PO_TRUE) { 20300Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 20310Sstevel@tonic-gate return (PO_FAIL); 20320Sstevel@tonic-gate } 20330Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS) 20340Sstevel@tonic-gate return (PO_FAIL); 20350Sstevel@tonic-gate return (PO_SUCCESS); 20360Sstevel@tonic-gate } 20370Sstevel@tonic-gate 20380Sstevel@tonic-gate /* 20390Sstevel@tonic-gate * Destroy an res. If the res cannot be found or removed an error is 20400Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure 20410Sstevel@tonic-gate * some type safety for the res subtype. 20420Sstevel@tonic-gate */ 20430Sstevel@tonic-gate int 20440Sstevel@tonic-gate pool_resource_destroy(pool_conf_t *conf, pool_resource_t *prs) 20450Sstevel@tonic-gate { 20460Sstevel@tonic-gate pool_elem_t *pe; 20470Sstevel@tonic-gate pool_component_t **rl; 20480Sstevel@tonic-gate uint_t res_size; 20490Sstevel@tonic-gate pool_t **pl; 20500Sstevel@tonic-gate uint_t npool; 20510Sstevel@tonic-gate int i; 20520Sstevel@tonic-gate 20530Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 20540Sstevel@tonic-gate return (PO_FAIL); 20550Sstevel@tonic-gate 20560Sstevel@tonic-gate pe = TO_ELEM(prs); 20570Sstevel@tonic-gate 20580Sstevel@tonic-gate if (resource_is_system(prs) == PO_TRUE) { 20590Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 20600Sstevel@tonic-gate return (PO_FAIL); 20610Sstevel@tonic-gate } 20620Sstevel@tonic-gate /* 20630Sstevel@tonic-gate * Walk all the pools and dissociate any pools which are using 20640Sstevel@tonic-gate * this resource. 20650Sstevel@tonic-gate */ 20660Sstevel@tonic-gate if ((pl = pool_query_pools(conf, &npool, NULL)) != NULL) { 20670Sstevel@tonic-gate for (i = 0; i < npool; i++) { 20680Sstevel@tonic-gate pool_resource_t **rl; 20690Sstevel@tonic-gate uint_t nres; 20700Sstevel@tonic-gate int j; 20710Sstevel@tonic-gate 20720Sstevel@tonic-gate if ((rl = pool_query_pool_resources(conf, pl[i], &nres, 20730Sstevel@tonic-gate NULL)) != NULL) { 20740Sstevel@tonic-gate for (j = 0; j < nres; j++) { 20750Sstevel@tonic-gate if (rl[j] == prs) { 20760Sstevel@tonic-gate if (pool_dissociate(conf, pl[i], 20770Sstevel@tonic-gate rl[j]) != PO_SUCCESS) { 20780Sstevel@tonic-gate free(rl); 20790Sstevel@tonic-gate free(pl); 20800Sstevel@tonic-gate return (PO_FAIL); 20810Sstevel@tonic-gate } 20820Sstevel@tonic-gate break; 20830Sstevel@tonic-gate } 20840Sstevel@tonic-gate } 20850Sstevel@tonic-gate free(rl); 20860Sstevel@tonic-gate } 20870Sstevel@tonic-gate } 20880Sstevel@tonic-gate free(pl); 20890Sstevel@tonic-gate } 20900Sstevel@tonic-gate if (pe->pe_class == PEC_RES_COMP) { 20910Sstevel@tonic-gate pool_resource_t *default_set_res; 20920Sstevel@tonic-gate 20930Sstevel@tonic-gate /* 20940Sstevel@tonic-gate * Use the xtransfer option to move comp around 20950Sstevel@tonic-gate */ 20960Sstevel@tonic-gate default_set_res = (pool_resource_t *)get_default_resource(prs); 20970Sstevel@tonic-gate 20980Sstevel@tonic-gate if ((rl = pool_query_resource_components(conf, prs, &res_size, 20990Sstevel@tonic-gate NULL)) != NULL) { 21000Sstevel@tonic-gate int ostate = conf->pc_state; 21010Sstevel@tonic-gate conf->pc_state = POF_DESTROY; 21020Sstevel@tonic-gate if (pool_resource_xtransfer(conf, prs, default_set_res, 21030Sstevel@tonic-gate rl) == PO_FAIL) { 21040Sstevel@tonic-gate free(rl); 21050Sstevel@tonic-gate conf->pc_state = ostate; 21060Sstevel@tonic-gate return (PO_FAIL); 21070Sstevel@tonic-gate } 21080Sstevel@tonic-gate conf->pc_state = ostate; 21090Sstevel@tonic-gate free(rl); 21100Sstevel@tonic-gate } 21110Sstevel@tonic-gate } 21120Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS) 21130Sstevel@tonic-gate return (PO_FAIL); 21140Sstevel@tonic-gate return (PO_SUCCESS); 21150Sstevel@tonic-gate } 21160Sstevel@tonic-gate 21170Sstevel@tonic-gate /* 21180Sstevel@tonic-gate * Destroy a comp. If the comp cannot be found or removed an error is 21190Sstevel@tonic-gate * returned. This is basically a wrapper around pool_elem_remove to ensure 21200Sstevel@tonic-gate * some type safety for the comp subtype. 21210Sstevel@tonic-gate */ 21220Sstevel@tonic-gate int 21230Sstevel@tonic-gate pool_component_destroy(pool_component_t *pr) 21240Sstevel@tonic-gate { 21250Sstevel@tonic-gate pool_elem_t *pe = TO_ELEM(pr); 21260Sstevel@tonic-gate 21270Sstevel@tonic-gate if (pool_elem_remove(pe) != PO_SUCCESS) 21280Sstevel@tonic-gate return (PO_FAIL); 21290Sstevel@tonic-gate return (PO_SUCCESS); 21300Sstevel@tonic-gate } 21310Sstevel@tonic-gate 21320Sstevel@tonic-gate /* 21330Sstevel@tonic-gate * Remove a pool_elem_t from a configuration. This has been "hidden" away as 21340Sstevel@tonic-gate * a static routine since the only elements which are currently being removed 21350Sstevel@tonic-gate * are pools, res & comp and the wrapper functions above provide type-safe 21360Sstevel@tonic-gate * access. However, if there is a need to remove other types of elements 21370Sstevel@tonic-gate * then this could be promoted to pool_impl.h or more wrappers could 21380Sstevel@tonic-gate * be added to pool_impl.h. 21390Sstevel@tonic-gate */ 21400Sstevel@tonic-gate int 21410Sstevel@tonic-gate pool_elem_remove(pool_elem_t *pe) 21420Sstevel@tonic-gate { 21430Sstevel@tonic-gate return (pe->pe_remove(pe)); 21440Sstevel@tonic-gate } 21450Sstevel@tonic-gate 21460Sstevel@tonic-gate /* 21470Sstevel@tonic-gate * Execute a query to search for a qualifying set of elements. 21480Sstevel@tonic-gate */ 21490Sstevel@tonic-gate pool_result_set_t * 21500Sstevel@tonic-gate pool_exec_query(const pool_conf_t *conf, const pool_elem_t *src, 21510Sstevel@tonic-gate const char *src_attr, pool_elem_class_t classes, pool_value_t **props) 21520Sstevel@tonic-gate { 21530Sstevel@tonic-gate return (conf->pc_prov->pc_exec_query(conf, src, src_attr, classes, 21540Sstevel@tonic-gate props)); 21550Sstevel@tonic-gate } 21560Sstevel@tonic-gate 21570Sstevel@tonic-gate /* 21580Sstevel@tonic-gate * Get the next result from a result set of elements. 21590Sstevel@tonic-gate */ 21600Sstevel@tonic-gate pool_elem_t * 21610Sstevel@tonic-gate pool_rs_next(pool_result_set_t *set) 21620Sstevel@tonic-gate { 21630Sstevel@tonic-gate return (set->prs_next(set)); 21640Sstevel@tonic-gate } 21650Sstevel@tonic-gate 21660Sstevel@tonic-gate /* 21670Sstevel@tonic-gate * Get the previous result from a result set of elements. 21680Sstevel@tonic-gate */ 21690Sstevel@tonic-gate pool_elem_t * 21700Sstevel@tonic-gate pool_rs_prev(pool_result_set_t *set) 21710Sstevel@tonic-gate { 21720Sstevel@tonic-gate return (set->prs_prev(set)); 21730Sstevel@tonic-gate } 21740Sstevel@tonic-gate 21750Sstevel@tonic-gate /* 21760Sstevel@tonic-gate * Get the first result from a result set of elements. 21770Sstevel@tonic-gate */ 21780Sstevel@tonic-gate pool_elem_t * 21790Sstevel@tonic-gate pool_rs_first(pool_result_set_t *set) 21800Sstevel@tonic-gate { 21810Sstevel@tonic-gate return (set->prs_first(set)); 21820Sstevel@tonic-gate } 21830Sstevel@tonic-gate 21840Sstevel@tonic-gate /* 21850Sstevel@tonic-gate * Get the last result from a result set of elements. 21860Sstevel@tonic-gate */ 21870Sstevel@tonic-gate pool_elem_t * 21880Sstevel@tonic-gate pool_rs_last(pool_result_set_t *set) 21890Sstevel@tonic-gate { 21900Sstevel@tonic-gate return (set->prs_last(set)); 21910Sstevel@tonic-gate } 21920Sstevel@tonic-gate 21930Sstevel@tonic-gate 21940Sstevel@tonic-gate /* 21950Sstevel@tonic-gate * Get the count for a result set of elements. 21960Sstevel@tonic-gate */ 21970Sstevel@tonic-gate int 21980Sstevel@tonic-gate pool_rs_count(pool_result_set_t *set) 21990Sstevel@tonic-gate { 22000Sstevel@tonic-gate return (set->prs_count(set)); 22010Sstevel@tonic-gate } 22020Sstevel@tonic-gate 22030Sstevel@tonic-gate /* 22040Sstevel@tonic-gate * Get the index for a result set of elements. 22050Sstevel@tonic-gate */ 22060Sstevel@tonic-gate int 22070Sstevel@tonic-gate pool_rs_get_index(pool_result_set_t *set) 22080Sstevel@tonic-gate { 22090Sstevel@tonic-gate return (set->prs_get_index(set)); 22100Sstevel@tonic-gate } 22110Sstevel@tonic-gate 22120Sstevel@tonic-gate /* 22130Sstevel@tonic-gate * Set the index for a result set of elements. 22140Sstevel@tonic-gate */ 22150Sstevel@tonic-gate int 22160Sstevel@tonic-gate pool_rs_set_index(pool_result_set_t *set, int index) 22170Sstevel@tonic-gate { 22180Sstevel@tonic-gate return (set->prs_set_index(set, index)); 22190Sstevel@tonic-gate } 22200Sstevel@tonic-gate 22210Sstevel@tonic-gate /* 22220Sstevel@tonic-gate * Close a result set of elements, freeing all associated resources. 22230Sstevel@tonic-gate */ 22240Sstevel@tonic-gate int 22250Sstevel@tonic-gate pool_rs_close(pool_result_set_t *set) 22260Sstevel@tonic-gate { 22270Sstevel@tonic-gate return (set->prs_close(set)); 22280Sstevel@tonic-gate } 22290Sstevel@tonic-gate 22300Sstevel@tonic-gate /* 22310Sstevel@tonic-gate * When transferring resource components using pool_resource_transfer, 22320Sstevel@tonic-gate * this function is invoked to choose which actual components will be 22330Sstevel@tonic-gate * transferred. 22340Sstevel@tonic-gate */ 22350Sstevel@tonic-gate int 22360Sstevel@tonic-gate choose_components(pool_resource_t *src, pool_resource_t *dst, uint64_t size) 22370Sstevel@tonic-gate { 22380Sstevel@tonic-gate pool_component_t **components = NULL, *moved[] = { NULL, NULL }; 22390Sstevel@tonic-gate int i; 22400Sstevel@tonic-gate uint_t ncomponent; 22410Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(TO_ELEM(src)); 22420Sstevel@tonic-gate 22430Sstevel@tonic-gate if (size == 0) 22440Sstevel@tonic-gate return (PO_SUCCESS); 22450Sstevel@tonic-gate /* 22460Sstevel@tonic-gate * Get the component list from our src component. 22470Sstevel@tonic-gate */ 22480Sstevel@tonic-gate if ((components = pool_query_resource_components(conf, src, &ncomponent, 22490Sstevel@tonic-gate NULL)) == NULL) { 22500Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 22510Sstevel@tonic-gate return (PO_FAIL); 22520Sstevel@tonic-gate } 22530Sstevel@tonic-gate qsort(components, ncomponent, sizeof (pool_elem_t *), 22540Sstevel@tonic-gate qsort_elem_compare); 22550Sstevel@tonic-gate /* 22560Sstevel@tonic-gate * Components that aren't specifically requested by the resource 22570Sstevel@tonic-gate * should be transferred out first. 22580Sstevel@tonic-gate */ 22590Sstevel@tonic-gate for (i = 0; size > 0 && components[i] != NULL; i++) { 22600Sstevel@tonic-gate if (!cpu_is_requested(components[i])) { 22610Sstevel@tonic-gate moved[0] = components[i]; 22620Sstevel@tonic-gate if (pool_resource_xtransfer(conf, src, dst, moved) == 22630Sstevel@tonic-gate PO_SUCCESS) { 22640Sstevel@tonic-gate size--; 22650Sstevel@tonic-gate } 22660Sstevel@tonic-gate } 22670Sstevel@tonic-gate } 22680Sstevel@tonic-gate 22690Sstevel@tonic-gate /* 22700Sstevel@tonic-gate * If we couldn't find enough "un-requested" components, select random 22710Sstevel@tonic-gate * requested components. 22720Sstevel@tonic-gate */ 22730Sstevel@tonic-gate for (i = 0; size > 0 && components[i] != NULL; i++) { 22740Sstevel@tonic-gate if (cpu_is_requested(components[i])) { 22750Sstevel@tonic-gate moved[0] = components[i]; 22760Sstevel@tonic-gate if (pool_resource_xtransfer(conf, src, dst, moved) == 22770Sstevel@tonic-gate PO_SUCCESS) { 22780Sstevel@tonic-gate size--; 22790Sstevel@tonic-gate } 22800Sstevel@tonic-gate } 22810Sstevel@tonic-gate } 22820Sstevel@tonic-gate 22830Sstevel@tonic-gate free(components); 22840Sstevel@tonic-gate /* 22850Sstevel@tonic-gate * If we couldn't transfer out all the resources we asked for, then 22860Sstevel@tonic-gate * return error. 22870Sstevel@tonic-gate */ 22880Sstevel@tonic-gate return (size == 0 ? PO_SUCCESS : PO_FAIL); 22890Sstevel@tonic-gate } 22900Sstevel@tonic-gate 22910Sstevel@tonic-gate /* 22920Sstevel@tonic-gate * Common processing for a resource transfer (xfer or xxfer). 22930Sstevel@tonic-gate * 22940Sstevel@tonic-gate * - Return XFER_CONTINUE if the transfer should proceeed 22950Sstevel@tonic-gate * - Return XFER_FAIL if the transfer should be stopped in failure 22960Sstevel@tonic-gate * - Return XFER_SUCCESS if the transfer should be stopped in success 22970Sstevel@tonic-gate */ 22980Sstevel@tonic-gate int 22990Sstevel@tonic-gate setup_transfer(pool_conf_t *conf, pool_resource_t *src, pool_resource_t *tgt, 23000Sstevel@tonic-gate uint64_t size, uint64_t *src_size, uint64_t *tgt_size) 23010Sstevel@tonic-gate { 23020Sstevel@tonic-gate uint64_t src_min; 23030Sstevel@tonic-gate uint64_t tgt_max; 23040Sstevel@tonic-gate 23050Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 23060Sstevel@tonic-gate return (XFER_FAIL); 23070Sstevel@tonic-gate 23080Sstevel@tonic-gate /* 23090Sstevel@tonic-gate * Makes sure the two resources are of the same type 23100Sstevel@tonic-gate */ 23110Sstevel@tonic-gate if (pool_resource_elem_class(TO_ELEM(src)) != 23120Sstevel@tonic-gate pool_resource_elem_class(TO_ELEM(tgt))) { 23130Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 23140Sstevel@tonic-gate return (XFER_FAIL); 23150Sstevel@tonic-gate } 23160Sstevel@tonic-gate 23170Sstevel@tonic-gate /* 23180Sstevel@tonic-gate * Transferring to yourself is a no-op 23190Sstevel@tonic-gate */ 23200Sstevel@tonic-gate if (src == tgt) 23210Sstevel@tonic-gate return (XFER_SUCCESS); 23220Sstevel@tonic-gate 23230Sstevel@tonic-gate /* 23240Sstevel@tonic-gate * Transferring nothing is a no-op 23250Sstevel@tonic-gate */ 23260Sstevel@tonic-gate if (size == 0) 23270Sstevel@tonic-gate return (XFER_SUCCESS); 23280Sstevel@tonic-gate 23290Sstevel@tonic-gate if (resource_get_min(src, &src_min) != PO_SUCCESS || 23300Sstevel@tonic-gate resource_get_size(src, src_size) != PO_SUCCESS || 23310Sstevel@tonic-gate resource_get_max(tgt, &tgt_max) != PO_SUCCESS || 23320Sstevel@tonic-gate resource_get_size(tgt, tgt_size) != PO_SUCCESS) { 23330Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 23340Sstevel@tonic-gate return (XFER_FAIL); 23350Sstevel@tonic-gate } 23360Sstevel@tonic-gate if (pool_conf_status(conf) != POF_DESTROY) { 23370Sstevel@tonic-gate /* 23380Sstevel@tonic-gate * src_size - donating >= src.min 23390Sstevel@tonic-gate * size + receiving <= tgt.max (except for default) 23400Sstevel@tonic-gate */ 23410Sstevel@tonic-gate #ifdef DEBUG 23420Sstevel@tonic-gate dprintf("conf is %s\n", pool_conf_location(conf)); 23430Sstevel@tonic-gate dprintf("setup_transfer: src_size %llu\n", *src_size); 23440Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(src)); 23450Sstevel@tonic-gate dprintf("setup_transfer: tgt_size %llu\n", *tgt_size); 23460Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(tgt)); 23470Sstevel@tonic-gate #endif /* DEBUG */ 23480Sstevel@tonic-gate if (*src_size - size < src_min || 23490Sstevel@tonic-gate (resource_is_default(tgt) == PO_FALSE && 23500Sstevel@tonic-gate *tgt_size + size > tgt_max)) { 23510Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 23520Sstevel@tonic-gate return (XFER_FAIL); 23530Sstevel@tonic-gate } 23540Sstevel@tonic-gate } 23550Sstevel@tonic-gate return (XFER_CONTINUE); 23560Sstevel@tonic-gate } 23570Sstevel@tonic-gate 23580Sstevel@tonic-gate /* 23590Sstevel@tonic-gate * Transfer resource quantities from one resource set to another. 23600Sstevel@tonic-gate */ 23610Sstevel@tonic-gate int 23620Sstevel@tonic-gate pool_resource_transfer(pool_conf_t *conf, pool_resource_t *src, 23630Sstevel@tonic-gate pool_resource_t *tgt, uint64_t size) 23640Sstevel@tonic-gate { 23650Sstevel@tonic-gate uint64_t src_size; 23660Sstevel@tonic-gate uint64_t tgt_size; 23670Sstevel@tonic-gate int ret; 23680Sstevel@tonic-gate 23690Sstevel@tonic-gate if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size)) 23700Sstevel@tonic-gate != XFER_CONTINUE) 23710Sstevel@tonic-gate return (ret); 23720Sstevel@tonic-gate /* 23730Sstevel@tonic-gate * If this resource is a res_comp we must call move components 23740Sstevel@tonic-gate */ 23750Sstevel@tonic-gate if (pool_elem_class(TO_ELEM(src)) == PEC_RES_COMP) 23760Sstevel@tonic-gate return (choose_components(src, tgt, size)); 23770Sstevel@tonic-gate /* 23780Sstevel@tonic-gate * Now do the transfer. 23790Sstevel@tonic-gate */ 23800Sstevel@tonic-gate ret = conf->pc_prov->pc_res_xfer(src, tgt, size); 23810Sstevel@tonic-gate /* 23820Sstevel@tonic-gate * Modify the sizes of the resource sets if the process was 23830Sstevel@tonic-gate * successful 23840Sstevel@tonic-gate */ 23850Sstevel@tonic-gate if (ret == PO_SUCCESS) { 23860Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 23870Sstevel@tonic-gate 23880Sstevel@tonic-gate src_size -= size; 23890Sstevel@tonic-gate tgt_size += size; 23900Sstevel@tonic-gate pool_value_set_uint64(&val, src_size); 23910Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop, 23920Sstevel@tonic-gate &val); 23930Sstevel@tonic-gate pool_value_set_uint64(&val, tgt_size); 23940Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop, 23950Sstevel@tonic-gate &val); 23960Sstevel@tonic-gate } 23970Sstevel@tonic-gate return (ret); 23980Sstevel@tonic-gate } 23990Sstevel@tonic-gate 24000Sstevel@tonic-gate /* 24010Sstevel@tonic-gate * Transfer resource components from one resource set to another. 24020Sstevel@tonic-gate */ 24030Sstevel@tonic-gate int 24040Sstevel@tonic-gate pool_resource_xtransfer(pool_conf_t *conf, pool_resource_t *src, 24050Sstevel@tonic-gate pool_resource_t *tgt, 24060Sstevel@tonic-gate pool_component_t **rl) 24070Sstevel@tonic-gate { 24080Sstevel@tonic-gate int i; 24090Sstevel@tonic-gate uint64_t src_size; 24100Sstevel@tonic-gate uint64_t tgt_size; 24110Sstevel@tonic-gate uint64_t size; 24120Sstevel@tonic-gate int ret; 24130Sstevel@tonic-gate 24140Sstevel@tonic-gate /* 24150Sstevel@tonic-gate * Make sure the components are all contained in 'src'. This 24160Sstevel@tonic-gate * processing must be done before setup_transfer so that size 24170Sstevel@tonic-gate * is known. 24180Sstevel@tonic-gate */ 24190Sstevel@tonic-gate for (i = 0; rl[i] != NULL; i++) { 24200Sstevel@tonic-gate #ifdef DEBUG 24210Sstevel@tonic-gate dprintf("resource xtransfer\n"); 24220Sstevel@tonic-gate dprintf("in conf %s\n", pool_conf_location(conf)); 24230Sstevel@tonic-gate dprintf("transferring component\n"); 24240Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(rl[i])); 24250Sstevel@tonic-gate dprintf("from\n"); 24260Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(src)); 24270Sstevel@tonic-gate dprintf("to\n"); 24280Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(tgt)); 24290Sstevel@tonic-gate #endif /* DEBUG */ 24300Sstevel@tonic-gate 24310Sstevel@tonic-gate if (pool_get_owning_resource(conf, rl[i]) != src) { 24320Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 24330Sstevel@tonic-gate return (PO_FAIL); 24340Sstevel@tonic-gate } 24350Sstevel@tonic-gate } 24360Sstevel@tonic-gate 24370Sstevel@tonic-gate size = (uint64_t)i; 24380Sstevel@tonic-gate 24390Sstevel@tonic-gate if ((ret = setup_transfer(conf, src, tgt, size, &src_size, &tgt_size)) 24400Sstevel@tonic-gate != XFER_CONTINUE) 24410Sstevel@tonic-gate return (ret); 24420Sstevel@tonic-gate 24430Sstevel@tonic-gate ret = conf->pc_prov->pc_res_xxfer(src, tgt, rl); 24440Sstevel@tonic-gate /* 24450Sstevel@tonic-gate * Modify the sizes of the resource sets if the process was 24460Sstevel@tonic-gate * successful 24470Sstevel@tonic-gate */ 24480Sstevel@tonic-gate if (ret == PO_SUCCESS) { 24490Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 24500Sstevel@tonic-gate 24510Sstevel@tonic-gate #ifdef DEBUG 24520Sstevel@tonic-gate dprintf("src_size %llu\n", src_size); 24530Sstevel@tonic-gate dprintf("tgt_size %llu\n", tgt_size); 24540Sstevel@tonic-gate dprintf("size %llu\n", size); 24550Sstevel@tonic-gate #endif /* DEBUG */ 24560Sstevel@tonic-gate src_size -= size; 24570Sstevel@tonic-gate tgt_size += size; 24580Sstevel@tonic-gate pool_value_set_uint64(&val, src_size); 24590Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(src), c_size_prop, 24600Sstevel@tonic-gate &val); 24610Sstevel@tonic-gate pool_value_set_uint64(&val, tgt_size); 24620Sstevel@tonic-gate (void) pool_put_any_ns_property(TO_ELEM(tgt), c_size_prop, 24630Sstevel@tonic-gate &val); 24640Sstevel@tonic-gate } 24650Sstevel@tonic-gate return (ret); 24660Sstevel@tonic-gate } 24670Sstevel@tonic-gate 24680Sstevel@tonic-gate /* 24690Sstevel@tonic-gate * Find the owning resource for a resource component. 24700Sstevel@tonic-gate */ 24710Sstevel@tonic-gate pool_resource_t * 24720Sstevel@tonic-gate pool_get_owning_resource(const pool_conf_t *conf, const pool_component_t *comp) 24730Sstevel@tonic-gate { 24740Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 24750Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 24760Sstevel@tonic-gate return (NULL); 24770Sstevel@tonic-gate } 24780Sstevel@tonic-gate return (pool_elem_res(pool_get_container(TO_ELEM(comp)))); 24790Sstevel@tonic-gate } 24800Sstevel@tonic-gate 24810Sstevel@tonic-gate /* 24820Sstevel@tonic-gate * pool_get_container() returns the container of pc. 24830Sstevel@tonic-gate */ 24840Sstevel@tonic-gate pool_elem_t * 24850Sstevel@tonic-gate pool_get_container(const pool_elem_t *pc) 24860Sstevel@tonic-gate { 24870Sstevel@tonic-gate return (pc->pe_get_container(pc)); 24880Sstevel@tonic-gate } 24890Sstevel@tonic-gate 24900Sstevel@tonic-gate /* 24910Sstevel@tonic-gate * pool_set_container() moves pc so that it is contained by pp. 24920Sstevel@tonic-gate * 24930Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 24940Sstevel@tonic-gate */ 24950Sstevel@tonic-gate int 24960Sstevel@tonic-gate pool_set_container(pool_elem_t *pp, pool_elem_t *pc) 24970Sstevel@tonic-gate { 24980Sstevel@tonic-gate return (pc->pe_set_container(pp, pc)); 24990Sstevel@tonic-gate } 25000Sstevel@tonic-gate 25010Sstevel@tonic-gate /* 25020Sstevel@tonic-gate * Conversion routines for converting to and from elem and it's various 25030Sstevel@tonic-gate * subtypes of system, pool, res and comp. 25040Sstevel@tonic-gate */ 25050Sstevel@tonic-gate pool_elem_t * 25060Sstevel@tonic-gate pool_system_elem(const pool_system_t *ph) 25070Sstevel@tonic-gate { 25080Sstevel@tonic-gate return ((pool_elem_t *)ph); 25090Sstevel@tonic-gate } 25100Sstevel@tonic-gate 25110Sstevel@tonic-gate pool_elem_t * 25120Sstevel@tonic-gate pool_conf_to_elem(const pool_conf_t *conf) 25130Sstevel@tonic-gate { 25140Sstevel@tonic-gate pool_system_t *sys; 25150Sstevel@tonic-gate 25160Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 25170Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25180Sstevel@tonic-gate return (NULL); 25190Sstevel@tonic-gate } 25200Sstevel@tonic-gate if ((sys = pool_conf_system(conf)) == NULL) { 25210Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25220Sstevel@tonic-gate return (NULL); 25230Sstevel@tonic-gate } 25240Sstevel@tonic-gate return (pool_system_elem(sys)); 25250Sstevel@tonic-gate } 25260Sstevel@tonic-gate 25270Sstevel@tonic-gate pool_elem_t * 25280Sstevel@tonic-gate pool_to_elem(const pool_conf_t *conf, const pool_t *pp) 25290Sstevel@tonic-gate { 25300Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 25310Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25320Sstevel@tonic-gate return (NULL); 25330Sstevel@tonic-gate } 25340Sstevel@tonic-gate return ((pool_elem_t *)pp); 25350Sstevel@tonic-gate } 25360Sstevel@tonic-gate 25370Sstevel@tonic-gate pool_elem_t * 25380Sstevel@tonic-gate pool_resource_to_elem(const pool_conf_t *conf, const pool_resource_t *prs) 25390Sstevel@tonic-gate { 25400Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 25410Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25420Sstevel@tonic-gate return (NULL); 25430Sstevel@tonic-gate } 25440Sstevel@tonic-gate return ((pool_elem_t *)prs); 25450Sstevel@tonic-gate } 25460Sstevel@tonic-gate 25470Sstevel@tonic-gate pool_elem_t * 25480Sstevel@tonic-gate pool_component_to_elem(const pool_conf_t *conf, const pool_component_t *pr) 25490Sstevel@tonic-gate { 25500Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 25510Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25520Sstevel@tonic-gate return (NULL); 25530Sstevel@tonic-gate } 25540Sstevel@tonic-gate return ((pool_elem_t *)pr); 25550Sstevel@tonic-gate } 25560Sstevel@tonic-gate 25570Sstevel@tonic-gate /* 25580Sstevel@tonic-gate * Walk all the pools of the configuration calling the user supplied function 25590Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE 25600Sstevel@tonic-gate */ 25610Sstevel@tonic-gate int 25620Sstevel@tonic-gate pool_walk_pools(pool_conf_t *conf, void *arg, 25630Sstevel@tonic-gate int (*callback)(pool_conf_t *conf, pool_t *pool, void *arg)) 25640Sstevel@tonic-gate { 25650Sstevel@tonic-gate pool_t **rs; 25660Sstevel@tonic-gate int i; 25670Sstevel@tonic-gate uint_t size; 25680Sstevel@tonic-gate int error = PO_SUCCESS; 25690Sstevel@tonic-gate 25700Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 25710Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 25720Sstevel@tonic-gate return (PO_FAIL); 25730Sstevel@tonic-gate } 25740Sstevel@tonic-gate 25750Sstevel@tonic-gate if ((rs = pool_query_pools(conf, &size, NULL)) == NULL) /* None */ 25760Sstevel@tonic-gate return (PO_SUCCESS); 25770Sstevel@tonic-gate for (i = 0; i < size; i++) 25780Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) { 25790Sstevel@tonic-gate error = PO_FAIL; 25800Sstevel@tonic-gate break; 25810Sstevel@tonic-gate } 25820Sstevel@tonic-gate free(rs); 25830Sstevel@tonic-gate return (error); 25840Sstevel@tonic-gate } 25850Sstevel@tonic-gate 25860Sstevel@tonic-gate /* 25870Sstevel@tonic-gate * Walk all the comp of the res calling the user supplied function 25880Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE 25890Sstevel@tonic-gate */ 25900Sstevel@tonic-gate int 25910Sstevel@tonic-gate pool_walk_components(pool_conf_t *conf, pool_resource_t *prs, void *arg, 25920Sstevel@tonic-gate int (*callback)(pool_conf_t *conf, pool_component_t *pr, void *arg)) 25930Sstevel@tonic-gate { 25940Sstevel@tonic-gate pool_component_t **rs; 25950Sstevel@tonic-gate int i; 25960Sstevel@tonic-gate uint_t size; 25970Sstevel@tonic-gate int error = PO_SUCCESS; 25980Sstevel@tonic-gate 25990Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 26000Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 26010Sstevel@tonic-gate return (PO_FAIL); 26020Sstevel@tonic-gate } 26030Sstevel@tonic-gate 26040Sstevel@tonic-gate if ((rs = pool_query_resource_components(conf, prs, &size, NULL)) == 26050Sstevel@tonic-gate NULL) 26060Sstevel@tonic-gate return (PO_SUCCESS); /* None */ 26070Sstevel@tonic-gate for (i = 0; i < size; i++) 26080Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) { 26090Sstevel@tonic-gate error = PO_FAIL; 26100Sstevel@tonic-gate break; 26110Sstevel@tonic-gate } 26120Sstevel@tonic-gate free(rs); 26130Sstevel@tonic-gate return (error); 26140Sstevel@tonic-gate } 26150Sstevel@tonic-gate 26160Sstevel@tonic-gate /* 26170Sstevel@tonic-gate * Return an array of all matching res for the supplied pool. 26180Sstevel@tonic-gate */ 26190Sstevel@tonic-gate pool_resource_t ** 26200Sstevel@tonic-gate pool_query_pool_resources(const pool_conf_t *conf, const pool_t *pp, 26210Sstevel@tonic-gate uint_t *size, pool_value_t **props) 26220Sstevel@tonic-gate { 26230Sstevel@tonic-gate pool_result_set_t *rs; 26240Sstevel@tonic-gate pool_elem_t *pe; 26250Sstevel@tonic-gate pool_resource_t **result = NULL; 26260Sstevel@tonic-gate int i = 0; 26270Sstevel@tonic-gate 26280Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 26290Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 26300Sstevel@tonic-gate return (NULL); 26310Sstevel@tonic-gate } 26320Sstevel@tonic-gate 26330Sstevel@tonic-gate pe = TO_ELEM(pp); 26340Sstevel@tonic-gate 26350Sstevel@tonic-gate rs = pool_exec_query(conf, pe, "res", PEC_QRY_RES, props); 26360Sstevel@tonic-gate if (rs == NULL) { 26370Sstevel@tonic-gate return (NULL); 26380Sstevel@tonic-gate } 26390Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) { 26400Sstevel@tonic-gate (void) pool_rs_close(rs); 26410Sstevel@tonic-gate return (NULL); 26420Sstevel@tonic-gate } 26430Sstevel@tonic-gate if ((result = malloc(sizeof (pool_resource_t *) * (*size + 1))) 26440Sstevel@tonic-gate == NULL) { 26450Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 26460Sstevel@tonic-gate (void) pool_rs_close(rs); 26470Sstevel@tonic-gate return (NULL); 26480Sstevel@tonic-gate } 26490Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_resource_t *) * (*size + 1)); 26500Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) { 26510Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_RES_COMP && 26520Sstevel@tonic-gate pool_elem_class(pe) != PEC_RES_AGG) { 26530Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 26540Sstevel@tonic-gate free(result); 26550Sstevel@tonic-gate (void) pool_rs_close(rs); 26560Sstevel@tonic-gate return (NULL); 26570Sstevel@tonic-gate } 26580Sstevel@tonic-gate result[i++] = pool_elem_res(pe); 26590Sstevel@tonic-gate } 26600Sstevel@tonic-gate (void) pool_rs_close(rs); 26610Sstevel@tonic-gate return (result); 26620Sstevel@tonic-gate } 26630Sstevel@tonic-gate 26640Sstevel@tonic-gate /* 26650Sstevel@tonic-gate * Walk all the res of the pool calling the user supplied function 26660Sstevel@tonic-gate * as long as the user function continues to return PO_TRUE 26670Sstevel@tonic-gate */ 26680Sstevel@tonic-gate int 26690Sstevel@tonic-gate pool_walk_resources(pool_conf_t *conf, pool_t *pp, void *arg, 26700Sstevel@tonic-gate int (*callback)(pool_conf_t *, pool_resource_t *, void *)) 26710Sstevel@tonic-gate { 26720Sstevel@tonic-gate pool_resource_t **rs; 26730Sstevel@tonic-gate int i; 26740Sstevel@tonic-gate uint_t size; 26750Sstevel@tonic-gate int error = PO_SUCCESS; 26760Sstevel@tonic-gate 26770Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 26780Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 26790Sstevel@tonic-gate return (PO_FAIL); 26800Sstevel@tonic-gate } 26810Sstevel@tonic-gate if ((rs = pool_query_pool_resources(conf, pp, &size, NULL)) == NULL) 26820Sstevel@tonic-gate return (PO_SUCCESS); /* None */ 26830Sstevel@tonic-gate for (i = 0; i < size; i++) 26840Sstevel@tonic-gate if (callback(conf, rs[i], arg) != PO_SUCCESS) { 26850Sstevel@tonic-gate error = PO_FAIL; 26860Sstevel@tonic-gate break; 26870Sstevel@tonic-gate } 26880Sstevel@tonic-gate free(rs); 26890Sstevel@tonic-gate return (error); 26900Sstevel@tonic-gate } 26910Sstevel@tonic-gate 26920Sstevel@tonic-gate /* 26930Sstevel@tonic-gate * Return a result set of all comp for the supplied res. 26940Sstevel@tonic-gate */ 26950Sstevel@tonic-gate pool_component_t ** 26960Sstevel@tonic-gate pool_query_resource_components(const pool_conf_t *conf, 26970Sstevel@tonic-gate const pool_resource_t *prs, uint_t *size, pool_value_t **props) 26980Sstevel@tonic-gate { 26990Sstevel@tonic-gate pool_result_set_t *rs; 27000Sstevel@tonic-gate pool_elem_t *pe; 27010Sstevel@tonic-gate pool_component_t **result = NULL; 27020Sstevel@tonic-gate int i = 0; 27030Sstevel@tonic-gate 27040Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 27050Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 27060Sstevel@tonic-gate return (NULL); 27070Sstevel@tonic-gate } 27080Sstevel@tonic-gate pe = TO_ELEM(prs); 27090Sstevel@tonic-gate 27100Sstevel@tonic-gate rs = pool_exec_query(conf, pe, NULL, PEC_QRY_COMP, props); 27110Sstevel@tonic-gate if (rs == NULL) { 27120Sstevel@tonic-gate return (NULL); 27130Sstevel@tonic-gate } 27140Sstevel@tonic-gate if ((*size = pool_rs_count(rs)) == 0) { 27150Sstevel@tonic-gate (void) pool_rs_close(rs); 27160Sstevel@tonic-gate return (NULL); 27170Sstevel@tonic-gate } 27180Sstevel@tonic-gate if ((result = malloc(sizeof (pool_component_t *) * (*size + 1))) 27190Sstevel@tonic-gate == NULL) { 27200Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 27210Sstevel@tonic-gate (void) pool_rs_close(rs); 27220Sstevel@tonic-gate return (NULL); 27230Sstevel@tonic-gate } 27240Sstevel@tonic-gate (void) memset(result, 0, sizeof (pool_component_t *) * (*size + 1)); 27250Sstevel@tonic-gate for (pe = rs->prs_next(rs); pe != NULL; pe = rs->prs_next(rs)) { 27260Sstevel@tonic-gate if (pool_elem_class(pe) != PEC_COMP) { 27270Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 27280Sstevel@tonic-gate free(result); 27290Sstevel@tonic-gate (void) pool_rs_close(rs); 27300Sstevel@tonic-gate return (NULL); 27310Sstevel@tonic-gate } 27320Sstevel@tonic-gate result[i++] = pool_elem_comp(pe); 27330Sstevel@tonic-gate } 27340Sstevel@tonic-gate (void) pool_rs_close(rs); 27350Sstevel@tonic-gate return (result); 27360Sstevel@tonic-gate } 27370Sstevel@tonic-gate 27380Sstevel@tonic-gate /* 27390Sstevel@tonic-gate * pool_version() returns the version of this library, depending on the supplied 27400Sstevel@tonic-gate * parameter. 27410Sstevel@tonic-gate * 27420Sstevel@tonic-gate * Returns: library version depening on the supplied ver parameter. 27430Sstevel@tonic-gate */ 27440Sstevel@tonic-gate uint_t 27450Sstevel@tonic-gate pool_version(uint_t ver) 27460Sstevel@tonic-gate { 27470Sstevel@tonic-gate switch (ver) { 27480Sstevel@tonic-gate case POOL_VER_NONE: 27490Sstevel@tonic-gate break; 27500Sstevel@tonic-gate case POOL_VER_CURRENT: 27510Sstevel@tonic-gate pool_workver = ver; 27520Sstevel@tonic-gate break; 27530Sstevel@tonic-gate default: 27540Sstevel@tonic-gate return (POOL_VER_NONE); 27550Sstevel@tonic-gate } 27560Sstevel@tonic-gate return (pool_workver); 27570Sstevel@tonic-gate } 27580Sstevel@tonic-gate 27590Sstevel@tonic-gate /* 27600Sstevel@tonic-gate * pool_associate() associates the supplied resource to the supplied pool. 27610Sstevel@tonic-gate * 27620Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL 27630Sstevel@tonic-gate */ 27640Sstevel@tonic-gate int 27650Sstevel@tonic-gate pool_associate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res) 27660Sstevel@tonic-gate { 27670Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 27680Sstevel@tonic-gate return (PO_FAIL); 27690Sstevel@tonic-gate 27700Sstevel@tonic-gate return (pool->pp_associate(pool, res)); 27710Sstevel@tonic-gate } 27720Sstevel@tonic-gate 27730Sstevel@tonic-gate /* 27740Sstevel@tonic-gate * pool_dissociate() dissociates the supplied resource from the supplied pool. 27750Sstevel@tonic-gate * 27760Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL 27770Sstevel@tonic-gate */ 27780Sstevel@tonic-gate int 27790Sstevel@tonic-gate pool_dissociate(pool_conf_t *conf, pool_t *pool, const pool_resource_t *res) 27800Sstevel@tonic-gate { 27810Sstevel@tonic-gate if (pool_conf_check(conf) != PO_SUCCESS) 27820Sstevel@tonic-gate return (PO_FAIL); 27830Sstevel@tonic-gate 27840Sstevel@tonic-gate if (elem_is_default(TO_ELEM(res))) 27850Sstevel@tonic-gate return (PO_SUCCESS); 27860Sstevel@tonic-gate return (pool->pp_dissociate(pool, res)); 27870Sstevel@tonic-gate } 27880Sstevel@tonic-gate 27890Sstevel@tonic-gate /* 27900Sstevel@tonic-gate * Compare two elements for purposes of ordering. 27910Sstevel@tonic-gate * Return: 27920Sstevel@tonic-gate * < 0 if e1 is "before" e2 27930Sstevel@tonic-gate * 0 if e1 "equals" e2 27940Sstevel@tonic-gate * > 0 if e1 comes after e2 27950Sstevel@tonic-gate */ 27960Sstevel@tonic-gate int 27970Sstevel@tonic-gate pool_elem_compare_name(const pool_elem_t *e1, const pool_elem_t *e2) 27980Sstevel@tonic-gate { 27990Sstevel@tonic-gate char *name1, *name2; 28000Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 28010Sstevel@tonic-gate int retval; 28020Sstevel@tonic-gate 28030Sstevel@tonic-gate /* 28040Sstevel@tonic-gate * We may be asked to compare two elements from different classes. 28050Sstevel@tonic-gate * They are different so return (1). 28060Sstevel@tonic-gate */ 28070Sstevel@tonic-gate if (pool_elem_same_class(e1, e2) != PO_TRUE) 28080Sstevel@tonic-gate return (1); 28090Sstevel@tonic-gate 28100Sstevel@tonic-gate /* 28110Sstevel@tonic-gate * If the class is PEC_SYSTEM, always match them 28120Sstevel@tonic-gate */ 28130Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_SYSTEM) 28140Sstevel@tonic-gate return (0); 28150Sstevel@tonic-gate 28160Sstevel@tonic-gate /* 28170Sstevel@tonic-gate * If we are going to compare components, then use sys_id 28180Sstevel@tonic-gate */ 28190Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_COMP) { 28200Sstevel@tonic-gate int64_t sys_id1, sys_id2; 28210Sstevel@tonic-gate 28220Sstevel@tonic-gate if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) { 28230Sstevel@tonic-gate return (-1); 28240Sstevel@tonic-gate } 28250Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id1); 28260Sstevel@tonic-gate if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) { 28270Sstevel@tonic-gate return (-1); 28280Sstevel@tonic-gate } 28290Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id2); 28300Sstevel@tonic-gate retval = (sys_id1 - sys_id2); 28310Sstevel@tonic-gate } else { 28320Sstevel@tonic-gate if (pool_get_ns_property(e1, "name", &val) == POC_INVAL) { 28330Sstevel@tonic-gate return (-1); 28340Sstevel@tonic-gate } 28350Sstevel@tonic-gate (void) pool_value_get_string(&val, (const char **)&name1); 28360Sstevel@tonic-gate if ((name1 = strdup(name1)) == NULL) { 28370Sstevel@tonic-gate return (-1); 28380Sstevel@tonic-gate } 28390Sstevel@tonic-gate 28400Sstevel@tonic-gate if (pool_get_ns_property(e2, "name", &val) == POC_INVAL) { 28410Sstevel@tonic-gate return (-1); 28420Sstevel@tonic-gate } 28430Sstevel@tonic-gate 28440Sstevel@tonic-gate (void) pool_value_get_string(&val, (const char **)&name2); 28450Sstevel@tonic-gate retval = strcmp(name1, name2); 28460Sstevel@tonic-gate free(name1); 28470Sstevel@tonic-gate } 28480Sstevel@tonic-gate return (retval); 28490Sstevel@tonic-gate } 28500Sstevel@tonic-gate 28510Sstevel@tonic-gate /* 28520Sstevel@tonic-gate * Compare two elements for purposes of ordering. 28530Sstevel@tonic-gate * Return: 28540Sstevel@tonic-gate * < 0 if e1 is "before" e2 28550Sstevel@tonic-gate * 0 if e1 "equals" e2 28560Sstevel@tonic-gate * > 0 if e1 comes after e2 28570Sstevel@tonic-gate */ 28580Sstevel@tonic-gate int 28590Sstevel@tonic-gate pool_elem_compare(const pool_elem_t *e1, const pool_elem_t *e2) 28600Sstevel@tonic-gate { 28610Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 28620Sstevel@tonic-gate int64_t sys_id1, sys_id2; 28630Sstevel@tonic-gate 28640Sstevel@tonic-gate /* 28650Sstevel@tonic-gate * We may be asked to compare two elements from different classes. 28660Sstevel@tonic-gate * They are different so return the difference in their classes 28670Sstevel@tonic-gate */ 28680Sstevel@tonic-gate if (pool_elem_same_class(e1, e2) != PO_TRUE) 28690Sstevel@tonic-gate return (1); 28700Sstevel@tonic-gate 28710Sstevel@tonic-gate /* 28720Sstevel@tonic-gate * If the class is PEC_SYSTEM, always match them 28730Sstevel@tonic-gate */ 28740Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_SYSTEM) 28750Sstevel@tonic-gate return (0); 28760Sstevel@tonic-gate 28770Sstevel@tonic-gate /* 28780Sstevel@tonic-gate * Compare with sys_id 28790Sstevel@tonic-gate */ 28800Sstevel@tonic-gate if (pool_get_ns_property(e1, c_sys_prop, &val) == POC_INVAL) { 28810Sstevel@tonic-gate assert(!"no sys_id on e1\n"); 28820Sstevel@tonic-gate } 28830Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id1); 28840Sstevel@tonic-gate if (pool_get_ns_property(e2, c_sys_prop, &val) == POC_INVAL) { 28850Sstevel@tonic-gate assert(!"no sys_id on e2\n"); 28860Sstevel@tonic-gate } 28870Sstevel@tonic-gate (void) pool_value_get_int64(&val, &sys_id2); 28880Sstevel@tonic-gate return (sys_id1 - sys_id2); 28890Sstevel@tonic-gate } 28900Sstevel@tonic-gate 28910Sstevel@tonic-gate /* 28920Sstevel@tonic-gate * Return PO_TRUE if the supplied elems are of the same class. 28930Sstevel@tonic-gate */ 28940Sstevel@tonic-gate int 28950Sstevel@tonic-gate pool_elem_same_class(const pool_elem_t *e1, const pool_elem_t *e2) 28960Sstevel@tonic-gate { 28970Sstevel@tonic-gate if (pool_elem_class(e1) != pool_elem_class(e2)) 28980Sstevel@tonic-gate return (PO_FALSE); 28990Sstevel@tonic-gate 29000Sstevel@tonic-gate /* 29010Sstevel@tonic-gate * Check to make sure the fundamental class of the elements match 29020Sstevel@tonic-gate */ 29030Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_RES_COMP || 29040Sstevel@tonic-gate pool_elem_class(e1) == PEC_RES_AGG) 29050Sstevel@tonic-gate if (pool_resource_elem_class(e1) != 29060Sstevel@tonic-gate pool_resource_elem_class(e2)) 29070Sstevel@tonic-gate return (PO_FALSE); 29080Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_COMP) 29090Sstevel@tonic-gate if (pool_component_elem_class(e1) != 29100Sstevel@tonic-gate pool_component_elem_class(e2)) 29110Sstevel@tonic-gate return (PO_FALSE); 29120Sstevel@tonic-gate return (PO_TRUE); 29130Sstevel@tonic-gate } 29140Sstevel@tonic-gate 29150Sstevel@tonic-gate /* 29160Sstevel@tonic-gate * pool_conf_check() checks that the configuration state isn't invalid 29170Sstevel@tonic-gate * and that the configuration was opened for modification. 29180Sstevel@tonic-gate */ 29190Sstevel@tonic-gate int 29200Sstevel@tonic-gate pool_conf_check(const pool_conf_t *conf) 29210Sstevel@tonic-gate { 29220Sstevel@tonic-gate if (pool_conf_status(conf) == POF_INVALID) { 29230Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 29240Sstevel@tonic-gate return (PO_FAIL); 29250Sstevel@tonic-gate } 29260Sstevel@tonic-gate 29270Sstevel@tonic-gate if ((conf->pc_prov->pc_oflags & PO_RDWR) == 0) { 29280Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 29290Sstevel@tonic-gate return (PO_FAIL); 29300Sstevel@tonic-gate } 29310Sstevel@tonic-gate return (PO_SUCCESS); 29320Sstevel@tonic-gate } 2933