1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3247 gjelinek * Common Development and Distribution License (the "License"). 6 3247 gjelinek * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 3247 gjelinek * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #ifndef _POOL_INTERNAL_H 27 0 stevel #define _POOL_INTERNAL_H 28 0 stevel 29 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 30 0 stevel 31 0 stevel #include <libnvpair.h> 32 0 stevel #include <stdarg.h> 33 0 stevel #include <sys/pool.h> 34 0 stevel #include <sys/pool_impl.h> 35 0 stevel 36 0 stevel #ifdef __cplusplus 37 0 stevel extern "C" { 38 0 stevel #endif 39 0 stevel 40 0 stevel /* 41 0 stevel * This file contains the libpool internal definitions which are not 42 0 stevel * directly related to the data access abstraction logic. 43 0 stevel */ 44 0 stevel 45 0 stevel /* 46 0 stevel * Define the various query specifiers for use in the 47 0 stevel * pool_connection_t query function, pc_exec_query. 48 0 stevel */ 49 0 stevel 50 0 stevel #define PEC_QRY_ANY (PEC_QRY_SYSTEM | PEC_QRY_POOL | PEC_QRY_RES | \ 51 0 stevel PEC_QRY_COMP) 52 0 stevel #define PEC_QRY_SYSTEM (1 << PEC_SYSTEM) 53 0 stevel #define PEC_QRY_POOL (1 << PEC_POOL) 54 0 stevel #define PEC_QRY_RES (PEC_QRY_RES_COMP | PEC_QRY_RES_AGG) 55 0 stevel #define PEC_QRY_RES_COMP (1 << PEC_RES_COMP) 56 0 stevel #define PEC_QRY_RES_AGG (1 << PEC_RES_AGG) 57 0 stevel #define PEC_QRY_COMP (1 << PEC_COMP) 58 0 stevel #define PEC_QRY_ELEM(e) (1 << pool_elem_class(e)) 59 0 stevel 60 0 stevel /* 61 0 stevel * Internal type conversion macros 62 0 stevel */ 63 0 stevel #define TO_ELEM(s) ((pool_elem_t *)s) 64 0 stevel /* 65 0 stevel * Get the configuration to which the supplied element belongs. 66 0 stevel */ 67 0 stevel #define TO_CONF(s) (s->pe_conf) 68 0 stevel 69 0 stevel /* 70 0 stevel * Known Data Store Types 71 0 stevel */ 72 0 stevel 73 0 stevel #define XML_DATA_STORE 0 74 0 stevel #define KERNEL_DATA_STORE 1 75 0 stevel 76 0 stevel /* 77 0 stevel * Limits on pool values names and strings 78 0 stevel */ 79 0 stevel #define PV_NAME_MAX_LEN 1024 80 0 stevel #define PV_VALUE_MAX_LEN 1024 81 0 stevel 82 0 stevel /* 83 0 stevel * CB_TAB_BUF_SIZE represents the maximum number of indents to which a 84 0 stevel * char_buf_t is expected to grow. This value would need to be raised 85 0 stevel * if it was ever exceeded. It is an arbitrary limit, but currently 86 0 stevel * the implementation does not exceed a depth of 4. 87 0 stevel */ 88 0 stevel 89 0 stevel #define CB_TAB_BUF_SIZE 8 90 0 stevel #define CB_DEFAULT_LEN 256 91 0 stevel 92 0 stevel /* 93 0 stevel * Helpful pset macros 94 0 stevel */ 95 0 stevel #define PSID_IS_SYSSET(psid) (psid == PS_NONE) 96 0 stevel #define POOL_SYSID_BAD (-2) 97 0 stevel #define POOL_SYSID_BAD_STRING "-2" 98 0 stevel 99 0 stevel /* 100 0 stevel * Size of generated ref_id buffer 101 0 stevel */ 102 0 stevel 103 0 stevel #define KEY_BUFFER_SIZE 48 104 0 stevel 105 0 stevel /* 106 0 stevel * Various useful constant strings which are often encountered 107 0 stevel */ 108 0 stevel extern const char *c_a_dtype; 109 0 stevel extern const char *c_name; 110 0 stevel extern const char *c_type; 111 0 stevel extern const char *c_ref_id; 112 0 stevel extern const char *c_max_prop; 113 0 stevel extern const char *c_min_prop; 114 0 stevel extern const char *c_size_prop; 115 0 stevel extern const char *c_sys_prop; 116 0 stevel 117 0 stevel /* 118 0 stevel * The char_buf_t type is a very simple string implementation which 119 0 stevel * makes it easier to manipulate complex character data. 120 0 stevel */ 121 0 stevel typedef struct char_buf 122 0 stevel { 123 0 stevel size_t cb_size; 124 0 stevel char *cb_buf; 125 0 stevel char cb_tab_buf[CB_TAB_BUF_SIZE]; 126 0 stevel } char_buf_t; 127 0 stevel 128 0 stevel /* 129 0 stevel * libpool uses an opaque discriminated union type, pool_value_t, to 130 0 stevel * contain values which are used to get/set properties on 131 0 stevel * configuration components. Each value is strictly typed and the 132 0 stevel * functions to manipulate these types are exported through the 133 0 stevel * external interface. 134 0 stevel */ 135 0 stevel 136 0 stevel /* 137 0 stevel * Initialize a pool_value_t 138 0 stevel */ 139 0 stevel #define POOL_VALUE_INITIALIZER /* = DEFAULT POOL VALUE */ \ 140 0 stevel {POC_INVAL, NULL, NULL } 141 0 stevel 142 0 stevel struct pool_value { 143 0 stevel pool_value_class_t pv_class; /* Value type */ 144 0 stevel const char *pv_name; /* Value name */ 145 0 stevel union 146 0 stevel { 147 0 stevel uint64_t u; 148 0 stevel int64_t i; 149 0 stevel double d; 150 0 stevel uchar_t b; 151 0 stevel const char *s; 152 0 stevel } pv_u; 153 0 stevel }; 154 0 stevel 155 0 stevel /* 156 0 stevel * The pool_prop_op_t structure is used to perform property specific validation 157 0 stevel * when setting the values of properties in a plugin and when getting a property 158 0 stevel * value which is not stored (i.e. it is generated dynamically by the plugin at 159 0 stevel * access. 160 0 stevel * 161 0 stevel * - ppo_get_value will provide a value for the specified property 162 0 stevel * - ppo_set_value will allow a provider to validate a value before setting it 163 0 stevel */ 164 0 stevel typedef struct pool_prop_op { 165 0 stevel int (*ppo_get_value)(const pool_elem_t *, pool_value_t *); 166 0 stevel int (*ppo_set_value)(pool_elem_t *, const pool_value_t *); 167 0 stevel } pool_prop_op_t; 168 0 stevel 169 0 stevel /* 170 0 stevel * The pool_prop_t structure is used to hold all property related information 171 0 stevel * for each property that a provider is interested in. 172 0 stevel * 173 0 stevel * - pp_pname is the name of the property 174 0 stevel * - pp_value is the initial value of the property 175 0 stevel * - pp_perms is an OR'd bitmap of the access characteristics for the property 176 0 stevel * - pp_init is a function which initialises the value member of the property 177 0 stevel * - pp_op is optional and supports access and validation of property values 178 0 stevel */ 179 0 stevel typedef struct pool_prop { 180 0 stevel const char *pp_pname; 181 0 stevel pool_value_t pp_value; 182 0 stevel uint_t pp_perms; 183 0 stevel int (*pp_init)(struct pool_prop *); 184 0 stevel pool_prop_op_t pp_op; 185 0 stevel } pool_prop_t; 186 0 stevel 187 0 stevel /* 188 0 stevel * log state 189 0 stevel */ 190 0 stevel enum log_state { 191 0 stevel LS_DO, 192 0 stevel LS_UNDO, 193 0 stevel LS_RECOVER, 194 0 stevel LS_FAIL 195 0 stevel }; 196 0 stevel 197 0 stevel /* 198 0 stevel * Forward declaration 199 0 stevel */ 200 0 stevel typedef struct log log_t; 201 0 stevel 202 0 stevel /* 203 0 stevel * log item. 204 0 stevel * 205 0 stevel * Used to describe each operation which needs to be logged. When 206 0 stevel * modifications are desired to the kernel, they are logged in the 207 0 stevel * configuration log file. If the user commits the changes, then the 208 0 stevel * log entries are processed in sequence. If rollback is called, the 209 0 stevel * log is dismissed without being processed. If the commit operation 210 0 stevel * fails, then the log is "rolled back" to undo the previously 211 0 stevel * successful operations. 212 0 stevel */ 213 0 stevel typedef struct log_item { 214 0 stevel log_t *li_log; /* Log containing this item */ 215 0 stevel int li_op; /* Type of operation */ 216 0 stevel void *li_details; /* Operation details */ 217 0 stevel struct log_item *li_next; /* List of log items */ 218 0 stevel struct log_item *li_prev; /* List of log items */ 219 0 stevel enum log_state li_state; /* Item state */ 220 0 stevel } log_item_t; 221 0 stevel 222 0 stevel /* 223 0 stevel * log. 224 0 stevel * 225 0 stevel * This maintains a list of log items. The sentinel is used to 226 0 stevel * simplify processing around the "empty list". The state of the log 227 0 stevel * indicates whether transactions are being processed normally, or 228 0 stevel * whether recovery is in progress. 229 0 stevel */ 230 0 stevel struct log 231 0 stevel { 232 0 stevel pool_conf_t *l_conf; /* Configuration for this log */ 233 0 stevel log_item_t *l_sentinel; /* Log sentinel */ 234 0 stevel enum log_state l_state; /* Log state */ 235 0 stevel }; 236 0 stevel 237 0 stevel 238 0 stevel /* 239 0 stevel * log item action function type 240 0 stevel */ 241 0 stevel typedef int (*log_item_action_t)(log_item_t *); 242 0 stevel 243 0 stevel /* 244 0 stevel * Get the max/min/size property value of a resource. 245 0 stevel */ 246 0 stevel extern int resource_get_max(const pool_resource_t *, uint64_t *); 247 0 stevel extern int resource_get_min(const pool_resource_t *, uint64_t *); 248 0 stevel extern int resource_get_size(const pool_resource_t *, uint64_t *); 249 0 stevel extern int resource_get_pinned(const pool_resource_t *, 250 0 stevel uint64_t *); 251 0 stevel 252 0 stevel /* 253 0 stevel * Element utility operations. 254 0 stevel */ 255 0 stevel extern char *elem_get_name(const pool_elem_t *); 256 0 stevel extern id_t elem_get_sysid(const pool_elem_t *); 257 0 stevel extern int elem_is_default(const pool_elem_t *); 258 3247 gjelinek extern boolean_t elem_is_tmp(const pool_elem_t *); 259 0 stevel extern const pool_elem_t *get_default_elem(const pool_elem_t *); 260 0 stevel extern int qsort_elem_compare(const void *, const void *); 261 0 stevel 262 0 stevel /* 263 0 stevel * Get the class of the supplied element. 264 0 stevel */ 265 0 stevel extern const char *pool_elem_class_string(const pool_elem_t *); 266 0 stevel extern const char *pool_resource_type_string(pool_resource_elem_class_t); 267 0 stevel extern const char *pool_component_type_string(pool_component_elem_class_t); 268 0 stevel 269 0 stevel /* 270 0 stevel * Commit the supplied configuration to the system. This function 271 0 stevel * attempts to make the system look like the supplied configuration. 272 0 stevel */ 273 0 stevel extern int pool_conf_commit_sys(pool_conf_t *, int); 274 0 stevel 275 0 stevel /* 276 0 stevel * Allocate an XML/kernel connection to a data representation. 277 0 stevel */ 278 0 stevel extern int pool_xml_connection_alloc(pool_conf_t *, int); 279 0 stevel extern int pool_knl_connection_alloc(pool_conf_t *, int); 280 0 stevel 281 0 stevel /* 282 0 stevel * Create/Destroy a pool component belonging to the supplied resource 283 0 stevel */ 284 0 stevel extern pool_component_t *pool_component_create(pool_conf_t *, 285 0 stevel const pool_resource_t *, int64_t); 286 0 stevel extern int pool_component_destroy(pool_component_t *); 287 0 stevel 288 0 stevel /* 289 0 stevel * Get/Set the owner (container) of a particular configuration 290 0 stevel * element. 291 0 stevel */ 292 0 stevel extern pool_elem_t *pool_get_container(const pool_elem_t *); 293 0 stevel extern int pool_set_container(pool_elem_t *, pool_elem_t *); 294 0 stevel 295 0 stevel /* 296 0 stevel * These functions are used for debugging. Setting the environment 297 0 stevel * variable LIBPOOL_DEBUG to 1, enables these functions. 298 0 stevel */ 299 0 stevel extern void do_dprintf(const char *, va_list); 300 0 stevel extern void dprintf(const char *, ...); 301 0 stevel 302 0 stevel /* 303 0 stevel * libpool maintains it's own error value, rather than further pollute 304 0 stevel * errno, this function is used to set the current error value for 305 0 stevel * retrieval. 306 0 stevel */ 307 0 stevel extern void pool_seterror(int); 308 0 stevel 309 0 stevel /* 310 0 stevel * Element Class 311 0 stevel */ 312 0 stevel extern pool_elem_class_t pool_elem_class(const pool_elem_t *); 313 0 stevel extern pool_resource_elem_class_t pool_resource_elem_class(const pool_elem_t *); 314 0 stevel extern pool_component_elem_class_t pool_component_elem_class(const 315 0 stevel pool_elem_t *); 316 0 stevel extern int pool_elem_same_class(const pool_elem_t *, const pool_elem_t *); 317 0 stevel extern pool_elem_class_t pool_elem_class_from_string(const char *); 318 0 stevel extern pool_resource_elem_class_t pool_resource_elem_class_from_string(const 319 0 stevel char *); 320 0 stevel extern pool_component_elem_class_t pool_component_elem_class_from_string(const 321 0 stevel char *); 322 0 stevel 323 0 stevel /* 324 0 stevel * Element Equivalency 325 0 stevel */ 326 0 stevel extern int pool_elem_compare(const pool_elem_t *, 327 0 stevel const pool_elem_t *); 328 0 stevel extern int pool_elem_compare_name(const pool_elem_t *, 329 0 stevel const pool_elem_t *); 330 0 stevel 331 0 stevel /* 332 0 stevel * Dynamic character buffers. Limited functionality but enough for our 333 0 stevel * purposes. 334 0 stevel */ 335 0 stevel extern char_buf_t *alloc_char_buf(size_t); 336 0 stevel extern void free_char_buf(char_buf_t *); 337 0 stevel extern int set_char_buf(char_buf_t *, const char *, ...); 338 0 stevel extern int append_char_buf(char_buf_t *, const char *, ...); 339 0 stevel 340 0 stevel /* 341 0 stevel * Internal functions for use with pool values. 342 0 stevel */ 343 0 stevel extern int pool_value_equal(pool_value_t *, pool_value_t *); 344 0 stevel extern int pool_value_from_nvpair(pool_value_t *, nvpair_t *); 345 0 stevel 346 0 stevel /* 347 0 stevel * Check to ensure that the supplied string is a valid name for a pool 348 0 stevel * element. 349 0 stevel */ 350 0 stevel extern int is_valid_name(const char *); 351 0 stevel 352 0 stevel /* 353 0 stevel * Functions related to element prefix manipulation. You can get the 354 0 stevel * prefix for a supplied element or find out if a supplied string is a 355 0 stevel * valid prefix for a certain class of element. 356 0 stevel */ 357 0 stevel extern const char *elem_get_prefix(const pool_elem_t *); 358 0 stevel extern const char *is_a_known_prefix(pool_elem_class_t, const char *); 359 0 stevel 360 0 stevel /* 361 0 stevel * Internal property manipulators 362 0 stevel */ 363 0 stevel extern int pool_put_ns_property(pool_elem_t *, const char *, 364 0 stevel const pool_value_t *); 365 0 stevel extern int pool_put_any_property(pool_elem_t *, const char *, 366 0 stevel const pool_value_t *); 367 0 stevel extern int pool_put_any_ns_property(pool_elem_t *, const char *, 368 0 stevel const pool_value_t *); 369 0 stevel extern pool_value_class_t pool_get_ns_property(const pool_elem_t *, 370 0 stevel const char *, pool_value_t *); 371 0 stevel extern int pool_walk_any_properties(pool_conf_t *, pool_elem_t *, 372 0 stevel void *, int (*)(pool_conf_t *, pool_elem_t *, const char *, 373 0 stevel pool_value_t *, void *), int); 374 3247 gjelinek extern int pool_set_temporary(pool_conf_t *, pool_elem_t *); 375 0 stevel 376 0 stevel /* 377 0 stevel * Namespace aware utility functions. 378 0 stevel */ 379 0 stevel extern const char *is_ns_property(const pool_elem_t *, const char *); 380 0 stevel extern const char *property_name_minus_ns(const pool_elem_t *, 381 0 stevel const char *); 382 0 stevel 383 0 stevel /* 384 0 stevel * Initialisation routines. 385 0 stevel */ 386 0 stevel extern void internal_init(void); 387 0 stevel 388 0 stevel /* 389 0 stevel * Is the supplied configuration the dynamic configuration? 390 0 stevel */ 391 0 stevel extern int conf_is_dynamic(const pool_conf_t *); 392 0 stevel 393 0 stevel /* 394 0 stevel * Update the library snapshot from the kernel 395 0 stevel */ 396 0 stevel extern int pool_knl_update(pool_conf_t *, int *); 397 0 stevel 398 0 stevel /* 399 0 stevel * Resource property functions 400 0 stevel */ 401 0 stevel extern int resource_is_default(const pool_resource_t *); 402 0 stevel extern int resource_is_system(const pool_resource_t *); 403 0 stevel extern int resource_can_associate(const pool_resource_t *); 404 0 stevel extern const pool_resource_t *get_default_resource(const pool_resource_t *); 405 0 stevel extern pool_resource_t *resource_by_sysid(const pool_conf_t *, id_t, 406 0 stevel const char *); 407 0 stevel 408 0 stevel /* 409 0 stevel * Resource property provider functions 410 0 stevel */ 411 0 stevel extern uint_t pool_get_provider_count(void); 412 0 stevel extern const pool_prop_t *provider_get_props(const pool_elem_t *); 413 0 stevel extern const pool_prop_t *provider_get_prop(const pool_elem_t *, 414 0 stevel const char *); 415 0 stevel extern int prop_is_stored(const pool_prop_t *); 416 0 stevel extern int prop_is_readonly(const pool_prop_t *); 417 0 stevel extern int prop_is_init(const pool_prop_t *); 418 0 stevel extern int prop_is_hidden(const pool_prop_t *); 419 0 stevel extern int prop_is_optional(const pool_prop_t *); 420 0 stevel 421 0 stevel /* 422 0 stevel * Component property functions 423 0 stevel */ 424 0 stevel extern int cpu_is_requested(pool_component_t *); 425 0 stevel 426 0 stevel /* 427 0 stevel * Simple initialisation routines for values used when initialising the 428 0 stevel * property arrays for each plugin 429 0 stevel * Return PO_SUCCESS/PO_FAIL to indicate success/failure 430 0 stevel */ 431 0 stevel extern int uint_init(pool_prop_t *, uint64_t); 432 0 stevel extern int int_init(pool_prop_t *, int64_t); 433 0 stevel extern int double_init(pool_prop_t *, double); 434 0 stevel extern int bool_init(pool_prop_t *, uchar_t); 435 0 stevel extern int string_init(pool_prop_t *, const char *); 436 0 stevel 437 0 stevel 438 0 stevel /* 439 0 stevel * log functions 440 0 stevel */ 441 0 stevel extern log_t *log_alloc(pool_conf_t *); 442 0 stevel extern void log_free(log_t *); 443 0 stevel extern void log_empty(log_t *); 444 0 stevel extern int log_walk(log_t *, log_item_action_t); 445 0 stevel extern int log_reverse_walk(log_t *, log_item_action_t); 446 0 stevel extern uint_t log_size(log_t *); 447 0 stevel extern int log_append(log_t *, int, void *); 448 0 stevel 449 0 stevel /* 450 0 stevel * log item functions 451 0 stevel */ 452 0 stevel extern log_item_t *log_item_alloc(log_t *, int, void *); 453 0 stevel extern int log_item_free(log_item_t *); 454 0 stevel 455 0 stevel extern int pool_validate_resource(const pool_conf_t *, 456 0 stevel const char *, const char *, int64_t); 457 0 stevel 458 0 stevel /* 459 0 stevel * String atom functions 460 0 stevel */ 461 0 stevel extern const char *atom_string(const char *); 462 0 stevel extern void atom_free(const char *); 463 0 stevel /* 464 0 stevel * debugging functions 465 0 stevel */ 466 0 stevel #ifdef DEBUG 467 0 stevel extern void log_item_dprintf(log_item_t *); 468 0 stevel extern void pool_value_dprintf(const pool_value_t *); 469 0 stevel extern void pool_elem_dprintf(const pool_elem_t *); 470 0 stevel #endif 471 0 stevel 472 0 stevel #ifdef __cplusplus 473 0 stevel } 474 0 stevel #endif 475 0 stevel 476 0 stevel #endif /* _POOL_INTERNAL_H */ 477