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