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