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