17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f9e2a31fSsdussud * Common Development and Distribution License (the "License"). 6f9e2a31fSsdussud * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22f9e2a31fSsdussud * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * These functions implement the process of commitment for a pool 307c478bd9Sstevel@tonic-gate * configuration. This process can be described as taking instructions 317c478bd9Sstevel@tonic-gate * from a static configuration file and using the information about 327c478bd9Sstevel@tonic-gate * the target system contained in the dynamic configuration to make 337c478bd9Sstevel@tonic-gate * decisions about how best to allocate resources to meet the 347c478bd9Sstevel@tonic-gate * constraints specified in the static configuration file. 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * Mechanically, this process relies upon ordering the individual 377c478bd9Sstevel@tonic-gate * components of the file and stepping through the lists of components 387c478bd9Sstevel@tonic-gate * and taking actions depending on their type and which file they are 397c478bd9Sstevel@tonic-gate * part of. 407c478bd9Sstevel@tonic-gate * 417c478bd9Sstevel@tonic-gate * Configuration components can be broken down into different types 427c478bd9Sstevel@tonic-gate * which are then treated according to the following table: 437c478bd9Sstevel@tonic-gate * 447c478bd9Sstevel@tonic-gate * Element Type Action 457c478bd9Sstevel@tonic-gate * system || pool || 467c478bd9Sstevel@tonic-gate * res_comp || res_agg If the element is a required element, then create or 477c478bd9Sstevel@tonic-gate * update it (don't destroy required elements in the 487c478bd9Sstevel@tonic-gate * static configuration) otherwise manipulate the 497c478bd9Sstevel@tonic-gate * dynamic configuration to create, destroy or update 507c478bd9Sstevel@tonic-gate * the element on the system. 517c478bd9Sstevel@tonic-gate * comp Create, destroy or update the static configuration 527c478bd9Sstevel@tonic-gate * component. 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * The treatment of the different elements reflects the fact that all 557c478bd9Sstevel@tonic-gate * elements other than comp are configurable and thus libpool can 567c478bd9Sstevel@tonic-gate * create, destroy and modify these elements at will. comp elements 577c478bd9Sstevel@tonic-gate * reflect the disposition of the system, these elements can be moved 587c478bd9Sstevel@tonic-gate * around but they can't be created or destroyed in the dynamic 597c478bd9Sstevel@tonic-gate * configuration in the commit process. comp elements can be created 607c478bd9Sstevel@tonic-gate * and destroyed in the static configuration file as a result of a 617c478bd9Sstevel@tonic-gate * commit operation, since it's possible for a comp to not appear in 627c478bd9Sstevel@tonic-gate * the dynamic configuration. For instance, if the static 637c478bd9Sstevel@tonic-gate * configuration file was created on a different machine or after a DR 647c478bd9Sstevel@tonic-gate * operation which has removed or added components. 657c478bd9Sstevel@tonic-gate * 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate #include <assert.h> 687c478bd9Sstevel@tonic-gate #include <stdio.h> 697c478bd9Sstevel@tonic-gate #include <stdlib.h> 707c478bd9Sstevel@tonic-gate #include <sys/types.h> 717c478bd9Sstevel@tonic-gate #include <errno.h> 727c478bd9Sstevel@tonic-gate #include <string.h> 737c478bd9Sstevel@tonic-gate #include <limits.h> 747c478bd9Sstevel@tonic-gate #include <unistd.h> 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #include <pool.h> 777c478bd9Sstevel@tonic-gate #include "pool_internal.h" 787c478bd9Sstevel@tonic-gate #include "pool_impl.h" 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate #define MIN(x, y) ((x) < (y) ? (x) : (y)) 817c478bd9Sstevel@tonic-gate #define MAX(x, y) ((x) > (y) ? (x) : (y)) 827c478bd9Sstevel@tonic-gate #define POA_IMPORTANCE_NUM 0 837c478bd9Sstevel@tonic-gate #define POA_SURPLUS_TO_DEFAULT_NUM 1 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate /* 867c478bd9Sstevel@tonic-gate * This resource specific structure is used to determine allocation of resources 877c478bd9Sstevel@tonic-gate * during resource set allocation. Each set will receive its min, plus 887c478bd9Sstevel@tonic-gate * some number of dealt resources based on the global allocation policy. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate typedef struct res_info { 917c478bd9Sstevel@tonic-gate pool_resource_t *ri_res; /* Resource set */ 927c478bd9Sstevel@tonic-gate uint64_t ri_min; /* Resource set's low watermark */ 937c478bd9Sstevel@tonic-gate uint64_t ri_max; /* Resource set's high watermark */ 947c478bd9Sstevel@tonic-gate uint64_t ri_oldsize; /* Size of resource set at the start */ 957c478bd9Sstevel@tonic-gate uint64_t ri_newsize; /* New resource set size allocated */ 967c478bd9Sstevel@tonic-gate uint64_t ri_pinned; /* Count of pinned resources in set */ 977c478bd9Sstevel@tonic-gate uint64_t ri_dealt; /* Count of resources dealt to set */ 987c478bd9Sstevel@tonic-gate int64_t ri_transfer; /* oldsize - newsize */ 997c478bd9Sstevel@tonic-gate /* The signed quantity of resources */ 1007c478bd9Sstevel@tonic-gate /* to tranfer into or out of this */ 1017c478bd9Sstevel@tonic-gate /* resource set */ 1027c478bd9Sstevel@tonic-gate /* + transfer: tranfer resources out */ 1037c478bd9Sstevel@tonic-gate /* - transfer: tranfer resources in */ 1047c478bd9Sstevel@tonic-gate } res_info_t; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate /* 1077c478bd9Sstevel@tonic-gate * diff_and_fix operations 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate static int commit_create(pool_conf_t *, pool_elem_t **); 1107c478bd9Sstevel@tonic-gate static int commit_delete(pool_elem_t *); 1117c478bd9Sstevel@tonic-gate static int commit_update(pool_elem_t *, pool_elem_t *, int); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1147c478bd9Sstevel@tonic-gate * configuration commit processing 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate static int diff_and_fix(pool_conf_t *, pool_conf_t *); 1177c478bd9Sstevel@tonic-gate static int process_elem_lt(pool_elem_t *, pool_conf_t *); 1187c478bd9Sstevel@tonic-gate static int process_elem_gt(pool_elem_t *, pool_conf_t *, 1197c478bd9Sstevel@tonic-gate pool_conf_t *); 1207c478bd9Sstevel@tonic-gate static int process_lists(int, pool_conf_t *, 1217c478bd9Sstevel@tonic-gate pool_conf_t *, int); 1227c478bd9Sstevel@tonic-gate static pool_elem_t **get_elem_list(const pool_conf_t *, int, uint_t *); 1237c478bd9Sstevel@tonic-gate static int share_resources(pool_conf_t *); 1247c478bd9Sstevel@tonic-gate static int resource_allocate(const char *, pool_resource_t **, 1257c478bd9Sstevel@tonic-gate uint_t); 1267c478bd9Sstevel@tonic-gate static int resource_allocate_default(pool_resource_t **, uint_t); 1277c478bd9Sstevel@tonic-gate static int pset_allocate_imp(pool_resource_t **, uint_t); 1287c478bd9Sstevel@tonic-gate static int resource_compare_by_descending_importance(const void *, 1297c478bd9Sstevel@tonic-gate const void *); 1307c478bd9Sstevel@tonic-gate static int compute_size_to_transfer(const void *, const void *); 1317c478bd9Sstevel@tonic-gate static int set_importance_cb(pool_conf_t *, pool_t *, void *); 1327c478bd9Sstevel@tonic-gate static int unset_importance_cb(pool_conf_t *, pool_t *, void *); 1337c478bd9Sstevel@tonic-gate static int add_importance_props(pool_conf_t *); 1347c478bd9Sstevel@tonic-gate static int remove_importance_props(pool_conf_t *); 1357c478bd9Sstevel@tonic-gate static int clone_element(pool_conf_t *, pool_elem_t *, 1367c478bd9Sstevel@tonic-gate const char *, pool_value_t *, void *); 1377c478bd9Sstevel@tonic-gate static int clean_element(pool_conf_t *, pool_elem_t *, 1387c478bd9Sstevel@tonic-gate const char *, pool_value_t *, void *); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* 1417c478bd9Sstevel@tonic-gate * commit_create() is used to create a configuration element upon the 1427c478bd9Sstevel@tonic-gate * system. Since only pools and resource actually need to perform any 1437c478bd9Sstevel@tonic-gate * action, other elements are ignored as a no-op. 1447c478bd9Sstevel@tonic-gate */ 1457c478bd9Sstevel@tonic-gate static int 1467c478bd9Sstevel@tonic-gate commit_create(pool_conf_t *conf, pool_elem_t **e1) 1477c478bd9Sstevel@tonic-gate { 1487c478bd9Sstevel@tonic-gate pool_resource_t *res; 1497c478bd9Sstevel@tonic-gate pool_t *pool; 1507c478bd9Sstevel@tonic-gate const char *res_type; 1517c478bd9Sstevel@tonic-gate pool_elem_t *src = *e1; 1527c478bd9Sstevel@tonic-gate uint64_t smin, smax, dmax; 1537c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 1547c478bd9Sstevel@tonic-gate char *name; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate switch (pool_elem_class(src)) { 1577c478bd9Sstevel@tonic-gate case PEC_SYSTEM: /* NO-OP */ 1587c478bd9Sstevel@tonic-gate break; 1597c478bd9Sstevel@tonic-gate case PEC_POOL: 1607c478bd9Sstevel@tonic-gate name = elem_get_name(src); 1617c478bd9Sstevel@tonic-gate if ((pool = pool_create(conf, name)) == NULL) { 1627c478bd9Sstevel@tonic-gate free(name); 1637c478bd9Sstevel@tonic-gate return (PO_FAIL); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate free(name); 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * Now copy the properties from the original pool to the 1687c478bd9Sstevel@tonic-gate * new one 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(src), src, TO_ELEM(pool), 1717c478bd9Sstevel@tonic-gate clone_element) != PO_SUCCESS) 1727c478bd9Sstevel@tonic-gate return (PO_FAIL); 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * Add a pointer to the src element which can be 1757c478bd9Sstevel@tonic-gate * updated with a sys_id when the sys_id is allocated 1767c478bd9Sstevel@tonic-gate * to the created element. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate pool_set_pair(TO_ELEM(pool), src); 1797c478bd9Sstevel@tonic-gate *e1 = TO_ELEM(pool); 1807c478bd9Sstevel@tonic-gate break; 1817c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 1827c478bd9Sstevel@tonic-gate case PEC_RES_AGG: 1837c478bd9Sstevel@tonic-gate name = elem_get_name(src); 1847c478bd9Sstevel@tonic-gate res_type = pool_elem_class_string(src); 1857c478bd9Sstevel@tonic-gate if ((res = pool_resource_create(conf, res_type, name)) == 1867c478bd9Sstevel@tonic-gate NULL) { 1877c478bd9Sstevel@tonic-gate free(name); 1887c478bd9Sstevel@tonic-gate return (PO_FAIL); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate free(name); 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * Need to do some ordering of property updates. 1937c478bd9Sstevel@tonic-gate * Compare the values of source min/max and 1947c478bd9Sstevel@tonic-gate * destination min/max. If smin < dmax then update the 1957c478bd9Sstevel@tonic-gate * smin first, else update the max first. 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate if (resource_get_min(pool_elem_res(src), &smin) != PO_SUCCESS || 1987c478bd9Sstevel@tonic-gate resource_get_max(pool_elem_res(src), &smax) != PO_SUCCESS || 1997c478bd9Sstevel@tonic-gate resource_get_max(res, &dmax) != PO_SUCCESS) 2007c478bd9Sstevel@tonic-gate return (PO_FAIL); 2017c478bd9Sstevel@tonic-gate if (smin < dmax) { 2027c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, smin); 2037c478bd9Sstevel@tonic-gate if (pool_put_ns_property(TO_ELEM(res), c_min_prop, 2047c478bd9Sstevel@tonic-gate &val) != PO_SUCCESS) 2057c478bd9Sstevel@tonic-gate return (PO_FAIL); 2067c478bd9Sstevel@tonic-gate } else { 2077c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, smax); 2087c478bd9Sstevel@tonic-gate if (pool_put_ns_property(TO_ELEM(res), c_max_prop, 2097c478bd9Sstevel@tonic-gate &val) != PO_SUCCESS) 2107c478bd9Sstevel@tonic-gate return (PO_FAIL); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate /* 2137c478bd9Sstevel@tonic-gate * Now copy the properties from the original resource 2147c478bd9Sstevel@tonic-gate * to the new one 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(src), src, TO_ELEM(res), 2177c478bd9Sstevel@tonic-gate clone_element) != PO_SUCCESS) 2187c478bd9Sstevel@tonic-gate return (PO_FAIL); 2197c478bd9Sstevel@tonic-gate /* 2207c478bd9Sstevel@tonic-gate * Add a pointer to the src element which can be 2217c478bd9Sstevel@tonic-gate * updated with a sys_id when the sys_id is allocated 2227c478bd9Sstevel@tonic-gate * to the created element. 2237c478bd9Sstevel@tonic-gate */ 2247c478bd9Sstevel@tonic-gate pool_set_pair(TO_ELEM(res), src); 2257c478bd9Sstevel@tonic-gate *e1 = TO_ELEM(res); 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate case PEC_COMP: /* NO-OP */ 2287c478bd9Sstevel@tonic-gate break; 2297c478bd9Sstevel@tonic-gate default: 2307c478bd9Sstevel@tonic-gate return (PO_FAIL); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * commit_delete() is used to delete a configuration element upon the 2387c478bd9Sstevel@tonic-gate * system. Since only pools and resources actually need to perform 2397c478bd9Sstevel@tonic-gate * any action, other elements are ignored as a no-op. 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate static int 2427c478bd9Sstevel@tonic-gate commit_delete(pool_elem_t *pe) 2437c478bd9Sstevel@tonic-gate { 2447c478bd9Sstevel@tonic-gate pool_resource_t *res; 2457c478bd9Sstevel@tonic-gate pool_t *pool; 2467c478bd9Sstevel@tonic-gate int ret = 0; 2477c478bd9Sstevel@tonic-gate 248*0209230bSgjelinek if (elem_is_tmp(pe)) 249*0209230bSgjelinek return (PO_SUCCESS); 250*0209230bSgjelinek 2517c478bd9Sstevel@tonic-gate switch (pool_elem_class(pe)) { 2527c478bd9Sstevel@tonic-gate case PEC_SYSTEM: /* NO-OP */ 2537c478bd9Sstevel@tonic-gate break; 2547c478bd9Sstevel@tonic-gate case PEC_POOL: 2557c478bd9Sstevel@tonic-gate pool = pool_elem_pool(pe); 2567c478bd9Sstevel@tonic-gate ret = pool_destroy(TO_CONF(pe), pool); 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 2597c478bd9Sstevel@tonic-gate case PEC_RES_AGG: 2607c478bd9Sstevel@tonic-gate res = pool_elem_res(pe); 2617c478bd9Sstevel@tonic-gate ret = pool_resource_destroy(TO_CONF(pe), res); 2627c478bd9Sstevel@tonic-gate break; 2637c478bd9Sstevel@tonic-gate case PEC_COMP: /* NO-OP */ 2647c478bd9Sstevel@tonic-gate break; 2657c478bd9Sstevel@tonic-gate default: 2667c478bd9Sstevel@tonic-gate return (PO_FAIL); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate return (ret); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate /* 2727c478bd9Sstevel@tonic-gate * commit_update() is used to update a configuration element upon the 2737c478bd9Sstevel@tonic-gate * system or in a static configuration file. The pass parameter 2747c478bd9Sstevel@tonic-gate * governs whether properties are being updated or associations. In 2757c478bd9Sstevel@tonic-gate * pass 0, properties are updated. If the element is of class 2767c478bd9Sstevel@tonic-gate * PEC_COMP, then make sure that the element in the static 2777c478bd9Sstevel@tonic-gate * configuration file is correctly located before proceeding with the 2787c478bd9Sstevel@tonic-gate * update. Then, the element in the dynamic configuration file is 2797c478bd9Sstevel@tonic-gate * updated. In pass 1, ie. pass != 0, any pool components have their 2807c478bd9Sstevel@tonic-gate * associations updated in the dynamic configuration. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate static int 2837c478bd9Sstevel@tonic-gate commit_update(pool_elem_t *e1, pool_elem_t *e2, int pass) 2847c478bd9Sstevel@tonic-gate { 2857c478bd9Sstevel@tonic-gate if (pass == 0) { 2867c478bd9Sstevel@tonic-gate pool_resource_t *res1; 2877c478bd9Sstevel@tonic-gate pool_resource_t *res2; 2887c478bd9Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_COMP) { 2897c478bd9Sstevel@tonic-gate res1 = pool_get_owning_resource(TO_CONF(e1), 2907c478bd9Sstevel@tonic-gate pool_elem_comp(e1)); 2917c478bd9Sstevel@tonic-gate res2 = pool_get_owning_resource(TO_CONF(e2), 2927c478bd9Sstevel@tonic-gate pool_elem_comp(e2)); 2937c478bd9Sstevel@tonic-gate if (pool_elem_compare_name(TO_ELEM(res1), 2947c478bd9Sstevel@tonic-gate TO_ELEM(res2)) != 0) { 2957c478bd9Sstevel@tonic-gate char *name; 2967c478bd9Sstevel@tonic-gate const pool_resource_t *newres; 2977c478bd9Sstevel@tonic-gate pool_component_t *comps[2] = { NULL }; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate comps[0] = pool_elem_comp(e2); 300f9e2a31fSsdussud name = elem_get_name(TO_ELEM(res1)); 3017c478bd9Sstevel@tonic-gate newres = pool_get_resource(TO_CONF(e2), 3027c478bd9Sstevel@tonic-gate pool_elem_class_string(TO_ELEM(res1)), 3037c478bd9Sstevel@tonic-gate name); 3047c478bd9Sstevel@tonic-gate free(name); 3057c478bd9Sstevel@tonic-gate assert(newres); 3067c478bd9Sstevel@tonic-gate #ifdef DEBUG 3077c478bd9Sstevel@tonic-gate dprintf("transferring: res, comp\n"); 3087c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(newres)); 3097c478bd9Sstevel@tonic-gate pool_elem_dprintf(e2); 3107c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3117c478bd9Sstevel@tonic-gate (void) pool_resource_xtransfer(TO_CONF(e2), 3127c478bd9Sstevel@tonic-gate res2, (pool_resource_t *)newres, comps); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(e2), e2, NULL, 3167c478bd9Sstevel@tonic-gate clean_element) != PO_SUCCESS) { 3177c478bd9Sstevel@tonic-gate return (PO_FAIL); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate /* 3207c478bd9Sstevel@tonic-gate * Need to do some ordering of property updates if the 3217c478bd9Sstevel@tonic-gate * element to be updated is a resource. Compare the 3227c478bd9Sstevel@tonic-gate * values of source min/max and destination 3237c478bd9Sstevel@tonic-gate * min/max. If smin < dmax then update the smin first, 3247c478bd9Sstevel@tonic-gate * else update the max first. 3257c478bd9Sstevel@tonic-gate */ 3267c478bd9Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_RES_COMP || 3277c478bd9Sstevel@tonic-gate pool_elem_class(e1) == PEC_RES_AGG) { 3287c478bd9Sstevel@tonic-gate uint64_t smin, smax, dmax; 3297c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate if (resource_get_min(pool_elem_res(e1), &smin) != 3327c478bd9Sstevel@tonic-gate PO_SUCCESS || 3337c478bd9Sstevel@tonic-gate resource_get_max(pool_elem_res(e1), &smax) != 3347c478bd9Sstevel@tonic-gate PO_SUCCESS || 3357c478bd9Sstevel@tonic-gate resource_get_max(pool_elem_res(e2), &dmax) != 3367c478bd9Sstevel@tonic-gate PO_SUCCESS) 3377c478bd9Sstevel@tonic-gate return (PO_FAIL); 3387c478bd9Sstevel@tonic-gate if (smin < dmax) { 3397c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, smin); 3407c478bd9Sstevel@tonic-gate if (pool_put_ns_property(e2, c_min_prop, 3417c478bd9Sstevel@tonic-gate &val) != PO_SUCCESS) 3427c478bd9Sstevel@tonic-gate return (PO_FAIL); 3437c478bd9Sstevel@tonic-gate } else { 3447c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, smax); 3457c478bd9Sstevel@tonic-gate if (pool_put_ns_property(e2, c_max_prop, 3467c478bd9Sstevel@tonic-gate &val) != PO_SUCCESS) 3477c478bd9Sstevel@tonic-gate return (PO_FAIL); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate /* 3517c478bd9Sstevel@tonic-gate * This next couple of steps needs some 3527c478bd9Sstevel@tonic-gate * explanation. The first walk, copies all the 3537c478bd9Sstevel@tonic-gate * properties that are writeable from the static 3547c478bd9Sstevel@tonic-gate * configuration to the dynamic configuration. The 3557c478bd9Sstevel@tonic-gate * second walk copies all properties (writeable or 3567c478bd9Sstevel@tonic-gate * not) from the dynamic configuration element back to 3577c478bd9Sstevel@tonic-gate * the static configuration element. This ensures that 3587c478bd9Sstevel@tonic-gate * updates from the static configuration element are 3597c478bd9Sstevel@tonic-gate * correctly applied to the dynamic configuration and 3607c478bd9Sstevel@tonic-gate * then the static configuration element is updated 3617c478bd9Sstevel@tonic-gate * with the latest values of the read-only xproperties 3627c478bd9Sstevel@tonic-gate * from the dynamic configuration element. The 3637c478bd9Sstevel@tonic-gate * enforcing of permisssions is performed in 3647c478bd9Sstevel@tonic-gate * clone_element by its choice of property 3657c478bd9Sstevel@tonic-gate * manipulation function. 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(e1), e1, e2, clone_element) != 3687c478bd9Sstevel@tonic-gate PO_SUCCESS) { 3697c478bd9Sstevel@tonic-gate return (PO_FAIL); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(e2), e2, e1, clone_element) != 3727c478bd9Sstevel@tonic-gate PO_SUCCESS) { 3737c478bd9Sstevel@tonic-gate return (PO_FAIL); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate } else { 3767c478bd9Sstevel@tonic-gate if (pool_elem_class(e1) == PEC_POOL) { 3777c478bd9Sstevel@tonic-gate pool_resource_t **rs; 3787c478bd9Sstevel@tonic-gate uint_t nelem; 3797c478bd9Sstevel@tonic-gate int i; 3807c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 3817c478bd9Sstevel@tonic-gate pool_value_t *pvals[] = { NULL, NULL }; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate pvals[0] = &val; 3847c478bd9Sstevel@tonic-gate if (pool_value_set_string(&val, "pset") != PO_SUCCESS || 3857c478bd9Sstevel@tonic-gate pool_value_set_name(&val, c_type) != PO_SUCCESS) 3867c478bd9Sstevel@tonic-gate return (PO_FAIL); 3877c478bd9Sstevel@tonic-gate if ((rs = pool_query_pool_resources(TO_CONF(e1), 3887c478bd9Sstevel@tonic-gate pool_elem_pool(e1), &nelem, pvals)) != NULL) { 3897c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 3907c478bd9Sstevel@tonic-gate const pool_resource_t *tgt_res; 3917c478bd9Sstevel@tonic-gate char *res_name = 3927c478bd9Sstevel@tonic-gate elem_get_name(TO_ELEM(rs[i])); 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate if ((tgt_res = pool_get_resource( 3957c478bd9Sstevel@tonic-gate TO_CONF(e2), pool_elem_class_string( 3967c478bd9Sstevel@tonic-gate TO_ELEM(rs[i])), res_name)) == 3977c478bd9Sstevel@tonic-gate NULL) { 3987c478bd9Sstevel@tonic-gate tgt_res = get_default_resource( 3997c478bd9Sstevel@tonic-gate rs[i]); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate free(res_name); 4027c478bd9Sstevel@tonic-gate if (pool_associate(TO_CONF(e2), 4037c478bd9Sstevel@tonic-gate pool_elem_pool(e2), tgt_res) != 4047c478bd9Sstevel@tonic-gate PO_SUCCESS) { 4057c478bd9Sstevel@tonic-gate free(rs); 4067c478bd9Sstevel@tonic-gate return (PO_FAIL); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate free(rs); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * diff_and_fix() works out the differences between two configurations 4187c478bd9Sstevel@tonic-gate * and modifies the state of the system to match the operations 4197c478bd9Sstevel@tonic-gate * required to bring the two configurations into sync. 4207c478bd9Sstevel@tonic-gate * 4217c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL. 4227c478bd9Sstevel@tonic-gate */ 4237c478bd9Sstevel@tonic-gate static int 4247c478bd9Sstevel@tonic-gate diff_and_fix(pool_conf_t *stc, pool_conf_t *dyn) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate /* 4277c478bd9Sstevel@tonic-gate * The ordering of the operations is significant, we must 4287c478bd9Sstevel@tonic-gate * process the system element, then the pools elements, then 4297c478bd9Sstevel@tonic-gate * the resource elements, then the pools elements again and 4307c478bd9Sstevel@tonic-gate * finally the resource components. 4317c478bd9Sstevel@tonic-gate * 4327c478bd9Sstevel@tonic-gate * TODO 4337c478bd9Sstevel@tonic-gate * PEC_RES_COMP are the only type of resources 4347c478bd9Sstevel@tonic-gate * currently. When PEC_RES_AGG resources are added they must 4357c478bd9Sstevel@tonic-gate * also be processed. 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate if (process_lists(PEC_SYSTEM, stc, dyn, 0) != PO_SUCCESS) { 4387c478bd9Sstevel@tonic-gate return (PO_FAIL); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate if (process_lists(PEC_POOL, stc, dyn, 0) != PO_SUCCESS) { 4417c478bd9Sstevel@tonic-gate return (PO_FAIL); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate if (process_lists(PEC_RES_COMP, stc, dyn, 0) != PO_SUCCESS) { 4447c478bd9Sstevel@tonic-gate return (PO_FAIL); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate if (process_lists(PEC_COMP, stc, dyn, 0) != PO_SUCCESS) { 4477c478bd9Sstevel@tonic-gate return (PO_FAIL); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate if (process_lists(PEC_POOL, stc, dyn, 1) != PO_SUCCESS) { 4507c478bd9Sstevel@tonic-gate return (PO_FAIL); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate /* 4537c478bd9Sstevel@tonic-gate * Share the resources. It has to be called for both 4547c478bd9Sstevel@tonic-gate * configurations to ensure that the configurations still look 4557c478bd9Sstevel@tonic-gate * the same. 4567c478bd9Sstevel@tonic-gate */ 4577c478bd9Sstevel@tonic-gate if (share_resources(dyn) != PO_SUCCESS) { 4587c478bd9Sstevel@tonic-gate return (PO_FAIL); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate if (share_resources(stc) != PO_SUCCESS) { 4617c478bd9Sstevel@tonic-gate return (PO_FAIL); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate static int 4677c478bd9Sstevel@tonic-gate process_elem_lt(pool_elem_t *pe, pool_conf_t *dyn) 4687c478bd9Sstevel@tonic-gate { 4697c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_COMP) { 4707c478bd9Sstevel@tonic-gate if (pool_component_destroy(pool_elem_comp(pe)) == PO_FAIL) { 4717c478bd9Sstevel@tonic-gate return (PO_FAIL); 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate } else if (! elem_is_default(pe)) { 4747c478bd9Sstevel@tonic-gate if (commit_create(dyn, &pe) != PO_SUCCESS) { 4757c478bd9Sstevel@tonic-gate return (PO_FAIL); 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate static int 4827c478bd9Sstevel@tonic-gate process_elem_gt(pool_elem_t *pe, pool_conf_t *stc, pool_conf_t *dyn) 4837c478bd9Sstevel@tonic-gate { 4847c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_COMP) { 4857c478bd9Sstevel@tonic-gate pool_resource_t *owner; 4867c478bd9Sstevel@tonic-gate const pool_resource_t *parent_res; 4877c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 4887c478bd9Sstevel@tonic-gate const pool_component_t *newcomp; 4897c478bd9Sstevel@tonic-gate const char *resname; 4907c478bd9Sstevel@tonic-gate const char *restype; 4917c478bd9Sstevel@tonic-gate /* 4927c478bd9Sstevel@tonic-gate * I have to find the right parent in the static 4937c478bd9Sstevel@tonic-gate * configuration. It may not exist, in which case it's 4947c478bd9Sstevel@tonic-gate * correct to put it in the default 4957c478bd9Sstevel@tonic-gate */ 4967c478bd9Sstevel@tonic-gate owner = pool_get_owning_resource(dyn, 4977c478bd9Sstevel@tonic-gate pool_elem_comp(pe)); 4987c478bd9Sstevel@tonic-gate if (pool_get_ns_property(TO_ELEM(owner), "name", &val) == 4997c478bd9Sstevel@tonic-gate POC_INVAL) 5007c478bd9Sstevel@tonic-gate return (PO_FAIL); 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate if (pool_value_get_string(&val, &resname) == PO_FAIL) 5037c478bd9Sstevel@tonic-gate return (PO_FAIL); 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate if ((resname = strdup(resname)) == NULL) 5067c478bd9Sstevel@tonic-gate return (PO_FAIL); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate restype = pool_elem_class_string(TO_ELEM(owner)); 5097c478bd9Sstevel@tonic-gate parent_res = pool_get_resource(stc, restype, resname); 5107c478bd9Sstevel@tonic-gate free((void *)resname); 5117c478bd9Sstevel@tonic-gate if (parent_res == NULL) 5127c478bd9Sstevel@tonic-gate parent_res = resource_by_sysid(stc, PS_NONE, restype); 5137c478bd9Sstevel@tonic-gate /* 5147c478bd9Sstevel@tonic-gate * Now need to make a copy of the component in the 5157c478bd9Sstevel@tonic-gate * dynamic configuration in the static configuration. 5167c478bd9Sstevel@tonic-gate */ 5177c478bd9Sstevel@tonic-gate if ((newcomp = pool_component_create(stc, parent_res, 5187c478bd9Sstevel@tonic-gate elem_get_sysid(pe))) == NULL) 5197c478bd9Sstevel@tonic-gate return (PO_FAIL); 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(pe), pe, TO_ELEM(newcomp), 5227c478bd9Sstevel@tonic-gate clone_element) != PO_SUCCESS) 5237c478bd9Sstevel@tonic-gate return (PO_FAIL); 5247c478bd9Sstevel@tonic-gate } else if (elem_is_default(pe)) { 5257c478bd9Sstevel@tonic-gate pool_resource_t *newres; 5267c478bd9Sstevel@tonic-gate pool_t *newpool; 5277c478bd9Sstevel@tonic-gate char *name; 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate if ((name = elem_get_name(pe)) == NULL) 5307c478bd9Sstevel@tonic-gate return (PO_FAIL); 5317c478bd9Sstevel@tonic-gate switch (pool_elem_class(pe)) { 5327c478bd9Sstevel@tonic-gate case PEC_POOL: 5337c478bd9Sstevel@tonic-gate if ((newpool = pool_create(stc, name)) == NULL) { 5347c478bd9Sstevel@tonic-gate free(name); 5357c478bd9Sstevel@tonic-gate return (PO_FAIL); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate free(name); 5387c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(pe), pe, 5397c478bd9Sstevel@tonic-gate TO_ELEM(newpool), clone_element) != PO_SUCCESS) 5407c478bd9Sstevel@tonic-gate return (PO_FAIL); 5417c478bd9Sstevel@tonic-gate break; 5427c478bd9Sstevel@tonic-gate case PEC_RES_AGG: 5437c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 5447c478bd9Sstevel@tonic-gate if ((newres = pool_resource_create(stc, 5457c478bd9Sstevel@tonic-gate pool_elem_class_string(pe), name)) == 5467c478bd9Sstevel@tonic-gate NULL) { 5477c478bd9Sstevel@tonic-gate free(name); 5487c478bd9Sstevel@tonic-gate return (PO_FAIL); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate free(name); 5517c478bd9Sstevel@tonic-gate if (pool_walk_properties(TO_CONF(pe), pe, 5527c478bd9Sstevel@tonic-gate TO_ELEM(newres), clone_element) != PO_SUCCESS) 5537c478bd9Sstevel@tonic-gate return (PO_FAIL); 5547c478bd9Sstevel@tonic-gate break; 5557c478bd9Sstevel@tonic-gate default: 5567c478bd9Sstevel@tonic-gate free(name); 5577c478bd9Sstevel@tonic-gate break; 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate } else { 5607c478bd9Sstevel@tonic-gate if (commit_delete(pe) != PO_SUCCESS) 5617c478bd9Sstevel@tonic-gate return (PO_FAIL); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate /* 5677c478bd9Sstevel@tonic-gate * This function compares the elements of the supplied type in the 5687c478bd9Sstevel@tonic-gate * static and dynamic configurations supplied. The lists of elements 5697c478bd9Sstevel@tonic-gate * are compared and used to create, delete and updated elements in 5707c478bd9Sstevel@tonic-gate * both the static and dynamic configurations. The pass parameter is 5717c478bd9Sstevel@tonic-gate * used to indicate to commit_update() whether property updates or 5727c478bd9Sstevel@tonic-gate * association updates should be performed. 5737c478bd9Sstevel@tonic-gate */ 5747c478bd9Sstevel@tonic-gate static int 5757c478bd9Sstevel@tonic-gate process_lists(int type, pool_conf_t *stc, pool_conf_t *dyn, int pass) 5767c478bd9Sstevel@tonic-gate { 5777c478bd9Sstevel@tonic-gate uint_t stc_nelem = 0, dyn_nelem = 0; 5787c478bd9Sstevel@tonic-gate pool_elem_t **stc_elems, **dyn_elems; 5797c478bd9Sstevel@tonic-gate int i, j; 5807c478bd9Sstevel@tonic-gate int status = PO_SUCCESS; 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate if ((stc_elems = get_elem_list(stc, type, &stc_nelem)) == NULL) 5837c478bd9Sstevel@tonic-gate return (PO_FAIL); 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate qsort(stc_elems, stc_nelem, sizeof (pool_elem_t *), 5867c478bd9Sstevel@tonic-gate qsort_elem_compare); 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate if ((dyn_elems = get_elem_list(dyn, type, &dyn_nelem)) == NULL) { 5897c478bd9Sstevel@tonic-gate free(stc_elems); 5907c478bd9Sstevel@tonic-gate return (PO_FAIL); 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate qsort(dyn_elems, dyn_nelem, sizeof (pool_elem_t *), 5947c478bd9Sstevel@tonic-gate qsort_elem_compare); 5957c478bd9Sstevel@tonic-gate /* 5967c478bd9Sstevel@tonic-gate * Step through and do the updating, remember that we are 5977c478bd9Sstevel@tonic-gate * comparing using the compare function for the configuration 5987c478bd9Sstevel@tonic-gate * and that is fixed. 5997c478bd9Sstevel@tonic-gate */ 6007c478bd9Sstevel@tonic-gate i = j = 0; 6017c478bd9Sstevel@tonic-gate while (status == PO_SUCCESS && i < stc_nelem && j < dyn_nelem) { 6027c478bd9Sstevel@tonic-gate int compare; 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * We are going to do this by stepping through the static 6057c478bd9Sstevel@tonic-gate * list first. 6067c478bd9Sstevel@tonic-gate */ 6077c478bd9Sstevel@tonic-gate if (elem_is_default(stc_elems[i]) && 6087c478bd9Sstevel@tonic-gate elem_is_default(dyn_elems[j])) 6097c478bd9Sstevel@tonic-gate compare = 0; 6107c478bd9Sstevel@tonic-gate else 6117c478bd9Sstevel@tonic-gate compare = pool_elem_compare_name(stc_elems[i], 6127c478bd9Sstevel@tonic-gate dyn_elems[j]); 6137c478bd9Sstevel@tonic-gate if (compare < 0) { 6147c478bd9Sstevel@tonic-gate status = process_elem_lt(stc_elems[i], dyn); 6157c478bd9Sstevel@tonic-gate i++; 6167c478bd9Sstevel@tonic-gate } else if (compare > 0) { 6177c478bd9Sstevel@tonic-gate status = process_elem_gt(dyn_elems[j], stc, dyn); 6187c478bd9Sstevel@tonic-gate j++; 6197c478bd9Sstevel@tonic-gate } else { /* compare == 0 */ 6207c478bd9Sstevel@tonic-gate if (commit_update(stc_elems[i], dyn_elems[j], pass) 6217c478bd9Sstevel@tonic-gate != PO_SUCCESS) { 6227c478bd9Sstevel@tonic-gate status = PO_FAIL; 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate i++; 6257c478bd9Sstevel@tonic-gate j++; 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate if (status == PO_FAIL) { 6297c478bd9Sstevel@tonic-gate free(stc_elems); 6307c478bd9Sstevel@tonic-gate free(dyn_elems); 6317c478bd9Sstevel@tonic-gate return (PO_FAIL); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate while (status == PO_SUCCESS && i < stc_nelem) { 6347c478bd9Sstevel@tonic-gate status = process_elem_lt(stc_elems[i], dyn); 6357c478bd9Sstevel@tonic-gate i++; 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate if (status == PO_FAIL) { 6387c478bd9Sstevel@tonic-gate free(stc_elems); 6397c478bd9Sstevel@tonic-gate free(dyn_elems); 6407c478bd9Sstevel@tonic-gate return (PO_FAIL); 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate while (status == PO_SUCCESS && j < dyn_nelem) { 6437c478bd9Sstevel@tonic-gate status = process_elem_gt(dyn_elems[j], stc, dyn); 6447c478bd9Sstevel@tonic-gate j++; 6457c478bd9Sstevel@tonic-gate } 6467c478bd9Sstevel@tonic-gate free(stc_elems); 6477c478bd9Sstevel@tonic-gate free(dyn_elems); 6487c478bd9Sstevel@tonic-gate return (status); 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * get_elem_list() returns a list of pool_elem_t's. The size of the 6537c478bd9Sstevel@tonic-gate * list is written into nelem. The list contains elements of all types 6547c478bd9Sstevel@tonic-gate * that pools is interested in: i.e. system, pool, resources and 6557c478bd9Sstevel@tonic-gate * resource components. It is the caller's responsibility to free the 6567c478bd9Sstevel@tonic-gate * list when it is finished with. 6577c478bd9Sstevel@tonic-gate * 6587c478bd9Sstevel@tonic-gate * The array of pointers returned by the type specific query can be 6597c478bd9Sstevel@tonic-gate * safely cast to be an array of pool_elem_t pointers. In the case of 6607c478bd9Sstevel@tonic-gate * PEC_RES_COMP some additional processing is required to qualify the 6617c478bd9Sstevel@tonic-gate * list of elements. 6627c478bd9Sstevel@tonic-gate * 6637c478bd9Sstevel@tonic-gate * Returns a pointer to a list of pool_elem_t's or NULL on failure. 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate static pool_elem_t ** 6667c478bd9Sstevel@tonic-gate get_elem_list(const pool_conf_t *conf, int type, uint_t *nelem) 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate pool_resource_t **rl; 6697c478bd9Sstevel@tonic-gate pool_t **pl; 6707c478bd9Sstevel@tonic-gate pool_component_t **cl; 6717c478bd9Sstevel@tonic-gate pool_elem_t **elems = NULL; 6727c478bd9Sstevel@tonic-gate int i; 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate switch (type) { 6757c478bd9Sstevel@tonic-gate case PEC_SYSTEM: 6767c478bd9Sstevel@tonic-gate if ((elems = malloc(sizeof (pool_elem_t *))) == NULL) 6777c478bd9Sstevel@tonic-gate return (NULL); 6787c478bd9Sstevel@tonic-gate *nelem = 1; 6797c478bd9Sstevel@tonic-gate elems[0] = pool_conf_to_elem(conf); 6807c478bd9Sstevel@tonic-gate break; 6817c478bd9Sstevel@tonic-gate case PEC_POOL: 6827c478bd9Sstevel@tonic-gate if ((pl = pool_query_pools(conf, nelem, NULL)) != NULL) { 6837c478bd9Sstevel@tonic-gate elems = (pool_elem_t **)pl; 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate break; 6867c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 6877c478bd9Sstevel@tonic-gate if ((rl = pool_query_resources(conf, nelem, NULL)) != NULL) { 6887c478bd9Sstevel@tonic-gate int j = 0; 6897c478bd9Sstevel@tonic-gate elems = (pool_elem_t **)rl; 6907c478bd9Sstevel@tonic-gate for (i = 0; i < *nelem; i++) { 6917c478bd9Sstevel@tonic-gate if (pool_elem_class(TO_ELEM(rl[i])) == 6927c478bd9Sstevel@tonic-gate PEC_RES_COMP) 6937c478bd9Sstevel@tonic-gate elems[j++] = TO_ELEM(rl[i]); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate *nelem = j; 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate break; 6987c478bd9Sstevel@tonic-gate case PEC_COMP: 6997c478bd9Sstevel@tonic-gate if ((cl = pool_query_components(conf, nelem, NULL)) != NULL) { 7007c478bd9Sstevel@tonic-gate elems = (pool_elem_t **)cl; 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate break; 7037c478bd9Sstevel@tonic-gate default: 7047c478bd9Sstevel@tonic-gate abort(); 7057c478bd9Sstevel@tonic-gate break; 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate return (elems); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate /* 7117c478bd9Sstevel@tonic-gate * share_resources() sets up the allocation of resources by each 7127c478bd9Sstevel@tonic-gate * provider. Firstly all resources are updated with the importance of 7137c478bd9Sstevel@tonic-gate * each pool, then each resource provider is invoked in turn with a 7147c478bd9Sstevel@tonic-gate * list of it's own resources. Finally, the pool importance details 7157c478bd9Sstevel@tonic-gate * are removed from the resources. 7167c478bd9Sstevel@tonic-gate * 7177c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 7187c478bd9Sstevel@tonic-gate */ 7197c478bd9Sstevel@tonic-gate static int 7207c478bd9Sstevel@tonic-gate share_resources(pool_conf_t *conf) 7217c478bd9Sstevel@tonic-gate { 7227c478bd9Sstevel@tonic-gate pool_resource_t **resources; 7237c478bd9Sstevel@tonic-gate uint_t nelem; 7247c478bd9Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL }; 7257c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate props[0] = &val; 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate /* 7307c478bd9Sstevel@tonic-gate * Call an allocation function for each type of supported resource. 7317c478bd9Sstevel@tonic-gate * This function is responsible for "sharing" resources to resource 7327c478bd9Sstevel@tonic-gate * sets as determined by the system.allocate-method. 7337c478bd9Sstevel@tonic-gate */ 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate if (pool_value_set_string(props[0], "pset") != PO_SUCCESS || 7367c478bd9Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS) 7377c478bd9Sstevel@tonic-gate return (PO_FAIL); 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate if (add_importance_props(conf) != PO_SUCCESS) { 7407c478bd9Sstevel@tonic-gate (void) remove_importance_props(conf); 7417c478bd9Sstevel@tonic-gate return (PO_FAIL); 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate if ((resources = pool_query_resources(conf, &nelem, props)) != NULL) { 7457c478bd9Sstevel@tonic-gate /* 7467c478bd9Sstevel@tonic-gate * 'pool.importance' defines the importance of a pool; 7477c478bd9Sstevel@tonic-gate * resources inherit the importance of the pool that 7487c478bd9Sstevel@tonic-gate * is associated with them. If more than one pool is 7497c478bd9Sstevel@tonic-gate * associated with a resource, the importance of the 7507c478bd9Sstevel@tonic-gate * resource is the maximum importance of all 7517c478bd9Sstevel@tonic-gate * associated pools. Use '_importance' on resources 7527c478bd9Sstevel@tonic-gate * to determine who gets extra. 7537c478bd9Sstevel@tonic-gate */ 7547c478bd9Sstevel@tonic-gate if (resource_allocate("pset", resources, nelem) != PO_SUCCESS) { 7557c478bd9Sstevel@tonic-gate free(resources); 7567c478bd9Sstevel@tonic-gate (void) remove_importance_props(conf); 7577c478bd9Sstevel@tonic-gate return (PO_FAIL); 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate free(resources); 7617c478bd9Sstevel@tonic-gate (void) remove_importance_props(conf); 7627c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate /* 7677c478bd9Sstevel@tonic-gate * Work out which allocation method to use based on the value of the 7687c478bd9Sstevel@tonic-gate * system.allocate-method property. 7697c478bd9Sstevel@tonic-gate */ 7707c478bd9Sstevel@tonic-gate int 7717c478bd9Sstevel@tonic-gate resource_allocate(const char *type, pool_resource_t **res, uint_t nelem) 7727c478bd9Sstevel@tonic-gate { 7737c478bd9Sstevel@tonic-gate pool_elem_t *pe; 7747c478bd9Sstevel@tonic-gate const char *method_name; 7757c478bd9Sstevel@tonic-gate uint64_t method; 7767c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 7777c478bd9Sstevel@tonic-gate int ret; 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate pe = pool_conf_to_elem(TO_CONF(TO_ELEM(res[0]))); 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate if (pool_get_ns_property(pe, "allocate-method", &val) != POC_STRING) 7827c478bd9Sstevel@tonic-gate method_name = POA_IMPORTANCE; 7837c478bd9Sstevel@tonic-gate else { 7847c478bd9Sstevel@tonic-gate (void) pool_value_get_string(&val, &method_name); 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate if (strcmp(POA_IMPORTANCE, method_name) != 0) { 7877c478bd9Sstevel@tonic-gate if (strcmp(POA_SURPLUS_TO_DEFAULT, method_name) != 0) { 7887c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 7897c478bd9Sstevel@tonic-gate return (PO_FAIL); 7907c478bd9Sstevel@tonic-gate } else { 7917c478bd9Sstevel@tonic-gate method = POA_SURPLUS_TO_DEFAULT_NUM; 7927c478bd9Sstevel@tonic-gate } 7937c478bd9Sstevel@tonic-gate } else { 7947c478bd9Sstevel@tonic-gate method = POA_IMPORTANCE_NUM; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate switch (method) { 7977c478bd9Sstevel@tonic-gate case POA_IMPORTANCE_NUM: 7987c478bd9Sstevel@tonic-gate /* 7997c478bd9Sstevel@tonic-gate * TODO: Add support for new resource types 8007c478bd9Sstevel@tonic-gate */ 8017c478bd9Sstevel@tonic-gate switch (pool_resource_elem_class_from_string(type)) { 8027c478bd9Sstevel@tonic-gate case PREC_PSET: 8037c478bd9Sstevel@tonic-gate ret = pset_allocate_imp(res, nelem); 8047c478bd9Sstevel@tonic-gate break; 8057c478bd9Sstevel@tonic-gate default: 8067c478bd9Sstevel@tonic-gate ret = PO_FAIL; 8077c478bd9Sstevel@tonic-gate break; 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate break; 8107c478bd9Sstevel@tonic-gate case POA_SURPLUS_TO_DEFAULT_NUM: 8117c478bd9Sstevel@tonic-gate ret = resource_allocate_default(res, nelem); 8127c478bd9Sstevel@tonic-gate break; 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate return (ret); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* 8197c478bd9Sstevel@tonic-gate * Each set will get its minimum, however if there is more than the 8207c478bd9Sstevel@tonic-gate * total minimum available, then leave this in the default set. 8217c478bd9Sstevel@tonic-gate */ 8227c478bd9Sstevel@tonic-gate int 8237c478bd9Sstevel@tonic-gate resource_allocate_default(pool_resource_t **res, uint_t nelem) 8247c478bd9Sstevel@tonic-gate { 8257c478bd9Sstevel@tonic-gate res_info_t *res_info; 8267c478bd9Sstevel@tonic-gate uint_t j; 8277c478bd9Sstevel@tonic-gate pool_resource_t *default_res = NULL; 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate if (nelem == 1) 8307c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate if ((res_info = calloc(nelem, sizeof (res_info_t))) == NULL) { 8337c478bd9Sstevel@tonic-gate return (PO_FAIL); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* Load current resource values. */ 8377c478bd9Sstevel@tonic-gate for (j = 0; j < nelem; j++) { 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gate if (default_res == NULL && 8407c478bd9Sstevel@tonic-gate resource_is_default(res[j]) == PO_TRUE) 8417c478bd9Sstevel@tonic-gate default_res = res[j]; 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate if (resource_get_max(res[j], 8447c478bd9Sstevel@tonic-gate &res_info[j].ri_max) == PO_FAIL || 8457c478bd9Sstevel@tonic-gate resource_get_min(res[j], 8467c478bd9Sstevel@tonic-gate &res_info[j].ri_min) == PO_FAIL || 8477c478bd9Sstevel@tonic-gate resource_get_size(res[j], 8487c478bd9Sstevel@tonic-gate &res_info[j].ri_oldsize) == PO_FAIL || 8497c478bd9Sstevel@tonic-gate resource_get_pinned(res[j], 8507c478bd9Sstevel@tonic-gate &res_info[j].ri_pinned) == PO_FAIL) { 8517c478bd9Sstevel@tonic-gate free(res_info); 8527c478bd9Sstevel@tonic-gate return (PO_FAIL); 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate res_info[j].ri_res = res[j]; 8557c478bd9Sstevel@tonic-gate } 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate /* 8587c478bd9Sstevel@tonic-gate * Firstly, for all resources that have size greater than min, 8597c478bd9Sstevel@tonic-gate * transfer all movable size above min to the default resource. 8607c478bd9Sstevel@tonic-gate */ 8617c478bd9Sstevel@tonic-gate for (j = 0; j < nelem; j++) { 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate uint64_t real_min; 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate /* compute the real minimum number of resources */ 8667c478bd9Sstevel@tonic-gate real_min = MAX(res_info[j].ri_pinned, res_info[j].ri_min); 8677c478bd9Sstevel@tonic-gate if (res_info[j].ri_res != default_res && 8687c478bd9Sstevel@tonic-gate res_info[j].ri_oldsize > real_min) { 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate uint64_t num; 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate num = res_info[j].ri_oldsize - real_min; 8737c478bd9Sstevel@tonic-gate if (pool_resource_transfer( 8747c478bd9Sstevel@tonic-gate TO_CONF(TO_ELEM(default_res)), 8757c478bd9Sstevel@tonic-gate res_info[j].ri_res, default_res, num) != 8767c478bd9Sstevel@tonic-gate PO_SUCCESS) { 8777c478bd9Sstevel@tonic-gate free(res_info); 8787c478bd9Sstevel@tonic-gate return (PO_FAIL); 8797c478bd9Sstevel@tonic-gate } 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * Now, transfer resources below min from the default. 8847c478bd9Sstevel@tonic-gate */ 8857c478bd9Sstevel@tonic-gate for (j = 0; j < nelem; j++) { 8867c478bd9Sstevel@tonic-gate /* 8877c478bd9Sstevel@tonic-gate * We don't want to interfere with resources which are reserved 8887c478bd9Sstevel@tonic-gate */ 8897c478bd9Sstevel@tonic-gate if (res_info[j].ri_res != default_res && 8907c478bd9Sstevel@tonic-gate res_info[j].ri_oldsize < res_info[j].ri_min) { 8917c478bd9Sstevel@tonic-gate if (pool_resource_transfer( 8927c478bd9Sstevel@tonic-gate TO_CONF(TO_ELEM(default_res)), 8937c478bd9Sstevel@tonic-gate default_res, res_info[j].ri_res, 8947c478bd9Sstevel@tonic-gate res_info[j].ri_min - res_info[j].ri_oldsize) != 8957c478bd9Sstevel@tonic-gate PO_SUCCESS) { 8967c478bd9Sstevel@tonic-gate free(res_info); 8977c478bd9Sstevel@tonic-gate return (PO_FAIL); 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate } 9017c478bd9Sstevel@tonic-gate free(res_info); 9027c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate /* 9067c478bd9Sstevel@tonic-gate * Allocate cpus to pset resource sets, favoring sets with higher importance. 9077c478bd9Sstevel@tonic-gate * 9087c478bd9Sstevel@tonic-gate * Step 1: Sort resource sets by decreasing importance, and load each sets 9097c478bd9Sstevel@tonic-gate * current size (oldsize), min, max, and number of pinned cpus. 9107c478bd9Sstevel@tonic-gate * Compute the total number of cpus by totaling oldsize. 9117c478bd9Sstevel@tonic-gate * 9127c478bd9Sstevel@tonic-gate * Step 2: Compute the newsize for each set: 9137c478bd9Sstevel@tonic-gate * 9147c478bd9Sstevel@tonic-gate * Give each set its min number of cpus. This min may be greater than 9157c478bd9Sstevel@tonic-gate * its pset.min due to pinned cpus. If there are more cpus than the total 9167c478bd9Sstevel@tonic-gate * of all mins, then the surplus cpus are dealt round-robin to all sets 9177c478bd9Sstevel@tonic-gate * (up to their max) in order of decreasing importance. A set may be 9187c478bd9Sstevel@tonic-gate * skipped during dealing because it started with more than its min due to 9197c478bd9Sstevel@tonic-gate * pinned cpus. The dealing stops when there are no more cpus or all 9207c478bd9Sstevel@tonic-gate * sets are at their max. If all sets are at their max, any remaining cpus 9217c478bd9Sstevel@tonic-gate * are given to the default set. 9227c478bd9Sstevel@tonic-gate * 9237c478bd9Sstevel@tonic-gate * Step 3: Transfer cpus from sets with (oldsize > newsize) to sets with 9247c478bd9Sstevel@tonic-gate * (oldsize < newsize). 9257c478bd9Sstevel@tonic-gate */ 9267c478bd9Sstevel@tonic-gate int 9277c478bd9Sstevel@tonic-gate pset_allocate_imp(pool_resource_t **res, uint_t nelem) 9287c478bd9Sstevel@tonic-gate { 9297c478bd9Sstevel@tonic-gate res_info_t *res_info; 9307c478bd9Sstevel@tonic-gate res_info_t *default_res_info; 9317c478bd9Sstevel@tonic-gate const pool_resource_t *default_res = NULL; 9327c478bd9Sstevel@tonic-gate uint64_t tot_resources = 0; /* total count of resources */ 9337c478bd9Sstevel@tonic-gate uint64_t tot_min = 0; /* total of all resource set mins */ 9347c478bd9Sstevel@tonic-gate uint64_t num_to_deal = 0; /* total resources above mins to deal */ 9357c478bd9Sstevel@tonic-gate uint64_t sets_maxed = 0; /* number of resource sets dealt to */ 9367c478bd9Sstevel@tonic-gate /* their max */ 9377c478bd9Sstevel@tonic-gate uint64_t sets_finished = 0; /* number of resource sets that have */ 9387c478bd9Sstevel@tonic-gate /* size == newsize */ 9397c478bd9Sstevel@tonic-gate int donor, receiver; 9407c478bd9Sstevel@tonic-gate int deal; 9417c478bd9Sstevel@tonic-gate int j; 9427c478bd9Sstevel@tonic-gate int ret = PO_SUCCESS; 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate /* 9457c478bd9Sstevel@tonic-gate * Build list of res_info_t's 9467c478bd9Sstevel@tonic-gate */ 9477c478bd9Sstevel@tonic-gate if ((res_info = calloc(nelem, sizeof (res_info_t))) == NULL) { 9487c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 9497c478bd9Sstevel@tonic-gate return (PO_FAIL); 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate /* Order resources by importance, most important being first */ 9537c478bd9Sstevel@tonic-gate qsort(res, nelem, sizeof (pool_resource_t *), 9547c478bd9Sstevel@tonic-gate resource_compare_by_descending_importance); 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate for (j = 0; j < nelem; j++) { 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate /* Track which resource is the default */ 9597c478bd9Sstevel@tonic-gate if (default_res == NULL && 9607c478bd9Sstevel@tonic-gate resource_is_default(res[j]) == PO_TRUE) { 9617c478bd9Sstevel@tonic-gate default_res = res[j]; 9627c478bd9Sstevel@tonic-gate default_res_info = &(res_info[j]); 9637c478bd9Sstevel@tonic-gate } 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate /* Load sets' current values */ 9667c478bd9Sstevel@tonic-gate if (resource_get_max(res[j], &res_info[j].ri_max) == PO_FAIL || 9677c478bd9Sstevel@tonic-gate resource_get_min(res[j], &res_info[j].ri_min) == PO_FAIL || 9687c478bd9Sstevel@tonic-gate resource_get_size(res[j], &res_info[j].ri_oldsize) == 9697c478bd9Sstevel@tonic-gate PO_FAIL || 9707c478bd9Sstevel@tonic-gate resource_get_pinned(res[j], 9717c478bd9Sstevel@tonic-gate &res_info[j].ri_pinned) == PO_FAIL) { 9727c478bd9Sstevel@tonic-gate free(res_info); 9737c478bd9Sstevel@tonic-gate return (PO_FAIL); 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate /* Start each set's newsize out at their min. */ 9777c478bd9Sstevel@tonic-gate res_info[j].ri_newsize = res_info[j].ri_min; 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate /* pre-deal pinned resources that exceed min */ 9807c478bd9Sstevel@tonic-gate if (res_info[j].ri_pinned > res_info[j].ri_min) { 9817c478bd9Sstevel@tonic-gate res_info[j].ri_newsize = res_info[j].ri_pinned; 9827c478bd9Sstevel@tonic-gate res_info[j].ri_dealt = 9837c478bd9Sstevel@tonic-gate res_info[j].ri_newsize - res_info[j].ri_min; 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate res_info[j].ri_res = res[j]; 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate /* Compute total number of resources to deal out */ 9887c478bd9Sstevel@tonic-gate tot_resources += res_info[j].ri_oldsize; 9897c478bd9Sstevel@tonic-gate tot_min += res_info[j].ri_newsize; 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate #ifdef DEBUG 9927c478bd9Sstevel@tonic-gate dprintf("res allocation details\n"); 9937c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(res[j])); 9947c478bd9Sstevel@tonic-gate dprintf("size=%llu\n", res_info[j].ri_oldsize); 9957c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate num_to_deal = tot_resources - tot_min; 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate /* 10017c478bd9Sstevel@tonic-gate * Deal one resource to each set, and then another, until all 10027c478bd9Sstevel@tonic-gate * resources are dealt or all sets are at their max. 10037c478bd9Sstevel@tonic-gate */ 10047c478bd9Sstevel@tonic-gate for (deal = 1; num_to_deal > 0 && sets_maxed < nelem; deal++) { 10057c478bd9Sstevel@tonic-gate for (j = 0; j < nelem; j++) { 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate /* 10087c478bd9Sstevel@tonic-gate * Skip this resource set if it has already been 10097c478bd9Sstevel@tonic-gate * pre-dealt a resource due to pinned resources. 10107c478bd9Sstevel@tonic-gate */ 10117c478bd9Sstevel@tonic-gate if (res_info[j].ri_dealt >= deal) 10127c478bd9Sstevel@tonic-gate continue; 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate if (res_info[j].ri_newsize < res_info[j].ri_max) { 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate res_info[j].ri_dealt++; 10177c478bd9Sstevel@tonic-gate res_info[j].ri_newsize++; 10187c478bd9Sstevel@tonic-gate if (res_info[j].ri_newsize == 10197c478bd9Sstevel@tonic-gate res_info[j].ri_max) 10207c478bd9Sstevel@tonic-gate sets_maxed++; 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate num_to_deal--; 10237c478bd9Sstevel@tonic-gate if (num_to_deal == 0) 10247c478bd9Sstevel@tonic-gate break; 10257c478bd9Sstevel@tonic-gate } 10267c478bd9Sstevel@tonic-gate } 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate /* 10307c478bd9Sstevel@tonic-gate * If all resource sets are at their max, deal the remaining to the 10317c478bd9Sstevel@tonic-gate * default resource set. 10327c478bd9Sstevel@tonic-gate */ 10337c478bd9Sstevel@tonic-gate if ((sets_maxed == nelem) && (num_to_deal > 0)) { 10347c478bd9Sstevel@tonic-gate default_res_info->ri_dealt += num_to_deal; 10357c478bd9Sstevel@tonic-gate default_res_info->ri_newsize += num_to_deal; 10367c478bd9Sstevel@tonic-gate } 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate /* 10397c478bd9Sstevel@tonic-gate * Sort so that resource sets needing resources preced resource sets 10407c478bd9Sstevel@tonic-gate * that have extra resources. The sort function will also compute 10417c478bd9Sstevel@tonic-gate * The quantity of resources that need to be transfered into or out 10427c478bd9Sstevel@tonic-gate * of each set so that it's size == newsize. 10437c478bd9Sstevel@tonic-gate */ 10447c478bd9Sstevel@tonic-gate qsort(res_info, nelem, sizeof (res_info_t), 10457c478bd9Sstevel@tonic-gate compute_size_to_transfer); 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate /* 10487c478bd9Sstevel@tonic-gate * The donor index starts at the end of the resource set list and 10497c478bd9Sstevel@tonic-gate * walks up. The receiver index starts at the beginning of the 10507c478bd9Sstevel@tonic-gate * resource set list and walks down. Cpu's are transfered from the 10517c478bd9Sstevel@tonic-gate * donors to the receivers until all sets have transfer == 0). 10527c478bd9Sstevel@tonic-gate */ 10537c478bd9Sstevel@tonic-gate donor = nelem - 1; 10547c478bd9Sstevel@tonic-gate receiver = 0; 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate /* Number of sets with transfer == 0 */ 10577c478bd9Sstevel@tonic-gate sets_finished = 0; 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate /* Tranfer resources so that each set's size becomes newsize */ 10607c478bd9Sstevel@tonic-gate for (;;) { 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate uint64_t ntrans; 10637c478bd9Sstevel@tonic-gate if (donor == receiver) { 10647c478bd9Sstevel@tonic-gate if (res_info[donor].ri_transfer != 0) { 10657c478bd9Sstevel@tonic-gate free(res_info); 10667c478bd9Sstevel@tonic-gate return (PO_FAIL); 10677c478bd9Sstevel@tonic-gate } 10687c478bd9Sstevel@tonic-gate sets_finished++; 10697c478bd9Sstevel@tonic-gate break; 10707c478bd9Sstevel@tonic-gate } 10717c478bd9Sstevel@tonic-gate if (res_info[donor].ri_transfer == 0) { 10727c478bd9Sstevel@tonic-gate sets_finished++; 10737c478bd9Sstevel@tonic-gate donor--; 10747c478bd9Sstevel@tonic-gate continue; 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate if (res_info[receiver].ri_transfer == 0) { 10777c478bd9Sstevel@tonic-gate sets_finished++; 10787c478bd9Sstevel@tonic-gate receiver++; 10797c478bd9Sstevel@tonic-gate continue; 10807c478bd9Sstevel@tonic-gate } 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate /* Transfer resources from the donor set to the receiver */ 10837c478bd9Sstevel@tonic-gate ntrans = MIN(res_info[donor].ri_transfer, 10847c478bd9Sstevel@tonic-gate -res_info[receiver].ri_transfer); 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate if (pool_resource_transfer( 10877c478bd9Sstevel@tonic-gate TO_CONF(TO_ELEM(res_info[donor].ri_res)), 10887c478bd9Sstevel@tonic-gate res_info[donor].ri_res, res_info[receiver].ri_res, 10897c478bd9Sstevel@tonic-gate ntrans) != PO_SUCCESS) { 10907c478bd9Sstevel@tonic-gate free(res_info); 10917c478bd9Sstevel@tonic-gate return (PO_FAIL); 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate res_info[donor].ri_transfer -= ntrans; 10947c478bd9Sstevel@tonic-gate res_info[receiver].ri_transfer += ntrans; 10957c478bd9Sstevel@tonic-gate } 10967c478bd9Sstevel@tonic-gate 10977c478bd9Sstevel@tonic-gate if (sets_finished != nelem) 10987c478bd9Sstevel@tonic-gate ret = PO_FAIL; 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate free(res_info); 11017c478bd9Sstevel@tonic-gate return (ret); 11027c478bd9Sstevel@tonic-gate } 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate /* 11057c478bd9Sstevel@tonic-gate * Used as a qsort parameter to help order resources in terms of their 11067c478bd9Sstevel@tonic-gate * importance, higher importance being first. 11077c478bd9Sstevel@tonic-gate */ 11087c478bd9Sstevel@tonic-gate int 11097c478bd9Sstevel@tonic-gate resource_compare_by_descending_importance(const void *arg1, const void *arg2) 11107c478bd9Sstevel@tonic-gate { 11117c478bd9Sstevel@tonic-gate pool_elem_t *elem1; 11127c478bd9Sstevel@tonic-gate pool_elem_t *elem2; 11137c478bd9Sstevel@tonic-gate pool_resource_t **res1 = (pool_resource_t **)arg1; 11147c478bd9Sstevel@tonic-gate pool_resource_t **res2 = (pool_resource_t **)arg2; 11157c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 11167c478bd9Sstevel@tonic-gate int64_t i1 = 0, i2 = 0; 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate elem1 = TO_ELEM(*res1); 11197c478bd9Sstevel@tonic-gate elem2 = TO_ELEM(*res2); 11207c478bd9Sstevel@tonic-gate 11217c478bd9Sstevel@tonic-gate if (pool_get_property(TO_CONF(elem1), elem1, "_importance", &val) == 11227c478bd9Sstevel@tonic-gate POC_INT) 11237c478bd9Sstevel@tonic-gate (void) pool_value_get_int64(&val, &i1); 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate if (pool_get_property(TO_CONF(elem2), elem2, "_importance", &val) == 11267c478bd9Sstevel@tonic-gate POC_INT) 11277c478bd9Sstevel@tonic-gate (void) pool_value_get_int64(&val, &i2); 11287c478bd9Sstevel@tonic-gate return (i1 > i2 ? -1 : (i1 < i2 ? 1 : 0)); 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate 11317c478bd9Sstevel@tonic-gate /* 11327c478bd9Sstevel@tonic-gate * Sort in increasing order so that resource sets with extra resources are at 11337c478bd9Sstevel@tonic-gate * the end and resource sets needing resources are at the beginning. 11347c478bd9Sstevel@tonic-gate */ 11357c478bd9Sstevel@tonic-gate int 11367c478bd9Sstevel@tonic-gate compute_size_to_transfer(const void *arg1, const void *arg2) 11377c478bd9Sstevel@tonic-gate { 11387c478bd9Sstevel@tonic-gate res_info_t *r1 = (res_info_t *)arg1, *r2 = (res_info_t *)arg2; 11397c478bd9Sstevel@tonic-gate r1->ri_transfer = (int64_t)r1->ri_oldsize - (int64_t)r1->ri_newsize; 11407c478bd9Sstevel@tonic-gate r2->ri_transfer = (int64_t)r2->ri_oldsize - (int64_t)r2->ri_newsize; 11417c478bd9Sstevel@tonic-gate return (r1->ri_transfer > r2->ri_transfer ? 1 : 11427c478bd9Sstevel@tonic-gate (r1->ri_transfer < r2->ri_transfer ? -1 : 0)); 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate 11457c478bd9Sstevel@tonic-gate /* 11467c478bd9Sstevel@tonic-gate * set_importance_cb() is used to create "_importance" props on each 11477c478bd9Sstevel@tonic-gate * resource associated with a pool. 11487c478bd9Sstevel@tonic-gate * 11497c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 11507c478bd9Sstevel@tonic-gate */ 11517c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11527c478bd9Sstevel@tonic-gate static int 11537c478bd9Sstevel@tonic-gate set_importance_cb(pool_conf_t *conf, pool_t *pool, void *unused) 11547c478bd9Sstevel@tonic-gate { 11557c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 11567c478bd9Sstevel@tonic-gate int64_t importance; 11577c478bd9Sstevel@tonic-gate pool_resource_t **res; 11587c478bd9Sstevel@tonic-gate uint_t nelem, i; 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate if (pool_get_property(conf, TO_ELEM(pool), "pool.importance", &val) != 11617c478bd9Sstevel@tonic-gate POC_INT) { 11627c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 11637c478bd9Sstevel@tonic-gate return (PO_FAIL); 11647c478bd9Sstevel@tonic-gate } 11657c478bd9Sstevel@tonic-gate (void) pool_value_get_int64(&val, &importance); 11667c478bd9Sstevel@tonic-gate if ((res = pool_query_pool_resources(conf, pool, &nelem, NULL)) == 11677c478bd9Sstevel@tonic-gate NULL) { 11687c478bd9Sstevel@tonic-gate return (PO_FAIL); 11697c478bd9Sstevel@tonic-gate } 11707c478bd9Sstevel@tonic-gate for (i = 0; res[i] != NULL; i++) { 11717c478bd9Sstevel@tonic-gate int64_t old_importance = INT64_MIN; 11727c478bd9Sstevel@tonic-gate pool_elem_t *elem = TO_ELEM(res[i]); 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate if (pool_get_property(conf, elem, "_importance", &val) == 11757c478bd9Sstevel@tonic-gate POC_INT) 11767c478bd9Sstevel@tonic-gate (void) pool_value_get_int64(&val, &old_importance); 11777c478bd9Sstevel@tonic-gate if (old_importance <= importance) { 11787c478bd9Sstevel@tonic-gate (void) pool_value_set_int64(&val, importance); 11797c478bd9Sstevel@tonic-gate (void) pool_put_property(conf, elem, "_importance", 11807c478bd9Sstevel@tonic-gate &val); 11817c478bd9Sstevel@tonic-gate } 11827c478bd9Sstevel@tonic-gate } 11837c478bd9Sstevel@tonic-gate free(res); 11847c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 11857c478bd9Sstevel@tonic-gate } 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate /* 11887c478bd9Sstevel@tonic-gate * unset_importance_cb() is used to remove "_importance" props from 11897c478bd9Sstevel@tonic-gate * each resource associated with a pool. 11907c478bd9Sstevel@tonic-gate * 11917c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 11927c478bd9Sstevel@tonic-gate */ 11937c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11947c478bd9Sstevel@tonic-gate static int 11957c478bd9Sstevel@tonic-gate unset_importance_cb(pool_conf_t *conf, pool_t *pool, void *unused) 11967c478bd9Sstevel@tonic-gate { 11977c478bd9Sstevel@tonic-gate pool_resource_t **res; 11987c478bd9Sstevel@tonic-gate uint_t nelem, i; 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate if ((res = pool_query_pool_resources(conf, pool, &nelem, NULL)) == 12017c478bd9Sstevel@tonic-gate NULL) { 12027c478bd9Sstevel@tonic-gate return (PO_FAIL); 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate for (i = 0; res[i] != NULL; i++) { 12057c478bd9Sstevel@tonic-gate if (pool_rm_property(conf, TO_ELEM(res[i]), "_importance") == 12067c478bd9Sstevel@tonic-gate PO_FAIL) { 12077c478bd9Sstevel@tonic-gate free(res); 12087c478bd9Sstevel@tonic-gate return (PO_FAIL); 12097c478bd9Sstevel@tonic-gate } 12107c478bd9Sstevel@tonic-gate } 12117c478bd9Sstevel@tonic-gate free(res); 12127c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate /* 12167c478bd9Sstevel@tonic-gate * add_importance_props() is used to create "_importance" props on 12177c478bd9Sstevel@tonic-gate * each resource associated with a pool. 12187c478bd9Sstevel@tonic-gate * 12197c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 12207c478bd9Sstevel@tonic-gate */ 12217c478bd9Sstevel@tonic-gate static int 12227c478bd9Sstevel@tonic-gate add_importance_props(pool_conf_t *conf) 12237c478bd9Sstevel@tonic-gate { 12247c478bd9Sstevel@tonic-gate return (pool_walk_pools(conf, NULL, set_importance_cb)); 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate /* 12287c478bd9Sstevel@tonic-gate * remove_importance_props() is used to remove "_importance" props on 12297c478bd9Sstevel@tonic-gate * each resource associated with a pool. 12307c478bd9Sstevel@tonic-gate * 12317c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 12327c478bd9Sstevel@tonic-gate */ 12337c478bd9Sstevel@tonic-gate static int 12347c478bd9Sstevel@tonic-gate remove_importance_props(pool_conf_t *conf) 12357c478bd9Sstevel@tonic-gate { 12367c478bd9Sstevel@tonic-gate return (pool_walk_pools(conf, NULL, unset_importance_cb)); 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate /* 12407c478bd9Sstevel@tonic-gate * pool_conf_commit_sys() takes a configuration and modifies both the 12417c478bd9Sstevel@tonic-gate * supplied configuration and the dynamic configuration. The goal of 12427c478bd9Sstevel@tonic-gate * this modification is to generate a dynamic configuration which best 12437c478bd9Sstevel@tonic-gate * represents the constraints laid down in the static configuration 12447c478bd9Sstevel@tonic-gate * and to update the static configuration with the results of this 12457c478bd9Sstevel@tonic-gate * process. 12467c478bd9Sstevel@tonic-gate * 12477c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 12487c478bd9Sstevel@tonic-gate */ 12497c478bd9Sstevel@tonic-gate int 12507c478bd9Sstevel@tonic-gate pool_conf_commit_sys(pool_conf_t *conf, int validate) 12517c478bd9Sstevel@tonic-gate { 12527c478bd9Sstevel@tonic-gate pool_conf_t *dyn; 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate if ((dyn = pool_conf_alloc()) == NULL) 12557c478bd9Sstevel@tonic-gate return (PO_FAIL); 12567c478bd9Sstevel@tonic-gate if (pool_conf_open(dyn, pool_dynamic_location(), PO_RDWR) != 12577c478bd9Sstevel@tonic-gate PO_SUCCESS) { 12587c478bd9Sstevel@tonic-gate pool_conf_free(dyn); 12597c478bd9Sstevel@tonic-gate return (PO_FAIL); 12607c478bd9Sstevel@tonic-gate } 12617c478bd9Sstevel@tonic-gate if (validate == PO_TRUE) { 12627c478bd9Sstevel@tonic-gate if (pool_conf_validate(conf, POV_RUNTIME) != PO_SUCCESS) { 12637c478bd9Sstevel@tonic-gate (void) pool_conf_close(dyn); 12647c478bd9Sstevel@tonic-gate pool_conf_free(dyn); 12657c478bd9Sstevel@tonic-gate return (PO_FAIL); 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate } 12687c478bd9Sstevel@tonic-gate /* 12697c478bd9Sstevel@tonic-gate * Now try to make the two things "the same". 12707c478bd9Sstevel@tonic-gate */ 12717c478bd9Sstevel@tonic-gate if (diff_and_fix(conf, dyn) != PO_SUCCESS) { 12727c478bd9Sstevel@tonic-gate (void) pool_conf_close(dyn); 12737c478bd9Sstevel@tonic-gate pool_conf_free(dyn); 12747c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 12757c478bd9Sstevel@tonic-gate return (PO_FAIL); 12767c478bd9Sstevel@tonic-gate } 12777c478bd9Sstevel@tonic-gate if (dyn->pc_prov->pc_commit(dyn) != PO_SUCCESS) { 12787c478bd9Sstevel@tonic-gate (void) pool_conf_close(dyn); 12797c478bd9Sstevel@tonic-gate pool_conf_free(dyn); 12807c478bd9Sstevel@tonic-gate return (PO_FAIL); 12817c478bd9Sstevel@tonic-gate } 12827c478bd9Sstevel@tonic-gate (void) pool_conf_close(dyn); 12837c478bd9Sstevel@tonic-gate pool_conf_free(dyn); 12847c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 12857c478bd9Sstevel@tonic-gate } 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate /* 12887c478bd9Sstevel@tonic-gate * Copies all properties from one element to another. If the property 12897c478bd9Sstevel@tonic-gate * is a readonly property, then don't copy it. 12907c478bd9Sstevel@tonic-gate */ 12917c478bd9Sstevel@tonic-gate /* ARGSUSED */ 12927c478bd9Sstevel@tonic-gate static int 12937c478bd9Sstevel@tonic-gate clone_element(pool_conf_t *conf, pool_elem_t *pe, const char *name, 12947c478bd9Sstevel@tonic-gate pool_value_t *pv, void *user) 12957c478bd9Sstevel@tonic-gate { 12967c478bd9Sstevel@tonic-gate pool_elem_t *tgt = (pool_elem_t *)user; 12977c478bd9Sstevel@tonic-gate const pool_prop_t *prop; 12987c478bd9Sstevel@tonic-gate #ifdef DEBUG 12997c478bd9Sstevel@tonic-gate dprintf("Cloning %s from %s\n", 13007c478bd9Sstevel@tonic-gate pool_conf_location(TO_CONF(TO_ELEM(tgt))), 13017c478bd9Sstevel@tonic-gate pool_conf_location(TO_CONF(pe))); 13027c478bd9Sstevel@tonic-gate assert(TO_CONF(TO_ELEM(tgt)) != TO_CONF(pe)); 13037c478bd9Sstevel@tonic-gate dprintf("clone_element: Processing %s\n", name); 13047c478bd9Sstevel@tonic-gate pool_value_dprintf(pv); 13057c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 13067c478bd9Sstevel@tonic-gate /* 13077c478bd9Sstevel@tonic-gate * Some properties should be ignored 13087c478bd9Sstevel@tonic-gate */ 13097c478bd9Sstevel@tonic-gate if ((prop = provider_get_prop(pe, name)) != NULL && 13107c478bd9Sstevel@tonic-gate prop_is_readonly(prop) == PO_TRUE) 13117c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 1312*0209230bSgjelinek 1313*0209230bSgjelinek /* The temporary property needs special handling */ 1314*0209230bSgjelinek if (strstr(name, ".temporary") != NULL) 1315*0209230bSgjelinek return (pool_set_temporary(TO_CONF(tgt), tgt) == 1316*0209230bSgjelinek PO_FAIL ? PO_FAIL : PO_SUCCESS); 1317*0209230bSgjelinek else 1318*0209230bSgjelinek return (pool_put_property(TO_CONF(tgt), tgt, name, pv) == 1319*0209230bSgjelinek PO_FAIL ? PO_FAIL : PO_SUCCESS); 13207c478bd9Sstevel@tonic-gate } 13217c478bd9Sstevel@tonic-gate 13227c478bd9Sstevel@tonic-gate /* 13237c478bd9Sstevel@tonic-gate * Removes all properties from one element. Properties which are 13247c478bd9Sstevel@tonic-gate * managed by the configuration are ignored. 13257c478bd9Sstevel@tonic-gate */ 13267c478bd9Sstevel@tonic-gate /* ARGSUSED3 */ 13277c478bd9Sstevel@tonic-gate static int 13287c478bd9Sstevel@tonic-gate clean_element(pool_conf_t *conf, pool_elem_t *pe, const char *name, 13297c478bd9Sstevel@tonic-gate pool_value_t *pv, void *user) 13307c478bd9Sstevel@tonic-gate { 13317c478bd9Sstevel@tonic-gate const pool_prop_t *prop; 13327c478bd9Sstevel@tonic-gate /* 13337c478bd9Sstevel@tonic-gate * Some properties should be ignored 13347c478bd9Sstevel@tonic-gate */ 1335*0209230bSgjelinek if (strstr(name, ".temporary") != NULL || 1336*0209230bSgjelinek ((prop = provider_get_prop(pe, name)) != NULL && 1337*0209230bSgjelinek prop_is_optional(prop) == PO_FALSE)) 13387c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 13397c478bd9Sstevel@tonic-gate return (pool_rm_property(conf, (pool_elem_t *)pe, name) == PO_FAIL); 13407c478bd9Sstevel@tonic-gate } 1341