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 50209230bSgjelinek * Common Development and Distribution License (the "License"). 60209230bSgjelinek * 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 */ 21*5ad42b1bSSurya Prakki 227c478bd9Sstevel@tonic-gate /* 23*5ad42b1bSSurya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <assert.h> 287c478bd9Sstevel@tonic-gate #include <errno.h> 297c478bd9Sstevel@tonic-gate #include <exacct.h> 307c478bd9Sstevel@tonic-gate #include <fcntl.h> 317c478bd9Sstevel@tonic-gate #include <libnvpair.h> 327c478bd9Sstevel@tonic-gate #include <limits.h> 337c478bd9Sstevel@tonic-gate #include <poll.h> 347c478bd9Sstevel@tonic-gate #include <pool.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate #include <string.h> 387c478bd9Sstevel@tonic-gate #include <strings.h> 397c478bd9Sstevel@tonic-gate #include <stropts.h> 407c478bd9Sstevel@tonic-gate #include <thread.h> 417c478bd9Sstevel@tonic-gate #include <time.h> 427c478bd9Sstevel@tonic-gate #include <unistd.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include <libxml/tree.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #include <sys/mman.h> 477c478bd9Sstevel@tonic-gate #include <sys/pool.h> 487c478bd9Sstevel@tonic-gate #include <sys/pool_impl.h> 497c478bd9Sstevel@tonic-gate #include <sys/priocntl.h> 507c478bd9Sstevel@tonic-gate #include <sys/stat.h> 517c478bd9Sstevel@tonic-gate #include <sys/time.h> 527c478bd9Sstevel@tonic-gate #include <sys/types.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include "dict.h" 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #include "pool_internal.h" 577c478bd9Sstevel@tonic-gate #include "pool_impl.h" 587c478bd9Sstevel@tonic-gate #include "pool_kernel_impl.h" 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* 617c478bd9Sstevel@tonic-gate * libpool kernel Manipulation Routines 627c478bd9Sstevel@tonic-gate * 637c478bd9Sstevel@tonic-gate * pool_kernel.c implements the kernel manipulation routines used by the 647c478bd9Sstevel@tonic-gate * libpool kernel datastore. The functions are grouped into the following 657c478bd9Sstevel@tonic-gate * logical areas 667c478bd9Sstevel@tonic-gate * 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 707c478bd9Sstevel@tonic-gate * Device snapshot transfer buffer size 717c478bd9Sstevel@tonic-gate */ 727c478bd9Sstevel@tonic-gate #define KERNEL_SNAPSHOT_BUF_SZ 65535 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* 757c478bd9Sstevel@tonic-gate * Kernel result set's initial size. 8 is probably large enough for 767c478bd9Sstevel@tonic-gate * most queries. Queries requiring more space are accomodated using 777c478bd9Sstevel@tonic-gate * realloc on a per result set basis. 787c478bd9Sstevel@tonic-gate */ 797c478bd9Sstevel@tonic-gate #define KERNEL_RS_INITIAL_SZ 8 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * Property manipulation macros 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate #define KERNEL_PROP_RDONLY 0x1 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate /* 877c478bd9Sstevel@tonic-gate * Information required to evaluate qualifying elements for a query 887c478bd9Sstevel@tonic-gate */ 897c478bd9Sstevel@tonic-gate struct query_obj { 907c478bd9Sstevel@tonic-gate const pool_conf_t *conf; 917c478bd9Sstevel@tonic-gate const pool_elem_t *src; 927c478bd9Sstevel@tonic-gate const char *src_attr; 937c478bd9Sstevel@tonic-gate pool_elem_class_t classes; 947c478bd9Sstevel@tonic-gate pool_value_t **props; 957c478bd9Sstevel@tonic-gate pool_knl_result_set_t *rs; 967c478bd9Sstevel@tonic-gate }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Identifies a pool element with a processor set id 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate typedef struct pool_set_xref { 1027c478bd9Sstevel@tonic-gate pool_knl_pool_t *psx_pool; 1037c478bd9Sstevel@tonic-gate uint_t psx_pset_id; 1047c478bd9Sstevel@tonic-gate struct pool_set_xref *psx_next; 1057c478bd9Sstevel@tonic-gate } pool_set_xref_t; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * Controls exacct snapshot load into libpool data structure 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate typedef struct pool_snap_load { 1117c478bd9Sstevel@tonic-gate int *psl_changed; 1127c478bd9Sstevel@tonic-gate pool_set_xref_t *psl_xref; 1137c478bd9Sstevel@tonic-gate pool_elem_t *psl_system; 1147c478bd9Sstevel@tonic-gate pool_knl_resource_t *psl_pset; 1157c478bd9Sstevel@tonic-gate } pool_snap_load_t; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Information about an XML document which is being constructed 1197c478bd9Sstevel@tonic-gate */ 1207c478bd9Sstevel@tonic-gate struct knl_to_xml { 1217c478bd9Sstevel@tonic-gate xmlDocPtr ktx_doc; 1227c478bd9Sstevel@tonic-gate xmlNodePtr ktx_node; 1237c478bd9Sstevel@tonic-gate }; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate /* 1267c478bd9Sstevel@tonic-gate * Undo structure processing. The following structures are all used to 1277c478bd9Sstevel@tonic-gate * allow changes to the libpool snapshot and kernel following an 1287c478bd9Sstevel@tonic-gate * unsuccessful commit. 1297c478bd9Sstevel@tonic-gate */ 1307c478bd9Sstevel@tonic-gate typedef struct pool_create_undo { 1317c478bd9Sstevel@tonic-gate pool_create_t pcu_ioctl; 1327c478bd9Sstevel@tonic-gate pool_elem_t *pcu_elem; 1337c478bd9Sstevel@tonic-gate } pool_create_undo_t; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate typedef struct pool_destroy_undo { 1367c478bd9Sstevel@tonic-gate pool_destroy_t pdu_ioctl; 1377c478bd9Sstevel@tonic-gate pool_elem_t *pdu_elem; 1387c478bd9Sstevel@tonic-gate } pool_destroy_undo_t; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate typedef struct pool_assoc_undo { 1417c478bd9Sstevel@tonic-gate pool_assoc_t pau_ioctl; 1427c478bd9Sstevel@tonic-gate pool_elem_t *pau_assoc; 1437c478bd9Sstevel@tonic-gate pool_elem_t *pau_oldres; 1447c478bd9Sstevel@tonic-gate pool_elem_t *pau_newres; 1457c478bd9Sstevel@tonic-gate } pool_assoc_undo_t; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate typedef struct pool_dissoc_undo { 1487c478bd9Sstevel@tonic-gate pool_dissoc_t pdu_ioctl; 1497c478bd9Sstevel@tonic-gate pool_elem_t *pdu_dissoc; 1507c478bd9Sstevel@tonic-gate pool_elem_t *pdu_oldres; 1517c478bd9Sstevel@tonic-gate pool_elem_t *pdu_newres; 1527c478bd9Sstevel@tonic-gate } pool_dissoc_undo_t; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate typedef struct pool_xtransfer_undo { 1557c478bd9Sstevel@tonic-gate pool_xtransfer_t pxu_ioctl; 1567c478bd9Sstevel@tonic-gate pool_elem_t *pxu_src; 1577c478bd9Sstevel@tonic-gate pool_elem_t *pxu_tgt; 1587c478bd9Sstevel@tonic-gate pool_component_t **pxu_rl; 1597c478bd9Sstevel@tonic-gate } pool_xtransfer_undo_t; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate typedef struct pool_propput_undo { 1627c478bd9Sstevel@tonic-gate pool_propput_t ppu_ioctl; 1637c478bd9Sstevel@tonic-gate pool_elem_t *ppu_elem; 1647c478bd9Sstevel@tonic-gate nvlist_t *ppu_alist; 1657c478bd9Sstevel@tonic-gate nvlist_t *ppu_blist; 1667c478bd9Sstevel@tonic-gate uchar_t ppu_doioctl; 1677c478bd9Sstevel@tonic-gate } pool_propput_undo_t; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate typedef struct pool_proprm_undo { 1707c478bd9Sstevel@tonic-gate pool_proprm_t pru_ioctl; 1717c478bd9Sstevel@tonic-gate pool_elem_t *pru_elem; 1727c478bd9Sstevel@tonic-gate pool_value_t pru_oldval; 1737c478bd9Sstevel@tonic-gate } pool_proprm_undo_t; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate extern const char *dtd_location; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate extern const char *element_class_tags[]; 1787c478bd9Sstevel@tonic-gate extern const char pool_info_location[]; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* 1817c478bd9Sstevel@tonic-gate * These functions are defined in pool_xml.c and represent the minimum 1827c478bd9Sstevel@tonic-gate * XML support required to allow a pool kernel configuration to be 1837c478bd9Sstevel@tonic-gate * exported as an XML document. 1847c478bd9Sstevel@tonic-gate */ 1857c478bd9Sstevel@tonic-gate extern int pool_xml_set_attr(xmlNodePtr, xmlChar *, const pool_value_t *); 1867c478bd9Sstevel@tonic-gate extern int pool_xml_set_prop(xmlNodePtr, xmlChar *, const pool_value_t *); 1877c478bd9Sstevel@tonic-gate extern void xml_init(void); 1887c478bd9Sstevel@tonic-gate extern xmlNodePtr node_create(xmlNodePtr, const xmlChar *); 1897c478bd9Sstevel@tonic-gate extern void pool_error_func(void *, const char *, ...); 1907c478bd9Sstevel@tonic-gate /* 1917c478bd9Sstevel@tonic-gate * Utilities 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate static int load_group(pool_conf_t *, pool_knl_elem_t *, ea_object_t *, 1947c478bd9Sstevel@tonic-gate pool_snap_load_t *); 1957c478bd9Sstevel@tonic-gate static void pool_knl_elem_free(pool_knl_elem_t *, int); 1967c478bd9Sstevel@tonic-gate static int pool_knl_put_xml_property(pool_elem_t *, xmlNodePtr, const char *, 1977c478bd9Sstevel@tonic-gate const pool_value_t *); 1987c478bd9Sstevel@tonic-gate static int pool_knl_snap_load_push(pool_snap_load_t *, pool_knl_pool_t *); 1997c478bd9Sstevel@tonic-gate static int pool_knl_snap_load_update(pool_snap_load_t *, int, uint_t); 2007c478bd9Sstevel@tonic-gate static int pool_knl_snap_load_remove(pool_snap_load_t *, int, uint_t); 2017c478bd9Sstevel@tonic-gate static nvpair_t *pool_knl_find_nvpair(nvlist_t *, const char *); 2027c478bd9Sstevel@tonic-gate static int pool_knl_nvlist_add_value(nvlist_t *, const char *, 2037c478bd9Sstevel@tonic-gate const pool_value_t *); 2047c478bd9Sstevel@tonic-gate static int pool_knl_recover(pool_conf_t *); 2057c478bd9Sstevel@tonic-gate static uint64_t hash_id(const pool_elem_t *); 2067c478bd9Sstevel@tonic-gate static int blocking_open(const char *, int); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate /* 2097c478bd9Sstevel@tonic-gate * Connections 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate static void pool_knl_connection_free(pool_knl_connection_t *); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * Configuration 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate static int pool_knl_close(pool_conf_t *); 2177c478bd9Sstevel@tonic-gate static int pool_knl_validate(const pool_conf_t *, pool_valid_level_t); 2187c478bd9Sstevel@tonic-gate static int pool_knl_commit(pool_conf_t *); 2197c478bd9Sstevel@tonic-gate static int pool_knl_export(const pool_conf_t *, const char *, 2207c478bd9Sstevel@tonic-gate pool_export_format_t); 2217c478bd9Sstevel@tonic-gate static int pool_knl_rollback(pool_conf_t *); 2227c478bd9Sstevel@tonic-gate static pool_result_set_t *pool_knl_exec_query(const pool_conf_t *, 2237c478bd9Sstevel@tonic-gate const pool_elem_t *, const char *, pool_elem_class_t, pool_value_t **); 2247c478bd9Sstevel@tonic-gate static int pool_knl_remove(pool_conf_t *); 2257c478bd9Sstevel@tonic-gate static char *pool_knl_get_binding(pool_conf_t *, pid_t); 2267c478bd9Sstevel@tonic-gate static int pool_knl_set_binding(pool_conf_t *, const char *, idtype_t, id_t); 2277c478bd9Sstevel@tonic-gate static char *pool_knl_get_resource_binding(pool_conf_t *, 2287c478bd9Sstevel@tonic-gate pool_resource_elem_class_t, pid_t); 2297c478bd9Sstevel@tonic-gate static int pool_knl_res_transfer(pool_resource_t *, pool_resource_t *, 2307c478bd9Sstevel@tonic-gate uint64_t); 2317c478bd9Sstevel@tonic-gate static int pool_knl_res_xtransfer(pool_resource_t *, pool_resource_t *, 2327c478bd9Sstevel@tonic-gate pool_component_t **); 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate /* 2357c478bd9Sstevel@tonic-gate * Result Sets 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate static pool_knl_result_set_t *pool_knl_result_set_alloc(const pool_conf_t *); 2387c478bd9Sstevel@tonic-gate static int pool_knl_result_set_append(pool_knl_result_set_t *, 2397c478bd9Sstevel@tonic-gate pool_knl_elem_t *); 2407c478bd9Sstevel@tonic-gate static int pool_knl_result_set_realloc(pool_knl_result_set_t *); 2417c478bd9Sstevel@tonic-gate static void pool_knl_result_set_free(pool_knl_result_set_t *); 2427c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_rs_next(pool_result_set_t *); 2437c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_rs_prev(pool_result_set_t *); 2447c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_rs_first(pool_result_set_t *); 2457c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_rs_last(pool_result_set_t *); 2467c478bd9Sstevel@tonic-gate static int pool_knl_rs_set_index(pool_result_set_t *, int); 2477c478bd9Sstevel@tonic-gate static int pool_knl_rs_get_index(pool_result_set_t *); 2487c478bd9Sstevel@tonic-gate static int pool_knl_rs_count(pool_result_set_t *); 2497c478bd9Sstevel@tonic-gate static int pool_knl_rs_close(pool_result_set_t *); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * Element (and sub-type) 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate static pool_knl_elem_t *pool_knl_elem_wrap(pool_conf_t *, pool_elem_class_t, 2557c478bd9Sstevel@tonic-gate pool_resource_elem_class_t, pool_component_elem_class_t); 2567c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_elem_create(pool_conf_t *, pool_elem_class_t, 2577c478bd9Sstevel@tonic-gate pool_resource_elem_class_t, pool_component_elem_class_t); 2587c478bd9Sstevel@tonic-gate static int pool_knl_elem_remove(pool_elem_t *); 2597c478bd9Sstevel@tonic-gate static int pool_knl_set_container(pool_elem_t *, pool_elem_t *); 2607c478bd9Sstevel@tonic-gate static pool_elem_t *pool_knl_get_container(const pool_elem_t *); 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * Pool element specific 2637c478bd9Sstevel@tonic-gate */ 2647c478bd9Sstevel@tonic-gate static int pool_knl_pool_associate(pool_t *, const pool_resource_t *); 2657c478bd9Sstevel@tonic-gate static int pool_knl_pool_dissociate(pool_t *, const pool_resource_t *); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * Resource elements specific 2697c478bd9Sstevel@tonic-gate */ 2707c478bd9Sstevel@tonic-gate static int pool_knl_resource_is_system(const pool_resource_t *); 2717c478bd9Sstevel@tonic-gate static int pool_knl_resource_can_associate(const pool_resource_t *); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /* Properties */ 2747c478bd9Sstevel@tonic-gate static pool_value_class_t pool_knl_get_property(const pool_elem_t *, 2757c478bd9Sstevel@tonic-gate const char *, pool_value_t *); 2767c478bd9Sstevel@tonic-gate static pool_value_class_t pool_knl_get_dynamic_property(const pool_elem_t *, 2777c478bd9Sstevel@tonic-gate const char *, pool_value_t *); 2787c478bd9Sstevel@tonic-gate static int pool_knl_put_property(pool_elem_t *, const char *, 2797c478bd9Sstevel@tonic-gate const pool_value_t *); 2807c478bd9Sstevel@tonic-gate static int pool_knl_rm_property(pool_elem_t *, const char *); 2817c478bd9Sstevel@tonic-gate static pool_value_t **pool_knl_get_properties(const pool_elem_t *, uint_t *); 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * Logging 2857c478bd9Sstevel@tonic-gate */ 2867c478bd9Sstevel@tonic-gate static int log_item_commit(log_item_t *); 2877c478bd9Sstevel@tonic-gate static int log_item_undo(log_item_t *); 2887c478bd9Sstevel@tonic-gate static int log_item_release(log_item_t *); 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * Utilities 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* 2957c478bd9Sstevel@tonic-gate * load_group() updates the library configuration with the kernel 2967c478bd9Sstevel@tonic-gate * snapshot supplied in ep. The function is designed to be called 2977c478bd9Sstevel@tonic-gate * recursively. This function depends implicitly on the ordering of 2987c478bd9Sstevel@tonic-gate * the data provided in ep. Changes to the ordering of data in ep must 2997c478bd9Sstevel@tonic-gate * be matched by changes to this function. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate int 3027c478bd9Sstevel@tonic-gate load_group(pool_conf_t *conf, pool_knl_elem_t *elem, ea_object_t *ep, 3037c478bd9Sstevel@tonic-gate pool_snap_load_t *psl) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate ea_object_t *eo; 3067c478bd9Sstevel@tonic-gate pool_knl_elem_t *old_elem; 3077c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 3087c478bd9Sstevel@tonic-gate int ret = PO_SUCCESS; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate if ((ep->eo_catalog & EXD_DATA_MASK) == EXD_GROUP_SYSTEM) { 3117c478bd9Sstevel@tonic-gate if ((elem = pool_knl_elem_wrap(conf, PEC_SYSTEM, PREC_INVALID, 3127c478bd9Sstevel@tonic-gate PCEC_INVALID)) == NULL) 3137c478bd9Sstevel@tonic-gate return (PO_FAIL); 3147c478bd9Sstevel@tonic-gate if (nvlist_alloc(&elem->pke_properties, NV_UNIQUE_NAME_TYPE, 3157c478bd9Sstevel@tonic-gate 0) != 0) { 3167c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 3177c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 3187c478bd9Sstevel@tonic-gate return (PO_FAIL); 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate /* 3217c478bd9Sstevel@tonic-gate * Check to see if we already have an element 3227c478bd9Sstevel@tonic-gate * for this data. If we have, free the newly 3237c478bd9Sstevel@tonic-gate * created elem and continue with the old one 3247c478bd9Sstevel@tonic-gate */ 3257c478bd9Sstevel@tonic-gate if ((old_elem = dict_get(prov->pkc_elements, elem)) != NULL) { 3267c478bd9Sstevel@tonic-gate nvlist_free(old_elem->pke_properties); 3277c478bd9Sstevel@tonic-gate old_elem->pke_properties = elem->pke_properties; 3287c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 3297c478bd9Sstevel@tonic-gate elem = old_elem; 3307c478bd9Sstevel@tonic-gate } else { 3317c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, elem, elem) != NULL) { 3327c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 3337c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 3347c478bd9Sstevel@tonic-gate return (PO_FAIL); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate psl->psl_system = (pool_elem_t *)elem; 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate for (eo = ep->eo_group.eg_objs; eo != NULL; eo = eo->eo_next) { 3417c478bd9Sstevel@tonic-gate int data; 3427c478bd9Sstevel@tonic-gate pool_knl_elem_t *prop_elem = NULL; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate data = (eo->eo_catalog & EXD_DATA_MASK); 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate switch (data) { 3477c478bd9Sstevel@tonic-gate case EXD_SYSTEM_TSTAMP: 3487c478bd9Sstevel@tonic-gate case EXD_POOL_TSTAMP: 3497c478bd9Sstevel@tonic-gate case EXD_PSET_TSTAMP: 3507c478bd9Sstevel@tonic-gate case EXD_CPU_TSTAMP: 3517c478bd9Sstevel@tonic-gate if (eo->eo_item.ei_uint64 > prov->pkc_lotime) { 3527c478bd9Sstevel@tonic-gate if (eo->eo_item.ei_uint64 > prov->pkc_ltime) 3537c478bd9Sstevel@tonic-gate prov->pkc_ltime = eo->eo_item.ei_uint64; 3547c478bd9Sstevel@tonic-gate if (psl->psl_changed) { 3557c478bd9Sstevel@tonic-gate switch (data) { 3567c478bd9Sstevel@tonic-gate case EXD_SYSTEM_TSTAMP: 3577c478bd9Sstevel@tonic-gate *psl->psl_changed |= POU_SYSTEM; 3587c478bd9Sstevel@tonic-gate break; 3597c478bd9Sstevel@tonic-gate case EXD_POOL_TSTAMP: 3607c478bd9Sstevel@tonic-gate *psl->psl_changed |= POU_POOL; 3617c478bd9Sstevel@tonic-gate break; 3627c478bd9Sstevel@tonic-gate case EXD_PSET_TSTAMP: 3637c478bd9Sstevel@tonic-gate *psl->psl_changed |= POU_PSET; 3647c478bd9Sstevel@tonic-gate break; 3657c478bd9Sstevel@tonic-gate case EXD_CPU_TSTAMP: 3667c478bd9Sstevel@tonic-gate *psl->psl_changed |= POU_CPU; 3677c478bd9Sstevel@tonic-gate break; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate break; 3727c478bd9Sstevel@tonic-gate case EXD_SYSTEM_PROP: 3737c478bd9Sstevel@tonic-gate case EXD_POOL_PROP: 3747c478bd9Sstevel@tonic-gate case EXD_PSET_PROP: 3757c478bd9Sstevel@tonic-gate case EXD_CPU_PROP: 3767c478bd9Sstevel@tonic-gate if (data == EXD_PSET_PROP) { 3777c478bd9Sstevel@tonic-gate prop_elem = elem; 3787c478bd9Sstevel@tonic-gate elem = (pool_knl_elem_t *)psl->psl_pset; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate nvlist_free(elem->pke_properties); 3817c478bd9Sstevel@tonic-gate if (nvlist_unpack(eo->eo_item.ei_raw, 3827c478bd9Sstevel@tonic-gate eo->eo_item.ei_size, &elem->pke_properties, 0) != 3837c478bd9Sstevel@tonic-gate 0) { 3847c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 3857c478bd9Sstevel@tonic-gate return (PO_FAIL); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate elem->pke_ltime = prov->pkc_ltime; 3887c478bd9Sstevel@tonic-gate if (data == EXD_PSET_PROP) { 3897c478bd9Sstevel@tonic-gate elem = prop_elem; 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate break; 3927c478bd9Sstevel@tonic-gate case EXD_POOL_POOLID: 3937c478bd9Sstevel@tonic-gate if (nvlist_alloc(&elem->pke_properties, 3947c478bd9Sstevel@tonic-gate NV_UNIQUE_NAME_TYPE, 0) != 0) { 3957c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 3967c478bd9Sstevel@tonic-gate return (PO_FAIL); 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate if (nvlist_add_int64(elem->pke_properties, 3997c478bd9Sstevel@tonic-gate "pool.sys_id", 4007c478bd9Sstevel@tonic-gate (int64_t)eo->eo_item.ei_uint32) != 0) { 4017c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4027c478bd9Sstevel@tonic-gate return (PO_FAIL); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate if ((old_elem = dict_get(prov->pkc_elements, elem)) != 4057c478bd9Sstevel@tonic-gate NULL) { 4067c478bd9Sstevel@tonic-gate nvlist_free(old_elem->pke_properties); 4077c478bd9Sstevel@tonic-gate old_elem->pke_properties = elem->pke_properties; 4087c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 4097c478bd9Sstevel@tonic-gate elem = old_elem; 4107c478bd9Sstevel@tonic-gate } else { 4117c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, elem, elem) != 4127c478bd9Sstevel@tonic-gate NULL) { 4137c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 4147c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4157c478bd9Sstevel@tonic-gate return (PO_FAIL); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate if (pool_knl_snap_load_push(psl, 4197c478bd9Sstevel@tonic-gate (pool_knl_pool_t *)elem) != PO_SUCCESS) { 4207c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4217c478bd9Sstevel@tonic-gate return (PO_FAIL); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate ((pool_knl_pool_t *)elem)->pkp_assoc[PREC_PSET] = NULL; 4247c478bd9Sstevel@tonic-gate break; 4257c478bd9Sstevel@tonic-gate case EXD_POOL_PSETID: 4267c478bd9Sstevel@tonic-gate if (pool_knl_snap_load_update(psl, EXD_POOL_PSETID, 4277c478bd9Sstevel@tonic-gate eo->eo_item.ei_uint32) != PO_SUCCESS) { 4287c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4297c478bd9Sstevel@tonic-gate return (PO_FAIL); 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate break; 4327c478bd9Sstevel@tonic-gate case EXD_PSET_PSETID: 4337c478bd9Sstevel@tonic-gate if (nvlist_alloc(&elem->pke_properties, 4347c478bd9Sstevel@tonic-gate NV_UNIQUE_NAME_TYPE, 0) != 0) { 4357c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4367c478bd9Sstevel@tonic-gate return (PO_FAIL); 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate if (nvlist_add_int64(elem->pke_properties, 4397c478bd9Sstevel@tonic-gate "pset.sys_id", 4407c478bd9Sstevel@tonic-gate (int64_t)eo->eo_item.ei_uint32) != 0) { 4417c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4427c478bd9Sstevel@tonic-gate return (PO_FAIL); 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate if ((old_elem = dict_get(prov->pkc_elements, elem)) != 4457c478bd9Sstevel@tonic-gate NULL) { 4467c478bd9Sstevel@tonic-gate nvlist_free(old_elem->pke_properties); 4477c478bd9Sstevel@tonic-gate old_elem->pke_properties = elem->pke_properties; 4487c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 4497c478bd9Sstevel@tonic-gate elem = old_elem; 4507c478bd9Sstevel@tonic-gate } else { 4517c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, elem, elem) != 4527c478bd9Sstevel@tonic-gate NULL) { 4537c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 4547c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4557c478bd9Sstevel@tonic-gate return (PO_FAIL); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate psl->psl_pset = (pool_knl_resource_t *)elem; 4597c478bd9Sstevel@tonic-gate if (pool_knl_snap_load_remove(psl, data, 4607c478bd9Sstevel@tonic-gate eo->eo_item.ei_uint32) != PO_SUCCESS) { 4617c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4627c478bd9Sstevel@tonic-gate return (PO_FAIL); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate break; 4657c478bd9Sstevel@tonic-gate case EXD_CPU_CPUID: 4667c478bd9Sstevel@tonic-gate if (nvlist_alloc(&elem->pke_properties, 4677c478bd9Sstevel@tonic-gate NV_UNIQUE_NAME_TYPE, 0) != 0) { 4687c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4697c478bd9Sstevel@tonic-gate return (PO_FAIL); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate if (nvlist_add_int64(elem->pke_properties, 4727c478bd9Sstevel@tonic-gate "cpu.sys_id", 4737c478bd9Sstevel@tonic-gate (int64_t)eo->eo_item.ei_uint32) != 0) { 4747c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4757c478bd9Sstevel@tonic-gate return (PO_FAIL); 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate if ((old_elem = dict_get(prov->pkc_elements, elem)) != 4787c478bd9Sstevel@tonic-gate NULL) { 4797c478bd9Sstevel@tonic-gate nvlist_free(old_elem->pke_properties); 4807c478bd9Sstevel@tonic-gate old_elem->pke_properties = elem->pke_properties; 4817c478bd9Sstevel@tonic-gate old_elem->pke_parent = elem->pke_parent; 4827c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 4837c478bd9Sstevel@tonic-gate elem = old_elem; 4847c478bd9Sstevel@tonic-gate } else { 4857c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, elem, elem) != 4867c478bd9Sstevel@tonic-gate NULL) { 4877c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 4887c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 4897c478bd9Sstevel@tonic-gate return (PO_FAIL); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate break; 4937c478bd9Sstevel@tonic-gate case EXD_GROUP_POOL: 4947c478bd9Sstevel@tonic-gate if ((elem = pool_knl_elem_wrap(conf, PEC_POOL, 4957c478bd9Sstevel@tonic-gate PREC_INVALID, PCEC_INVALID)) == NULL) 4967c478bd9Sstevel@tonic-gate return (PO_FAIL); 4977c478bd9Sstevel@tonic-gate if (pool_set_container(psl->psl_system, 4987c478bd9Sstevel@tonic-gate (pool_elem_t *)elem) != PO_SUCCESS) { 4997c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 5007c478bd9Sstevel@tonic-gate return (PO_FAIL); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate break; 5037c478bd9Sstevel@tonic-gate case EXD_GROUP_PSET: 5047c478bd9Sstevel@tonic-gate if ((elem = pool_knl_elem_wrap(conf, PEC_RES_COMP, 5057c478bd9Sstevel@tonic-gate PREC_PSET, PCEC_INVALID)) == NULL) 5067c478bd9Sstevel@tonic-gate return (PO_FAIL); 5077c478bd9Sstevel@tonic-gate if (pool_set_container(psl->psl_system, 5087c478bd9Sstevel@tonic-gate (pool_elem_t *)elem) != PO_SUCCESS) { 5097c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 5107c478bd9Sstevel@tonic-gate return (PO_FAIL); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate break; 5137c478bd9Sstevel@tonic-gate case EXD_GROUP_CPU: 5147c478bd9Sstevel@tonic-gate if ((elem = pool_knl_elem_wrap(conf, PEC_COMP, 5157c478bd9Sstevel@tonic-gate PREC_INVALID, PCEC_CPU)) == NULL) 5167c478bd9Sstevel@tonic-gate return (PO_FAIL); 5177c478bd9Sstevel@tonic-gate if (pool_set_container((pool_elem_t *)psl->psl_pset, 5187c478bd9Sstevel@tonic-gate (pool_elem_t *)elem) != PO_SUCCESS) { 5197c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 5207c478bd9Sstevel@tonic-gate return (PO_FAIL); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate break; 5237c478bd9Sstevel@tonic-gate default: 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate if (eo->eo_type == EO_GROUP) { 5297c478bd9Sstevel@tonic-gate if ((ret = load_group(conf, elem, eo, psl)) == PO_FAIL) 5307c478bd9Sstevel@tonic-gate break; 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate return (ret); 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate /* 5377c478bd9Sstevel@tonic-gate * Push a snapshot entry onto the list of pools in the snapshot. 5387c478bd9Sstevel@tonic-gate */ 5397c478bd9Sstevel@tonic-gate int 5407c478bd9Sstevel@tonic-gate pool_knl_snap_load_push(pool_snap_load_t *psl, pool_knl_pool_t *pkp) 5417c478bd9Sstevel@tonic-gate { 5427c478bd9Sstevel@tonic-gate pool_set_xref_t *psx; 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate if ((psx = malloc(sizeof (pool_set_xref_t))) == NULL) { 5457c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 5467c478bd9Sstevel@tonic-gate return (PO_FAIL); 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate (void) memset(psx, 0, sizeof (pool_set_xref_t)); 5497c478bd9Sstevel@tonic-gate psx->psx_pool = pkp; 5507c478bd9Sstevel@tonic-gate /* 5517c478bd9Sstevel@tonic-gate * Push onto the list of pools 5527c478bd9Sstevel@tonic-gate */ 5537c478bd9Sstevel@tonic-gate psx->psx_next = psl->psl_xref; 5547c478bd9Sstevel@tonic-gate psl->psl_xref = psx; 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate /* 5607c478bd9Sstevel@tonic-gate * Update the current cross-reference for the supplied type of 5617c478bd9Sstevel@tonic-gate * resource. 5627c478bd9Sstevel@tonic-gate */ 5637c478bd9Sstevel@tonic-gate int 5647c478bd9Sstevel@tonic-gate pool_knl_snap_load_update(pool_snap_load_t *psl, int type, uint_t id) 5657c478bd9Sstevel@tonic-gate { 5667c478bd9Sstevel@tonic-gate switch (type) { 5677c478bd9Sstevel@tonic-gate case EXD_POOL_PSETID: 5687c478bd9Sstevel@tonic-gate psl->psl_xref->psx_pset_id = id; 5697c478bd9Sstevel@tonic-gate break; 5707c478bd9Sstevel@tonic-gate default: 5717c478bd9Sstevel@tonic-gate return (PO_FAIL); 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * Remove a resource entry with the supplied type and id from the 5797c478bd9Sstevel@tonic-gate * snapshot list when it is no longer required. 5807c478bd9Sstevel@tonic-gate */ 5817c478bd9Sstevel@tonic-gate int 5827c478bd9Sstevel@tonic-gate pool_knl_snap_load_remove(pool_snap_load_t *psl, int type, uint_t id) 5837c478bd9Sstevel@tonic-gate { 5847c478bd9Sstevel@tonic-gate pool_set_xref_t *current, *prev, *next; 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate for (prev = NULL, current = psl->psl_xref; current != NULL; 5877c478bd9Sstevel@tonic-gate current = next) { 5887c478bd9Sstevel@tonic-gate switch (type) { 5897c478bd9Sstevel@tonic-gate case EXD_PSET_PSETID: 5907c478bd9Sstevel@tonic-gate if (current->psx_pset_id == id) 5917c478bd9Sstevel@tonic-gate current->psx_pool->pkp_assoc[PREC_PSET] = 5927c478bd9Sstevel@tonic-gate psl->psl_pset; 5937c478bd9Sstevel@tonic-gate break; 5947c478bd9Sstevel@tonic-gate default: 5957c478bd9Sstevel@tonic-gate return (PO_FAIL); 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate next = current->psx_next; 5987c478bd9Sstevel@tonic-gate if (current->psx_pool->pkp_assoc[PREC_PSET] != NULL) { 5997c478bd9Sstevel@tonic-gate if (prev != NULL) { 6007c478bd9Sstevel@tonic-gate prev->psx_next = current->psx_next; 6017c478bd9Sstevel@tonic-gate } else { 6027c478bd9Sstevel@tonic-gate psl->psl_xref = current->psx_next; 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate free(current); 6057c478bd9Sstevel@tonic-gate } else 6067c478bd9Sstevel@tonic-gate prev = current; 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate /* 6137c478bd9Sstevel@tonic-gate * Return the nvpair with the supplied name from the supplied list. 6147c478bd9Sstevel@tonic-gate * 6157c478bd9Sstevel@tonic-gate * NULL is returned if the name cannot be found in the list. 6167c478bd9Sstevel@tonic-gate */ 6177c478bd9Sstevel@tonic-gate nvpair_t * 6187c478bd9Sstevel@tonic-gate pool_knl_find_nvpair(nvlist_t *l, const char *name) 6197c478bd9Sstevel@tonic-gate { 6207c478bd9Sstevel@tonic-gate nvpair_t *pair; 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate for (pair = nvlist_next_nvpair(l, NULL); pair != NULL; 623*5ad42b1bSSurya Prakki pair = nvlist_next_nvpair(l, pair)) { 6247c478bd9Sstevel@tonic-gate if (strcmp(nvpair_name(pair), name) == 0) 6257c478bd9Sstevel@tonic-gate break; 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate return (pair); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate /* 6317c478bd9Sstevel@tonic-gate * Close the configuration. There are a few steps to closing a configuration: 6327c478bd9Sstevel@tonic-gate * - Close the pseudo device 6337c478bd9Sstevel@tonic-gate * - Free the data provider 6347c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 6357c478bd9Sstevel@tonic-gate */ 6367c478bd9Sstevel@tonic-gate int 6377c478bd9Sstevel@tonic-gate pool_knl_close(pool_conf_t *conf) 6387c478bd9Sstevel@tonic-gate { 6397c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate if (close(prov->pkc_fd) < 0) { 6427c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 6437c478bd9Sstevel@tonic-gate return (PO_FAIL); 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate /* 6467c478bd9Sstevel@tonic-gate * Rollback any pending changes before freeing the prov. This 6470209230bSgjelinek * ensures there are no memory leaks from pending transactions. 6480209230bSgjelinek * However, don't rollback when we've done a temporary pool since the 6490209230bSgjelinek * pool/resources haven't really been committed in this case. 6500209230bSgjelinek * They will all be freed in pool_knl_connection_free and we don't 6510209230bSgjelinek * want to double free them. 6527c478bd9Sstevel@tonic-gate */ 6530209230bSgjelinek if (!(conf->pc_prov->pc_oflags & PO_TEMP)) 6540209230bSgjelinek (void) pool_knl_rollback(conf); 6557c478bd9Sstevel@tonic-gate pool_knl_connection_free(prov); 6567c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate /* 6607c478bd9Sstevel@tonic-gate * Remove elements in this map (previously identified as "dead") from 6617c478bd9Sstevel@tonic-gate * the configuration map (prov->pkc_elements). 6627c478bd9Sstevel@tonic-gate */ 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 6657c478bd9Sstevel@tonic-gate static void 6667c478bd9Sstevel@tonic-gate remove_dead_elems(const void *key, void **value, void *cl) 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)key; 6697c478bd9Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(TO_ELEM(pke)); 6707c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate assert(dict_remove(prov->pkc_elements, pke) != NULL); 6737c478bd9Sstevel@tonic-gate #ifdef DEBUG 6747c478bd9Sstevel@tonic-gate dprintf("remove_dead_elems:\n"); 6757c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(pke)); 6767c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6777c478bd9Sstevel@tonic-gate pool_knl_elem_free(pke, PO_TRUE); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate /* 6817c478bd9Sstevel@tonic-gate * Find elements which were not updated the last time that 6827c478bd9Sstevel@tonic-gate * load_group() was called. Add those elements into a separate map 6837c478bd9Sstevel@tonic-gate * (passed in cl) which will be later used to remove these elements 6847c478bd9Sstevel@tonic-gate * from the configuration map. 6857c478bd9Sstevel@tonic-gate */ 6867c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 6877c478bd9Sstevel@tonic-gate static void 6887c478bd9Sstevel@tonic-gate find_dead_elems(const void *key, void **value, void *cl) 6897c478bd9Sstevel@tonic-gate { 6907c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)key; 6917c478bd9Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(TO_ELEM(pke)); 6927c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 6937c478bd9Sstevel@tonic-gate dict_hdl_t *dead_map = (dict_hdl_t *)cl; 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate if (pke->pke_ltime < prov->pkc_ltime) 6967c478bd9Sstevel@tonic-gate (void) dict_put(dead_map, pke, pke); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate /* 7007c478bd9Sstevel@tonic-gate * Update the snapshot held by the library. This function acts as the 7017c478bd9Sstevel@tonic-gate * controller for the snapshot update procedure. Then snapshot is 7027c478bd9Sstevel@tonic-gate * actually updated in multiple phases by the load_group() function 7037c478bd9Sstevel@tonic-gate * (which updates existing elements and creates new elements as 7047c478bd9Sstevel@tonic-gate * required) and then by find_dead_elems and remove_dead_elems 7057c478bd9Sstevel@tonic-gate * (respectively responsible for identifying elements which are to be 7067c478bd9Sstevel@tonic-gate * removed and then removing them). 7077c478bd9Sstevel@tonic-gate * 7087c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS 7097c478bd9Sstevel@tonic-gate */ 7107c478bd9Sstevel@tonic-gate int 7117c478bd9Sstevel@tonic-gate pool_knl_update(pool_conf_t *conf, int *changed) 7127c478bd9Sstevel@tonic-gate { 7137c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 7147c478bd9Sstevel@tonic-gate pool_query_t query = {0}; 7157c478bd9Sstevel@tonic-gate ea_object_t *ep; 7167c478bd9Sstevel@tonic-gate dict_hdl_t *dead_map; 7177c478bd9Sstevel@tonic-gate pool_snap_load_t psl = { NULL }; 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate /* 7207c478bd9Sstevel@tonic-gate * Ensure the library snapshot is consistent, if there are any 7217c478bd9Sstevel@tonic-gate * outstanding transactions return failure. 7227c478bd9Sstevel@tonic-gate */ 7237c478bd9Sstevel@tonic-gate if (log_size(prov->pkc_log) != 0) { 7247c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 7257c478bd9Sstevel@tonic-gate return (PO_FAIL); 7267c478bd9Sstevel@tonic-gate } 7277c478bd9Sstevel@tonic-gate /* 7287c478bd9Sstevel@tonic-gate * Query the kernel for a snapshot of the configuration state. Use 7297c478bd9Sstevel@tonic-gate * load_group to allocate the user-land representation of the 7307c478bd9Sstevel@tonic-gate * data returned in the snapshot. 7317c478bd9Sstevel@tonic-gate */ 7327c478bd9Sstevel@tonic-gate /* LINTED E_CONSTANT_CONDITION */ 7337c478bd9Sstevel@tonic-gate while (1) { 7347c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_QUERY, &query) < 0) { 7357c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7367c478bd9Sstevel@tonic-gate return (PO_FAIL); 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate if ((query.pq_io_buf = calloc(1, 7397c478bd9Sstevel@tonic-gate (query.pq_io_bufsize < KERNEL_SNAPSHOT_BUF_SZ) ? 7407c478bd9Sstevel@tonic-gate query.pq_io_bufsize * 2 : query.pq_io_bufsize)) == NULL) { 7417c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7427c478bd9Sstevel@tonic-gate return (PO_FAIL); 7437c478bd9Sstevel@tonic-gate } 7447c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_QUERY, &query) < 0) { 7457c478bd9Sstevel@tonic-gate free(query.pq_io_buf); 7467c478bd9Sstevel@tonic-gate if (errno != ENOMEM) { 7477c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7487c478bd9Sstevel@tonic-gate return (PO_FAIL); 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate query.pq_io_bufsize = 0; 7517c478bd9Sstevel@tonic-gate query.pq_io_buf = NULL; 7527c478bd9Sstevel@tonic-gate } else 7537c478bd9Sstevel@tonic-gate break; 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate if (ea_unpack_object(&ep, EUP_NOALLOC, query.pq_io_buf, 7567c478bd9Sstevel@tonic-gate query.pq_io_bufsize) != EO_GROUP) { 7577c478bd9Sstevel@tonic-gate free(query.pq_io_buf); 7587c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 7597c478bd9Sstevel@tonic-gate return (PO_FAIL); 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate /* 7627c478bd9Sstevel@tonic-gate * Update the library snapshot 7637c478bd9Sstevel@tonic-gate */ 7647c478bd9Sstevel@tonic-gate psl.psl_changed = changed; 7657c478bd9Sstevel@tonic-gate prov->pkc_lotime = prov->pkc_ltime; 7667c478bd9Sstevel@tonic-gate if (load_group(conf, NULL, ep, &psl) != PO_SUCCESS) { 7677c478bd9Sstevel@tonic-gate free(query.pq_io_buf); 7687c478bd9Sstevel@tonic-gate ea_free_object(ep, EUP_NOALLOC); 7697c478bd9Sstevel@tonic-gate return (PO_FAIL); 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate free(query.pq_io_buf); 7737c478bd9Sstevel@tonic-gate ea_free_object(ep, EUP_NOALLOC); 7747c478bd9Sstevel@tonic-gate /* 7757c478bd9Sstevel@tonic-gate * Now search the dictionary for items that must be removed because 7767c478bd9Sstevel@tonic-gate * they were neither created nor updated. 7777c478bd9Sstevel@tonic-gate */ 7787c478bd9Sstevel@tonic-gate if ((dead_map = dict_new((int (*)(const void *, const void *)) 7797c478bd9Sstevel@tonic-gate pool_elem_compare, (uint64_t (*)(const void *))hash_id)) == NULL) { 7807c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 7817c478bd9Sstevel@tonic-gate return (PO_FAIL); 7827c478bd9Sstevel@tonic-gate } 7837c478bd9Sstevel@tonic-gate dict_map(prov->pkc_elements, find_dead_elems, dead_map); 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate if (dict_length(dead_map) > 0) { 7867c478bd9Sstevel@tonic-gate dict_map(dead_map, remove_dead_elems, NULL); 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate dict_free(&dead_map); 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate /* 7947c478bd9Sstevel@tonic-gate * Rely on the kernel to always keep a kernel configuration valid. 7957c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS 7967c478bd9Sstevel@tonic-gate */ 7977c478bd9Sstevel@tonic-gate /* ARGSUSED */ 7987c478bd9Sstevel@tonic-gate int 7997c478bd9Sstevel@tonic-gate pool_knl_validate(const pool_conf_t *conf, pool_valid_level_t level) 8007c478bd9Sstevel@tonic-gate { 8017c478bd9Sstevel@tonic-gate return ((conf->pc_state == POF_INVALID) ? PO_FAIL : PO_SUCCESS); 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate /* 8057c478bd9Sstevel@tonic-gate * Process all the outstanding transactions in the log. If the processing 8067c478bd9Sstevel@tonic-gate * fails, then attempt to rollback and "undo" the changes. 8077c478bd9Sstevel@tonic-gate */ 8087c478bd9Sstevel@tonic-gate int 8097c478bd9Sstevel@tonic-gate pool_knl_commit(pool_conf_t *conf) 8107c478bd9Sstevel@tonic-gate { 8117c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 8127c478bd9Sstevel@tonic-gate int lock = 1; 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate /* 8157c478bd9Sstevel@tonic-gate * Lock the kernel state for the commit 8167c478bd9Sstevel@tonic-gate */ 8177c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_COMMIT, lock) < 0) { 8187c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 8197c478bd9Sstevel@tonic-gate return (PO_FAIL); 8207c478bd9Sstevel@tonic-gate } 8217c478bd9Sstevel@tonic-gate lock = 0; 8227c478bd9Sstevel@tonic-gate /* 8237c478bd9Sstevel@tonic-gate * If the state is LS_FAIL, then try to recover before 8247c478bd9Sstevel@tonic-gate * performing the commit. 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state == LS_FAIL) { 8277c478bd9Sstevel@tonic-gate if (pool_knl_recover(conf) == PO_FAIL) { 8287c478bd9Sstevel@tonic-gate /* 8297c478bd9Sstevel@tonic-gate * Unlock the kernel state for the 8307c478bd9Sstevel@tonic-gate * commit. Assert that this * can't fail, 8317c478bd9Sstevel@tonic-gate * since if it ever does fail the library is 8327c478bd9Sstevel@tonic-gate * unusable. 8337c478bd9Sstevel@tonic-gate */ 8347c478bd9Sstevel@tonic-gate assert(ioctl(prov->pkc_fd, POOL_COMMIT, lock) >= 0); 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate /* 8387c478bd9Sstevel@tonic-gate * Commit the log 8397c478bd9Sstevel@tonic-gate */ 8407c478bd9Sstevel@tonic-gate if (log_walk(prov->pkc_log, log_item_commit) != PO_SUCCESS) { 8417c478bd9Sstevel@tonic-gate (void) pool_knl_recover(conf); 8427c478bd9Sstevel@tonic-gate /* 8437c478bd9Sstevel@tonic-gate * Unlock the kernel state for the commit. Assert that 8447c478bd9Sstevel@tonic-gate * this can't fail, since if it ever does fail the 8457c478bd9Sstevel@tonic-gate * library is unusable. 8467c478bd9Sstevel@tonic-gate */ 8477c478bd9Sstevel@tonic-gate assert(ioctl(prov->pkc_fd, POOL_COMMIT, lock) >= 0); 8487c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 8497c478bd9Sstevel@tonic-gate return (PO_FAIL); 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate /* 8527c478bd9Sstevel@tonic-gate * Unlock the kernel state for the commit. Assert that this 8537c478bd9Sstevel@tonic-gate * can't fail, since if it ever does fail the library is 8547c478bd9Sstevel@tonic-gate * unusable. 8557c478bd9Sstevel@tonic-gate */ 8567c478bd9Sstevel@tonic-gate assert(ioctl(prov->pkc_fd, POOL_COMMIT, lock) >= 0); 8577c478bd9Sstevel@tonic-gate /* 8587c478bd9Sstevel@tonic-gate * Release the log resources 8597c478bd9Sstevel@tonic-gate */ 8607c478bd9Sstevel@tonic-gate (void) log_walk(prov->pkc_log, log_item_release); 8617c478bd9Sstevel@tonic-gate log_empty(prov->pkc_log); 8627c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate /* 8667c478bd9Sstevel@tonic-gate * prop_build_cb() is designed to be called from 8677c478bd9Sstevel@tonic-gate * pool_walk_properties(). The property value is used to put an XML 8687c478bd9Sstevel@tonic-gate * property on the supplied ktx_node. This is an essential part of the 8697c478bd9Sstevel@tonic-gate * mechanism used to export a kernel configuration in libpool XML 8707c478bd9Sstevel@tonic-gate * form. 8717c478bd9Sstevel@tonic-gate */ 8727c478bd9Sstevel@tonic-gate /* ARGSUSED */ 8737c478bd9Sstevel@tonic-gate static int 8747c478bd9Sstevel@tonic-gate prop_build_cb(pool_conf_t *UNUSED, pool_elem_t *pe, const char *name, 8757c478bd9Sstevel@tonic-gate pool_value_t *pval, void *user) 8767c478bd9Sstevel@tonic-gate { 8777c478bd9Sstevel@tonic-gate struct knl_to_xml *info = (struct knl_to_xml *)user; 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate return (pool_knl_put_xml_property((pool_elem_t *)pe, info->ktx_node, 880*5ad42b1bSSurya Prakki name, pval)); 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate /* 8847c478bd9Sstevel@tonic-gate * Duplicate some of the functionality from pool_xml_put_property() 8857c478bd9Sstevel@tonic-gate * (see pool_xml.c) to allow a kernel configuration to add XML nodes 8867c478bd9Sstevel@tonic-gate * to an XML tree which represents the kernel configuration. This is 8877c478bd9Sstevel@tonic-gate * an essential part of the mechanism used to export a kernel 8887c478bd9Sstevel@tonic-gate * configuration in libpool XML form. 8897c478bd9Sstevel@tonic-gate */ 8907c478bd9Sstevel@tonic-gate int 8917c478bd9Sstevel@tonic-gate pool_knl_put_xml_property(pool_elem_t *pe, xmlNodePtr node, const char *name, 8927c478bd9Sstevel@tonic-gate const pool_value_t *val) 8937c478bd9Sstevel@tonic-gate { 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate /* 8967c478bd9Sstevel@tonic-gate * "type" is a special attribute which is not visible ever outside of 8977c478bd9Sstevel@tonic-gate * libpool. Use the specific type accessor function. 8987c478bd9Sstevel@tonic-gate */ 8997c478bd9Sstevel@tonic-gate if (strcmp(name, c_type) == 0) { 9007c478bd9Sstevel@tonic-gate return (pool_xml_set_attr(node, BAD_CAST name, 9017c478bd9Sstevel@tonic-gate val)); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate if (is_ns_property(pe, name) != NULL) { /* in ns */ 9047c478bd9Sstevel@tonic-gate if (pool_xml_set_attr(node, 9057c478bd9Sstevel@tonic-gate BAD_CAST property_name_minus_ns(pe, name), val) == PO_FAIL) 9067c478bd9Sstevel@tonic-gate return (pool_xml_set_prop(node, BAD_CAST name, 9077c478bd9Sstevel@tonic-gate val)); 9087c478bd9Sstevel@tonic-gate } else 9097c478bd9Sstevel@tonic-gate return (pool_xml_set_prop(node, BAD_CAST name, val)); 9107c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate /* 9147c478bd9Sstevel@tonic-gate * Export the kernel configuration as an XML file. The configuration 9157c478bd9Sstevel@tonic-gate * is used to build an XML document in memory. This document is then 9167c478bd9Sstevel@tonic-gate * saved to the supplied location. 9177c478bd9Sstevel@tonic-gate */ 9187c478bd9Sstevel@tonic-gate int 9197c478bd9Sstevel@tonic-gate pool_knl_export(const pool_conf_t *conf, const char *location, 9207c478bd9Sstevel@tonic-gate pool_export_format_t fmt) 9217c478bd9Sstevel@tonic-gate { 9227c478bd9Sstevel@tonic-gate xmlNodePtr node_comment; 9237c478bd9Sstevel@tonic-gate xmlNodePtr system; 9247c478bd9Sstevel@tonic-gate int ret; 9257c478bd9Sstevel@tonic-gate pool_t **ps; 9267c478bd9Sstevel@tonic-gate pool_resource_t **rs; 9277c478bd9Sstevel@tonic-gate uint_t nelem; 9287c478bd9Sstevel@tonic-gate int i; 9297c478bd9Sstevel@tonic-gate struct knl_to_xml info; 9307c478bd9Sstevel@tonic-gate char_buf_t *cb = NULL; 9317c478bd9Sstevel@tonic-gate xmlValidCtxtPtr cvp; 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate xml_init(); 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate switch (fmt) { 9377c478bd9Sstevel@tonic-gate case POX_NATIVE: 9387c478bd9Sstevel@tonic-gate info.ktx_doc = xmlNewDoc(BAD_CAST "1.0"); 939*5ad42b1bSSurya Prakki (void) xmlCreateIntSubset(info.ktx_doc, BAD_CAST "system", 9407c478bd9Sstevel@tonic-gate BAD_CAST "-//Sun Microsystems Inc//DTD Resource " 9417c478bd9Sstevel@tonic-gate "Management All//EN", 9427c478bd9Sstevel@tonic-gate BAD_CAST dtd_location); 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate if ((cvp = xmlNewValidCtxt()) == NULL) { 9457c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9467c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 9477c478bd9Sstevel@tonic-gate return (PO_FAIL); 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate /* 9507c478bd9Sstevel@tonic-gate * Call xmlValidateDocument() to force the parsing of 9517c478bd9Sstevel@tonic-gate * the DTD. Ignore errors and warning messages as we 9527c478bd9Sstevel@tonic-gate * know the document isn't valid. 9537c478bd9Sstevel@tonic-gate */ 9547c478bd9Sstevel@tonic-gate (void) xmlValidateDocument(cvp, info.ktx_doc); 9557c478bd9Sstevel@tonic-gate xmlFreeValidCtxt(cvp); 9567c478bd9Sstevel@tonic-gate if ((info.ktx_node = node_create(NULL, BAD_CAST "system")) == 9577c478bd9Sstevel@tonic-gate NULL) { 9587c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9597c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 9607c478bd9Sstevel@tonic-gate return (PO_FAIL); 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate system = info.ktx_node; 9647c478bd9Sstevel@tonic-gate info.ktx_doc->_private = (void *)conf; 9657c478bd9Sstevel@tonic-gate 966*5ad42b1bSSurya Prakki (void) xmlDocSetRootElement(info.ktx_doc, info.ktx_node); 967*5ad42b1bSSurya Prakki (void) xmlSetProp(info.ktx_node, BAD_CAST c_ref_id, 968*5ad42b1bSSurya Prakki BAD_CAST "dummy"); 9697c478bd9Sstevel@tonic-gate if ((node_comment = xmlNewDocComment(info.ktx_doc, 9707c478bd9Sstevel@tonic-gate BAD_CAST "\nConfiguration for pools facility. Do NOT" 9717c478bd9Sstevel@tonic-gate " edit this file by hand - use poolcfg(1)" 9727c478bd9Sstevel@tonic-gate " or libpool(3POOL) instead.\n")) == NULL) { 9737c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9747c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 9757c478bd9Sstevel@tonic-gate return (PO_FAIL); 9767c478bd9Sstevel@tonic-gate } 9777c478bd9Sstevel@tonic-gate if (xmlAddPrevSibling(info.ktx_node, node_comment) == NULL) { 9787c478bd9Sstevel@tonic-gate xmlFree(node_comment); 9797c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9807c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 9817c478bd9Sstevel@tonic-gate return (PO_FAIL); 9827c478bd9Sstevel@tonic-gate } 9837c478bd9Sstevel@tonic-gate if (pool_walk_any_properties((pool_conf_t *)conf, 9847c478bd9Sstevel@tonic-gate pool_conf_to_elem(conf), &info, prop_build_cb, 1) == 9857c478bd9Sstevel@tonic-gate PO_FAIL) { 9867c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9877c478bd9Sstevel@tonic-gate return (PO_FAIL); 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) { 9907c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 9917c478bd9Sstevel@tonic-gate return (PO_FAIL); 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate /* 9947c478bd9Sstevel@tonic-gate * Now add pool details 9957c478bd9Sstevel@tonic-gate */ 9967c478bd9Sstevel@tonic-gate if ((ps = pool_query_pools(conf, &nelem, NULL)) != NULL) { 9977c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 9987c478bd9Sstevel@tonic-gate pool_elem_t *elem = TO_ELEM(ps[i]); 9997c478bd9Sstevel@tonic-gate uint_t nreselem; 10007c478bd9Sstevel@tonic-gate const char *sep = ""; 10017c478bd9Sstevel@tonic-gate int j; 10027c478bd9Sstevel@tonic-gate 10030209230bSgjelinek if (elem_is_tmp(elem)) 10040209230bSgjelinek continue; 10050209230bSgjelinek 10067c478bd9Sstevel@tonic-gate if ((info.ktx_node = node_create(system, 10077c478bd9Sstevel@tonic-gate BAD_CAST element_class_tags 10087c478bd9Sstevel@tonic-gate [pool_elem_class(elem)])) == NULL) { 10097c478bd9Sstevel@tonic-gate free(ps); 10107c478bd9Sstevel@tonic-gate free_char_buf(cb); 10117c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10127c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 10137c478bd9Sstevel@tonic-gate return (PO_FAIL); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate if (pool_walk_any_properties( 10167c478bd9Sstevel@tonic-gate (pool_conf_t *)conf, 10177c478bd9Sstevel@tonic-gate elem, &info, prop_build_cb, 1) == PO_FAIL) { 10187c478bd9Sstevel@tonic-gate free(ps); 10197c478bd9Sstevel@tonic-gate free_char_buf(cb); 10207c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10217c478bd9Sstevel@tonic-gate return (PO_FAIL); 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate /* 10247c478bd9Sstevel@tonic-gate * TODO: pset specific res manipulation 10257c478bd9Sstevel@tonic-gate */ 10267c478bd9Sstevel@tonic-gate if ((rs = pool_query_pool_resources(conf, ps[i], 10277c478bd9Sstevel@tonic-gate &nreselem, NULL)) == NULL) { 10287c478bd9Sstevel@tonic-gate free(ps); 10297c478bd9Sstevel@tonic-gate free_char_buf(cb); 10307c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10317c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 10327c478bd9Sstevel@tonic-gate return (PO_FAIL); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "") == PO_FAIL) { 10357c478bd9Sstevel@tonic-gate free(rs); 10367c478bd9Sstevel@tonic-gate free(ps); 10377c478bd9Sstevel@tonic-gate free_char_buf(cb); 10387c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10397c478bd9Sstevel@tonic-gate return (PO_FAIL); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate for (j = 0; j < nreselem; j++) { 10427c478bd9Sstevel@tonic-gate pool_elem_t *reselem = TO_ELEM(rs[j]); 10437c478bd9Sstevel@tonic-gate if (append_char_buf(cb, "%s%s_%d", sep, 10447c478bd9Sstevel@tonic-gate pool_elem_class_string(reselem), 10457c478bd9Sstevel@tonic-gate (int)elem_get_sysid(reselem)) == 10467c478bd9Sstevel@tonic-gate PO_FAIL) { 10477c478bd9Sstevel@tonic-gate free(rs); 10487c478bd9Sstevel@tonic-gate free(ps); 10497c478bd9Sstevel@tonic-gate free_char_buf(cb); 10507c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10517c478bd9Sstevel@tonic-gate return (PO_FAIL); 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate sep = " "; 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate free(rs); 1056*5ad42b1bSSurya Prakki (void) xmlSetProp(info.ktx_node, BAD_CAST "res", 10577c478bd9Sstevel@tonic-gate BAD_CAST cb->cb_buf); 10587c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s_%d", 10597c478bd9Sstevel@tonic-gate pool_elem_class_string(elem), 10607c478bd9Sstevel@tonic-gate (int)elem_get_sysid(elem)) == PO_FAIL) { 10617c478bd9Sstevel@tonic-gate free(ps); 10627c478bd9Sstevel@tonic-gate free_char_buf(cb); 10637c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10647c478bd9Sstevel@tonic-gate return (PO_FAIL); 10657c478bd9Sstevel@tonic-gate } 1066*5ad42b1bSSurya Prakki (void) xmlSetProp(info.ktx_node, 1067*5ad42b1bSSurya Prakki BAD_CAST c_ref_id, 10687c478bd9Sstevel@tonic-gate BAD_CAST cb->cb_buf); 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate free(ps); 10717c478bd9Sstevel@tonic-gate } 10727c478bd9Sstevel@tonic-gate /* 10737c478bd9Sstevel@tonic-gate * Now add resource details (including components) 10747c478bd9Sstevel@tonic-gate */ 10757c478bd9Sstevel@tonic-gate if ((rs = pool_query_resources(conf, &nelem, NULL)) != NULL) { 10767c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 10777c478bd9Sstevel@tonic-gate pool_elem_t *elem = TO_ELEM(rs[i]); 10787c478bd9Sstevel@tonic-gate pool_component_t **cs = NULL; 10797c478bd9Sstevel@tonic-gate uint_t ncompelem; 10807c478bd9Sstevel@tonic-gate int j; 10817c478bd9Sstevel@tonic-gate 10820209230bSgjelinek if (elem_is_tmp(elem)) 10830209230bSgjelinek continue; 10840209230bSgjelinek 10857c478bd9Sstevel@tonic-gate if ((info.ktx_node = node_create(system, 10867c478bd9Sstevel@tonic-gate BAD_CAST element_class_tags 10877c478bd9Sstevel@tonic-gate [pool_elem_class(elem)])) == NULL) { 10887c478bd9Sstevel@tonic-gate free(rs); 10897c478bd9Sstevel@tonic-gate free_char_buf(cb); 10907c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 10917c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 10927c478bd9Sstevel@tonic-gate return (PO_FAIL); 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate if (pool_walk_any_properties( 10957c478bd9Sstevel@tonic-gate (pool_conf_t *)conf, 10967c478bd9Sstevel@tonic-gate elem, &info, prop_build_cb, 1) == PO_FAIL) { 10977c478bd9Sstevel@tonic-gate free(rs); 10987c478bd9Sstevel@tonic-gate free_char_buf(cb); 10997c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 11007c478bd9Sstevel@tonic-gate return (PO_FAIL); 11017c478bd9Sstevel@tonic-gate } 11027c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s_%d", 11037c478bd9Sstevel@tonic-gate pool_elem_class_string(elem), 11047c478bd9Sstevel@tonic-gate (int)elem_get_sysid(elem)) == PO_FAIL) { 11057c478bd9Sstevel@tonic-gate free(rs); 11067c478bd9Sstevel@tonic-gate free_char_buf(cb); 11077c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 11087c478bd9Sstevel@tonic-gate return (PO_FAIL); 11097c478bd9Sstevel@tonic-gate } 1110*5ad42b1bSSurya Prakki (void) xmlSetProp(info.ktx_node, 1111*5ad42b1bSSurya Prakki BAD_CAST c_ref_id, 11127c478bd9Sstevel@tonic-gate BAD_CAST cb->cb_buf); 11137c478bd9Sstevel@tonic-gate if ((cs = pool_query_resource_components(conf, 11147c478bd9Sstevel@tonic-gate rs[i], &ncompelem, NULL)) != NULL) { 11157c478bd9Sstevel@tonic-gate xmlNodePtr resource = info.ktx_node; 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate for (j = 0; j < ncompelem; j++) { 11187c478bd9Sstevel@tonic-gate pool_elem_t *compelem = 11197c478bd9Sstevel@tonic-gate TO_ELEM(cs[j]); 11207c478bd9Sstevel@tonic-gate if ((info.ktx_node = 11217c478bd9Sstevel@tonic-gate node_create(resource, 11227c478bd9Sstevel@tonic-gate BAD_CAST element_class_tags 11237c478bd9Sstevel@tonic-gate [pool_elem_class( 11247c478bd9Sstevel@tonic-gate compelem)])) == NULL) { 11257c478bd9Sstevel@tonic-gate pool_seterror( 11267c478bd9Sstevel@tonic-gate POE_DATASTORE); 11277c478bd9Sstevel@tonic-gate free(rs); 11287c478bd9Sstevel@tonic-gate free(cs); 11297c478bd9Sstevel@tonic-gate free_char_buf(cb); 11307c478bd9Sstevel@tonic-gate xmlFreeDoc(info. 11317c478bd9Sstevel@tonic-gate ktx_doc); 11327c478bd9Sstevel@tonic-gate return (PO_FAIL); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate if (pool_walk_any_properties( 11357c478bd9Sstevel@tonic-gate (pool_conf_t *)conf, 11367c478bd9Sstevel@tonic-gate compelem, &info, 11377c478bd9Sstevel@tonic-gate prop_build_cb, 1) == 11387c478bd9Sstevel@tonic-gate PO_FAIL) { 11397c478bd9Sstevel@tonic-gate free(rs); 11407c478bd9Sstevel@tonic-gate free(cs); 11417c478bd9Sstevel@tonic-gate free_char_buf(cb); 11427c478bd9Sstevel@tonic-gate xmlFreeDoc(info. 11437c478bd9Sstevel@tonic-gate ktx_doc); 11447c478bd9Sstevel@tonic-gate return (PO_FAIL); 11457c478bd9Sstevel@tonic-gate } 11467c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s_%d", 11477c478bd9Sstevel@tonic-gate pool_elem_class_string( 11487c478bd9Sstevel@tonic-gate compelem), 11497c478bd9Sstevel@tonic-gate (int)elem_get_sysid( 11507c478bd9Sstevel@tonic-gate compelem)) == PO_FAIL) { 11517c478bd9Sstevel@tonic-gate free(rs); 11527c478bd9Sstevel@tonic-gate free(cs); 11537c478bd9Sstevel@tonic-gate free_char_buf(cb); 11547c478bd9Sstevel@tonic-gate xmlFreeDoc(info. 11557c478bd9Sstevel@tonic-gate ktx_doc); 11567c478bd9Sstevel@tonic-gate return (PO_FAIL); 11577c478bd9Sstevel@tonic-gate } 1158*5ad42b1bSSurya Prakki (void) xmlSetProp(info.ktx_node, 11597c478bd9Sstevel@tonic-gate BAD_CAST c_ref_id, 11607c478bd9Sstevel@tonic-gate BAD_CAST cb->cb_buf); 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate free(cs); 11637c478bd9Sstevel@tonic-gate } 11647c478bd9Sstevel@tonic-gate } 11657c478bd9Sstevel@tonic-gate free(rs); 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate free_char_buf(cb); 11687c478bd9Sstevel@tonic-gate /* 11697c478bd9Sstevel@tonic-gate * Set up the message handlers prior to calling 11707c478bd9Sstevel@tonic-gate * xmlValidateDocument() 11717c478bd9Sstevel@tonic-gate */ 11727c478bd9Sstevel@tonic-gate if ((cvp = xmlNewValidCtxt()) == NULL) { 11737c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 11747c478bd9Sstevel@tonic-gate pool_seterror(POE_DATASTORE); 11757c478bd9Sstevel@tonic-gate return (PO_FAIL); 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate cvp->error = pool_error_func; 11787c478bd9Sstevel@tonic-gate cvp->warning = pool_error_func; 11797c478bd9Sstevel@tonic-gate if (xmlValidateDocument(cvp, info.ktx_doc) == 0) { 11807c478bd9Sstevel@tonic-gate xmlFreeValidCtxt(cvp); 11817c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 11827c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 11837c478bd9Sstevel@tonic-gate return (PO_FAIL); 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate xmlFreeValidCtxt(cvp); 11867c478bd9Sstevel@tonic-gate ret = xmlSaveFormatFile(location, info.ktx_doc, 1); 11877c478bd9Sstevel@tonic-gate xmlFreeDoc(info.ktx_doc); 11887c478bd9Sstevel@tonic-gate if (ret == -1) { 11897c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 11907c478bd9Sstevel@tonic-gate return (PO_FAIL); 11917c478bd9Sstevel@tonic-gate } 11927c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 11937c478bd9Sstevel@tonic-gate default: 11947c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 11957c478bd9Sstevel@tonic-gate return (PO_FAIL); 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate } 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate /* 12007c478bd9Sstevel@tonic-gate * Rollback the changes to the kernel 12017c478bd9Sstevel@tonic-gate */ 12027c478bd9Sstevel@tonic-gate int 12037c478bd9Sstevel@tonic-gate pool_knl_recover(pool_conf_t *conf) 12047c478bd9Sstevel@tonic-gate { 12057c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_RECOVER; 12087c478bd9Sstevel@tonic-gate if (log_reverse_walk(prov->pkc_log, log_item_undo) != PO_SUCCESS) { 12097c478bd9Sstevel@tonic-gate dprintf("Library configuration consistency error\n"); 12107c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_FAIL; 12117c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 12127c478bd9Sstevel@tonic-gate return (PO_FAIL); 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_DO; 12157c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate /* 12197c478bd9Sstevel@tonic-gate * Rollback the changes to the configuration 12207c478bd9Sstevel@tonic-gate */ 12217c478bd9Sstevel@tonic-gate int 12227c478bd9Sstevel@tonic-gate pool_knl_rollback(pool_conf_t *conf) 12237c478bd9Sstevel@tonic-gate { 12247c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 12257c478bd9Sstevel@tonic-gate 12267c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_UNDO; 12277c478bd9Sstevel@tonic-gate if (log_reverse_walk(prov->pkc_log, log_item_undo) != PO_SUCCESS) { 12287c478bd9Sstevel@tonic-gate dprintf("Kernel configuration consistency error\n"); 12297c478bd9Sstevel@tonic-gate (void) log_walk(prov->pkc_log, log_item_release); 12307c478bd9Sstevel@tonic-gate log_empty(prov->pkc_log); 12317c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_FAIL; 12327c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 12337c478bd9Sstevel@tonic-gate return (PO_FAIL); 12347c478bd9Sstevel@tonic-gate } 12357c478bd9Sstevel@tonic-gate (void) log_walk(prov->pkc_log, log_item_release); 12367c478bd9Sstevel@tonic-gate log_empty(prov->pkc_log); 12377c478bd9Sstevel@tonic-gate prov->pkc_log->l_state = LS_DO; 12387c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate 12417c478bd9Sstevel@tonic-gate /* 12427c478bd9Sstevel@tonic-gate * Callback used to build the result set for a query. Each invocation will 12437c478bd9Sstevel@tonic-gate * supply a candidate element for inclusion. The element is filtered by: 12447c478bd9Sstevel@tonic-gate * - class 12457c478bd9Sstevel@tonic-gate * - properties 12467c478bd9Sstevel@tonic-gate * If the element "matches" the target, then it is added to the result 12477c478bd9Sstevel@tonic-gate * set, otherwise it is ignored. 12487c478bd9Sstevel@tonic-gate */ 12497c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 12507c478bd9Sstevel@tonic-gate static void 12517c478bd9Sstevel@tonic-gate build_result_set(const void *key, void **value, void *cl) 12527c478bd9Sstevel@tonic-gate { 12537c478bd9Sstevel@tonic-gate struct query_obj *qo = (struct query_obj *)cl; 12547c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)key; 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate /* 12577c478bd9Sstevel@tonic-gate * Check to see if it's the right class of element 12587c478bd9Sstevel@tonic-gate */ 12597c478bd9Sstevel@tonic-gate if (qo->classes & (1 << pool_elem_class((pool_elem_t *)key))) { 12607c478bd9Sstevel@tonic-gate int i; 12617c478bd9Sstevel@tonic-gate /* 12627c478bd9Sstevel@tonic-gate * Now check to see if the src element is correct. If no src 12637c478bd9Sstevel@tonic-gate * element is supplied, ignore this check 12647c478bd9Sstevel@tonic-gate */ 12657c478bd9Sstevel@tonic-gate if (qo->src) { 12667c478bd9Sstevel@tonic-gate pool_knl_elem_t *parent; 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate for (parent = pke; parent != NULL; 12697c478bd9Sstevel@tonic-gate parent = parent->pke_parent) { 12707c478bd9Sstevel@tonic-gate if (parent == (pool_knl_elem_t *)qo->src) 12717c478bd9Sstevel@tonic-gate break; 12727c478bd9Sstevel@tonic-gate } 12737c478bd9Sstevel@tonic-gate if (parent == NULL) 12747c478bd9Sstevel@tonic-gate return; 12757c478bd9Sstevel@tonic-gate } 12767c478bd9Sstevel@tonic-gate /* 12777c478bd9Sstevel@tonic-gate * Now check for property matches (if there are any specified) 12787c478bd9Sstevel@tonic-gate */ 12797c478bd9Sstevel@tonic-gate if (qo->props) { 12807c478bd9Sstevel@tonic-gate int matched = PO_TRUE; 12817c478bd9Sstevel@tonic-gate for (i = 0; qo->props[i] != NULL; i++) { 12827c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate if (pool_get_property(TO_CONF(TO_ELEM(pke)), 12857c478bd9Sstevel@tonic-gate (pool_elem_t *)pke, 12867c478bd9Sstevel@tonic-gate pool_value_get_name(qo->props[i]), &val) == 12877c478bd9Sstevel@tonic-gate POC_INVAL) { 12887c478bd9Sstevel@tonic-gate matched = PO_FALSE; 12897c478bd9Sstevel@tonic-gate break; 12907c478bd9Sstevel@tonic-gate } else { 12917c478bd9Sstevel@tonic-gate if (pool_value_equal(qo->props[i], 12927c478bd9Sstevel@tonic-gate &val) != PO_TRUE) { 12937c478bd9Sstevel@tonic-gate matched = PO_FALSE; 12947c478bd9Sstevel@tonic-gate break; 12957c478bd9Sstevel@tonic-gate } 12967c478bd9Sstevel@tonic-gate } 12977c478bd9Sstevel@tonic-gate } 12987c478bd9Sstevel@tonic-gate if (matched == PO_TRUE) 12997c478bd9Sstevel@tonic-gate (void) pool_knl_result_set_append(qo->rs, 1300*5ad42b1bSSurya Prakki (pool_knl_elem_t *)key); 13017c478bd9Sstevel@tonic-gate } else { 13027c478bd9Sstevel@tonic-gate (void) pool_knl_result_set_append(qo->rs, 13037c478bd9Sstevel@tonic-gate (pool_knl_elem_t *)key); 13047c478bd9Sstevel@tonic-gate } 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate } 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate /* 13097c478bd9Sstevel@tonic-gate * Execute the supplied query and return a result set which contains 13107c478bd9Sstevel@tonic-gate * all qualifying elements. 13117c478bd9Sstevel@tonic-gate */ 13127c478bd9Sstevel@tonic-gate pool_result_set_t * 13137c478bd9Sstevel@tonic-gate pool_knl_exec_query(const pool_conf_t *conf, const pool_elem_t *src, 13147c478bd9Sstevel@tonic-gate const char *src_attr, pool_elem_class_t classes, pool_value_t **props) 13157c478bd9Sstevel@tonic-gate { 13167c478bd9Sstevel@tonic-gate pool_knl_result_set_t *rs; 13177c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 13187c478bd9Sstevel@tonic-gate struct query_obj qo; 13197c478bd9Sstevel@tonic-gate int matched = PO_TRUE; 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate /* 13227c478bd9Sstevel@tonic-gate * Have a buffer at this point, that we can use 13237c478bd9Sstevel@tonic-gate */ 13247c478bd9Sstevel@tonic-gate if ((rs = pool_knl_result_set_alloc(conf)) == NULL) { 13257c478bd9Sstevel@tonic-gate return (NULL); 13267c478bd9Sstevel@tonic-gate } 13277c478bd9Sstevel@tonic-gate qo.conf = conf; 13287c478bd9Sstevel@tonic-gate qo.src = src; 13297c478bd9Sstevel@tonic-gate qo.src_attr = src_attr; 13307c478bd9Sstevel@tonic-gate qo.classes = classes; 13317c478bd9Sstevel@tonic-gate qo.props = props; 13327c478bd9Sstevel@tonic-gate qo.rs = rs; 13337c478bd9Sstevel@tonic-gate if (src_attr != NULL) { 13347c478bd9Sstevel@tonic-gate pool_knl_pool_t *pkp = (pool_knl_pool_t *)src; 13357c478bd9Sstevel@tonic-gate 13367c478bd9Sstevel@tonic-gate /* 13377c478bd9Sstevel@tonic-gate * Note: This logic is resource specific and must be 13387c478bd9Sstevel@tonic-gate * extended for additional resource types. 13397c478bd9Sstevel@tonic-gate */ 13407c478bd9Sstevel@tonic-gate /* 13417c478bd9Sstevel@tonic-gate * Check for property matches (if there are any specified) 13427c478bd9Sstevel@tonic-gate */ 13437c478bd9Sstevel@tonic-gate if (props) { 13447c478bd9Sstevel@tonic-gate int i; 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate for (i = 0; props[i] != NULL; i++) { 13477c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 13487c478bd9Sstevel@tonic-gate 13497c478bd9Sstevel@tonic-gate if (pool_get_property(conf, 13507c478bd9Sstevel@tonic-gate (pool_elem_t *)pkp->pkp_assoc[PREC_PSET], 13517c478bd9Sstevel@tonic-gate pool_value_get_name(props[i]), &val) == 13527c478bd9Sstevel@tonic-gate POC_INVAL) { 13537c478bd9Sstevel@tonic-gate matched = PO_FALSE; 13547c478bd9Sstevel@tonic-gate break; 13557c478bd9Sstevel@tonic-gate } else { 13567c478bd9Sstevel@tonic-gate if (pool_value_equal(props[i], 13577c478bd9Sstevel@tonic-gate &val) != PO_TRUE) { 13587c478bd9Sstevel@tonic-gate matched = PO_FALSE; 13597c478bd9Sstevel@tonic-gate break; 13607c478bd9Sstevel@tonic-gate } 13617c478bd9Sstevel@tonic-gate } 13627c478bd9Sstevel@tonic-gate } 13637c478bd9Sstevel@tonic-gate } 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate if (matched == PO_TRUE) 13667c478bd9Sstevel@tonic-gate (void) pool_knl_result_set_append(rs, 13677c478bd9Sstevel@tonic-gate (pool_knl_elem_t *)pkp->pkp_assoc[PREC_PSET]); 13687c478bd9Sstevel@tonic-gate } else 13697c478bd9Sstevel@tonic-gate dict_map(prov->pkc_elements, build_result_set, &qo); 13707c478bd9Sstevel@tonic-gate 137126d8ba22Sgarypen if (rs->pkr_count == 0) 137226d8ba22Sgarypen pool_seterror(POE_INVALID_SEARCH); 13737c478bd9Sstevel@tonic-gate return ((pool_result_set_t *)rs); 13747c478bd9Sstevel@tonic-gate } 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate /* 13777c478bd9Sstevel@tonic-gate * Callback function intended to be used from pool_walk_pools(). If 13787c478bd9Sstevel@tonic-gate * the supplied pool is not the default pool attempt to destroy it. 13797c478bd9Sstevel@tonic-gate */ 13807c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 13817c478bd9Sstevel@tonic-gate static int 13827c478bd9Sstevel@tonic-gate destroy_pool_cb(pool_conf_t *conf, pool_t *pool, void *unused) 13837c478bd9Sstevel@tonic-gate { 13847c478bd9Sstevel@tonic-gate if (elem_is_default(TO_ELEM(pool)) != PO_TRUE) 13857c478bd9Sstevel@tonic-gate return (pool_destroy(conf, pool)); 13867c478bd9Sstevel@tonic-gate /* 13877c478bd9Sstevel@tonic-gate * Return PO_SUCCESS even though we don't delete the default 13887c478bd9Sstevel@tonic-gate * pool so that the walk continues 13897c478bd9Sstevel@tonic-gate */ 13907c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 13917c478bd9Sstevel@tonic-gate } 13927c478bd9Sstevel@tonic-gate 13937c478bd9Sstevel@tonic-gate /* 13947c478bd9Sstevel@tonic-gate * Remove the configuration details. This means remove all elements 13957c478bd9Sstevel@tonic-gate * apart from the system elements. 13967c478bd9Sstevel@tonic-gate */ 13977c478bd9Sstevel@tonic-gate int 13987c478bd9Sstevel@tonic-gate pool_knl_remove(pool_conf_t *conf) 13997c478bd9Sstevel@tonic-gate { 14007c478bd9Sstevel@tonic-gate uint_t i, nelem; 14017c478bd9Sstevel@tonic-gate pool_resource_t **resources; 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate conf->pc_state = POF_DESTROY; 14047c478bd9Sstevel@tonic-gate if ((resources = pool_query_resources(conf, &nelem, NULL)) != NULL) { 14057c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 14067c478bd9Sstevel@tonic-gate if (resource_is_system(resources[i]) == PO_FALSE) 14077c478bd9Sstevel@tonic-gate if (pool_resource_destroy(conf, resources[i]) != 14087c478bd9Sstevel@tonic-gate PO_SUCCESS) { 14097c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 14107c478bd9Sstevel@tonic-gate return (PO_FAIL); 14117c478bd9Sstevel@tonic-gate } 14127c478bd9Sstevel@tonic-gate } 14137c478bd9Sstevel@tonic-gate free(resources); 14147c478bd9Sstevel@tonic-gate } 14157c478bd9Sstevel@tonic-gate (void) pool_walk_pools(conf, conf, destroy_pool_cb); 14167c478bd9Sstevel@tonic-gate if (pool_conf_commit(conf, PO_FALSE) != PO_SUCCESS) 14177c478bd9Sstevel@tonic-gate return (PO_FAIL); 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate if (pool_conf_close(conf) != PO_SUCCESS) 14207c478bd9Sstevel@tonic-gate return (PO_FAIL); 14217c478bd9Sstevel@tonic-gate 14227c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 14237c478bd9Sstevel@tonic-gate } 14247c478bd9Sstevel@tonic-gate 14257c478bd9Sstevel@tonic-gate /* 14267c478bd9Sstevel@tonic-gate * Determine the name of the pool to which the supplied pid is 14277c478bd9Sstevel@tonic-gate * bound. If it cannot be determined return NULL. 14287c478bd9Sstevel@tonic-gate */ 14297c478bd9Sstevel@tonic-gate char * 14307c478bd9Sstevel@tonic-gate pool_knl_get_binding(pool_conf_t *conf, pid_t pid) 14317c478bd9Sstevel@tonic-gate { 14327c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 14337c478bd9Sstevel@tonic-gate const char *sval; 14347c478bd9Sstevel@tonic-gate char *name = NULL; 14357c478bd9Sstevel@tonic-gate pool_bindq_t bindq; 14367c478bd9Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL }; 14377c478bd9Sstevel@tonic-gate uint_t nelem = 0; 14387c478bd9Sstevel@tonic-gate pool_t **pools; 14397c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate props[0] = &val; 14427c478bd9Sstevel@tonic-gate 14437c478bd9Sstevel@tonic-gate bindq.pb_o_id_type = P_PID; 14447c478bd9Sstevel@tonic-gate bindq.pb_o_id = pid; 14457c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_BINDQ, &bindq) < 0) { 14467c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 14477c478bd9Sstevel@tonic-gate return (NULL); 14487c478bd9Sstevel@tonic-gate } 14497c478bd9Sstevel@tonic-gate 14507c478bd9Sstevel@tonic-gate if (pool_value_set_name(props[0], "pool.sys_id") != PO_SUCCESS) { 14517c478bd9Sstevel@tonic-gate return (NULL); 14527c478bd9Sstevel@tonic-gate } 14537c478bd9Sstevel@tonic-gate pool_value_set_int64(props[0], bindq.pb_i_id); 14547c478bd9Sstevel@tonic-gate if ((pools = pool_query_pools(conf, &nelem, props)) == NULL) { 14557c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 14567c478bd9Sstevel@tonic-gate return (NULL); 14577c478bd9Sstevel@tonic-gate } 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate if (nelem != 1) { 14607c478bd9Sstevel@tonic-gate free(pools); 14617c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 14627c478bd9Sstevel@tonic-gate return (NULL); 14637c478bd9Sstevel@tonic-gate } 14647c478bd9Sstevel@tonic-gate if (pool_get_ns_property(TO_ELEM(pools[0]), c_name, props[0]) 14657c478bd9Sstevel@tonic-gate == POC_INVAL) { 14667c478bd9Sstevel@tonic-gate free(pools); 14677c478bd9Sstevel@tonic-gate return (NULL); 14687c478bd9Sstevel@tonic-gate } 14697c478bd9Sstevel@tonic-gate if (pool_value_get_string(props[0], &sval) != PO_SUCCESS) { 14707c478bd9Sstevel@tonic-gate free(pools); 14717c478bd9Sstevel@tonic-gate return (NULL); 14727c478bd9Sstevel@tonic-gate } 14737c478bd9Sstevel@tonic-gate if ((name = strdup(sval)) == NULL) { 14747c478bd9Sstevel@tonic-gate free(pools); 14757c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 14767c478bd9Sstevel@tonic-gate return (NULL); 14777c478bd9Sstevel@tonic-gate } 14787c478bd9Sstevel@tonic-gate return (name); 14797c478bd9Sstevel@tonic-gate } 14807c478bd9Sstevel@tonic-gate 14817c478bd9Sstevel@tonic-gate /* 14827c478bd9Sstevel@tonic-gate * Bind idtype id to the pool name. 14837c478bd9Sstevel@tonic-gate */ 14847c478bd9Sstevel@tonic-gate int 14857c478bd9Sstevel@tonic-gate pool_knl_set_binding(pool_conf_t *conf, const char *pool_name, idtype_t idtype, 14867c478bd9Sstevel@tonic-gate id_t id) 14877c478bd9Sstevel@tonic-gate { 14887c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 14897c478bd9Sstevel@tonic-gate pool_bind_t bind; 14907c478bd9Sstevel@tonic-gate pool_t *pool; 14917c478bd9Sstevel@tonic-gate int ret; 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate if ((pool = pool_get_pool(conf, pool_name)) == NULL) 14947c478bd9Sstevel@tonic-gate return (PO_FAIL); 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate bind.pb_o_id_type = idtype; 14977c478bd9Sstevel@tonic-gate bind.pb_o_id = id; 14987c478bd9Sstevel@tonic-gate bind.pb_o_pool_id = elem_get_sysid(TO_ELEM(pool)); 14997c478bd9Sstevel@tonic-gate 15007c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_BIND, &bind)) < 0 && 1501*5ad42b1bSSurya Prakki errno == EAGAIN) 1502*5ad42b1bSSurya Prakki ; 15037c478bd9Sstevel@tonic-gate if (ret < 0) { 15047c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 15057c478bd9Sstevel@tonic-gate return (PO_FAIL); 15067c478bd9Sstevel@tonic-gate } 15077c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 15087c478bd9Sstevel@tonic-gate } 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate /* 15117c478bd9Sstevel@tonic-gate * pool_knl_get_resource_binding() returns the binding for a pid to 15127c478bd9Sstevel@tonic-gate * the supplied type of resource. If a binding cannot be determined, 15137c478bd9Sstevel@tonic-gate * NULL is returned. 15147c478bd9Sstevel@tonic-gate */ 15157c478bd9Sstevel@tonic-gate char * 15167c478bd9Sstevel@tonic-gate pool_knl_get_resource_binding(pool_conf_t *conf, 15177c478bd9Sstevel@tonic-gate pool_resource_elem_class_t type, pid_t pid) 15187c478bd9Sstevel@tonic-gate { 15197c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 15207c478bd9Sstevel@tonic-gate const char *sval; 15217c478bd9Sstevel@tonic-gate char *name = NULL; 15227c478bd9Sstevel@tonic-gate pool_bindq_t bindq; 15237c478bd9Sstevel@tonic-gate pool_value_t *props[] = { NULL, NULL }; 15247c478bd9Sstevel@tonic-gate uint_t nelem = 0; 15257c478bd9Sstevel@tonic-gate pool_t **pools; 15267c478bd9Sstevel@tonic-gate pool_resource_t **resources; 15277c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 15287c478bd9Sstevel@tonic-gate 15297c478bd9Sstevel@tonic-gate props[0] = &val; 15307c478bd9Sstevel@tonic-gate bindq.pb_o_id_type = P_PID; 15317c478bd9Sstevel@tonic-gate bindq.pb_o_id = pid; 15327c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_BINDQ, &bindq) < 0) { 15337c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 15347c478bd9Sstevel@tonic-gate return (NULL); 15357c478bd9Sstevel@tonic-gate } 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate if (pool_value_set_name(props[0], "pool.sys_id") != PO_SUCCESS) { 15387c478bd9Sstevel@tonic-gate return (NULL); 15397c478bd9Sstevel@tonic-gate } 15407c478bd9Sstevel@tonic-gate pool_value_set_int64(props[0], bindq.pb_i_id); 15417c478bd9Sstevel@tonic-gate if ((pools = pool_query_pools(conf, &nelem, props)) == NULL) { 15427c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 15437c478bd9Sstevel@tonic-gate return (NULL); 15447c478bd9Sstevel@tonic-gate } 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate if (nelem != 1) { 15477c478bd9Sstevel@tonic-gate free(pools); 15487c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 15497c478bd9Sstevel@tonic-gate return (NULL); 15507c478bd9Sstevel@tonic-gate } 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate if (pool_value_set_string(props[0], pool_resource_type_string(type)) != 15537c478bd9Sstevel@tonic-gate PO_SUCCESS || 15547c478bd9Sstevel@tonic-gate pool_value_set_name(props[0], c_type) != PO_SUCCESS) { 15557c478bd9Sstevel@tonic-gate free(pools); 15567c478bd9Sstevel@tonic-gate return (NULL); 15577c478bd9Sstevel@tonic-gate } 15587c478bd9Sstevel@tonic-gate 15597c478bd9Sstevel@tonic-gate if ((resources = pool_query_pool_resources(conf, pools[0], &nelem, 15607c478bd9Sstevel@tonic-gate NULL)) == NULL) { 15617c478bd9Sstevel@tonic-gate free(pools); 15627c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 15637c478bd9Sstevel@tonic-gate return (NULL); 15647c478bd9Sstevel@tonic-gate } 15657c478bd9Sstevel@tonic-gate free(pools); 15667c478bd9Sstevel@tonic-gate if (nelem != 1) { 15677c478bd9Sstevel@tonic-gate free(resources); 15687c478bd9Sstevel@tonic-gate pool_seterror(POE_INVALID_CONF); 15697c478bd9Sstevel@tonic-gate return (NULL); 15707c478bd9Sstevel@tonic-gate } 15717c478bd9Sstevel@tonic-gate if (pool_get_ns_property(TO_ELEM(resources[0]), c_name, props[0]) == 15727c478bd9Sstevel@tonic-gate POC_INVAL) { 15737c478bd9Sstevel@tonic-gate free(resources); 15747c478bd9Sstevel@tonic-gate return (NULL); 15757c478bd9Sstevel@tonic-gate } 15767c478bd9Sstevel@tonic-gate free(resources); 15777c478bd9Sstevel@tonic-gate if (pool_value_get_string(props[0], &sval) != PO_SUCCESS) { 15787c478bd9Sstevel@tonic-gate return (NULL); 15797c478bd9Sstevel@tonic-gate } 15807c478bd9Sstevel@tonic-gate if ((name = strdup(sval)) == NULL) { 15817c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 15827c478bd9Sstevel@tonic-gate return (NULL); 15837c478bd9Sstevel@tonic-gate } 15847c478bd9Sstevel@tonic-gate return (name); 15857c478bd9Sstevel@tonic-gate } 15867c478bd9Sstevel@tonic-gate 15877c478bd9Sstevel@tonic-gate /* 15887c478bd9Sstevel@tonic-gate * Allocate the required library data structure and initialise it. 15897c478bd9Sstevel@tonic-gate */ 15907c478bd9Sstevel@tonic-gate pool_knl_elem_t * 15917c478bd9Sstevel@tonic-gate pool_knl_elem_wrap(pool_conf_t *conf, pool_elem_class_t class, 15927c478bd9Sstevel@tonic-gate pool_resource_elem_class_t res_class, 15937c478bd9Sstevel@tonic-gate pool_component_elem_class_t comp_class) 15947c478bd9Sstevel@tonic-gate { 15957c478bd9Sstevel@tonic-gate pool_knl_elem_t *elem; 15967c478bd9Sstevel@tonic-gate pool_elem_t *pe; 15977c478bd9Sstevel@tonic-gate 15987c478bd9Sstevel@tonic-gate switch (class) { 15997c478bd9Sstevel@tonic-gate case PEC_SYSTEM: 16007c478bd9Sstevel@tonic-gate if ((elem = malloc(sizeof (pool_knl_system_t))) == NULL) { 16017c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 16027c478bd9Sstevel@tonic-gate return (NULL); 16037c478bd9Sstevel@tonic-gate } 16047c478bd9Sstevel@tonic-gate (void) memset(elem, 0, sizeof (pool_knl_system_t)); 16057c478bd9Sstevel@tonic-gate break; 16067c478bd9Sstevel@tonic-gate case PEC_POOL: 16077c478bd9Sstevel@tonic-gate if ((elem = malloc(sizeof (pool_knl_pool_t))) == NULL) { 16087c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 16097c478bd9Sstevel@tonic-gate return (NULL); 16107c478bd9Sstevel@tonic-gate } 16117c478bd9Sstevel@tonic-gate (void) memset(elem, 0, sizeof (pool_knl_pool_t)); 16127c478bd9Sstevel@tonic-gate break; 16137c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 16147c478bd9Sstevel@tonic-gate case PEC_RES_AGG: 16157c478bd9Sstevel@tonic-gate if ((elem = malloc(sizeof (pool_knl_resource_t))) == NULL) { 16167c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 16177c478bd9Sstevel@tonic-gate return (NULL); 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate (void) memset(elem, 0, sizeof (pool_knl_resource_t)); 16207c478bd9Sstevel@tonic-gate break; 16217c478bd9Sstevel@tonic-gate case PEC_COMP: 16227c478bd9Sstevel@tonic-gate if ((elem = malloc(sizeof (pool_knl_component_t))) == NULL) { 16237c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 16247c478bd9Sstevel@tonic-gate return (NULL); 16257c478bd9Sstevel@tonic-gate } 16267c478bd9Sstevel@tonic-gate (void) memset(elem, 0, sizeof (pool_knl_component_t)); 16277c478bd9Sstevel@tonic-gate break; 16287c478bd9Sstevel@tonic-gate default: 16297c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 16307c478bd9Sstevel@tonic-gate return (NULL); 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate pe = TO_ELEM(elem); 16337c478bd9Sstevel@tonic-gate pe->pe_conf = conf; 16347c478bd9Sstevel@tonic-gate pe->pe_class = class; 16357c478bd9Sstevel@tonic-gate pe->pe_resource_class = res_class; 16367c478bd9Sstevel@tonic-gate pe->pe_component_class = comp_class; 16377c478bd9Sstevel@tonic-gate /* Set up the function pointers for element manipulation */ 16387c478bd9Sstevel@tonic-gate pe->pe_get_prop = pool_knl_get_property; 16397c478bd9Sstevel@tonic-gate pe->pe_put_prop = pool_knl_put_property; 16407c478bd9Sstevel@tonic-gate pe->pe_rm_prop = pool_knl_rm_property; 16417c478bd9Sstevel@tonic-gate pe->pe_get_props = pool_knl_get_properties; 16427c478bd9Sstevel@tonic-gate pe->pe_remove = pool_knl_elem_remove; 16437c478bd9Sstevel@tonic-gate pe->pe_get_container = pool_knl_get_container; 16447c478bd9Sstevel@tonic-gate pe->pe_set_container = pool_knl_set_container; 16457c478bd9Sstevel@tonic-gate /* 16467c478bd9Sstevel@tonic-gate * Specific initialisation for different types of element 16477c478bd9Sstevel@tonic-gate */ 16487c478bd9Sstevel@tonic-gate if (class == PEC_POOL) { 16497c478bd9Sstevel@tonic-gate pool_knl_pool_t *pp = (pool_knl_pool_t *)elem; 16507c478bd9Sstevel@tonic-gate pp->pp_associate = pool_knl_pool_associate; 16517c478bd9Sstevel@tonic-gate pp->pp_dissociate = pool_knl_pool_dissociate; 16527c478bd9Sstevel@tonic-gate pp->pkp_assoc[PREC_PSET] = (pool_knl_resource_t *) 16537c478bd9Sstevel@tonic-gate resource_by_sysid(conf, PS_NONE, "pset"); 16547c478bd9Sstevel@tonic-gate } 16557c478bd9Sstevel@tonic-gate if (class == PEC_RES_COMP || class == PEC_RES_AGG) { 16567c478bd9Sstevel@tonic-gate pool_knl_resource_t *pr = (pool_knl_resource_t *)elem; 16577c478bd9Sstevel@tonic-gate pr->pr_is_system = pool_knl_resource_is_system; 16587c478bd9Sstevel@tonic-gate pr->pr_can_associate = pool_knl_resource_can_associate; 16597c478bd9Sstevel@tonic-gate } 16607c478bd9Sstevel@tonic-gate #if DEBUG 16617c478bd9Sstevel@tonic-gate if (dict_put(((pool_knl_connection_t *)conf->pc_prov)->pkc_leaks, 16627c478bd9Sstevel@tonic-gate elem, elem) != NULL) 16637c478bd9Sstevel@tonic-gate assert(!"leak map put failed"); 16647c478bd9Sstevel@tonic-gate dprintf("allocated %p\n", elem); 16657c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 16667c478bd9Sstevel@tonic-gate return (elem); 16677c478bd9Sstevel@tonic-gate } 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate /* 16707c478bd9Sstevel@tonic-gate * Allocate a new pool_knl_elem_t in the supplied configuration of the 16717c478bd9Sstevel@tonic-gate * specified class. 16727c478bd9Sstevel@tonic-gate * Returns element pointer/NULL 16737c478bd9Sstevel@tonic-gate */ 16747c478bd9Sstevel@tonic-gate pool_elem_t * 16757c478bd9Sstevel@tonic-gate pool_knl_elem_create(pool_conf_t *conf, pool_elem_class_t class, 16767c478bd9Sstevel@tonic-gate pool_resource_elem_class_t res_class, 16777c478bd9Sstevel@tonic-gate pool_component_elem_class_t comp_class) 16787c478bd9Sstevel@tonic-gate { 16797c478bd9Sstevel@tonic-gate pool_knl_elem_t *elem; 16807c478bd9Sstevel@tonic-gate pool_create_undo_t *create; 16817c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = (pool_knl_connection_t *)conf->pc_prov; 16827c478bd9Sstevel@tonic-gate static int id = -3; 16837c478bd9Sstevel@tonic-gate char_buf_t *cb; 16847c478bd9Sstevel@tonic-gate 16857c478bd9Sstevel@tonic-gate if ((elem = pool_knl_elem_wrap(conf, class, res_class, comp_class)) == 16867c478bd9Sstevel@tonic-gate NULL) 16877c478bd9Sstevel@tonic-gate return (NULL); 16887c478bd9Sstevel@tonic-gate 16897c478bd9Sstevel@tonic-gate /* 16907c478bd9Sstevel@tonic-gate * Allocate an nvlist to hold properties 16917c478bd9Sstevel@tonic-gate */ 16927c478bd9Sstevel@tonic-gate if (nvlist_alloc(&elem->pke_properties, NV_UNIQUE_NAME_TYPE, 0) != 0) { 16937c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_FALSE); 16947c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 16957c478bd9Sstevel@tonic-gate return (NULL); 16967c478bd9Sstevel@tonic-gate } 16977c478bd9Sstevel@tonic-gate /* 16987c478bd9Sstevel@tonic-gate * Allocate a temporary ID and name until the element is 16997c478bd9Sstevel@tonic-gate * created for real 17007c478bd9Sstevel@tonic-gate */ 17017c478bd9Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) { 17027c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 17037c478bd9Sstevel@tonic-gate return (NULL); 17047c478bd9Sstevel@tonic-gate } 17057c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s.sys_id", 17067c478bd9Sstevel@tonic-gate pool_elem_class_string((pool_elem_t *)elem)) != PO_SUCCESS) { 17077c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 17087c478bd9Sstevel@tonic-gate free_char_buf(cb); 17097c478bd9Sstevel@tonic-gate return (NULL); 17107c478bd9Sstevel@tonic-gate } 17117c478bd9Sstevel@tonic-gate (void) nvlist_add_int64(elem->pke_properties, cb->cb_buf, id--); 17127c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s.name", 17137c478bd9Sstevel@tonic-gate pool_elem_class_string((pool_elem_t *)elem)) != PO_SUCCESS) { 17147c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 17157c478bd9Sstevel@tonic-gate free_char_buf(cb); 17167c478bd9Sstevel@tonic-gate return (NULL); 17177c478bd9Sstevel@tonic-gate } 17187c478bd9Sstevel@tonic-gate (void) nvlist_add_string(elem->pke_properties, cb->cb_buf, ""); 17197c478bd9Sstevel@tonic-gate /* 17207c478bd9Sstevel@tonic-gate * If it's a resource class, it will need an initial size 17217c478bd9Sstevel@tonic-gate */ 17227c478bd9Sstevel@tonic-gate if (class == PEC_RES_COMP || class == PEC_RES_AGG) { 17237c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s.size", 17247c478bd9Sstevel@tonic-gate pool_elem_class_string((pool_elem_t *)elem)) != 17257c478bd9Sstevel@tonic-gate PO_SUCCESS) { 17267c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 17277c478bd9Sstevel@tonic-gate free_char_buf(cb); 17287c478bd9Sstevel@tonic-gate return (NULL); 17297c478bd9Sstevel@tonic-gate } 17307c478bd9Sstevel@tonic-gate (void) nvlist_add_uint64(elem->pke_properties, cb->cb_buf, 0); 17317c478bd9Sstevel@tonic-gate } 17327c478bd9Sstevel@tonic-gate free_char_buf(cb); 17337c478bd9Sstevel@tonic-gate 17347c478bd9Sstevel@tonic-gate /* 17357c478bd9Sstevel@tonic-gate * Register the newly created element 17367c478bd9Sstevel@tonic-gate */ 17377c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, elem, elem) != NULL) { 17387c478bd9Sstevel@tonic-gate pool_knl_elem_free(elem, PO_TRUE); 17397c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 17407c478bd9Sstevel@tonic-gate return (NULL); 17417c478bd9Sstevel@tonic-gate } 17427c478bd9Sstevel@tonic-gate 17437c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) 17447c478bd9Sstevel@tonic-gate return ((pool_elem_t *)elem); 17457c478bd9Sstevel@tonic-gate 17467c478bd9Sstevel@tonic-gate /* 17477c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 17487c478bd9Sstevel@tonic-gate * POOL_CREATE ioctl and appending the details into the log. 17497c478bd9Sstevel@tonic-gate */ 17507c478bd9Sstevel@tonic-gate if ((create = malloc(sizeof (pool_create_undo_t))) == NULL) { 17517c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 17527c478bd9Sstevel@tonic-gate return (NULL); 17537c478bd9Sstevel@tonic-gate } 17547c478bd9Sstevel@tonic-gate create->pcu_ioctl.pc_o_type = class; 17557c478bd9Sstevel@tonic-gate switch (class) { 17567c478bd9Sstevel@tonic-gate case PEC_SYSTEM: 17577c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 17587c478bd9Sstevel@tonic-gate free(create); 17597c478bd9Sstevel@tonic-gate return (NULL); 17607c478bd9Sstevel@tonic-gate case PEC_POOL: /* NO-OP */ 17617c478bd9Sstevel@tonic-gate break; 17627c478bd9Sstevel@tonic-gate case PEC_RES_COMP: 17637c478bd9Sstevel@tonic-gate case PEC_RES_AGG: 17647c478bd9Sstevel@tonic-gate create->pcu_ioctl.pc_o_sub_type = res_class; 17657c478bd9Sstevel@tonic-gate break; 17667c478bd9Sstevel@tonic-gate case PEC_COMP: 17677c478bd9Sstevel@tonic-gate create->pcu_ioctl.pc_o_sub_type = comp_class; 17687c478bd9Sstevel@tonic-gate break; 17697c478bd9Sstevel@tonic-gate default: 17707c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 17717c478bd9Sstevel@tonic-gate free(create); 17727c478bd9Sstevel@tonic-gate return (NULL); 17737c478bd9Sstevel@tonic-gate } 17747c478bd9Sstevel@tonic-gate 17757c478bd9Sstevel@tonic-gate create->pcu_elem = (pool_elem_t *)elem; 17767c478bd9Sstevel@tonic-gate 17777c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_CREATE, (void *)create) != 17787c478bd9Sstevel@tonic-gate PO_SUCCESS) { 17797c478bd9Sstevel@tonic-gate free(create); 17807c478bd9Sstevel@tonic-gate return (NULL); 17817c478bd9Sstevel@tonic-gate } 17827c478bd9Sstevel@tonic-gate return ((pool_elem_t *)elem); 17837c478bd9Sstevel@tonic-gate } 17847c478bd9Sstevel@tonic-gate 17857c478bd9Sstevel@tonic-gate /* 17867c478bd9Sstevel@tonic-gate * Remove the details of the element from our userland copy and destroy 17877c478bd9Sstevel@tonic-gate * the element (if appropriate) in the kernel. 17887c478bd9Sstevel@tonic-gate */ 17897c478bd9Sstevel@tonic-gate int 17907c478bd9Sstevel@tonic-gate pool_knl_elem_remove(pool_elem_t *pe) 17917c478bd9Sstevel@tonic-gate { 17927c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov; 17937c478bd9Sstevel@tonic-gate pool_destroy_undo_t *destroy; 17947c478bd9Sstevel@tonic-gate 17957c478bd9Sstevel@tonic-gate prov = (pool_knl_connection_t *)(TO_CONF(pe))->pc_prov; 17967c478bd9Sstevel@tonic-gate 17977c478bd9Sstevel@tonic-gate if (dict_remove(prov->pkc_elements, pe) == NULL) { 17987c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 17997c478bd9Sstevel@tonic-gate return (PO_FAIL); 18007c478bd9Sstevel@tonic-gate } 18017c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 18027c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 18037c478bd9Sstevel@tonic-gate } 18047c478bd9Sstevel@tonic-gate 18057c478bd9Sstevel@tonic-gate /* 18067c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 18077c478bd9Sstevel@tonic-gate * POOL_DESTROY ioctl and appending the details into the log. 18087c478bd9Sstevel@tonic-gate */ 18097c478bd9Sstevel@tonic-gate if ((destroy = malloc(sizeof (pool_destroy_undo_t))) == NULL) { 18107c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 18117c478bd9Sstevel@tonic-gate return (PO_FAIL); 18127c478bd9Sstevel@tonic-gate } 18137c478bd9Sstevel@tonic-gate destroy->pdu_ioctl.pd_o_type = pool_elem_class(pe); 18147c478bd9Sstevel@tonic-gate 18157c478bd9Sstevel@tonic-gate if (destroy->pdu_ioctl.pd_o_type == PEC_RES_COMP || 18167c478bd9Sstevel@tonic-gate destroy->pdu_ioctl.pd_o_type == PEC_RES_AGG) 18177c478bd9Sstevel@tonic-gate destroy->pdu_ioctl.pd_o_sub_type = pool_resource_elem_class(pe); 18187c478bd9Sstevel@tonic-gate 18197c478bd9Sstevel@tonic-gate if (destroy->pdu_ioctl.pd_o_type == PEC_COMP) 18207c478bd9Sstevel@tonic-gate destroy->pdu_ioctl.pd_o_sub_type = 18217c478bd9Sstevel@tonic-gate pool_component_elem_class(pe); 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate destroy->pdu_elem = pe; 18247c478bd9Sstevel@tonic-gate 18257c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_DESTROY, (void *)destroy) != 18267c478bd9Sstevel@tonic-gate PO_SUCCESS) { 18277c478bd9Sstevel@tonic-gate free(destroy); 18287c478bd9Sstevel@tonic-gate return (PO_FAIL); 18297c478bd9Sstevel@tonic-gate } 18307c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 18317c478bd9Sstevel@tonic-gate } 18327c478bd9Sstevel@tonic-gate 18337c478bd9Sstevel@tonic-gate /* 18347c478bd9Sstevel@tonic-gate * Set the parent of the supplied child to the supplied parent 18357c478bd9Sstevel@tonic-gate */ 18367c478bd9Sstevel@tonic-gate int 18377c478bd9Sstevel@tonic-gate pool_knl_set_container(pool_elem_t *pp, pool_elem_t *pc) 18387c478bd9Sstevel@tonic-gate { 18397c478bd9Sstevel@tonic-gate pool_knl_elem_t *pkp = (pool_knl_elem_t *)pp; 18407c478bd9Sstevel@tonic-gate pool_knl_elem_t *pkc = (pool_knl_elem_t *)pc; 18417c478bd9Sstevel@tonic-gate 18427c478bd9Sstevel@tonic-gate pkc->pke_parent = pkp; 18437c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 18447c478bd9Sstevel@tonic-gate } 18457c478bd9Sstevel@tonic-gate 18467c478bd9Sstevel@tonic-gate /* 18477c478bd9Sstevel@tonic-gate * TODO: Needed for msets and ssets. 18487c478bd9Sstevel@tonic-gate */ 18497c478bd9Sstevel@tonic-gate /* ARGSUSED */ 18507c478bd9Sstevel@tonic-gate int 18517c478bd9Sstevel@tonic-gate pool_knl_res_transfer(pool_resource_t *src, pool_resource_t *tgt, 18527c478bd9Sstevel@tonic-gate uint64_t size) { 18537c478bd9Sstevel@tonic-gate return (PO_FAIL); 18547c478bd9Sstevel@tonic-gate } 18557c478bd9Sstevel@tonic-gate 18567c478bd9Sstevel@tonic-gate /* 18577c478bd9Sstevel@tonic-gate * Transfer resource components from one resource set to another. 18587c478bd9Sstevel@tonic-gate */ 18597c478bd9Sstevel@tonic-gate int 18607c478bd9Sstevel@tonic-gate pool_knl_res_xtransfer(pool_resource_t *src, pool_resource_t *tgt, 18617c478bd9Sstevel@tonic-gate pool_component_t **rl) { 18627c478bd9Sstevel@tonic-gate pool_elem_t *src_e = TO_ELEM(src); 18637c478bd9Sstevel@tonic-gate pool_elem_t *tgt_e = TO_ELEM(tgt); 18647c478bd9Sstevel@tonic-gate pool_xtransfer_undo_t *xtransfer; 18657c478bd9Sstevel@tonic-gate size_t size; 18667c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = 18677c478bd9Sstevel@tonic-gate (pool_knl_connection_t *)TO_CONF(src_e)->pc_prov; 18687c478bd9Sstevel@tonic-gate 18697c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 18707c478bd9Sstevel@tonic-gate /* 18717c478bd9Sstevel@tonic-gate * Walk the Result Set and move the resource components 18727c478bd9Sstevel@tonic-gate */ 18737c478bd9Sstevel@tonic-gate for (size = 0; rl[size] != NULL; size++) { 18747c478bd9Sstevel@tonic-gate if (pool_set_container(TO_ELEM(tgt), 18757c478bd9Sstevel@tonic-gate TO_ELEM(rl[size])) == PO_FAIL) { 18767c478bd9Sstevel@tonic-gate return (PO_FAIL); 18777c478bd9Sstevel@tonic-gate } 18787c478bd9Sstevel@tonic-gate } 18797c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 18807c478bd9Sstevel@tonic-gate } 18817c478bd9Sstevel@tonic-gate 18827c478bd9Sstevel@tonic-gate /* 18837c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 18847c478bd9Sstevel@tonic-gate * POOL_XTRANSFER ioctl and appending the details into the log. 18857c478bd9Sstevel@tonic-gate */ 18867c478bd9Sstevel@tonic-gate if ((xtransfer = malloc(sizeof (pool_xtransfer_undo_t))) == NULL) { 18877c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 18887c478bd9Sstevel@tonic-gate return (PO_FAIL); 18897c478bd9Sstevel@tonic-gate } 18907c478bd9Sstevel@tonic-gate 18917c478bd9Sstevel@tonic-gate if (pool_elem_class(src_e) == PEC_RES_COMP) { 18927c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_id_type = 18937c478bd9Sstevel@tonic-gate pool_resource_elem_class(src_e); 18947c478bd9Sstevel@tonic-gate } else { 18957c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 18967c478bd9Sstevel@tonic-gate return (PO_FAIL); 18977c478bd9Sstevel@tonic-gate } 18987c478bd9Sstevel@tonic-gate 18997c478bd9Sstevel@tonic-gate 19007c478bd9Sstevel@tonic-gate for (xtransfer->pxu_ioctl.px_o_complist_size = 0; 19017c478bd9Sstevel@tonic-gate rl[xtransfer->pxu_ioctl.px_o_complist_size] != NULL; 19027c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_complist_size++) 19037c478bd9Sstevel@tonic-gate /* calculate the size using the terminating NULL */; 19047c478bd9Sstevel@tonic-gate if ((xtransfer->pxu_ioctl.px_o_comp_list = 19057c478bd9Sstevel@tonic-gate calloc(xtransfer->pxu_ioctl.px_o_complist_size, 19067c478bd9Sstevel@tonic-gate sizeof (id_t))) == NULL) { 19077c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 19087c478bd9Sstevel@tonic-gate return (PO_FAIL); 19097c478bd9Sstevel@tonic-gate } 19107c478bd9Sstevel@tonic-gate if ((xtransfer->pxu_rl = calloc( 19117c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_complist_size + 1, 19127c478bd9Sstevel@tonic-gate sizeof (pool_component_t *))) == NULL) { 19137c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 19147c478bd9Sstevel@tonic-gate return (PO_FAIL); 19157c478bd9Sstevel@tonic-gate } 19167c478bd9Sstevel@tonic-gate (void) memcpy(xtransfer->pxu_rl, rl, 19177c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_complist_size * 19187c478bd9Sstevel@tonic-gate sizeof (pool_component_t *)); 19197c478bd9Sstevel@tonic-gate xtransfer->pxu_src = src_e; 19207c478bd9Sstevel@tonic-gate xtransfer->pxu_tgt = tgt_e; 19217c478bd9Sstevel@tonic-gate 19227c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_XTRANSFER, (void *)xtransfer) != 19237c478bd9Sstevel@tonic-gate PO_SUCCESS) { 19247c478bd9Sstevel@tonic-gate free(xtransfer); 19257c478bd9Sstevel@tonic-gate return (PO_FAIL); 19267c478bd9Sstevel@tonic-gate } 19277c478bd9Sstevel@tonic-gate for (size = 0; rl[size] != NULL; size++) { 19287c478bd9Sstevel@tonic-gate if (pool_set_container(TO_ELEM(tgt), TO_ELEM(rl[size])) == 19297c478bd9Sstevel@tonic-gate PO_FAIL) { 19307c478bd9Sstevel@tonic-gate return (PO_FAIL); 19317c478bd9Sstevel@tonic-gate } 19327c478bd9Sstevel@tonic-gate } 19337c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 19347c478bd9Sstevel@tonic-gate } 19357c478bd9Sstevel@tonic-gate 19367c478bd9Sstevel@tonic-gate /* 19377c478bd9Sstevel@tonic-gate * Return the parent of an element. 19387c478bd9Sstevel@tonic-gate */ 19397c478bd9Sstevel@tonic-gate pool_elem_t * 19407c478bd9Sstevel@tonic-gate pool_knl_get_container(const pool_elem_t *pe) 19417c478bd9Sstevel@tonic-gate { 19427c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)pe; 19437c478bd9Sstevel@tonic-gate 19447c478bd9Sstevel@tonic-gate return ((pool_elem_t *)pke->pke_parent); 19457c478bd9Sstevel@tonic-gate } 19467c478bd9Sstevel@tonic-gate 19477c478bd9Sstevel@tonic-gate /* 19487c478bd9Sstevel@tonic-gate * Note: This function is resource specific, needs extending for other 19497c478bd9Sstevel@tonic-gate * resource types 19507c478bd9Sstevel@tonic-gate */ 19517c478bd9Sstevel@tonic-gate int 19527c478bd9Sstevel@tonic-gate pool_knl_resource_is_system(const pool_resource_t *pr) 19537c478bd9Sstevel@tonic-gate { 19547c478bd9Sstevel@tonic-gate switch (pool_resource_elem_class(TO_ELEM(pr))) { 19557c478bd9Sstevel@tonic-gate case PREC_PSET: 19567c478bd9Sstevel@tonic-gate return (PSID_IS_SYSSET( 19577c478bd9Sstevel@tonic-gate elem_get_sysid(TO_ELEM(pr)))); 19587c478bd9Sstevel@tonic-gate default: 19597c478bd9Sstevel@tonic-gate return (PO_FALSE); 19607c478bd9Sstevel@tonic-gate } 19617c478bd9Sstevel@tonic-gate } 19627c478bd9Sstevel@tonic-gate 19637c478bd9Sstevel@tonic-gate /* 19647c478bd9Sstevel@tonic-gate * Note: This function is resource specific, needs extending for other 19657c478bd9Sstevel@tonic-gate * resource types 19667c478bd9Sstevel@tonic-gate */ 19677c478bd9Sstevel@tonic-gate int 19687c478bd9Sstevel@tonic-gate pool_knl_resource_can_associate(const pool_resource_t *pr) 19697c478bd9Sstevel@tonic-gate { 19707c478bd9Sstevel@tonic-gate switch (pool_resource_elem_class(TO_ELEM(pr))) { 19717c478bd9Sstevel@tonic-gate case PREC_PSET: 19727c478bd9Sstevel@tonic-gate return (PO_TRUE); 19737c478bd9Sstevel@tonic-gate default: 19747c478bd9Sstevel@tonic-gate return (PO_FALSE); 19757c478bd9Sstevel@tonic-gate } 19767c478bd9Sstevel@tonic-gate } 19777c478bd9Sstevel@tonic-gate 19787c478bd9Sstevel@tonic-gate /* 19797c478bd9Sstevel@tonic-gate * pool_knl_pool_associate() associates the supplied resource to the 19807c478bd9Sstevel@tonic-gate * supplied pool. 19817c478bd9Sstevel@tonic-gate * 19827c478bd9Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL 19837c478bd9Sstevel@tonic-gate */ 19847c478bd9Sstevel@tonic-gate int 19857c478bd9Sstevel@tonic-gate pool_knl_pool_associate(pool_t *pool, const pool_resource_t *resource) 19867c478bd9Sstevel@tonic-gate { 19877c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov; 19887c478bd9Sstevel@tonic-gate pool_knl_pool_t *pkp = (pool_knl_pool_t *)pool; 19897c478bd9Sstevel@tonic-gate pool_resource_elem_class_t res_class = 19907c478bd9Sstevel@tonic-gate pool_resource_elem_class(TO_ELEM(resource)); 19917c478bd9Sstevel@tonic-gate pool_assoc_undo_t *assoc; 19927c478bd9Sstevel@tonic-gate pool_knl_resource_t *orig_res = pkp->pkp_assoc[res_class]; 19937c478bd9Sstevel@tonic-gate 19947c478bd9Sstevel@tonic-gate /* 19957c478bd9Sstevel@tonic-gate * Are we allowed to associate with this target? 19967c478bd9Sstevel@tonic-gate */ 19977c478bd9Sstevel@tonic-gate if (pool_knl_resource_can_associate(resource) == PO_FALSE) { 19987c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 19997c478bd9Sstevel@tonic-gate return (PO_FAIL); 20007c478bd9Sstevel@tonic-gate } 20017c478bd9Sstevel@tonic-gate prov = (pool_knl_connection_t *)(TO_CONF(TO_ELEM(pool)))->pc_prov; 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 20047c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = (pool_knl_resource_t *)resource; 20057c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 20067c478bd9Sstevel@tonic-gate } 20077c478bd9Sstevel@tonic-gate 20087c478bd9Sstevel@tonic-gate /* 20097c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 20107c478bd9Sstevel@tonic-gate * POOL_ASSOC ioctl and appending the details into the log. 20117c478bd9Sstevel@tonic-gate */ 20127c478bd9Sstevel@tonic-gate if ((assoc = malloc(sizeof (pool_assoc_undo_t))) == NULL) { 20137c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 20147c478bd9Sstevel@tonic-gate return (PO_FAIL); 20157c478bd9Sstevel@tonic-gate } 20167c478bd9Sstevel@tonic-gate assoc->pau_assoc = TO_ELEM(pool); 20177c478bd9Sstevel@tonic-gate assoc->pau_oldres = (pool_elem_t *)orig_res; 20187c478bd9Sstevel@tonic-gate assoc->pau_newres = TO_ELEM(resource); 20197c478bd9Sstevel@tonic-gate 20207c478bd9Sstevel@tonic-gate assoc->pau_ioctl.pa_o_id_type = res_class; 20217c478bd9Sstevel@tonic-gate 20227c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_ASSOC, (void *)assoc) != 20237c478bd9Sstevel@tonic-gate PO_SUCCESS) { 20247c478bd9Sstevel@tonic-gate free(assoc); 20257c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = orig_res; 20267c478bd9Sstevel@tonic-gate return (PO_FAIL); 20277c478bd9Sstevel@tonic-gate } 20287c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = (pool_knl_resource_t *)resource; 20297c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 20307c478bd9Sstevel@tonic-gate } 20317c478bd9Sstevel@tonic-gate 20327c478bd9Sstevel@tonic-gate /* 20337c478bd9Sstevel@tonic-gate * pool_knl_pool_dissociate() dissociates the supplied resource from 20347c478bd9Sstevel@tonic-gate * the supplied pool. 20357c478bd9Sstevel@tonic-gate * 20367c478bd9Sstevel@tonic-gate * Returns: PO_SUCCESS/PO_FAIL 20377c478bd9Sstevel@tonic-gate */ 20387c478bd9Sstevel@tonic-gate int 20397c478bd9Sstevel@tonic-gate pool_knl_pool_dissociate(pool_t *pool, const pool_resource_t *resource) 20407c478bd9Sstevel@tonic-gate { 20417c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov; 20427c478bd9Sstevel@tonic-gate pool_dissoc_undo_t *dissoc; 20437c478bd9Sstevel@tonic-gate pool_knl_pool_t *pkp = (pool_knl_pool_t *)pool; 20447c478bd9Sstevel@tonic-gate pool_resource_t *default_res = (pool_resource_t *)get_default_resource( 20457c478bd9Sstevel@tonic-gate resource); 20467c478bd9Sstevel@tonic-gate pool_resource_elem_class_t res_class = 20477c478bd9Sstevel@tonic-gate pool_resource_elem_class(TO_ELEM(resource)); 20487c478bd9Sstevel@tonic-gate 20497c478bd9Sstevel@tonic-gate prov = (pool_knl_connection_t *)(TO_CONF(TO_ELEM(pool)))->pc_prov; 20507c478bd9Sstevel@tonic-gate 20517c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 20527c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = (pool_knl_resource_t *)default_res; 20537c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 20547c478bd9Sstevel@tonic-gate } 20557c478bd9Sstevel@tonic-gate /* 20567c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 20577c478bd9Sstevel@tonic-gate * POOL_DISSOC ioctl and appending the details into the log. 20587c478bd9Sstevel@tonic-gate */ 20597c478bd9Sstevel@tonic-gate if ((dissoc = malloc(sizeof (pool_dissoc_undo_t))) == NULL) { 20607c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 20617c478bd9Sstevel@tonic-gate return (PO_FAIL); 20627c478bd9Sstevel@tonic-gate } 20637c478bd9Sstevel@tonic-gate dissoc->pdu_dissoc = TO_ELEM(pool); 20647c478bd9Sstevel@tonic-gate dissoc->pdu_oldres = TO_ELEM(resource); 20657c478bd9Sstevel@tonic-gate dissoc->pdu_newres = TO_ELEM(default_res); 20667c478bd9Sstevel@tonic-gate 20677c478bd9Sstevel@tonic-gate dissoc->pdu_ioctl.pd_o_id_type = res_class; 20687c478bd9Sstevel@tonic-gate 20697c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_DISSOC, (void *)dissoc) != 20707c478bd9Sstevel@tonic-gate PO_SUCCESS) { 20717c478bd9Sstevel@tonic-gate free(dissoc); 20727c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = (pool_knl_resource_t *)resource; 20737c478bd9Sstevel@tonic-gate return (PO_FAIL); 20747c478bd9Sstevel@tonic-gate } 20757c478bd9Sstevel@tonic-gate 20767c478bd9Sstevel@tonic-gate /* 20777c478bd9Sstevel@tonic-gate * Update our local copy 20787c478bd9Sstevel@tonic-gate */ 20797c478bd9Sstevel@tonic-gate pkp->pkp_assoc[res_class] = (pool_knl_resource_t *)default_res; 20807c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 20817c478bd9Sstevel@tonic-gate } 20827c478bd9Sstevel@tonic-gate 20837c478bd9Sstevel@tonic-gate /* 20847c478bd9Sstevel@tonic-gate * Allocate a data provider for the supplied configuration and optionally 20857c478bd9Sstevel@tonic-gate * discover resources. 20867c478bd9Sstevel@tonic-gate * The data provider is the cross over point from the "abstract" configuration 20877c478bd9Sstevel@tonic-gate * functions into the data representation specific manipulation routines. 20887c478bd9Sstevel@tonic-gate * This function sets up all the required pointers to create a kernel aware 20897c478bd9Sstevel@tonic-gate * data provider. 20907c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 20917c478bd9Sstevel@tonic-gate */ 20927c478bd9Sstevel@tonic-gate int 20937c478bd9Sstevel@tonic-gate pool_knl_connection_alloc(pool_conf_t *conf, int oflags) 20947c478bd9Sstevel@tonic-gate { 20957c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov; 20967c478bd9Sstevel@tonic-gate 20977c478bd9Sstevel@tonic-gate if ((prov = malloc(sizeof (pool_knl_connection_t))) == NULL) { 20987c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 20997c478bd9Sstevel@tonic-gate return (PO_FAIL); 21007c478bd9Sstevel@tonic-gate } 21017c478bd9Sstevel@tonic-gate (void) memset(prov, 0, sizeof (pool_knl_connection_t)); 21027c478bd9Sstevel@tonic-gate /* 21037c478bd9Sstevel@tonic-gate * Initialise data members 21047c478bd9Sstevel@tonic-gate */ 21057c478bd9Sstevel@tonic-gate prov->pc_name = strdup("kernel"); 21067c478bd9Sstevel@tonic-gate prov->pc_store_type = KERNEL_DATA_STORE; 21077c478bd9Sstevel@tonic-gate prov->pc_oflags = oflags; 21087c478bd9Sstevel@tonic-gate /* 21097c478bd9Sstevel@tonic-gate * Initialise function pointers 21107c478bd9Sstevel@tonic-gate */ 21117c478bd9Sstevel@tonic-gate prov->pc_close = pool_knl_close; 21127c478bd9Sstevel@tonic-gate prov->pc_validate = pool_knl_validate; 21137c478bd9Sstevel@tonic-gate prov->pc_commit = pool_knl_commit; 21147c478bd9Sstevel@tonic-gate prov->pc_export = pool_knl_export; 21157c478bd9Sstevel@tonic-gate prov->pc_rollback = pool_knl_rollback; 21167c478bd9Sstevel@tonic-gate prov->pc_exec_query = pool_knl_exec_query; 21177c478bd9Sstevel@tonic-gate prov->pc_elem_create = pool_knl_elem_create; 21187c478bd9Sstevel@tonic-gate prov->pc_remove = pool_knl_remove; 21197c478bd9Sstevel@tonic-gate prov->pc_res_xfer = pool_knl_res_transfer; 21207c478bd9Sstevel@tonic-gate prov->pc_res_xxfer = pool_knl_res_xtransfer; 21217c478bd9Sstevel@tonic-gate prov->pc_get_binding = pool_knl_get_binding; 21227c478bd9Sstevel@tonic-gate prov->pc_set_binding = pool_knl_set_binding; 21237c478bd9Sstevel@tonic-gate prov->pc_get_resource_binding = pool_knl_get_resource_binding; 21247c478bd9Sstevel@tonic-gate /* 21257c478bd9Sstevel@tonic-gate * Associate the provider to it's configuration 21267c478bd9Sstevel@tonic-gate */ 21277c478bd9Sstevel@tonic-gate conf->pc_prov = (pool_connection_t *)prov; 21287c478bd9Sstevel@tonic-gate /* 21297c478bd9Sstevel@tonic-gate * End of common initialisation 21307c478bd9Sstevel@tonic-gate */ 21317c478bd9Sstevel@tonic-gate /* 21327c478bd9Sstevel@tonic-gate * Attempt to open the pseudo device, if the configuration is opened 21337c478bd9Sstevel@tonic-gate * readonly then try to open an info device, otherwise try to open 21347c478bd9Sstevel@tonic-gate * the writeable device. 21357c478bd9Sstevel@tonic-gate */ 21367c478bd9Sstevel@tonic-gate if (oflags & PO_RDWR) { 21377c478bd9Sstevel@tonic-gate if ((prov->pkc_fd = blocking_open(pool_dynamic_location(), 21387c478bd9Sstevel@tonic-gate O_RDWR)) < 0) { 21397c478bd9Sstevel@tonic-gate free(prov); 21407c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 21417c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 21427c478bd9Sstevel@tonic-gate return (PO_FAIL); 21437c478bd9Sstevel@tonic-gate } 21447c478bd9Sstevel@tonic-gate } else { 21457c478bd9Sstevel@tonic-gate if ((prov->pkc_fd = open(pool_info_location, O_RDWR)) < 0) { 21467c478bd9Sstevel@tonic-gate free(prov); 21477c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 21487c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 21497c478bd9Sstevel@tonic-gate return (PO_FAIL); 21507c478bd9Sstevel@tonic-gate } 21517c478bd9Sstevel@tonic-gate } 21527c478bd9Sstevel@tonic-gate /* 21537c478bd9Sstevel@tonic-gate * Allocate the element dictionary 21547c478bd9Sstevel@tonic-gate */ 21557c478bd9Sstevel@tonic-gate if ((prov->pkc_elements = dict_new((int (*)(const void *, const void *)) 21567c478bd9Sstevel@tonic-gate pool_elem_compare, (uint64_t (*)(const void *))hash_id)) == NULL) { 21577c478bd9Sstevel@tonic-gate (void) close(prov->pkc_fd); 21587c478bd9Sstevel@tonic-gate free(prov); 21597c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 21607c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 21617c478bd9Sstevel@tonic-gate return (PO_FAIL); 21627c478bd9Sstevel@tonic-gate } 21637c478bd9Sstevel@tonic-gate #if DEBUG 21647c478bd9Sstevel@tonic-gate if ((prov->pkc_leaks = dict_new(NULL, NULL)) == NULL) { 21657c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_elements); 21667c478bd9Sstevel@tonic-gate (void) close(prov->pkc_fd); 21677c478bd9Sstevel@tonic-gate free(prov); 21687c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 21697c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 21707c478bd9Sstevel@tonic-gate return (PO_FAIL); 21717c478bd9Sstevel@tonic-gate } 21727c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 21737c478bd9Sstevel@tonic-gate /* 21747c478bd9Sstevel@tonic-gate * Allocate the transaction log 21757c478bd9Sstevel@tonic-gate */ 21767c478bd9Sstevel@tonic-gate if ((prov->pkc_log = log_alloc(conf)) == NULL) { 21777c478bd9Sstevel@tonic-gate #if DEBUG 21787c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_leaks); 21797c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 21807c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_elements); 21817c478bd9Sstevel@tonic-gate (void) close(prov->pkc_fd); 21827c478bd9Sstevel@tonic-gate free(prov); 21837c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 21847c478bd9Sstevel@tonic-gate return (PO_FAIL); 21857c478bd9Sstevel@tonic-gate } 21867c478bd9Sstevel@tonic-gate /* 21877c478bd9Sstevel@tonic-gate * At this point the configuration provider has been initialized, 21887c478bd9Sstevel@tonic-gate * mark the configuration as valid so that the various routines 21897c478bd9Sstevel@tonic-gate * which rely on a valid configuration will work correctly. 21907c478bd9Sstevel@tonic-gate */ 21917c478bd9Sstevel@tonic-gate conf->pc_state = POF_VALID; 21927c478bd9Sstevel@tonic-gate /* 21937c478bd9Sstevel@tonic-gate * Update the library snapshot from the kernel 21947c478bd9Sstevel@tonic-gate */ 21957c478bd9Sstevel@tonic-gate if (pool_knl_update(conf, NULL) != PO_SUCCESS) { 21967c478bd9Sstevel@tonic-gate #if DEBUG 21977c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_leaks); 21987c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 21997c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_elements); 22007c478bd9Sstevel@tonic-gate (void) close(prov->pkc_fd); 22017c478bd9Sstevel@tonic-gate free(prov); 22027c478bd9Sstevel@tonic-gate conf->pc_prov = NULL; 22037c478bd9Sstevel@tonic-gate conf->pc_state = POF_INVALID; 22047c478bd9Sstevel@tonic-gate return (PO_FAIL); 22057c478bd9Sstevel@tonic-gate } 22067c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 22077c478bd9Sstevel@tonic-gate } 22087c478bd9Sstevel@tonic-gate 22097c478bd9Sstevel@tonic-gate #if DEBUG 22107c478bd9Sstevel@tonic-gate static void 22117c478bd9Sstevel@tonic-gate pool_knl_elem_printf_cb(const void *key, void **value, void *cl) 22127c478bd9Sstevel@tonic-gate { 22137c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)key; 22147c478bd9Sstevel@tonic-gate dict_hdl_t *map = (dict_hdl_t *)cl; 22157c478bd9Sstevel@tonic-gate 22167c478bd9Sstevel@tonic-gate dprintf("leak elem:%p\n", pke); 22177c478bd9Sstevel@tonic-gate if (pke->pke_properties != NULL) { 22187c478bd9Sstevel@tonic-gate nvlist_print(stdout, pke->pke_properties); 22197c478bd9Sstevel@tonic-gate } else 22207c478bd9Sstevel@tonic-gate dprintf("no properties\n"); 22217c478bd9Sstevel@tonic-gate assert(dict_get(map, pke) == NULL); 22227c478bd9Sstevel@tonic-gate } 22237c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 22247c478bd9Sstevel@tonic-gate /* 22257c478bd9Sstevel@tonic-gate * pool_knl_elem_free() releases the resources associated with the 22267c478bd9Sstevel@tonic-gate * supplied element. 22277c478bd9Sstevel@tonic-gate */ 22287c478bd9Sstevel@tonic-gate static void 22297c478bd9Sstevel@tonic-gate pool_knl_elem_free(pool_knl_elem_t *pke, int freeprop) 22307c478bd9Sstevel@tonic-gate { 22317c478bd9Sstevel@tonic-gate #if DEBUG 22327c478bd9Sstevel@tonic-gate pool_conf_t *conf = TO_CONF(TO_ELEM(pke)); 22337c478bd9Sstevel@tonic-gate if (dict_remove(((pool_knl_connection_t *)conf->pc_prov)->pkc_leaks, 22347c478bd9Sstevel@tonic-gate pke) == NULL) 22357c478bd9Sstevel@tonic-gate dprintf("%p, wasn't in the leak map\n", pke); 22367c478bd9Sstevel@tonic-gate if (freeprop == PO_TRUE) { 22377c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(pke)); 22387c478bd9Sstevel@tonic-gate } 22397c478bd9Sstevel@tonic-gate dprintf("released %p\n", pke); 22407c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 22417c478bd9Sstevel@tonic-gate if (freeprop == PO_TRUE) { 22427c478bd9Sstevel@tonic-gate nvlist_free(pke->pke_properties); 22437c478bd9Sstevel@tonic-gate } 22447c478bd9Sstevel@tonic-gate free(pke); 22457c478bd9Sstevel@tonic-gate } 22467c478bd9Sstevel@tonic-gate 22477c478bd9Sstevel@tonic-gate /* 22487c478bd9Sstevel@tonic-gate * pool_knl_elem_free_cb() is designed to be used with 22497c478bd9Sstevel@tonic-gate * dict_map(). When a connection is freed, this function is used to 22507c478bd9Sstevel@tonic-gate * free all element resources. 22517c478bd9Sstevel@tonic-gate */ 22527c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 22537c478bd9Sstevel@tonic-gate static void 22547c478bd9Sstevel@tonic-gate pool_knl_elem_free_cb(const void *key, void **value, void *cl) 22557c478bd9Sstevel@tonic-gate { 22567c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)key; 22577c478bd9Sstevel@tonic-gate 22587c478bd9Sstevel@tonic-gate #ifdef DEBUG 22597c478bd9Sstevel@tonic-gate dprintf("pool_knl_elem_free_cb:\n"); 22607c478bd9Sstevel@tonic-gate dprintf("about to release %p ", pke); 22617c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(pke)); 22627c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 22637c478bd9Sstevel@tonic-gate pool_knl_elem_free(pke, PO_TRUE); 22647c478bd9Sstevel@tonic-gate } 22657c478bd9Sstevel@tonic-gate 22667c478bd9Sstevel@tonic-gate /* 22677c478bd9Sstevel@tonic-gate * Free the resources for a kernel data provider. 22687c478bd9Sstevel@tonic-gate */ 22697c478bd9Sstevel@tonic-gate void 22707c478bd9Sstevel@tonic-gate pool_knl_connection_free(pool_knl_connection_t *prov) 22717c478bd9Sstevel@tonic-gate { 22727c478bd9Sstevel@tonic-gate if (prov->pkc_log != NULL) { 22737c478bd9Sstevel@tonic-gate (void) log_walk(prov->pkc_log, log_item_release); 22747c478bd9Sstevel@tonic-gate log_free(prov->pkc_log); 22757c478bd9Sstevel@tonic-gate } 22767c478bd9Sstevel@tonic-gate if (prov->pkc_elements != NULL) { 22777c478bd9Sstevel@tonic-gate dict_map(prov->pkc_elements, pool_knl_elem_free_cb, NULL); 22787c478bd9Sstevel@tonic-gate #if DEBUG 22797c478bd9Sstevel@tonic-gate dprintf("dict length is %llu\n", dict_length(prov->pkc_leaks)); 22807c478bd9Sstevel@tonic-gate dict_map(prov->pkc_leaks, pool_knl_elem_printf_cb, 22817c478bd9Sstevel@tonic-gate prov->pkc_elements); 22827c478bd9Sstevel@tonic-gate assert(dict_length(prov->pkc_leaks) == 0); 22837c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_leaks); 22847c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 22857c478bd9Sstevel@tonic-gate dict_free(&prov->pkc_elements); 22867c478bd9Sstevel@tonic-gate } 22877c478bd9Sstevel@tonic-gate free((void *)prov->pc_name); 22887c478bd9Sstevel@tonic-gate free(prov); 22897c478bd9Sstevel@tonic-gate } 22907c478bd9Sstevel@tonic-gate 22917c478bd9Sstevel@tonic-gate /* 22927c478bd9Sstevel@tonic-gate * Return the specified property value. 22937c478bd9Sstevel@tonic-gate * 22947c478bd9Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated 22957c478bd9Sstevel@tonic-gate * to indicate the cause of the error. 22967c478bd9Sstevel@tonic-gate */ 22977c478bd9Sstevel@tonic-gate pool_value_class_t 22987c478bd9Sstevel@tonic-gate pool_knl_get_property(const pool_elem_t *pe, const char *name, 22997c478bd9Sstevel@tonic-gate pool_value_t *val) 23007c478bd9Sstevel@tonic-gate { 23017c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)pe; 23027c478bd9Sstevel@tonic-gate nvpair_t *pair; 23037c478bd9Sstevel@tonic-gate const pool_prop_t *prop; 23047c478bd9Sstevel@tonic-gate 23057c478bd9Sstevel@tonic-gate if ((prop = provider_get_prop(pe, name)) != NULL) 23067c478bd9Sstevel@tonic-gate if (prop_is_stored(prop) == PO_FALSE) 23077c478bd9Sstevel@tonic-gate return (pool_knl_get_dynamic_property(pe, name, val)); 23087c478bd9Sstevel@tonic-gate 23097c478bd9Sstevel@tonic-gate if ((pair = pool_knl_find_nvpair(pke->pke_properties, name)) == NULL) { 23107c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 23117c478bd9Sstevel@tonic-gate return (POC_INVAL); 23127c478bd9Sstevel@tonic-gate } 23137c478bd9Sstevel@tonic-gate 23147c478bd9Sstevel@tonic-gate if (pool_value_from_nvpair(val, pair) == PO_FAIL) { 23157c478bd9Sstevel@tonic-gate return (POC_INVAL); 23167c478bd9Sstevel@tonic-gate } 23177c478bd9Sstevel@tonic-gate 23187c478bd9Sstevel@tonic-gate return (pool_value_get_type(val)); 23197c478bd9Sstevel@tonic-gate } 23207c478bd9Sstevel@tonic-gate 23217c478bd9Sstevel@tonic-gate /* 23227c478bd9Sstevel@tonic-gate * Return the specified property value. 23237c478bd9Sstevel@tonic-gate * 23247c478bd9Sstevel@tonic-gate * If a property is designated as dynamic, then this function will 23257c478bd9Sstevel@tonic-gate * always try to return the latest value of the property from the 23267c478bd9Sstevel@tonic-gate * kernel. 23277c478bd9Sstevel@tonic-gate * 23287c478bd9Sstevel@tonic-gate * POC_INVAL is returned if an error is detected and the error code is updated 23297c478bd9Sstevel@tonic-gate * to indicate the cause of the error. 23307c478bd9Sstevel@tonic-gate */ 23317c478bd9Sstevel@tonic-gate pool_value_class_t 23327c478bd9Sstevel@tonic-gate pool_knl_get_dynamic_property(const pool_elem_t *pe, const char *name, 23337c478bd9Sstevel@tonic-gate pool_value_t *val) 23347c478bd9Sstevel@tonic-gate { 23357c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov; 23367c478bd9Sstevel@tonic-gate pool_propget_t propget = { 0 }; 23377c478bd9Sstevel@tonic-gate nvlist_t *proplist; 23387c478bd9Sstevel@tonic-gate nvpair_t *pair; 23397c478bd9Sstevel@tonic-gate 23407c478bd9Sstevel@tonic-gate propget.pp_o_id_type = pool_elem_class(pe); 23417c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_RES_COMP || 23427c478bd9Sstevel@tonic-gate pool_elem_class(pe) == PEC_RES_AGG) 23437c478bd9Sstevel@tonic-gate propget.pp_o_id_subtype = pool_resource_elem_class(pe); 23447c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_COMP) 23457c478bd9Sstevel@tonic-gate propget.pp_o_id_subtype = 23467c478bd9Sstevel@tonic-gate (pool_resource_elem_class_t)pool_component_elem_class(pe); 23477c478bd9Sstevel@tonic-gate 23487c478bd9Sstevel@tonic-gate propget.pp_o_id = elem_get_sysid(pe); 23497c478bd9Sstevel@tonic-gate propget.pp_o_prop_name_size = strlen(name); 23507c478bd9Sstevel@tonic-gate propget.pp_o_prop_name = (char *)name; 23517c478bd9Sstevel@tonic-gate propget.pp_i_bufsize = KERNEL_SNAPSHOT_BUF_SZ; 23527c478bd9Sstevel@tonic-gate propget.pp_i_buf = malloc(KERNEL_SNAPSHOT_BUF_SZ); 23537c478bd9Sstevel@tonic-gate bzero(propget.pp_i_buf, KERNEL_SNAPSHOT_BUF_SZ); 23547c478bd9Sstevel@tonic-gate 23557c478bd9Sstevel@tonic-gate prov = (pool_knl_connection_t *)(TO_CONF(pe))->pc_prov; 23567c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPGET, &propget) < 0) { 23577c478bd9Sstevel@tonic-gate free(propget.pp_i_buf); 23587c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 23597c478bd9Sstevel@tonic-gate return (POC_INVAL); 23607c478bd9Sstevel@tonic-gate } 23617c478bd9Sstevel@tonic-gate if (nvlist_unpack(propget.pp_i_buf, propget.pp_i_bufsize, 23627c478bd9Sstevel@tonic-gate &proplist, 0) != 0) { 23637c478bd9Sstevel@tonic-gate free(propget.pp_i_buf); 23647c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 23657c478bd9Sstevel@tonic-gate return (POC_INVAL); 23667c478bd9Sstevel@tonic-gate } 23677c478bd9Sstevel@tonic-gate free(propget.pp_i_buf); 23687c478bd9Sstevel@tonic-gate 23697c478bd9Sstevel@tonic-gate if ((pair = nvlist_next_nvpair(proplist, NULL)) == NULL) { 23707c478bd9Sstevel@tonic-gate nvlist_free(proplist); 23717c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 23727c478bd9Sstevel@tonic-gate return (POC_INVAL); 23737c478bd9Sstevel@tonic-gate } 23747c478bd9Sstevel@tonic-gate 23757c478bd9Sstevel@tonic-gate if (pool_value_from_nvpair(val, pair) == PO_FAIL) { 23767c478bd9Sstevel@tonic-gate nvlist_free(proplist); 23777c478bd9Sstevel@tonic-gate return (POC_INVAL); 23787c478bd9Sstevel@tonic-gate } 23797c478bd9Sstevel@tonic-gate nvlist_free(proplist); 23807c478bd9Sstevel@tonic-gate return (pool_value_get_type(val)); 23817c478bd9Sstevel@tonic-gate } 23827c478bd9Sstevel@tonic-gate 23837c478bd9Sstevel@tonic-gate /* 23847c478bd9Sstevel@tonic-gate * Update the specified property value. 23857c478bd9Sstevel@tonic-gate * 23867c478bd9Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is updated 23877c478bd9Sstevel@tonic-gate * to indicate the cause of the error. 23887c478bd9Sstevel@tonic-gate */ 23897c478bd9Sstevel@tonic-gate int 23907c478bd9Sstevel@tonic-gate pool_knl_put_property(pool_elem_t *pe, const char *name, 23917c478bd9Sstevel@tonic-gate const pool_value_t *val) 23927c478bd9Sstevel@tonic-gate { 23937c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)pe; 23947c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = 23957c478bd9Sstevel@tonic-gate (pool_knl_connection_t *)(TO_CONF(pe))->pc_prov; 23967c478bd9Sstevel@tonic-gate nvpair_t *bp, *ap; 23977c478bd9Sstevel@tonic-gate pool_propput_undo_t *propput; 23987c478bd9Sstevel@tonic-gate nvlist_t *bl = NULL; 23997c478bd9Sstevel@tonic-gate const pool_prop_t *prop; 24007c478bd9Sstevel@tonic-gate 24017c478bd9Sstevel@tonic-gate if ((bp = pool_knl_find_nvpair(pke->pke_properties, name)) != NULL) { 24027c478bd9Sstevel@tonic-gate if (nvlist_alloc(&bl, NV_UNIQUE_NAME_TYPE, 0) != 0) { 24037c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24047c478bd9Sstevel@tonic-gate return (PO_FAIL); 24057c478bd9Sstevel@tonic-gate } 24067c478bd9Sstevel@tonic-gate if (nvlist_add_nvpair(bl, bp) != 0) { 24077c478bd9Sstevel@tonic-gate nvlist_free(bl); 24087c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24097c478bd9Sstevel@tonic-gate return (PO_FAIL); 24107c478bd9Sstevel@tonic-gate } 24117c478bd9Sstevel@tonic-gate } 24127c478bd9Sstevel@tonic-gate if (pool_knl_nvlist_add_value(pke->pke_properties, name, val) != 24137c478bd9Sstevel@tonic-gate PO_SUCCESS) 24147c478bd9Sstevel@tonic-gate return (PO_FAIL); 24157c478bd9Sstevel@tonic-gate 24167c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 24177c478bd9Sstevel@tonic-gate if (bl) 24187c478bd9Sstevel@tonic-gate nvlist_free(bl); 24197c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 24207c478bd9Sstevel@tonic-gate } 24217c478bd9Sstevel@tonic-gate /* 24227c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 24237c478bd9Sstevel@tonic-gate * POOL_PROPPUT ioctl and appending the details into the log. 24247c478bd9Sstevel@tonic-gate */ 24257c478bd9Sstevel@tonic-gate if ((propput = malloc(sizeof (pool_propput_undo_t))) == NULL) { 24267c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24277c478bd9Sstevel@tonic-gate return (PO_FAIL); 24287c478bd9Sstevel@tonic-gate } 24297c478bd9Sstevel@tonic-gate (void) memset(propput, 0, sizeof (pool_propput_undo_t)); 24307c478bd9Sstevel@tonic-gate propput->ppu_blist = bl; 24317c478bd9Sstevel@tonic-gate 24327c478bd9Sstevel@tonic-gate ap = pool_knl_find_nvpair(pke->pke_properties, name); 24337c478bd9Sstevel@tonic-gate 24347c478bd9Sstevel@tonic-gate if (nvlist_alloc(&propput->ppu_alist, NV_UNIQUE_NAME_TYPE, 0) != 0) { 24357c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_blist); 24367c478bd9Sstevel@tonic-gate free(propput); 24377c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24387c478bd9Sstevel@tonic-gate return (PO_FAIL); 24397c478bd9Sstevel@tonic-gate } 24407c478bd9Sstevel@tonic-gate if (nvlist_add_nvpair(propput->ppu_alist, ap) != 0) { 24417c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_blist); 24427c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_alist); 24437c478bd9Sstevel@tonic-gate free(propput); 24447c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24457c478bd9Sstevel@tonic-gate return (PO_FAIL); 24467c478bd9Sstevel@tonic-gate } 24477c478bd9Sstevel@tonic-gate 24487c478bd9Sstevel@tonic-gate if (nvlist_pack(propput->ppu_alist, 24497c478bd9Sstevel@tonic-gate (char **)&propput->ppu_ioctl.pp_o_buf, 24507c478bd9Sstevel@tonic-gate &propput->ppu_ioctl.pp_o_bufsize, NV_ENCODE_NATIVE, 0) != 0) { 24517c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 24527c478bd9Sstevel@tonic-gate return (PO_FAIL); 24537c478bd9Sstevel@tonic-gate } 24547c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_alist); 24557c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id_type = pool_elem_class(pe); 24567c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_RES_COMP || 24577c478bd9Sstevel@tonic-gate pool_elem_class(pe) == PEC_RES_AGG) 24587c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id_sub_type = 24597c478bd9Sstevel@tonic-gate pool_resource_elem_class(pe); 24607c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_COMP) 24617c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id_sub_type = 24627c478bd9Sstevel@tonic-gate (pool_resource_elem_class_t)pool_component_elem_class(pe); 24637c478bd9Sstevel@tonic-gate 24647c478bd9Sstevel@tonic-gate propput->ppu_elem = pe; 24657c478bd9Sstevel@tonic-gate if ((prop = provider_get_prop(propput->ppu_elem, name)) != NULL) { 24667c478bd9Sstevel@tonic-gate if (prop_is_readonly(prop) == PO_TRUE) 24677c478bd9Sstevel@tonic-gate propput->ppu_doioctl |= KERNEL_PROP_RDONLY; 24687c478bd9Sstevel@tonic-gate } 24697c478bd9Sstevel@tonic-gate 24707c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_PROPPUT, (void *)propput) != 24717c478bd9Sstevel@tonic-gate PO_SUCCESS) { 24727c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_blist); 24737c478bd9Sstevel@tonic-gate free(propput); 24747c478bd9Sstevel@tonic-gate return (PO_FAIL); 24757c478bd9Sstevel@tonic-gate } 24767c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 24777c478bd9Sstevel@tonic-gate } 24787c478bd9Sstevel@tonic-gate 24797c478bd9Sstevel@tonic-gate /* 24807c478bd9Sstevel@tonic-gate * Remove the specified property value. 24817c478bd9Sstevel@tonic-gate * 24827c478bd9Sstevel@tonic-gate * PO_FAIL is returned if an error is detected and the error code is 24837c478bd9Sstevel@tonic-gate * updated to indicate the cause of the error. 24847c478bd9Sstevel@tonic-gate */ 24857c478bd9Sstevel@tonic-gate int 24867c478bd9Sstevel@tonic-gate pool_knl_rm_property(pool_elem_t *pe, const char *name) 24877c478bd9Sstevel@tonic-gate { 24887c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)pe; 24897c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = 24907c478bd9Sstevel@tonic-gate (pool_knl_connection_t *)(TO_CONF(pe))->pc_prov; 24917c478bd9Sstevel@tonic-gate pool_proprm_undo_t *proprm; 24927c478bd9Sstevel@tonic-gate 24937c478bd9Sstevel@tonic-gate if (pool_knl_find_nvpair(pke->pke_properties, name) == NULL) { 24947c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 24957c478bd9Sstevel@tonic-gate return (PO_FAIL); 24967c478bd9Sstevel@tonic-gate } 24977c478bd9Sstevel@tonic-gate 24987c478bd9Sstevel@tonic-gate if ((proprm = malloc(sizeof (pool_proprm_undo_t))) == NULL) { 24997c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 25007c478bd9Sstevel@tonic-gate return (PO_FAIL); 25017c478bd9Sstevel@tonic-gate } 25027c478bd9Sstevel@tonic-gate (void) memset(proprm, 0, sizeof (pool_proprm_undo_t)); 25037c478bd9Sstevel@tonic-gate proprm->pru_oldval.pv_class = POC_INVAL; 25047c478bd9Sstevel@tonic-gate (void) pool_get_property(TO_CONF(pe), pe, name, &proprm->pru_oldval); 25057c478bd9Sstevel@tonic-gate 25067c478bd9Sstevel@tonic-gate if (prov->pkc_log->l_state != LS_DO) { 25077c478bd9Sstevel@tonic-gate free(proprm); 25087c478bd9Sstevel@tonic-gate (void) nvlist_remove_all(pke->pke_properties, (char *)name); 25097c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 25107c478bd9Sstevel@tonic-gate } 25117c478bd9Sstevel@tonic-gate /* 25127c478bd9Sstevel@tonic-gate * The remaining logic is setting up the arguments for the 25137c478bd9Sstevel@tonic-gate * POOL_PROPRM ioctl and appending the details into the log. 25147c478bd9Sstevel@tonic-gate */ 25157c478bd9Sstevel@tonic-gate 25167c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_id_type = pool_elem_class(pe); 25177c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_RES_COMP || 25187c478bd9Sstevel@tonic-gate pool_elem_class(pe) == PEC_RES_AGG) 25197c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_id_sub_type = 25207c478bd9Sstevel@tonic-gate pool_resource_elem_class(pe); 25217c478bd9Sstevel@tonic-gate 25227c478bd9Sstevel@tonic-gate if (pool_elem_class(pe) == PEC_COMP) 25237c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_id_sub_type = 25247c478bd9Sstevel@tonic-gate (pool_resource_elem_class_t)pool_component_elem_class(pe); 25257c478bd9Sstevel@tonic-gate 25267c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_prop_name_size = strlen(name); 25277c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_prop_name = 25287c478bd9Sstevel@tonic-gate (char *)pool_value_get_name(&proprm->pru_oldval); 25297c478bd9Sstevel@tonic-gate proprm->pru_elem = pe; 25307c478bd9Sstevel@tonic-gate 25317c478bd9Sstevel@tonic-gate if (log_append(prov->pkc_log, POOL_PROPRM, (void *)proprm) != 25327c478bd9Sstevel@tonic-gate PO_SUCCESS) { 25337c478bd9Sstevel@tonic-gate free(proprm); 25347c478bd9Sstevel@tonic-gate return (PO_FAIL); 25357c478bd9Sstevel@tonic-gate } 25367c478bd9Sstevel@tonic-gate 25377c478bd9Sstevel@tonic-gate (void) nvlist_remove_all(pke->pke_properties, (char *)name); 25387c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 25397c478bd9Sstevel@tonic-gate } 25407c478bd9Sstevel@tonic-gate 25417c478bd9Sstevel@tonic-gate /* 25427c478bd9Sstevel@tonic-gate * Return a NULL terminated array of pool_value_t which represents all 25437c478bd9Sstevel@tonic-gate * of the properties stored for an element 25447c478bd9Sstevel@tonic-gate * 25457c478bd9Sstevel@tonic-gate * Return NULL on failure. It is the caller's responsibility to free 25467c478bd9Sstevel@tonic-gate * the returned array of values. 25477c478bd9Sstevel@tonic-gate */ 25487c478bd9Sstevel@tonic-gate pool_value_t ** 25497c478bd9Sstevel@tonic-gate pool_knl_get_properties(const pool_elem_t *pe, uint_t *nprops) 25507c478bd9Sstevel@tonic-gate { 25517c478bd9Sstevel@tonic-gate nvpair_t *pair; 25527c478bd9Sstevel@tonic-gate pool_value_t **result; 25537c478bd9Sstevel@tonic-gate pool_knl_elem_t *pke = (pool_knl_elem_t *)pe; 25547c478bd9Sstevel@tonic-gate int i = 0; 25557c478bd9Sstevel@tonic-gate 25567c478bd9Sstevel@tonic-gate *nprops = 0; 25577c478bd9Sstevel@tonic-gate 25587c478bd9Sstevel@tonic-gate for (pair = nvlist_next_nvpair(pke->pke_properties, NULL); pair != NULL; 2559*5ad42b1bSSurya Prakki pair = nvlist_next_nvpair(pke->pke_properties, pair)) 25607c478bd9Sstevel@tonic-gate (*nprops)++; 25617c478bd9Sstevel@tonic-gate if ((result = calloc(*nprops + 1, sizeof (pool_value_t *))) == NULL) { 25627c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 25637c478bd9Sstevel@tonic-gate return (NULL); 25647c478bd9Sstevel@tonic-gate } 25657c478bd9Sstevel@tonic-gate for (pair = nvlist_next_nvpair(pke->pke_properties, NULL); pair != NULL; 25667c478bd9Sstevel@tonic-gate pair = nvlist_next_nvpair(pke->pke_properties, pair), i++) { 25677c478bd9Sstevel@tonic-gate result[i] = pool_value_alloc(); 25687c478bd9Sstevel@tonic-gate if (pool_value_from_nvpair(result[i], pair) == PO_FAIL) { 25697c478bd9Sstevel@tonic-gate while (i-- >= 0) 25707c478bd9Sstevel@tonic-gate pool_value_free(result[i]); 25717c478bd9Sstevel@tonic-gate free(result); 25727c478bd9Sstevel@tonic-gate return (NULL); 25737c478bd9Sstevel@tonic-gate } 25747c478bd9Sstevel@tonic-gate } 25757c478bd9Sstevel@tonic-gate return (result); 25767c478bd9Sstevel@tonic-gate } 25777c478bd9Sstevel@tonic-gate 25787c478bd9Sstevel@tonic-gate /* 25797c478bd9Sstevel@tonic-gate * Append an entry to a result set. Reallocate the array used to store 25807c478bd9Sstevel@tonic-gate * results if it's full. 25817c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 25827c478bd9Sstevel@tonic-gate */ 25837c478bd9Sstevel@tonic-gate int 25847c478bd9Sstevel@tonic-gate pool_knl_result_set_append(pool_knl_result_set_t *rs, pool_knl_elem_t *pke) 25857c478bd9Sstevel@tonic-gate { 25867c478bd9Sstevel@tonic-gate if (rs->pkr_count == rs->pkr_size) 25877c478bd9Sstevel@tonic-gate if (pool_knl_result_set_realloc(rs) != PO_SUCCESS) 25887c478bd9Sstevel@tonic-gate return (PO_FAIL); 25897c478bd9Sstevel@tonic-gate 25907c478bd9Sstevel@tonic-gate rs->pkr_list[rs->pkr_count++] = pke; 25917c478bd9Sstevel@tonic-gate 25927c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 25937c478bd9Sstevel@tonic-gate } 25947c478bd9Sstevel@tonic-gate 25957c478bd9Sstevel@tonic-gate /* 25967c478bd9Sstevel@tonic-gate * Resize the array used to store results. A simple doubling strategy 25977c478bd9Sstevel@tonic-gate * is used. 25987c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 25997c478bd9Sstevel@tonic-gate */ 26007c478bd9Sstevel@tonic-gate int 26017c478bd9Sstevel@tonic-gate pool_knl_result_set_realloc(pool_knl_result_set_t *rs) 26027c478bd9Sstevel@tonic-gate { 26037c478bd9Sstevel@tonic-gate pool_knl_elem_t **old_list = rs->pkr_list; 26047c478bd9Sstevel@tonic-gate int new_size = rs->pkr_size * 2; 26057c478bd9Sstevel@tonic-gate 26067c478bd9Sstevel@tonic-gate if ((rs->pkr_list = realloc(rs->pkr_list, 26077c478bd9Sstevel@tonic-gate new_size * sizeof (pool_knl_elem_t *))) == NULL) { 26087c478bd9Sstevel@tonic-gate rs->pkr_list = old_list; 26097c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 26107c478bd9Sstevel@tonic-gate return (PO_FAIL); 26117c478bd9Sstevel@tonic-gate } 26127c478bd9Sstevel@tonic-gate rs->pkr_size = new_size; 26137c478bd9Sstevel@tonic-gate 26147c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 26157c478bd9Sstevel@tonic-gate } 26167c478bd9Sstevel@tonic-gate 26177c478bd9Sstevel@tonic-gate /* 26187c478bd9Sstevel@tonic-gate * Allocate a result set. The Result Set stores the result of a query. 26197c478bd9Sstevel@tonic-gate * Returns pool_knl_result_set_t pointer/NULL 26207c478bd9Sstevel@tonic-gate */ 26217c478bd9Sstevel@tonic-gate pool_knl_result_set_t * 26227c478bd9Sstevel@tonic-gate pool_knl_result_set_alloc(const pool_conf_t *conf) 26237c478bd9Sstevel@tonic-gate { 26247c478bd9Sstevel@tonic-gate pool_knl_result_set_t *rs; 26257c478bd9Sstevel@tonic-gate 26267c478bd9Sstevel@tonic-gate if ((rs = malloc(sizeof (pool_knl_result_set_t))) == NULL) { 26277c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 26287c478bd9Sstevel@tonic-gate return (NULL); 26297c478bd9Sstevel@tonic-gate } 26307c478bd9Sstevel@tonic-gate (void) memset(rs, 0, sizeof (pool_knl_result_set_t)); 26317c478bd9Sstevel@tonic-gate rs->pkr_size = KERNEL_RS_INITIAL_SZ; 26327c478bd9Sstevel@tonic-gate if (pool_knl_result_set_realloc(rs) == PO_FAIL) { 26337c478bd9Sstevel@tonic-gate free(rs); 26347c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 26357c478bd9Sstevel@tonic-gate return (NULL); 26367c478bd9Sstevel@tonic-gate } 26377c478bd9Sstevel@tonic-gate rs->prs_conf = conf; 26387c478bd9Sstevel@tonic-gate rs->prs_index = -1; 26397c478bd9Sstevel@tonic-gate rs->prs_active = PO_TRUE; 26407c478bd9Sstevel@tonic-gate /* Fix up the result set accessor functions to the knl specfic ones */ 26417c478bd9Sstevel@tonic-gate rs->prs_next = pool_knl_rs_next; 26427c478bd9Sstevel@tonic-gate rs->prs_prev = pool_knl_rs_prev; 26437c478bd9Sstevel@tonic-gate rs->prs_first = pool_knl_rs_first; 26447c478bd9Sstevel@tonic-gate rs->prs_last = pool_knl_rs_last; 26457c478bd9Sstevel@tonic-gate rs->prs_get_index = pool_knl_rs_get_index; 26467c478bd9Sstevel@tonic-gate rs->prs_set_index = pool_knl_rs_set_index; 26477c478bd9Sstevel@tonic-gate rs->prs_close = pool_knl_rs_close; 26487c478bd9Sstevel@tonic-gate rs->prs_count = pool_knl_rs_count; 26497c478bd9Sstevel@tonic-gate return (rs); 26507c478bd9Sstevel@tonic-gate } 26517c478bd9Sstevel@tonic-gate 26527c478bd9Sstevel@tonic-gate /* 26537c478bd9Sstevel@tonic-gate * Free a result set. Ensure that the resources are all released at 26547c478bd9Sstevel@tonic-gate * this point. 26557c478bd9Sstevel@tonic-gate */ 26567c478bd9Sstevel@tonic-gate void 26577c478bd9Sstevel@tonic-gate pool_knl_result_set_free(pool_knl_result_set_t *rs) 26587c478bd9Sstevel@tonic-gate { 26597c478bd9Sstevel@tonic-gate free(rs->pkr_list); 26607c478bd9Sstevel@tonic-gate free(rs); 26617c478bd9Sstevel@tonic-gate } 26627c478bd9Sstevel@tonic-gate /* 26637c478bd9Sstevel@tonic-gate * Return the next element in a result set. 26647c478bd9Sstevel@tonic-gate * Returns pool_elem_t pointer/NULL 26657c478bd9Sstevel@tonic-gate */ 26667c478bd9Sstevel@tonic-gate pool_elem_t * 26677c478bd9Sstevel@tonic-gate pool_knl_rs_next(pool_result_set_t *set) 26687c478bd9Sstevel@tonic-gate { 26697c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 26707c478bd9Sstevel@tonic-gate 26717c478bd9Sstevel@tonic-gate if (kset->prs_index == kset->pkr_count - 1) 26727c478bd9Sstevel@tonic-gate return (NULL); 26737c478bd9Sstevel@tonic-gate return ((pool_elem_t *)kset->pkr_list[++kset->prs_index]); 26747c478bd9Sstevel@tonic-gate } 26757c478bd9Sstevel@tonic-gate 26767c478bd9Sstevel@tonic-gate /* 26777c478bd9Sstevel@tonic-gate * Return the previous element in a result set. 26787c478bd9Sstevel@tonic-gate * Returns pool_elem_t pointer/NULL 26797c478bd9Sstevel@tonic-gate */ 26807c478bd9Sstevel@tonic-gate pool_elem_t * 26817c478bd9Sstevel@tonic-gate pool_knl_rs_prev(pool_result_set_t *set) 26827c478bd9Sstevel@tonic-gate { 26837c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 26847c478bd9Sstevel@tonic-gate 26857c478bd9Sstevel@tonic-gate if (kset->prs_index < 0) 26867c478bd9Sstevel@tonic-gate return (NULL); 26877c478bd9Sstevel@tonic-gate return ((pool_elem_t *)kset->pkr_list[kset->prs_index--]); 26887c478bd9Sstevel@tonic-gate } 26897c478bd9Sstevel@tonic-gate 26907c478bd9Sstevel@tonic-gate /* 26917c478bd9Sstevel@tonic-gate * Sets the current index in a result set. 26927c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 26937c478bd9Sstevel@tonic-gate */ 26947c478bd9Sstevel@tonic-gate int 26957c478bd9Sstevel@tonic-gate pool_knl_rs_set_index(pool_result_set_t *set, int index) 26967c478bd9Sstevel@tonic-gate { 26977c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 26987c478bd9Sstevel@tonic-gate 26997c478bd9Sstevel@tonic-gate if (index < 0 || index >= kset->pkr_count) { 27007c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 27017c478bd9Sstevel@tonic-gate return (PO_FAIL); 27027c478bd9Sstevel@tonic-gate } 27037c478bd9Sstevel@tonic-gate kset->prs_index = index; 27047c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 27057c478bd9Sstevel@tonic-gate } 27067c478bd9Sstevel@tonic-gate 27077c478bd9Sstevel@tonic-gate /* 27087c478bd9Sstevel@tonic-gate * Return the current index in a result set. 27097c478bd9Sstevel@tonic-gate * Returns current index 27107c478bd9Sstevel@tonic-gate */ 27117c478bd9Sstevel@tonic-gate int 27127c478bd9Sstevel@tonic-gate pool_knl_rs_get_index(pool_result_set_t *set) 27137c478bd9Sstevel@tonic-gate { 27147c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 27157c478bd9Sstevel@tonic-gate 27167c478bd9Sstevel@tonic-gate return (kset->prs_index); 27177c478bd9Sstevel@tonic-gate } 27187c478bd9Sstevel@tonic-gate 27197c478bd9Sstevel@tonic-gate /* 27207c478bd9Sstevel@tonic-gate * Return the first element in a result set. 27217c478bd9Sstevel@tonic-gate * Returns pool_elem_t pointer/NULL 27227c478bd9Sstevel@tonic-gate */ 27237c478bd9Sstevel@tonic-gate pool_elem_t * 27247c478bd9Sstevel@tonic-gate pool_knl_rs_first(pool_result_set_t *set) 27257c478bd9Sstevel@tonic-gate { 27267c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 27277c478bd9Sstevel@tonic-gate 27287c478bd9Sstevel@tonic-gate return ((pool_elem_t *)kset->pkr_list[0]); 27297c478bd9Sstevel@tonic-gate } 27307c478bd9Sstevel@tonic-gate 27317c478bd9Sstevel@tonic-gate /* 27327c478bd9Sstevel@tonic-gate * Return the last element in a result set. 27337c478bd9Sstevel@tonic-gate * Returns pool_elem_t pointer/NULL 27347c478bd9Sstevel@tonic-gate */ 27357c478bd9Sstevel@tonic-gate pool_elem_t * 27367c478bd9Sstevel@tonic-gate pool_knl_rs_last(pool_result_set_t *set) 27377c478bd9Sstevel@tonic-gate { 27387c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 27397c478bd9Sstevel@tonic-gate 27407c478bd9Sstevel@tonic-gate return ((pool_elem_t *)kset->pkr_list[kset->pkr_count - 1]); 27417c478bd9Sstevel@tonic-gate } 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate /* 27447c478bd9Sstevel@tonic-gate * Return the number of results in a result set. 27457c478bd9Sstevel@tonic-gate * Returns result count 27467c478bd9Sstevel@tonic-gate */ 27477c478bd9Sstevel@tonic-gate int 27487c478bd9Sstevel@tonic-gate pool_knl_rs_count(pool_result_set_t *set) 27497c478bd9Sstevel@tonic-gate { 27507c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 27517c478bd9Sstevel@tonic-gate 27527c478bd9Sstevel@tonic-gate return (kset->pkr_count); 27537c478bd9Sstevel@tonic-gate } 27547c478bd9Sstevel@tonic-gate 27557c478bd9Sstevel@tonic-gate 27567c478bd9Sstevel@tonic-gate /* 27577c478bd9Sstevel@tonic-gate * Close a result set. Free the resources 27587c478bd9Sstevel@tonic-gate * Returns PO_SUCCESS/PO_FAIL 27597c478bd9Sstevel@tonic-gate */ 27607c478bd9Sstevel@tonic-gate int 27617c478bd9Sstevel@tonic-gate pool_knl_rs_close(pool_result_set_t *set) 27627c478bd9Sstevel@tonic-gate { 27637c478bd9Sstevel@tonic-gate pool_knl_result_set_t *kset = (pool_knl_result_set_t *)set; 27647c478bd9Sstevel@tonic-gate 27657c478bd9Sstevel@tonic-gate pool_knl_result_set_free(kset); 27667c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 27677c478bd9Sstevel@tonic-gate } 27687c478bd9Sstevel@tonic-gate 27697c478bd9Sstevel@tonic-gate /* 27707c478bd9Sstevel@tonic-gate * Commit an individual transaction log item(). This processing is 27717c478bd9Sstevel@tonic-gate * essential to the pool_conf_commit() logic. When pool_conf_commit() 27727c478bd9Sstevel@tonic-gate * is invoked, the pending transaction log for the configuration is 27737c478bd9Sstevel@tonic-gate * walked and all pending changes to the kernel are invoked. If a 27747c478bd9Sstevel@tonic-gate * change succeeds it is marked in the log as successful and 27757c478bd9Sstevel@tonic-gate * processing continues, if it fails then failure is returned and the 27767c478bd9Sstevel@tonic-gate * log will be "rolled back" to undo changes to the library snapshot 27777c478bd9Sstevel@tonic-gate * and the kernel. 27787c478bd9Sstevel@tonic-gate */ 27797c478bd9Sstevel@tonic-gate int 27807c478bd9Sstevel@tonic-gate log_item_commit(log_item_t *li) 27817c478bd9Sstevel@tonic-gate { 27827c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = 27837c478bd9Sstevel@tonic-gate (pool_knl_connection_t *)li->li_log->l_conf->pc_prov; 27847c478bd9Sstevel@tonic-gate pool_create_undo_t *create; 27857c478bd9Sstevel@tonic-gate pool_destroy_undo_t *destroy; 27867c478bd9Sstevel@tonic-gate pool_assoc_undo_t *assoc; 27877c478bd9Sstevel@tonic-gate pool_dissoc_undo_t *dissoc; 27887c478bd9Sstevel@tonic-gate pool_propput_undo_t *propput; 27897c478bd9Sstevel@tonic-gate pool_proprm_undo_t *proprm; 27907c478bd9Sstevel@tonic-gate pool_xtransfer_undo_t *xtransfer; 27917c478bd9Sstevel@tonic-gate char_buf_t *cb; 27927c478bd9Sstevel@tonic-gate size_t size; 27937c478bd9Sstevel@tonic-gate pool_elem_t *pair; 27947c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 27957c478bd9Sstevel@tonic-gate int ret; 27967c478bd9Sstevel@tonic-gate 27977c478bd9Sstevel@tonic-gate switch (li->li_op) { 27987c478bd9Sstevel@tonic-gate case POOL_CREATE: 27997c478bd9Sstevel@tonic-gate create = (pool_create_undo_t *)li->li_details; 28007c478bd9Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) 28017c478bd9Sstevel@tonic-gate return (PO_FAIL); 28027c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s.sys_id", 28037c478bd9Sstevel@tonic-gate pool_elem_class_string(create->pcu_elem)) != PO_SUCCESS) { 28047c478bd9Sstevel@tonic-gate free_char_buf(cb); 28057c478bd9Sstevel@tonic-gate return (PO_FAIL); 28067c478bd9Sstevel@tonic-gate } 28077c478bd9Sstevel@tonic-gate #ifdef DEBUG 28087c478bd9Sstevel@tonic-gate dprintf("log_item_commit: POOL_CREATE, remove from dict\n"); 28097c478bd9Sstevel@tonic-gate pool_elem_dprintf(create->pcu_elem); 28107c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 28117c478bd9Sstevel@tonic-gate /* 28127c478bd9Sstevel@tonic-gate * May not need to remove the element if it was 28137c478bd9Sstevel@tonic-gate * already destroyed before commit. Just cast the 28147c478bd9Sstevel@tonic-gate * return to void. 28157c478bd9Sstevel@tonic-gate */ 28167c478bd9Sstevel@tonic-gate (void) dict_remove(prov->pkc_elements, 28177c478bd9Sstevel@tonic-gate (pool_knl_elem_t *)create->pcu_elem); 28187c478bd9Sstevel@tonic-gate 28197c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_CREATE, &create->pcu_ioctl) < 0) { 28207c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 28217c478bd9Sstevel@tonic-gate return (PO_FAIL); 28227c478bd9Sstevel@tonic-gate } 28237c478bd9Sstevel@tonic-gate /* 28247c478bd9Sstevel@tonic-gate * Now that we have created our element in the kernel, 28257c478bd9Sstevel@tonic-gate * it has a valid allocated system id. Remove the 28267c478bd9Sstevel@tonic-gate * element from the element dictionary, using the 28277c478bd9Sstevel@tonic-gate * current key, and then re-insert under the new key. 28287c478bd9Sstevel@tonic-gate */ 28297c478bd9Sstevel@tonic-gate #ifdef DEBUG 28307c478bd9Sstevel@tonic-gate pool_elem_dprintf(create->pcu_elem); 28317c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 28327c478bd9Sstevel@tonic-gate assert(nvlist_add_int64( 28337c478bd9Sstevel@tonic-gate ((pool_knl_elem_t *)create->pcu_elem)->pke_properties, 28347c478bd9Sstevel@tonic-gate cb->cb_buf, create->pcu_ioctl.pc_i_id) == 0); 28357c478bd9Sstevel@tonic-gate free_char_buf(cb); 28367c478bd9Sstevel@tonic-gate assert(dict_put(prov->pkc_elements, create->pcu_elem, 28377c478bd9Sstevel@tonic-gate create->pcu_elem) == NULL); 28387c478bd9Sstevel@tonic-gate /* 28397c478bd9Sstevel@tonic-gate * If the element has a pair in the static 28407c478bd9Sstevel@tonic-gate * configuration, update it with the sys_id 28417c478bd9Sstevel@tonic-gate */ 28427c478bd9Sstevel@tonic-gate if ((pair = pool_get_pair(create->pcu_elem)) != NULL) { 28437c478bd9Sstevel@tonic-gate pool_value_set_int64(&val, create->pcu_ioctl.pc_i_id); 28447c478bd9Sstevel@tonic-gate assert(pool_put_any_ns_property(pair, c_sys_prop, &val) 28457c478bd9Sstevel@tonic-gate == PO_SUCCESS); 28467c478bd9Sstevel@tonic-gate } 28477c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 28487c478bd9Sstevel@tonic-gate break; 28497c478bd9Sstevel@tonic-gate case POOL_DESTROY: 28507c478bd9Sstevel@tonic-gate destroy = (pool_destroy_undo_t *)li->li_details; 28517c478bd9Sstevel@tonic-gate 28527c478bd9Sstevel@tonic-gate destroy->pdu_ioctl.pd_o_id = elem_get_sysid(destroy->pdu_elem); 28537c478bd9Sstevel@tonic-gate 28547c478bd9Sstevel@tonic-gate /* 28557c478bd9Sstevel@tonic-gate * It may be that this element was created in the last 28567c478bd9Sstevel@tonic-gate * transaction. In which case POOL_CREATE, above, will 28577c478bd9Sstevel@tonic-gate * have re-inserted the element in the dictionary. Try 28587c478bd9Sstevel@tonic-gate * to remove it just in case this has occurred. 28597c478bd9Sstevel@tonic-gate */ 28607c478bd9Sstevel@tonic-gate (void) dict_remove(prov->pkc_elements, 28617c478bd9Sstevel@tonic-gate (pool_knl_elem_t *)destroy->pdu_elem); 28627c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_DESTROY, 2863*5ad42b1bSSurya Prakki &destroy->pdu_ioctl)) < 0 && errno == EAGAIN) 2864*5ad42b1bSSurya Prakki ; 28657c478bd9Sstevel@tonic-gate if (ret < 0) { 28667c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 28677c478bd9Sstevel@tonic-gate return (PO_FAIL); 28687c478bd9Sstevel@tonic-gate } 28697c478bd9Sstevel@tonic-gate #ifdef DEBUG 28707c478bd9Sstevel@tonic-gate dprintf("log_item_commit: POOL_DESTROY\n"); 28717c478bd9Sstevel@tonic-gate pool_elem_dprintf(destroy->pdu_elem); 28727c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 28737c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 28747c478bd9Sstevel@tonic-gate break; 28757c478bd9Sstevel@tonic-gate case POOL_ASSOC: 28767c478bd9Sstevel@tonic-gate assoc = (pool_assoc_undo_t *)li->li_details; 28777c478bd9Sstevel@tonic-gate 28787c478bd9Sstevel@tonic-gate assoc->pau_ioctl.pa_o_pool_id = 28797c478bd9Sstevel@tonic-gate elem_get_sysid(assoc->pau_assoc); 28807c478bd9Sstevel@tonic-gate assoc->pau_ioctl.pa_o_res_id = 28817c478bd9Sstevel@tonic-gate elem_get_sysid(assoc->pau_newres); 28827c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_ASSOC, 2883*5ad42b1bSSurya Prakki &assoc->pau_ioctl)) < 0 && errno == EAGAIN) 2884*5ad42b1bSSurya Prakki ; 28857c478bd9Sstevel@tonic-gate if (ret < 0) { 28867c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 28877c478bd9Sstevel@tonic-gate return (PO_FAIL); 28887c478bd9Sstevel@tonic-gate } 28897c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 28907c478bd9Sstevel@tonic-gate break; 28917c478bd9Sstevel@tonic-gate case POOL_DISSOC: 28927c478bd9Sstevel@tonic-gate dissoc = (pool_dissoc_undo_t *)li->li_details; 28937c478bd9Sstevel@tonic-gate 28947c478bd9Sstevel@tonic-gate dissoc->pdu_ioctl.pd_o_pool_id = 28957c478bd9Sstevel@tonic-gate elem_get_sysid(dissoc->pdu_dissoc); 28967c478bd9Sstevel@tonic-gate 28977c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_DISSOC, 2898*5ad42b1bSSurya Prakki &dissoc->pdu_ioctl)) < 0 && errno == EAGAIN) 2899*5ad42b1bSSurya Prakki ; 29007c478bd9Sstevel@tonic-gate if (ret < 0) { 29017c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 29027c478bd9Sstevel@tonic-gate return (PO_FAIL); 29037c478bd9Sstevel@tonic-gate } 29047c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 29057c478bd9Sstevel@tonic-gate break; 29067c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 29077c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 29087c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 29097c478bd9Sstevel@tonic-gate return (PO_FAIL); 29107c478bd9Sstevel@tonic-gate break; 29117c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 29127c478bd9Sstevel@tonic-gate xtransfer = (pool_xtransfer_undo_t *)li->li_details; 29137c478bd9Sstevel@tonic-gate 29147c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_src_id = 29157c478bd9Sstevel@tonic-gate elem_get_sysid(xtransfer->pxu_src); 29167c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_tgt_id = 29177c478bd9Sstevel@tonic-gate elem_get_sysid(xtransfer->pxu_tgt); 29187c478bd9Sstevel@tonic-gate for (size = 0; xtransfer->pxu_rl[size] != NULL; size ++) { 29197c478bd9Sstevel@tonic-gate xtransfer->pxu_ioctl.px_o_comp_list[size] = 29207c478bd9Sstevel@tonic-gate elem_get_sysid(TO_ELEM(xtransfer->pxu_rl[size])); 29217c478bd9Sstevel@tonic-gate #ifdef DEBUG 29227c478bd9Sstevel@tonic-gate dprintf("log_item_commit: POOL_XTRANSFER\n"); 29237c478bd9Sstevel@tonic-gate pool_elem_dprintf(TO_ELEM(xtransfer->pxu_rl[size])); 29247c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 29257c478bd9Sstevel@tonic-gate } 29267c478bd9Sstevel@tonic-gate 29277c478bd9Sstevel@tonic-gate /* 29287c478bd9Sstevel@tonic-gate * Don't actually transfer resources if the configuration 29297c478bd9Sstevel@tonic-gate * is in POF_DESTROY state. This is to prevent problems 29307c478bd9Sstevel@tonic-gate * relating to transferring off-line CPUs. Instead rely 29317c478bd9Sstevel@tonic-gate * on the POOL_DESTROY ioctl to transfer the CPUS. 29327c478bd9Sstevel@tonic-gate */ 29337c478bd9Sstevel@tonic-gate if (li->li_log->l_conf->pc_state != POF_DESTROY && 29347c478bd9Sstevel@tonic-gate ioctl(prov->pkc_fd, POOL_XTRANSFER, 29357c478bd9Sstevel@tonic-gate &xtransfer->pxu_ioctl) < 0) { 29367c478bd9Sstevel@tonic-gate #ifdef DEBUG 29377c478bd9Sstevel@tonic-gate dprintf("log_item_commit: POOL_XTRANSFER, ioctl " 29387c478bd9Sstevel@tonic-gate "failed\n"); 29397c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 29407c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 29417c478bd9Sstevel@tonic-gate return (PO_FAIL); 29427c478bd9Sstevel@tonic-gate } 29437c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 29447c478bd9Sstevel@tonic-gate break; 29457c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 29467c478bd9Sstevel@tonic-gate propput = (pool_propput_undo_t *)li->li_details; 29477c478bd9Sstevel@tonic-gate 29487c478bd9Sstevel@tonic-gate if (pool_elem_class(propput->ppu_elem) != PEC_SYSTEM) { 29497c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id = 29507c478bd9Sstevel@tonic-gate elem_get_sysid(propput->ppu_elem); 29517c478bd9Sstevel@tonic-gate } 29527c478bd9Sstevel@tonic-gate /* 29537c478bd9Sstevel@tonic-gate * Some properties, e.g. pset.size, are read-only in the 29547c478bd9Sstevel@tonic-gate * kernel and attempting to change them will fail and cause 29557c478bd9Sstevel@tonic-gate * problems. Although this property is read-only through the 29567c478bd9Sstevel@tonic-gate * public interface, the library needs to modify it's value. 29577c478bd9Sstevel@tonic-gate */ 29587c478bd9Sstevel@tonic-gate if ((propput->ppu_doioctl & KERNEL_PROP_RDONLY) == 0) { 29597c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPPUT, 29607c478bd9Sstevel@tonic-gate &propput->ppu_ioctl) < 0) { 29617c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 29627c478bd9Sstevel@tonic-gate return (PO_FAIL); 29637c478bd9Sstevel@tonic-gate } 29647c478bd9Sstevel@tonic-gate } 29657c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 29667c478bd9Sstevel@tonic-gate break; 29677c478bd9Sstevel@tonic-gate case POOL_PROPRM: 29687c478bd9Sstevel@tonic-gate proprm = (pool_proprm_undo_t *)li->li_details; 29697c478bd9Sstevel@tonic-gate 29707c478bd9Sstevel@tonic-gate if (pool_elem_class(proprm->pru_elem) != PEC_SYSTEM) { 29717c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_id = 29727c478bd9Sstevel@tonic-gate elem_get_sysid(proprm->pru_elem); 29737c478bd9Sstevel@tonic-gate } 29747c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPRM, &proprm->pru_ioctl) < 0) { 29757c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 29767c478bd9Sstevel@tonic-gate return (PO_FAIL); 29777c478bd9Sstevel@tonic-gate } 29787c478bd9Sstevel@tonic-gate li->li_state = LS_UNDO; 29797c478bd9Sstevel@tonic-gate break; 29807c478bd9Sstevel@tonic-gate default: 29817c478bd9Sstevel@tonic-gate return (PO_FAIL); 29827c478bd9Sstevel@tonic-gate } 29837c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 29847c478bd9Sstevel@tonic-gate } 29857c478bd9Sstevel@tonic-gate 29867c478bd9Sstevel@tonic-gate /* 29877c478bd9Sstevel@tonic-gate * Undo an individual transaction log item(). This processing is 29887c478bd9Sstevel@tonic-gate * essential to the pool_conf_commit() and pool_conf_rollback() 29897c478bd9Sstevel@tonic-gate * logic. Changes to the libpool snapshot and the kernel are carried 29907c478bd9Sstevel@tonic-gate * out separately. The library snapshot is updated synchronously, 29917c478bd9Sstevel@tonic-gate * however the kernel update is delayed until the user calls 29927c478bd9Sstevel@tonic-gate * pool_conf_commit(). 29937c478bd9Sstevel@tonic-gate * 29947c478bd9Sstevel@tonic-gate * When undoing transactions, library changes will be undone unless 29957c478bd9Sstevel@tonic-gate * this invocation is as a result of a commit failure, in which case 29967c478bd9Sstevel@tonic-gate * the log state will be LS_RECOVER. Kernel changes will only be 29977c478bd9Sstevel@tonic-gate * undone if they are marked as having been done, in which case the 29987c478bd9Sstevel@tonic-gate * log item state will be LS_UNDO. 29997c478bd9Sstevel@tonic-gate */ 30007c478bd9Sstevel@tonic-gate int 30017c478bd9Sstevel@tonic-gate log_item_undo(log_item_t *li) 30027c478bd9Sstevel@tonic-gate { 30037c478bd9Sstevel@tonic-gate pool_knl_connection_t *prov = 30047c478bd9Sstevel@tonic-gate (pool_knl_connection_t *)li->li_log->l_conf->pc_prov; 30057c478bd9Sstevel@tonic-gate pool_create_undo_t *create; 30067c478bd9Sstevel@tonic-gate pool_destroy_undo_t *destroy; 30077c478bd9Sstevel@tonic-gate pool_assoc_undo_t *assoc; 30087c478bd9Sstevel@tonic-gate pool_dissoc_undo_t *dissoc; 30097c478bd9Sstevel@tonic-gate pool_propput_undo_t *propput; 30107c478bd9Sstevel@tonic-gate pool_proprm_undo_t *proprm; 30117c478bd9Sstevel@tonic-gate pool_xtransfer_undo_t *xtransfer; 30127c478bd9Sstevel@tonic-gate char_buf_t *cb; 30137c478bd9Sstevel@tonic-gate size_t size; 30147c478bd9Sstevel@tonic-gate pool_destroy_t u_destroy; 30157c478bd9Sstevel@tonic-gate pool_create_t u_create; 30167c478bd9Sstevel@tonic-gate pool_assoc_t u_assoc; 30177c478bd9Sstevel@tonic-gate pool_xtransfer_t u_xtransfer; 30187c478bd9Sstevel@tonic-gate pool_propput_t u_propput; 30197c478bd9Sstevel@tonic-gate pool_proprm_t u_proprm; 30207c478bd9Sstevel@tonic-gate pool_conf_t *conf = li->li_log->l_conf; 30217c478bd9Sstevel@tonic-gate nvpair_t *pair; 30227c478bd9Sstevel@tonic-gate nvlist_t *tmplist; 30237c478bd9Sstevel@tonic-gate int ret; 30247c478bd9Sstevel@tonic-gate 30257c478bd9Sstevel@tonic-gate if (li->li_log->l_state != LS_RECOVER) { 30267c478bd9Sstevel@tonic-gate switch (li->li_op) { 30277c478bd9Sstevel@tonic-gate case POOL_CREATE: 30287c478bd9Sstevel@tonic-gate create = (pool_create_undo_t *)li->li_details; 30297c478bd9Sstevel@tonic-gate 30307c478bd9Sstevel@tonic-gate (void) dict_remove(prov->pkc_elements, create->pcu_elem); 30317c478bd9Sstevel@tonic-gate #ifdef DEBUG 30327c478bd9Sstevel@tonic-gate dprintf("log_item_undo: POOL_CREATE\n"); 30337c478bd9Sstevel@tonic-gate assert(create->pcu_elem != NULL); 30347c478bd9Sstevel@tonic-gate dprintf("log_item_undo: POOL_CREATE %p\n", create->pcu_elem); 30357c478bd9Sstevel@tonic-gate pool_elem_dprintf(create->pcu_elem); 30367c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 30377c478bd9Sstevel@tonic-gate pool_knl_elem_free((pool_knl_elem_t *)create->pcu_elem, 30387c478bd9Sstevel@tonic-gate PO_TRUE); 30397c478bd9Sstevel@tonic-gate break; 30407c478bd9Sstevel@tonic-gate case POOL_DESTROY: 30417c478bd9Sstevel@tonic-gate destroy = (pool_destroy_undo_t *)li->li_details; 30427c478bd9Sstevel@tonic-gate 30437c478bd9Sstevel@tonic-gate assert(dict_put(prov->pkc_elements, destroy->pdu_elem, 30447c478bd9Sstevel@tonic-gate destroy->pdu_elem) == NULL); 30457c478bd9Sstevel@tonic-gate break; 30467c478bd9Sstevel@tonic-gate case POOL_ASSOC: 30477c478bd9Sstevel@tonic-gate assoc = (pool_assoc_undo_t *)li->li_details; 30487c478bd9Sstevel@tonic-gate 30497c478bd9Sstevel@tonic-gate if (assoc->pau_oldres != NULL) 30507c478bd9Sstevel@tonic-gate ((pool_knl_pool_t *)assoc->pau_assoc)->pkp_assoc 30517c478bd9Sstevel@tonic-gate [pool_resource_elem_class(assoc->pau_oldres)] = 30527c478bd9Sstevel@tonic-gate (pool_knl_resource_t *)assoc->pau_oldres; 30537c478bd9Sstevel@tonic-gate break; 30547c478bd9Sstevel@tonic-gate case POOL_DISSOC: 30557c478bd9Sstevel@tonic-gate dissoc = (pool_dissoc_undo_t *)li->li_details; 30567c478bd9Sstevel@tonic-gate 30577c478bd9Sstevel@tonic-gate if (dissoc->pdu_oldres != NULL) 30587c478bd9Sstevel@tonic-gate ((pool_knl_pool_t *)dissoc->pdu_dissoc)->pkp_assoc 30597c478bd9Sstevel@tonic-gate [pool_resource_elem_class(dissoc->pdu_oldres)] = 30607c478bd9Sstevel@tonic-gate (pool_knl_resource_t *)dissoc->pdu_oldres; 30617c478bd9Sstevel@tonic-gate break; 30627c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 30637c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 30647c478bd9Sstevel@tonic-gate return (PO_FAIL); 30657c478bd9Sstevel@tonic-gate break; 30667c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 30677c478bd9Sstevel@tonic-gate xtransfer = (pool_xtransfer_undo_t *)li->li_details; 30687c478bd9Sstevel@tonic-gate 30697c478bd9Sstevel@tonic-gate for (size = 0; xtransfer->pxu_rl[size] != NULL; size++) { 30707c478bd9Sstevel@tonic-gate pool_value_t val = POOL_VALUE_INITIALIZER; 30717c478bd9Sstevel@tonic-gate uint64_t src_size; 30727c478bd9Sstevel@tonic-gate uint64_t tgt_size; 30737c478bd9Sstevel@tonic-gate 30747c478bd9Sstevel@tonic-gate if (pool_set_container(xtransfer->pxu_src, 30757c478bd9Sstevel@tonic-gate TO_ELEM(xtransfer->pxu_rl[size])) == PO_FAIL) { 30767c478bd9Sstevel@tonic-gate return (PO_FAIL); 30777c478bd9Sstevel@tonic-gate } 30787c478bd9Sstevel@tonic-gate /* 30797c478bd9Sstevel@tonic-gate * Maintain the library view of the size 30807c478bd9Sstevel@tonic-gate */ 30817c478bd9Sstevel@tonic-gate if (resource_get_size(pool_elem_res(xtransfer->pxu_src), 30827c478bd9Sstevel@tonic-gate &src_size) != PO_SUCCESS || 30837c478bd9Sstevel@tonic-gate resource_get_size(pool_elem_res(xtransfer->pxu_tgt), 30847c478bd9Sstevel@tonic-gate &tgt_size) != PO_SUCCESS) { 30857c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 30867c478bd9Sstevel@tonic-gate return (PO_FAIL); 30877c478bd9Sstevel@tonic-gate } 30887c478bd9Sstevel@tonic-gate src_size++; 30897c478bd9Sstevel@tonic-gate tgt_size--; 30907c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, src_size); 30917c478bd9Sstevel@tonic-gate (void) pool_put_any_ns_property(xtransfer->pxu_src, 30927c478bd9Sstevel@tonic-gate c_size_prop, &val); 30937c478bd9Sstevel@tonic-gate pool_value_set_uint64(&val, tgt_size); 30947c478bd9Sstevel@tonic-gate (void) pool_put_any_ns_property(xtransfer->pxu_tgt, 30957c478bd9Sstevel@tonic-gate c_size_prop, &val); 30967c478bd9Sstevel@tonic-gate } 30977c478bd9Sstevel@tonic-gate break; 30987c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 30997c478bd9Sstevel@tonic-gate propput = (pool_propput_undo_t *)li->li_details; 31007c478bd9Sstevel@tonic-gate 31017c478bd9Sstevel@tonic-gate if ((propput->ppu_doioctl & KERNEL_PROP_RDONLY) == 0) { 31027c478bd9Sstevel@tonic-gate if (propput->ppu_blist != NULL) { 31037c478bd9Sstevel@tonic-gate if (nvlist_merge( 31047c478bd9Sstevel@tonic-gate ((pool_knl_elem_t *)propput->ppu_elem)-> 31057c478bd9Sstevel@tonic-gate pke_properties, propput->ppu_blist, 0) 31067c478bd9Sstevel@tonic-gate != 0) { 31077c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 31087c478bd9Sstevel@tonic-gate return (PO_FAIL); 31097c478bd9Sstevel@tonic-gate } 31107c478bd9Sstevel@tonic-gate } else { 31117c478bd9Sstevel@tonic-gate if (nvlist_unpack(propput->ppu_ioctl.pp_o_buf, 31127c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_bufsize, 31137c478bd9Sstevel@tonic-gate &propput->ppu_alist, 0) != 0) { 31147c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 31157c478bd9Sstevel@tonic-gate return (PO_FAIL); 31167c478bd9Sstevel@tonic-gate } 31177c478bd9Sstevel@tonic-gate pair = nvlist_next_nvpair(propput->ppu_alist, 31187c478bd9Sstevel@tonic-gate NULL); 31197c478bd9Sstevel@tonic-gate (void) nvlist_remove_all(((pool_knl_elem_t *) 31207c478bd9Sstevel@tonic-gate propput->ppu_elem)->pke_properties, 31217c478bd9Sstevel@tonic-gate nvpair_name(pair)); 31227c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_alist); 31237c478bd9Sstevel@tonic-gate } 31247c478bd9Sstevel@tonic-gate } 31257c478bd9Sstevel@tonic-gate break; 31267c478bd9Sstevel@tonic-gate case POOL_PROPRM: 31277c478bd9Sstevel@tonic-gate proprm = (pool_proprm_undo_t *)li->li_details; 31287c478bd9Sstevel@tonic-gate 31297c478bd9Sstevel@tonic-gate if (pool_value_get_type(&proprm->pru_oldval) != POC_INVAL) { 31307c478bd9Sstevel@tonic-gate if (pool_put_property(conf, proprm->pru_elem, 31317c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_prop_name, 31327c478bd9Sstevel@tonic-gate &proprm->pru_oldval) != PO_SUCCESS) { 31337c478bd9Sstevel@tonic-gate return (PO_FAIL); 31347c478bd9Sstevel@tonic-gate } 31357c478bd9Sstevel@tonic-gate } 31367c478bd9Sstevel@tonic-gate break; 31377c478bd9Sstevel@tonic-gate default: 31387c478bd9Sstevel@tonic-gate return (PO_FAIL); 31397c478bd9Sstevel@tonic-gate } 31407c478bd9Sstevel@tonic-gate } 31417c478bd9Sstevel@tonic-gate /* 31427c478bd9Sstevel@tonic-gate * Only try to undo the state of the kernel if we modified it. 31437c478bd9Sstevel@tonic-gate */ 31447c478bd9Sstevel@tonic-gate if (li->li_state == LS_DO) { 31457c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 31467c478bd9Sstevel@tonic-gate } 31477c478bd9Sstevel@tonic-gate 31487c478bd9Sstevel@tonic-gate switch (li->li_op) { 31497c478bd9Sstevel@tonic-gate case POOL_CREATE: 31507c478bd9Sstevel@tonic-gate create = (pool_create_undo_t *)li->li_details; 31517c478bd9Sstevel@tonic-gate 31527c478bd9Sstevel@tonic-gate u_destroy.pd_o_type = create->pcu_ioctl.pc_o_type; 31537c478bd9Sstevel@tonic-gate u_destroy.pd_o_sub_type = create->pcu_ioctl.pc_o_sub_type; 31547c478bd9Sstevel@tonic-gate u_destroy.pd_o_id = create->pcu_ioctl.pc_i_id; 31557c478bd9Sstevel@tonic-gate 31567c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_DESTROY, 3157*5ad42b1bSSurya Prakki &u_destroy)) < 0 && errno == EAGAIN) 3158*5ad42b1bSSurya Prakki ; 31597c478bd9Sstevel@tonic-gate if (ret < 0) { 31607c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 31617c478bd9Sstevel@tonic-gate return (PO_FAIL); 31627c478bd9Sstevel@tonic-gate } 31637c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 31647c478bd9Sstevel@tonic-gate break; 31657c478bd9Sstevel@tonic-gate case POOL_DESTROY: 31667c478bd9Sstevel@tonic-gate destroy = (pool_destroy_undo_t *)li->li_details; 31677c478bd9Sstevel@tonic-gate 31687c478bd9Sstevel@tonic-gate u_create.pc_o_type = destroy->pdu_ioctl.pd_o_type; 31697c478bd9Sstevel@tonic-gate u_create.pc_o_sub_type = destroy->pdu_ioctl.pd_o_sub_type; 31707c478bd9Sstevel@tonic-gate 31717c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_CREATE, &u_create) < 0) { 31727c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 31737c478bd9Sstevel@tonic-gate return (PO_FAIL); 31747c478bd9Sstevel@tonic-gate } 31757c478bd9Sstevel@tonic-gate 31767c478bd9Sstevel@tonic-gate if ((cb = alloc_char_buf(CB_DEFAULT_LEN)) == NULL) { 31777c478bd9Sstevel@tonic-gate return (PO_FAIL); 31787c478bd9Sstevel@tonic-gate } 31797c478bd9Sstevel@tonic-gate if (set_char_buf(cb, "%s.sys_id", 31807c478bd9Sstevel@tonic-gate pool_elem_class_string(destroy->pdu_elem)) != PO_SUCCESS) { 31817c478bd9Sstevel@tonic-gate free_char_buf(cb); 31827c478bd9Sstevel@tonic-gate return (PO_FAIL); 31837c478bd9Sstevel@tonic-gate } 31847c478bd9Sstevel@tonic-gate (void) nvlist_add_int64( 31857c478bd9Sstevel@tonic-gate ((pool_knl_elem_t *)destroy->pdu_elem)->pke_properties, 31867c478bd9Sstevel@tonic-gate cb->cb_buf, u_create.pc_i_id); 31877c478bd9Sstevel@tonic-gate free_char_buf(cb); 31887c478bd9Sstevel@tonic-gate if (dict_put(prov->pkc_elements, destroy->pdu_elem, 31897c478bd9Sstevel@tonic-gate destroy->pdu_elem) != NULL) { 31907c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 31917c478bd9Sstevel@tonic-gate return (PO_FAIL); 31927c478bd9Sstevel@tonic-gate } 31937c478bd9Sstevel@tonic-gate /* 31947c478bd9Sstevel@tonic-gate * Now we need to reset all the properties and 31957c478bd9Sstevel@tonic-gate * associations in the kernel for this newly created 31967c478bd9Sstevel@tonic-gate * replacement. 31977c478bd9Sstevel@tonic-gate */ 31987c478bd9Sstevel@tonic-gate u_propput.pp_o_id_type = destroy->pdu_ioctl.pd_o_type; 31997c478bd9Sstevel@tonic-gate u_propput.pp_o_id_sub_type = destroy->pdu_ioctl.pd_o_sub_type; 32007c478bd9Sstevel@tonic-gate u_propput.pp_o_id = u_create.pc_i_id; 32017c478bd9Sstevel@tonic-gate u_propput.pp_o_buf = NULL; 32027c478bd9Sstevel@tonic-gate /* 32037c478bd9Sstevel@tonic-gate * Remove the read-only properties before attempting 32047c478bd9Sstevel@tonic-gate * to restore the state of the newly created property 32057c478bd9Sstevel@tonic-gate */ 32067c478bd9Sstevel@tonic-gate (void) nvlist_dup(((pool_knl_elem_t *)destroy->pdu_elem)-> 3207*5ad42b1bSSurya Prakki pke_properties, &tmplist, 0); 32087c478bd9Sstevel@tonic-gate for (pair = nvlist_next_nvpair(tmplist, NULL); pair != NULL; 32097c478bd9Sstevel@tonic-gate pair = nvlist_next_nvpair(tmplist, pair)) { 32107c478bd9Sstevel@tonic-gate const pool_prop_t *prop; 32117c478bd9Sstevel@tonic-gate char *name = nvpair_name(pair); 32127c478bd9Sstevel@tonic-gate if ((prop = provider_get_prop(destroy->pdu_elem, 32137c478bd9Sstevel@tonic-gate name)) != NULL) 32147c478bd9Sstevel@tonic-gate if (prop_is_readonly(prop) == PO_TRUE) 32157c478bd9Sstevel@tonic-gate (void) nvlist_remove_all(tmplist, name); 32167c478bd9Sstevel@tonic-gate } 32177c478bd9Sstevel@tonic-gate if (nvlist_pack(tmplist, (char **)&u_propput.pp_o_buf, 32187c478bd9Sstevel@tonic-gate &u_propput.pp_o_bufsize, NV_ENCODE_NATIVE, 0) != 0) { 32197c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32207c478bd9Sstevel@tonic-gate return (PO_FAIL); 32217c478bd9Sstevel@tonic-gate } 32227c478bd9Sstevel@tonic-gate nvlist_free(tmplist); 32237c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPPUT, &u_propput) < 0) { 32247c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 32257c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32267c478bd9Sstevel@tonic-gate return (PO_FAIL); 32277c478bd9Sstevel@tonic-gate } 32287c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 32297c478bd9Sstevel@tonic-gate /* 32307c478bd9Sstevel@tonic-gate * Now reset the associations for all the resource 32317c478bd9Sstevel@tonic-gate * types if the thing which we are recreating is a 32327c478bd9Sstevel@tonic-gate * pool 32337c478bd9Sstevel@tonic-gate * 32347c478bd9Sstevel@tonic-gate * TODO: This is resource specific and must be 32357c478bd9Sstevel@tonic-gate * extended for additional resource types. 32367c478bd9Sstevel@tonic-gate */ 32377c478bd9Sstevel@tonic-gate if (destroy->pdu_ioctl.pd_o_type == PEC_POOL) { 32387c478bd9Sstevel@tonic-gate u_assoc.pa_o_pool_id = u_create.pc_i_id; 32397c478bd9Sstevel@tonic-gate u_assoc.pa_o_res_id = 32407c478bd9Sstevel@tonic-gate elem_get_sysid( 32417c478bd9Sstevel@tonic-gate TO_ELEM(((pool_knl_pool_t *)destroy->pdu_elem)-> 32427c478bd9Sstevel@tonic-gate pkp_assoc[PREC_PSET])); 32437c478bd9Sstevel@tonic-gate u_assoc.pa_o_id_type = PREC_PSET; 32447c478bd9Sstevel@tonic-gate 32457c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_ASSOC, &u_assoc) < 0) { 32467c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32477c478bd9Sstevel@tonic-gate return (PO_FAIL); 32487c478bd9Sstevel@tonic-gate } 32497c478bd9Sstevel@tonic-gate } 32507c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 32517c478bd9Sstevel@tonic-gate break; 32527c478bd9Sstevel@tonic-gate case POOL_ASSOC: 32537c478bd9Sstevel@tonic-gate assoc = (pool_assoc_undo_t *)li->li_details; 32547c478bd9Sstevel@tonic-gate 32557c478bd9Sstevel@tonic-gate u_assoc.pa_o_pool_id = elem_get_sysid(assoc->pau_assoc); 32567c478bd9Sstevel@tonic-gate u_assoc.pa_o_res_id = elem_get_sysid(assoc->pau_oldres); 32577c478bd9Sstevel@tonic-gate u_assoc.pa_o_id_type = assoc->pau_ioctl.pa_o_id_type; 32587c478bd9Sstevel@tonic-gate 32597c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_ASSOC, &u_assoc)) < 0 && 3260*5ad42b1bSSurya Prakki errno == EAGAIN) 3261*5ad42b1bSSurya Prakki ; 32627c478bd9Sstevel@tonic-gate if (ret < 0) { 32637c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32647c478bd9Sstevel@tonic-gate return (PO_FAIL); 32657c478bd9Sstevel@tonic-gate } 32667c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 32677c478bd9Sstevel@tonic-gate break; 32687c478bd9Sstevel@tonic-gate case POOL_DISSOC: 32697c478bd9Sstevel@tonic-gate dissoc = (pool_dissoc_undo_t *)li->li_details; 32707c478bd9Sstevel@tonic-gate 32717c478bd9Sstevel@tonic-gate u_assoc.pa_o_pool_id = elem_get_sysid(dissoc->pdu_dissoc); 32727c478bd9Sstevel@tonic-gate u_assoc.pa_o_res_id = elem_get_sysid(dissoc->pdu_oldres); 32737c478bd9Sstevel@tonic-gate u_assoc.pa_o_id_type = dissoc->pdu_ioctl.pd_o_id_type; 32747c478bd9Sstevel@tonic-gate 32757c478bd9Sstevel@tonic-gate while ((ret = ioctl(prov->pkc_fd, POOL_ASSOC, &u_assoc)) < 0 && 3276*5ad42b1bSSurya Prakki errno == EAGAIN) 3277*5ad42b1bSSurya Prakki ; 32787c478bd9Sstevel@tonic-gate if (ret < 0) { 32797c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32807c478bd9Sstevel@tonic-gate return (PO_FAIL); 32817c478bd9Sstevel@tonic-gate } 32827c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 32837c478bd9Sstevel@tonic-gate break; 32847c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 32857c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 32867c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 32877c478bd9Sstevel@tonic-gate return (PO_FAIL); 32887c478bd9Sstevel@tonic-gate break; 32897c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 32907c478bd9Sstevel@tonic-gate xtransfer = (pool_xtransfer_undo_t *)li->li_details; 32917c478bd9Sstevel@tonic-gate 32927c478bd9Sstevel@tonic-gate (void) memcpy(&u_xtransfer, &xtransfer->pxu_ioctl, 32937c478bd9Sstevel@tonic-gate sizeof (pool_xtransfer_t)); 32947c478bd9Sstevel@tonic-gate u_xtransfer.px_o_src_id = elem_get_sysid(xtransfer->pxu_tgt); 32957c478bd9Sstevel@tonic-gate u_xtransfer.px_o_tgt_id = elem_get_sysid(xtransfer->pxu_src); 32967c478bd9Sstevel@tonic-gate 32977c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_XTRANSFER, &u_xtransfer) < 0) { 32987c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 32997c478bd9Sstevel@tonic-gate return (PO_FAIL); 33007c478bd9Sstevel@tonic-gate } 33017c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 33027c478bd9Sstevel@tonic-gate break; 33037c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 33047c478bd9Sstevel@tonic-gate propput = (pool_propput_undo_t *)li->li_details; 33057c478bd9Sstevel@tonic-gate 33067c478bd9Sstevel@tonic-gate if ((propput->ppu_doioctl & KERNEL_PROP_RDONLY) == 0) { 33077c478bd9Sstevel@tonic-gate if (propput->ppu_blist) { 33087c478bd9Sstevel@tonic-gate (void) memcpy(&u_propput, &propput->ppu_ioctl, 33097c478bd9Sstevel@tonic-gate sizeof (pool_propput_t)); 33107c478bd9Sstevel@tonic-gate u_propput.pp_o_id = 33117c478bd9Sstevel@tonic-gate elem_get_sysid(propput->ppu_elem); 33127c478bd9Sstevel@tonic-gate u_propput.pp_o_buf = NULL; 33137c478bd9Sstevel@tonic-gate if (nvlist_pack(propput->ppu_blist, 33147c478bd9Sstevel@tonic-gate (char **)&u_propput.pp_o_buf, 33157c478bd9Sstevel@tonic-gate &u_propput.pp_o_bufsize, 33167c478bd9Sstevel@tonic-gate NV_ENCODE_NATIVE, 0) != 0) { 33177c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33187c478bd9Sstevel@tonic-gate return (PO_FAIL); 33197c478bd9Sstevel@tonic-gate } 33207c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPPUT, 33217c478bd9Sstevel@tonic-gate &u_propput) < 0) { 33227c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 33237c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33247c478bd9Sstevel@tonic-gate return (PO_FAIL); 33257c478bd9Sstevel@tonic-gate } 33267c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 33277c478bd9Sstevel@tonic-gate } else { 33287c478bd9Sstevel@tonic-gate if (nvlist_unpack(propput-> 33297c478bd9Sstevel@tonic-gate ppu_ioctl.pp_o_buf, 33307c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_bufsize, 33317c478bd9Sstevel@tonic-gate &propput->ppu_alist, 0) != 0) { 33327c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33337c478bd9Sstevel@tonic-gate return (PO_FAIL); 33347c478bd9Sstevel@tonic-gate } 33357c478bd9Sstevel@tonic-gate u_proprm.pp_o_id_type = 33367c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id_type; 33377c478bd9Sstevel@tonic-gate u_proprm.pp_o_id_sub_type = 33387c478bd9Sstevel@tonic-gate propput->ppu_ioctl.pp_o_id_sub_type; 33397c478bd9Sstevel@tonic-gate u_proprm.pp_o_id = 33407c478bd9Sstevel@tonic-gate elem_get_sysid(propput->ppu_elem); 33417c478bd9Sstevel@tonic-gate pair = nvlist_next_nvpair(propput->ppu_alist, 33427c478bd9Sstevel@tonic-gate NULL); 33437c478bd9Sstevel@tonic-gate u_proprm.pp_o_prop_name = nvpair_name(pair); 33447c478bd9Sstevel@tonic-gate u_proprm.pp_o_prop_name_size = 33457c478bd9Sstevel@tonic-gate strlen(u_proprm.pp_o_prop_name); 33467c478bd9Sstevel@tonic-gate 33477c478bd9Sstevel@tonic-gate if (provider_get_prop(propput->ppu_elem, 33487c478bd9Sstevel@tonic-gate u_proprm.pp_o_prop_name) == NULL) { 33497c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPRM, 33507c478bd9Sstevel@tonic-gate &u_proprm) < 0) { 33517c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_alist); 33527c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33537c478bd9Sstevel@tonic-gate return (PO_FAIL); 33547c478bd9Sstevel@tonic-gate } 33557c478bd9Sstevel@tonic-gate } 33567c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_alist); 33577c478bd9Sstevel@tonic-gate } 33587c478bd9Sstevel@tonic-gate } 33597c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 33607c478bd9Sstevel@tonic-gate break; 33617c478bd9Sstevel@tonic-gate case POOL_PROPRM: 33627c478bd9Sstevel@tonic-gate proprm = (pool_proprm_undo_t *)li->li_details; 33637c478bd9Sstevel@tonic-gate 33647c478bd9Sstevel@tonic-gate u_propput.pp_o_id_type = proprm->pru_ioctl.pp_o_id_type; 33657c478bd9Sstevel@tonic-gate u_propput.pp_o_id_sub_type = 33667c478bd9Sstevel@tonic-gate proprm->pru_ioctl.pp_o_id_sub_type; 33677c478bd9Sstevel@tonic-gate u_propput.pp_o_id = elem_get_sysid(proprm->pru_elem); 33687c478bd9Sstevel@tonic-gate u_propput.pp_o_buf = NULL; 33697c478bd9Sstevel@tonic-gate /* 33707c478bd9Sstevel@tonic-gate * Only try to remove the appropriate property 33717c478bd9Sstevel@tonic-gate */ 33727c478bd9Sstevel@tonic-gate if (nvlist_alloc(&tmplist, NV_UNIQUE_NAME_TYPE, 0) != 33737c478bd9Sstevel@tonic-gate 0) { 33747c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33757c478bd9Sstevel@tonic-gate return (PO_FAIL); 33767c478bd9Sstevel@tonic-gate } 33777c478bd9Sstevel@tonic-gate if (pool_knl_nvlist_add_value(tmplist, 33787c478bd9Sstevel@tonic-gate pool_value_get_name(&proprm->pru_oldval), 33797c478bd9Sstevel@tonic-gate &proprm->pru_oldval) != PO_SUCCESS) 33807c478bd9Sstevel@tonic-gate return (PO_FAIL); 33817c478bd9Sstevel@tonic-gate 33827c478bd9Sstevel@tonic-gate if (nvlist_pack(tmplist, 33837c478bd9Sstevel@tonic-gate (char **)&u_propput.pp_o_buf, &u_propput.pp_o_bufsize, 33847c478bd9Sstevel@tonic-gate NV_ENCODE_NATIVE, 0) != 0) { 33857c478bd9Sstevel@tonic-gate nvlist_free(tmplist); 33867c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33877c478bd9Sstevel@tonic-gate return (PO_FAIL); 33887c478bd9Sstevel@tonic-gate } 33897c478bd9Sstevel@tonic-gate nvlist_free(tmplist); 33907c478bd9Sstevel@tonic-gate if (ioctl(prov->pkc_fd, POOL_PROPPUT, &u_propput) < 0) { 33917c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 33927c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 33937c478bd9Sstevel@tonic-gate return (PO_FAIL); 33947c478bd9Sstevel@tonic-gate } 33957c478bd9Sstevel@tonic-gate free(u_propput.pp_o_buf); 33967c478bd9Sstevel@tonic-gate li->li_state = LS_DO; 33977c478bd9Sstevel@tonic-gate break; 33987c478bd9Sstevel@tonic-gate default: 33997c478bd9Sstevel@tonic-gate return (PO_FAIL); 34007c478bd9Sstevel@tonic-gate } 34017c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 34027c478bd9Sstevel@tonic-gate } 34037c478bd9Sstevel@tonic-gate 34047c478bd9Sstevel@tonic-gate /* 34057c478bd9Sstevel@tonic-gate * A log item stores state about the transaction it represents. This 34067c478bd9Sstevel@tonic-gate * function releases the resources associated with the transaction and 34077c478bd9Sstevel@tonic-gate * used to store the transaction state. 34087c478bd9Sstevel@tonic-gate */ 34097c478bd9Sstevel@tonic-gate int 34107c478bd9Sstevel@tonic-gate log_item_release(log_item_t *li) 34117c478bd9Sstevel@tonic-gate { 34127c478bd9Sstevel@tonic-gate pool_create_undo_t *create; 34137c478bd9Sstevel@tonic-gate pool_destroy_undo_t *destroy; 34147c478bd9Sstevel@tonic-gate pool_assoc_undo_t *assoc; 34157c478bd9Sstevel@tonic-gate pool_dissoc_undo_t *dissoc; 34167c478bd9Sstevel@tonic-gate pool_propput_undo_t *propput; 34177c478bd9Sstevel@tonic-gate pool_proprm_undo_t *proprm; 34187c478bd9Sstevel@tonic-gate pool_xtransfer_undo_t *xtransfer; 34197c478bd9Sstevel@tonic-gate 34207c478bd9Sstevel@tonic-gate switch (li->li_op) { 34217c478bd9Sstevel@tonic-gate case POOL_CREATE: 34227c478bd9Sstevel@tonic-gate create = (pool_create_undo_t *)li->li_details; 34237c478bd9Sstevel@tonic-gate 34247c478bd9Sstevel@tonic-gate free(create); 34257c478bd9Sstevel@tonic-gate break; 34267c478bd9Sstevel@tonic-gate case POOL_DESTROY: 34277c478bd9Sstevel@tonic-gate destroy = (pool_destroy_undo_t *)li->li_details; 34287c478bd9Sstevel@tonic-gate 34297c478bd9Sstevel@tonic-gate #ifdef DEBUG 34307c478bd9Sstevel@tonic-gate dprintf("log_item_release: POOL_DESTROY\n"); 34317c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 34327c478bd9Sstevel@tonic-gate 34337c478bd9Sstevel@tonic-gate if (li->li_state == LS_UNDO) { 34347c478bd9Sstevel@tonic-gate #ifdef DEBUG 34357c478bd9Sstevel@tonic-gate pool_elem_dprintf(destroy->pdu_elem); 34367c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 34377c478bd9Sstevel@tonic-gate pool_knl_elem_free((pool_knl_elem_t *)destroy-> 34387c478bd9Sstevel@tonic-gate pdu_elem, PO_TRUE); 34397c478bd9Sstevel@tonic-gate } 34407c478bd9Sstevel@tonic-gate free(destroy); 34417c478bd9Sstevel@tonic-gate break; 34427c478bd9Sstevel@tonic-gate case POOL_ASSOC: 34437c478bd9Sstevel@tonic-gate assoc = (pool_assoc_undo_t *)li->li_details; 34447c478bd9Sstevel@tonic-gate 34457c478bd9Sstevel@tonic-gate free(assoc); 34467c478bd9Sstevel@tonic-gate break; 34477c478bd9Sstevel@tonic-gate case POOL_DISSOC: 34487c478bd9Sstevel@tonic-gate dissoc = (pool_dissoc_undo_t *)li->li_details; 34497c478bd9Sstevel@tonic-gate 34507c478bd9Sstevel@tonic-gate free(dissoc); 34517c478bd9Sstevel@tonic-gate break; 34527c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 34537c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 34547c478bd9Sstevel@tonic-gate return (PO_FAIL); 34557c478bd9Sstevel@tonic-gate break; 34567c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 34577c478bd9Sstevel@tonic-gate xtransfer = (pool_xtransfer_undo_t *)li->li_details; 34587c478bd9Sstevel@tonic-gate 34597c478bd9Sstevel@tonic-gate free(xtransfer->pxu_rl); 34607c478bd9Sstevel@tonic-gate free(xtransfer->pxu_ioctl.px_o_comp_list); 34617c478bd9Sstevel@tonic-gate free(xtransfer); 34627c478bd9Sstevel@tonic-gate break; 34637c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 34647c478bd9Sstevel@tonic-gate propput = (pool_propput_undo_t *)li->li_details; 34657c478bd9Sstevel@tonic-gate 34667c478bd9Sstevel@tonic-gate if (propput->ppu_blist) 34677c478bd9Sstevel@tonic-gate nvlist_free(propput->ppu_blist); 34687c478bd9Sstevel@tonic-gate free(propput->ppu_ioctl.pp_o_buf); 34697c478bd9Sstevel@tonic-gate free(propput); 34707c478bd9Sstevel@tonic-gate break; 34717c478bd9Sstevel@tonic-gate case POOL_PROPRM: 34727c478bd9Sstevel@tonic-gate proprm = (pool_proprm_undo_t *)li->li_details; 34737c478bd9Sstevel@tonic-gate 34747c478bd9Sstevel@tonic-gate free(proprm); 34757c478bd9Sstevel@tonic-gate break; 34767c478bd9Sstevel@tonic-gate default: 34777c478bd9Sstevel@tonic-gate return (PO_FAIL); 34787c478bd9Sstevel@tonic-gate } 34797c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 34807c478bd9Sstevel@tonic-gate } 34817c478bd9Sstevel@tonic-gate 34827c478bd9Sstevel@tonic-gate /* 34837c478bd9Sstevel@tonic-gate * pool_knl_nvlist_add_value() adds a pool_value_t to an nvlist. 34847c478bd9Sstevel@tonic-gate */ 34857c478bd9Sstevel@tonic-gate int 34867c478bd9Sstevel@tonic-gate pool_knl_nvlist_add_value(nvlist_t *list, const char *name, 34877c478bd9Sstevel@tonic-gate const pool_value_t *pv) 34887c478bd9Sstevel@tonic-gate { 34897c478bd9Sstevel@tonic-gate uint64_t uval; 34907c478bd9Sstevel@tonic-gate int64_t ival; 34917c478bd9Sstevel@tonic-gate double dval; 34927c478bd9Sstevel@tonic-gate uchar_t dval_b[sizeof (double)]; 34937c478bd9Sstevel@tonic-gate uchar_t bval; 34947c478bd9Sstevel@tonic-gate const char *sval; 34957c478bd9Sstevel@tonic-gate pool_value_class_t type; 34967c478bd9Sstevel@tonic-gate char *nv_name; 34977c478bd9Sstevel@tonic-gate 34987c478bd9Sstevel@tonic-gate if ((type = pool_value_get_type(pv)) == POC_INVAL) { 34997c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 35007c478bd9Sstevel@tonic-gate return (PO_FAIL); 35017c478bd9Sstevel@tonic-gate } 35027c478bd9Sstevel@tonic-gate nv_name = (char *)name; 35037c478bd9Sstevel@tonic-gate 35047c478bd9Sstevel@tonic-gate switch (type) { 35057c478bd9Sstevel@tonic-gate case POC_UINT: 35067c478bd9Sstevel@tonic-gate if (pool_value_get_uint64(pv, &uval) == POC_INVAL) { 35077c478bd9Sstevel@tonic-gate return (PO_FAIL); 35087c478bd9Sstevel@tonic-gate } 35097c478bd9Sstevel@tonic-gate if (nvlist_add_uint64(list, nv_name, uval) != 0) { 35107c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 35117c478bd9Sstevel@tonic-gate return (PO_FAIL); 35127c478bd9Sstevel@tonic-gate } 35137c478bd9Sstevel@tonic-gate break; 35147c478bd9Sstevel@tonic-gate case POC_INT: 35157c478bd9Sstevel@tonic-gate if (pool_value_get_int64(pv, &ival) == POC_INVAL) { 35167c478bd9Sstevel@tonic-gate return (PO_FAIL); 35177c478bd9Sstevel@tonic-gate } 35187c478bd9Sstevel@tonic-gate if (nvlist_add_int64(list, nv_name, ival) != 0) { 35197c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 35207c478bd9Sstevel@tonic-gate return (PO_FAIL); 35217c478bd9Sstevel@tonic-gate } 35227c478bd9Sstevel@tonic-gate break; 35237c478bd9Sstevel@tonic-gate case POC_DOUBLE: 35247c478bd9Sstevel@tonic-gate if (pool_value_get_double(pv, &dval) == POC_INVAL) { 35257c478bd9Sstevel@tonic-gate return (PO_FAIL); 35267c478bd9Sstevel@tonic-gate } 35277c478bd9Sstevel@tonic-gate /* 35287c478bd9Sstevel@tonic-gate * Since there is no support for doubles in the 35297c478bd9Sstevel@tonic-gate * kernel, store the double value in a byte array. 35307c478bd9Sstevel@tonic-gate */ 35317c478bd9Sstevel@tonic-gate (void) memcpy(dval_b, &dval, sizeof (double)); 35327c478bd9Sstevel@tonic-gate if (nvlist_add_byte_array(list, nv_name, dval_b, 35337c478bd9Sstevel@tonic-gate sizeof (double)) != 0) { 35347c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 35357c478bd9Sstevel@tonic-gate return (PO_FAIL); 35367c478bd9Sstevel@tonic-gate } 35377c478bd9Sstevel@tonic-gate break; 35387c478bd9Sstevel@tonic-gate case POC_BOOL: 35397c478bd9Sstevel@tonic-gate if (pool_value_get_bool(pv, &bval) == POC_INVAL) { 35407c478bd9Sstevel@tonic-gate return (PO_FAIL); 35417c478bd9Sstevel@tonic-gate } 35427c478bd9Sstevel@tonic-gate if (nvlist_add_byte(list, nv_name, bval) != 0) { 35437c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 35447c478bd9Sstevel@tonic-gate return (PO_FAIL); 35457c478bd9Sstevel@tonic-gate } 35467c478bd9Sstevel@tonic-gate break; 35477c478bd9Sstevel@tonic-gate case POC_STRING: 35487c478bd9Sstevel@tonic-gate if (pool_value_get_string(pv, &sval) == POC_INVAL) { 35497c478bd9Sstevel@tonic-gate return (PO_FAIL); 35507c478bd9Sstevel@tonic-gate } 35517c478bd9Sstevel@tonic-gate if (nvlist_add_string(list, nv_name, (char *)sval) != 0) { 35527c478bd9Sstevel@tonic-gate pool_seterror(POE_SYSTEM); 35537c478bd9Sstevel@tonic-gate return (PO_FAIL); 35547c478bd9Sstevel@tonic-gate } 35557c478bd9Sstevel@tonic-gate break; 35567c478bd9Sstevel@tonic-gate default: 35577c478bd9Sstevel@tonic-gate pool_seterror(POE_BADPARAM); 35587c478bd9Sstevel@tonic-gate return (PO_FAIL); 35597c478bd9Sstevel@tonic-gate } 35607c478bd9Sstevel@tonic-gate return (PO_SUCCESS); 35617c478bd9Sstevel@tonic-gate } 35627c478bd9Sstevel@tonic-gate 35637c478bd9Sstevel@tonic-gate /* 35647c478bd9Sstevel@tonic-gate * hash_id() hashes all elements in a pool configuration using the 35657c478bd9Sstevel@tonic-gate * "sys_id" property. Not all elements have a "sys_id" property, 35667c478bd9Sstevel@tonic-gate * however elem_get_sysid() caters for this by always returning a 35677c478bd9Sstevel@tonic-gate * constant value for those elements. This isn't anticipated to lead 35687c478bd9Sstevel@tonic-gate * to a performance degradation in the hash, since those elements 35697c478bd9Sstevel@tonic-gate * which are likely to be most prevalent in a configuration do have 35707c478bd9Sstevel@tonic-gate * "sys_id" as a property. 35717c478bd9Sstevel@tonic-gate */ 35727c478bd9Sstevel@tonic-gate uint64_t 35737c478bd9Sstevel@tonic-gate hash_id(const pool_elem_t *pe) 35747c478bd9Sstevel@tonic-gate { 35757c478bd9Sstevel@tonic-gate id_t id; 35767c478bd9Sstevel@tonic-gate 35777c478bd9Sstevel@tonic-gate id = elem_get_sysid(pe); 35787c478bd9Sstevel@tonic-gate return (hash_buf(&id, sizeof (id))); 35797c478bd9Sstevel@tonic-gate } 35807c478bd9Sstevel@tonic-gate 35817c478bd9Sstevel@tonic-gate /* 35827c478bd9Sstevel@tonic-gate * blocking_open() guarantees access to the pool device, if open() 35837c478bd9Sstevel@tonic-gate * is failing with EBUSY. 35847c478bd9Sstevel@tonic-gate */ 35857c478bd9Sstevel@tonic-gate int 35867c478bd9Sstevel@tonic-gate blocking_open(const char *path, int oflag) 35877c478bd9Sstevel@tonic-gate { 35887c478bd9Sstevel@tonic-gate int fd; 35897c478bd9Sstevel@tonic-gate 35907c478bd9Sstevel@tonic-gate while ((fd = open(path, oflag)) == -1 && errno == EBUSY) 35917c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 1 * MILLISEC); 35927c478bd9Sstevel@tonic-gate 35937c478bd9Sstevel@tonic-gate return (fd); 35947c478bd9Sstevel@tonic-gate } 3595