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
load_group(pool_conf_t * conf,pool_knl_elem_t * elem,ea_object_t * ep,pool_snap_load_t * psl)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
pool_knl_snap_load_push(pool_snap_load_t * psl,pool_knl_pool_t * pkp)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
pool_knl_snap_load_update(pool_snap_load_t * psl,int type,uint_t id)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
pool_knl_snap_load_remove(pool_snap_load_t * psl,int type,uint_t id)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 *
pool_knl_find_nvpair(nvlist_t * l,const char * name)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
pool_knl_close(pool_conf_t * conf)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
remove_dead_elems(const void * key,void ** value,void * cl)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
find_dead_elems(const void * key,void ** value,void * cl)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
pool_knl_update(pool_conf_t * conf,int * changed)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
pool_knl_validate(const pool_conf_t * conf,pool_valid_level_t level)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
pool_knl_commit(pool_conf_t * conf)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
prop_build_cb(pool_conf_t * UNUSED,pool_elem_t * pe,const char * name,pool_value_t * pval,void * user)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
pool_knl_put_xml_property(pool_elem_t * pe,xmlNodePtr node,const char * name,const pool_value_t * val)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
pool_knl_export(const pool_conf_t * conf,const char * location,pool_export_format_t fmt)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
pool_knl_recover(pool_conf_t * conf)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
pool_knl_rollback(pool_conf_t * conf)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
build_result_set(const void * key,void ** value,void * cl)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 *
pool_knl_exec_query(const pool_conf_t * conf,const pool_elem_t * src,const char * src_attr,pool_elem_class_t classes,pool_value_t ** props)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
destroy_pool_cb(pool_conf_t * conf,pool_t * pool,void * unused)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
pool_knl_remove(pool_conf_t * conf)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 *
pool_knl_get_binding(pool_conf_t * conf,pid_t pid)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
pool_knl_set_binding(pool_conf_t * conf,const char * pool_name,idtype_t idtype,id_t id)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 *
pool_knl_get_resource_binding(pool_conf_t * conf,pool_resource_elem_class_t type,pid_t pid)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 *
pool_knl_elem_wrap(pool_conf_t * conf,pool_elem_class_t class,pool_resource_elem_class_t res_class,pool_component_elem_class_t comp_class)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 *
pool_knl_elem_create(pool_conf_t * conf,pool_elem_class_t class,pool_resource_elem_class_t res_class,pool_component_elem_class_t comp_class)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
pool_knl_elem_remove(pool_elem_t * pe)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
pool_knl_set_container(pool_elem_t * pp,pool_elem_t * pc)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
pool_knl_res_transfer(pool_resource_t * src,pool_resource_t * tgt,uint64_t size)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
pool_knl_res_xtransfer(pool_resource_t * src,pool_resource_t * tgt,pool_component_t ** rl)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 *
pool_knl_get_container(const pool_elem_t * pe)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
pool_knl_resource_is_system(const pool_resource_t * pr)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
pool_knl_resource_can_associate(const pool_resource_t * pr)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
pool_knl_pool_associate(pool_t * pool,const pool_resource_t * resource)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
pool_knl_pool_dissociate(pool_t * pool,const pool_resource_t * resource)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
pool_knl_connection_alloc(pool_conf_t * conf,int oflags)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
pool_knl_elem_printf_cb(const void * key,void ** value,void * cl)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
pool_knl_elem_free(pool_knl_elem_t * pke,int freeprop)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
pool_knl_elem_free_cb(const void * key,void ** value,void * cl)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
pool_knl_connection_free(pool_knl_connection_t * prov)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
pool_knl_get_property(const pool_elem_t * pe,const char * name,pool_value_t * val)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
pool_knl_get_dynamic_property(const pool_elem_t * pe,const char * name,pool_value_t * val)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
pool_knl_put_property(pool_elem_t * pe,const char * name,const pool_value_t * val)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
pool_knl_rm_property(pool_elem_t * pe,const char * name)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 **
pool_knl_get_properties(const pool_elem_t * pe,uint_t * nprops)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
pool_knl_result_set_append(pool_knl_result_set_t * rs,pool_knl_elem_t * pke)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
pool_knl_result_set_realloc(pool_knl_result_set_t * rs)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 *
pool_knl_result_set_alloc(const pool_conf_t * conf)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
pool_knl_result_set_free(pool_knl_result_set_t * rs)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 *
pool_knl_rs_next(pool_result_set_t * set)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 *
pool_knl_rs_prev(pool_result_set_t * set)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
pool_knl_rs_set_index(pool_result_set_t * set,int index)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
pool_knl_rs_get_index(pool_result_set_t * set)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 *
pool_knl_rs_first(pool_result_set_t * set)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 *
pool_knl_rs_last(pool_result_set_t * set)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
pool_knl_rs_count(pool_result_set_t * set)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
pool_knl_rs_close(pool_result_set_t * set)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
log_item_commit(log_item_t * li)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
log_item_undo(log_item_t * li)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
log_item_release(log_item_t * li)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
pool_knl_nvlist_add_value(nvlist_t * list,const char * name,const pool_value_t * pv)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
hash_id(const pool_elem_t * pe)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
blocking_open(const char * path,int oflag)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