xref: /illumos-gate/usr/src/cmd/svc/configd/configd.h (revision 54d02241)
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 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 2015, Joyent, Inc. All rights reserved.
29  */
30 
31 #ifndef	_CONFIGD_H
32 #define	_CONFIGD_H
33 
34 #include <bsm/adt.h>
35 #include <door.h>
36 #include <pthread.h>
37 #include <synch.h>
38 #include <string.h>
39 #include <sys/types.h>
40 
41 #include <libscf.h>
42 #include <repcache_protocol.h>
43 #include <libuutil.h>
44 
45 #include <configd_exit.h>
46 
47 #ifdef	__cplusplus
48 extern "C" {
49 #endif
50 
51 /*
52  * Lock order:
53  *
54  *	client lock
55  *		iter locks, in ID order
56  *		entity locks, in ID order
57  *
58  *		(any iter/entity locks)
59  *			backend locks (NORMAL, then NONPERSIST)
60  *				rc_node lock
61  *					children's rc_node lock
62  *				cache bucket lock
63  *					rc_node lock[*]
64  *
65  *	* only one node may be grabbed while holding a bucket lock
66  *
67  *	leaf locks:  (no other locks may be aquired while holding one)
68  *		rc_pg_notify_lock
69  *		rc_annotate_lock
70  */
71 
72 /*
73  * Returns the minimum size for a structure of type 't' such
74  * that it is safe to access field 'f'.
75  */
76 #define	offsetofend(t, f)	(offsetof(t, f) + sizeof (((t *)0)->f))
77 
78 /*
79  * We want MUTEX_HELD, but we also want pthreads.  So we're stuck with this
80  * for the native build, at least until the build machines can catch up
81  * with the latest version of MUTEX_HELD() in <synch.h>.
82  */
83 #if defined(NATIVE_BUILD)
84 #undef	MUTEX_HELD
85 #define	MUTEX_HELD(m)		_mutex_held((mutex_t *)(m))
86 #endif
87 
88 /*
89  * Maximum levels of composition.
90  */
91 #define	COMPOSITION_DEPTH	2
92 
93 #define	CONFIGD_CORE	"core.%f.%t.%p"
94 
95 #define	bad_error(f, e)							\
96 	uu_panic("%s:%d: %s() returned bad error %d.  Aborting.\n",	\
97 	    __FILE__, __LINE__, f, e);
98 
99 typedef enum backend_type {
100 	BACKEND_TYPE_NORMAL		= 0,
101 	BACKEND_TYPE_NONPERSIST,
102 	BACKEND_TYPE_TOTAL			/* backend use only */
103 } backend_type_t;
104 
105 /*
106  * pre-declare rc_* types
107  */
108 typedef struct rc_node rc_node_t;
109 typedef struct rc_snapshot rc_snapshot_t;
110 typedef struct rc_snaplevel rc_snaplevel_t;
111 
112 /*
113  * notification layer -- protected by rc_pg_notify_lock
114  */
115 typedef struct rc_notify_info rc_notify_info_t;
116 typedef struct rc_notify_delete rc_notify_delete_t;
117 
118 #define	RC_NOTIFY_MAX_NAMES	4	/* enough for now */
119 
120 typedef struct rc_notify {
121 	uu_list_node_t	rcn_list_node;
122 	rc_node_t	*rcn_node;
123 	rc_notify_info_t *rcn_info;
124 	rc_notify_delete_t *rcn_delete;
125 } rc_notify_t;
126 
127 struct rc_notify_delete {
128 	rc_notify_t rnd_notify;
129 	char rnd_fmri[REP_PROTOCOL_FMRI_LEN];
130 };
131 
132 struct rc_notify_info {
133 	uu_list_node_t	rni_list_node;
134 	rc_notify_t	rni_notify;
135 	const char	*rni_namelist[RC_NOTIFY_MAX_NAMES];
136 	const char	*rni_typelist[RC_NOTIFY_MAX_NAMES];
137 
138 	int		rni_flags;
139 	int		rni_waiters;
140 	pthread_cond_t	rni_cv;
141 };
142 #define	RC_NOTIFY_ACTIVE	0x00000001
143 #define	RC_NOTIFY_DRAIN		0x00000002
144 #define	RC_NOTIFY_EMPTYING	0x00000004
145 
146 typedef struct rc_node_pg_notify {
147 	uu_list_node_t	rnpn_node;
148 	int		rnpn_fd;
149 	rc_node_t	*rnpn_pg;
150 } rc_node_pg_notify_t;
151 
152 /*
153  * cache layer
154  */
155 
156 /*
157  * The 'key' for the main object hash.  main_id is the main object
158  * identifier.  The rl_ids array contains:
159  *
160  *	TYPE		RL_IDS
161  *	scope		unused
162  *	service		unused
163  *	instance	{service_id}
164  *	snapshot	{service_id, instance_id}
165  *	snaplevel	{service_id, instance_id, name_id, snapshot_id}
166  *	propertygroup	{service_id, (instance_id or 0), (name_id or 0),
167  *			    (snapshot_id or 0), (l_id or 0)}
168  *	property	{service_id, (instance_id or 0), (name_id or 0),
169  *			    (snapshot_id or 0), (l_id or 0), pg_id, gen_id}
170  */
171 #define	ID_SERVICE	0
172 #define	ID_INSTANCE	1
173 #define	ID_NAME		2
174 #define	ID_SNAPSHOT	3
175 #define	ID_LEVEL	4
176 #define	ID_PG		5
177 #define	ID_GEN		6
178 #define	MAX_IDS	7
179 typedef struct rc_node_lookup {
180 	uint16_t	rl_type;		/* REP_PROTOCOL_ENTITY_* */
181 	uint16_t	rl_backend;		/* BACKEND_TYPE_* */
182 	uint32_t	rl_main_id;		/* primary identifier */
183 	uint32_t	rl_ids[MAX_IDS];	/* context */
184 } rc_node_lookup_t;
185 
186 struct rc_node {
187 	/*
188 	 * read-only data
189 	 */
190 	rc_node_lookup_t rn_id;			/* must be first */
191 	uint32_t	rn_hash;
192 	const char	*rn_name;
193 
194 	/*
195 	 * type-specific state
196 	 * (if space becomes an issue, these can become a union)
197 	 */
198 
199 	/*
200 	 * Used by instances, snapshots, and "composed property groups" only.
201 	 * These are the entities whose properties should appear composed when
202 	 * this entity is traversed by a composed iterator.  0 is the top-most
203 	 * entity, down to COMPOSITION_DEPTH - 1.
204 	 */
205 	rc_node_t	*rn_cchain[COMPOSITION_DEPTH];
206 
207 	/*
208 	 * used by property groups only
209 	 */
210 	const char	*rn_type;
211 	uint32_t	rn_pgflags;
212 	uint32_t	rn_gen_id;
213 	uu_list_t	*rn_pg_notify_list;	/* prot by rc_pg_notify_lock */
214 	rc_notify_t	rn_notify;		/* prot by rc_pg_notify_lock */
215 
216 	/*
217 	 * used by properties only
218 	 */
219 	rep_protocol_value_type_t rn_valtype;
220 	const char	*rn_values;		/* protected by rn_lock */
221 	size_t		rn_values_count;	/* protected by rn_lock */
222 	size_t		rn_values_size;		/* protected by rn_lock */
223 
224 	/*
225 	 * used by snapshots only
226 	 */
227 	uint32_t	rn_snapshot_id;
228 	rc_snapshot_t	*rn_snapshot;		/* protected by rn_lock */
229 
230 	/*
231 	 * used by snaplevels only
232 	 */
233 	rc_snaplevel_t	*rn_snaplevel;
234 
235 	/*
236 	 * mutable state
237 	 */
238 	pthread_mutex_t	rn_lock;
239 	pthread_cond_t	rn_cv;
240 	uint32_t	rn_flags;
241 	uint32_t	rn_refs;		/* client reference count */
242 	uint32_t	rn_erefs;		/* ephemeral ref count */
243 	uint32_t	rn_other_refs;		/* atomic refcount */
244 	uint32_t	rn_other_refs_held;	/* for 1->0 transitions */
245 
246 	uu_list_t	*rn_children;
247 	uu_list_node_t	rn_sibling_node;
248 
249 	rc_node_t	*rn_parent;		/* set if on child list */
250 	rc_node_t	*rn_former;		/* next former node */
251 	rc_node_t	*rn_parent_ref;		/* reference count target */
252 	const char	*rn_fmri;
253 
254 	/*
255 	 * external state (protected by hash chain lock)
256 	 */
257 	rc_node_t	*rn_hash_next;
258 };
259 
260 /*
261  * flag ordering:
262  *	RC_DYING
263  *		RC_NODE_CHILDREN_CHANGING
264  *		RC_NODE_CREATING_CHILD
265  *		RC_NODE_USING_PARENT
266  *			RC_NODE_IN_TX
267  *
268  * RC_NODE_USING_PARENT is special, because it lets you proceed up the tree,
269  * in the reverse of the usual locking order.  Because of this, there are
270  * limitations on what you can do while holding it.  While holding
271  * RC_NODE_USING_PARENT, you may:
272  *	bump or release your parent's reference count
273  *	access fields in your parent
274  *	hold RC_NODE_USING_PARENT in the parent, proceeding recursively.
275  *
276  * If you are only holding *one* node's RC_NODE_USING_PARENT, and:
277  *	you are *not* proceeding recursively, you can hold your
278  *	    immediate parent's RC_NODE_CHILDREN_CHANGING flag.
279  *	you hold your parent's RC_NODE_CHILDREN_CHANGING flag, you can add
280  *	    RC_NODE_IN_TX to your flags.
281  *	you want to grab a flag in your parent, you must lock your parent,
282  *	    lock yourself, drop RC_NODE_USING_PARENT, unlock yourself,
283  *	    then proceed to manipulate the parent.
284  */
285 #define	RC_NODE_CHILDREN_CHANGING	0x00000001 /* child list in flux */
286 #define	RC_NODE_HAS_CHILDREN		0x00000002 /* child list is accurate */
287 
288 #define	RC_NODE_IN_PARENT		0x00000004 /* I'm in my parent's list */
289 #define	RC_NODE_USING_PARENT		0x00000008 /* parent ptr in use */
290 #define	RC_NODE_CREATING_CHILD		0x00000010 /* a create is in progress */
291 #define	RC_NODE_IN_TX			0x00000020 /* a tx is in progess */
292 
293 #define	RC_NODE_OLD			0x00000400 /* out-of-date object */
294 #define	RC_NODE_ON_FORMER		0x00000800 /* on an rn_former list */
295 
296 #define	RC_NODE_PARENT_REF		0x00001000 /* parent_ref in use */
297 #define	RC_NODE_UNREFED			0x00002000 /* unref processing active */
298 #define	RC_NODE_DYING			0x00004000 /* node is being deleted */
299 #define	RC_NODE_DEAD			0x00008000 /* node has been deleted */
300 
301 /*
302  * RC_NODE_DEAD means that the node no longer represents data in the
303  * backend, and we should return _DELETED errors to clients who try to use
304  * it.  Very much like a zombie process.
305  *
306  * RC_NODE_OLD also means that the node no longer represents data in the
307  * backend, but it's ok for clients to access it because we've loaded all of
308  * the children.  (This only happens for transactional objects such as
309  * property groups and snapshots, where we guarantee a stable view once
310  * a reference is obtained.)  When all client references are destroyed,
311  * however, the node should be destroyed.
312  *
313  * Though RC_NODE_DEAD is set by the rc_node_delete() code, it is also set
314  * by rc_node_no_client_refs() for RC_NODE_OLD nodes not long before
315  * they're destroyed.
316  */
317 
318 #define	RC_NODE_DYING_FLAGS						\
319 	(RC_NODE_CHILDREN_CHANGING | RC_NODE_IN_TX | RC_NODE_DYING |	\
320 	    RC_NODE_CREATING_CHILD)
321 
322 #define	RC_NODE_WAITING_FLAGS						\
323 	(RC_NODE_DYING_FLAGS | RC_NODE_USING_PARENT)
324 
325 
326 #define	NODE_LOCK(n)	(void) pthread_mutex_lock(&(n)->rn_lock)
327 #define	NODE_UNLOCK(n)	(void) pthread_mutex_unlock(&(n)->rn_lock)
328 
329 
330 typedef enum rc_auth_state {
331 	RC_AUTH_UNKNOWN = 0,		/* No checks done yet. */
332 	RC_AUTH_FAILED,			/* Authorization checked & failed. */
333 	RC_AUTH_PASSED			/* Authorization succeeded. */
334 } rc_auth_state_t;
335 
336 /*
337  * Some authorization checks are performed in rc_node_setup_tx() in
338  * response to the REP_PROTOCOL_PROPERTYGRP_TX_START message.  Other checks
339  * must wait until the actual transaction operations are received in the
340  * REP_PROTOCOL_PROPERTYGRP_TX_COMMIT message.  This second set of checks
341  * is performed in rc_tx_commit().  rnp_auth_string and rnp_authorized in
342  * the following structure are used to hold the results of the
343  * authorization checking done in rc_node_setup_tx() for later use by
344  * rc_tx_commit().
345  *
346  * In client.c transactions are represented by rc_node_ptr structures which
347  * point to a property group rc_node_t.  Thus, this is an appropriate place
348  * to hold authorization state.
349  */
350 typedef struct rc_node_ptr {
351 	rc_node_t	*rnp_node;
352 	const char	*rnp_auth_string;	/* authorization string */
353 	rc_auth_state_t	rnp_authorized;		/* transaction pre-auth rslt. */
354 	char		rnp_deleted;		/* object was deleted */
355 } rc_node_ptr_t;
356 
357 #define	NODE_PTR_NOT_HELD(npp) \
358 	    ((npp)->rnp_node == NULL || !MUTEX_HELD(&(npp)->rnp_node->rn_lock))
359 
360 typedef int rc_iter_filter_func(rc_node_t *, void *);
361 
362 typedef struct rc_node_iter {
363 	rc_node_t	*rni_parent;
364 	int		rni_clevel;	/* index into rni_parent->rn_cchain[] */
365 	rc_node_t	*rni_iter_node;
366 	uu_list_walk_t	*rni_iter;
367 	uint32_t	rni_type;
368 
369 	/*
370 	 * for normal walks
371 	 */
372 	rc_iter_filter_func *rni_filter;
373 	void		*rni_filter_arg;
374 
375 	/*
376 	 * for value walks
377 	 */
378 	uint32_t	rni_offset;		/* next value offset */
379 	uint32_t	rni_last_offset;	/* previous value offset */
380 } rc_node_iter_t;
381 
382 typedef struct rc_node_tx {
383 	rc_node_ptr_t	rnt_ptr;
384 	int		rnt_authorized;		/* No need to check anymore. */
385 } rc_node_tx_t;
386 
387 
388 typedef struct cache_bucket {
389 	pthread_mutex_t	cb_lock;
390 	rc_node_t	*cb_head;
391 
392 	char		cb_pad[64 - sizeof (pthread_mutex_t) -
393 			    2 * sizeof (rc_node_t *)];
394 } cache_bucket_t;
395 
396 /*
397  * tx_commit_data_tx is an opaque structure which is defined in object.c.
398  * It contains the data of the transaction that is to be committed.
399  * Accessor functions in object.c allow other modules to retrieve
400  * information.
401  */
402 typedef struct tx_commit_data tx_commit_data_t;
403 
404 /*
405  * Snapshots
406  */
407 struct rc_snapshot {
408 	uint32_t	rs_snap_id;
409 
410 	pthread_mutex_t	rs_lock;
411 	pthread_cond_t	rs_cv;
412 
413 	uint32_t	rs_flags;
414 	uint32_t	rs_refcnt;	/* references from rc_nodes */
415 	uint32_t	rs_childref;	/* references to children */
416 
417 	rc_snaplevel_t	*rs_levels;	/* list of levels */
418 	rc_snapshot_t	*rs_hash_next;
419 };
420 #define	RC_SNAPSHOT_FILLING	0x00000001	/* rs_levels changing */
421 #define	RC_SNAPSHOT_READY	0x00000002
422 #define	RC_SNAPSHOT_DEAD	0x00000004	/* no resources */
423 
424 typedef struct rc_snaplevel_pgs {
425 	uint32_t	rsp_pg_id;
426 	uint32_t	rsp_gen_id;
427 } rc_snaplevel_pgs_t;
428 
429 struct rc_snaplevel {
430 	rc_snapshot_t	*rsl_parent;
431 	uint32_t	rsl_level_num;
432 	uint32_t	rsl_level_id;
433 
434 	uint32_t	rsl_service_id;
435 	uint32_t	rsl_instance_id;
436 
437 	const char	*rsl_scope;
438 	const char	*rsl_service;
439 	const char	*rsl_instance;
440 
441 	rc_snaplevel_t	*rsl_next;
442 };
443 
444 /*
445  * Client layer -- the IDs fields must be first, in order for the search
446  * routines to work correctly.
447  */
448 enum repcache_txstate {
449 	REPCACHE_TX_INIT,
450 	REPCACHE_TX_SETUP,
451 	REPCACHE_TX_COMMITTED
452 };
453 
454 typedef struct repcache_entity {
455 	uint32_t	re_id;
456 	uu_avl_node_t	re_link;
457 	uint32_t	re_changeid;
458 
459 	pthread_mutex_t	re_lock;
460 	uint32_t	re_type;
461 	rc_node_ptr_t	re_node;
462 	enum repcache_txstate re_txstate;	/* property groups only */
463 } repcache_entity_t;
464 
465 typedef struct repcache_iter {
466 	uint32_t	ri_id;
467 	uu_avl_node_t	ri_link;
468 
469 	uint32_t	ri_type;	/* result type */
470 
471 	pthread_mutex_t	ri_lock;
472 	uint32_t	ri_sequence;
473 	rc_node_iter_t	*ri_iter;
474 } repcache_iter_t;
475 
476 typedef struct repcache_client {
477 	/*
478 	 * constants
479 	 */
480 	uint32_t	rc_id;		/* must be first */
481 	int		rc_all_auths;	/* bypass auth checks */
482 	uint32_t	rc_debug;	/* debug flags */
483 	pid_t		rc_pid;		/* pid of opening process */
484 	door_id_t	rc_doorid;	/* a globally unique identifier */
485 	int		rc_doorfd;	/* our door's FD */
486 
487 	/*
488 	 * Constants used for security auditing
489 	 *
490 	 * rc_adt_session points to the audit session data that is used for
491 	 * the life of the client.  rc_adt_sessionid is the session ID that
492 	 * is initially assigned when the audit session is started.  See
493 	 * start_audit_session() in client.c.  This session id is used for
494 	 * audit events except when we are processing a set of annotated
495 	 * events.  Annotated events use a separate session id so that they
496 	 * can be grouped.  See set_annotation() in client.c.
497 	 */
498 	adt_session_data_t *rc_adt_session;	/* Session data. */
499 	au_asid_t	rc_adt_sessionid;	/* Main session ID for */
500 						/* auditing */
501 
502 	/*
503 	 * client list linkage, protected by hash chain lock
504 	 */
505 	uu_list_node_t	rc_link;
506 
507 	/*
508 	 * notification information, protected by rc_node layer
509 	 */
510 	rc_node_pg_notify_t	rc_pg_notify;
511 	rc_notify_info_t	rc_notify_info;
512 
513 	/*
514 	 * client_wait output, only usable by rc_notify_thr
515 	 */
516 	rc_node_ptr_t	rc_notify_ptr;
517 
518 	/*
519 	 * register sets, protected by rc_lock
520 	 */
521 	uu_avl_t	*rc_entities;
522 	uu_avl_t	*rc_iters;
523 
524 	/*
525 	 * Variables, protected by rc_lock
526 	 */
527 	int		rc_refcnt;	/* in-progress door calls */
528 	int		rc_flags;	/* see RC_CLIENT_* symbols below */
529 	uint32_t	rc_changeid;	/* used to make backups idempotent */
530 	pthread_t	rc_insert_thr;	/* single thread trying to insert */
531 	pthread_t	rc_notify_thr;	/* single thread waiting for notify */
532 	pthread_cond_t	rc_cv;
533 	pthread_mutex_t	rc_lock;
534 
535 	/*
536 	 * Per-client audit information.  These fields must be protected by
537 	 * rc_annotate_lock separately from rc_lock because they may need
538 	 * to be accessed from rc_node.c with an entity or iterator lock
539 	 * held, and those must be taken after rc_lock.
540 	 */
541 	int		rc_annotate;	/* generate annotation event if set */
542 	const char	*rc_operation;	/* operation for audit annotation */
543 	const char	*rc_file;	/* file name for audit annotation */
544 	pthread_mutex_t	rc_annotate_lock;
545 } repcache_client_t;
546 
547 /* Bit definitions for rc_flags. */
548 #define	RC_CLIENT_DEAD			0x00000001
549 
550 typedef struct client_bucket {
551 	pthread_mutex_t	cb_lock;
552 	uu_list_t	*cb_list;
553 	char ch_pad[64 - sizeof (pthread_mutex_t) - sizeof (uu_list_t *)];
554 } client_bucket_t;
555 
556 enum rc_ptr_type {
557 	RC_PTR_TYPE_ENTITY = 1,
558 	RC_PTR_TYPE_ITER
559 };
560 
561 typedef struct request_log_ptr {
562 	enum rc_ptr_type	rlp_type;
563 	uint32_t		rlp_id;
564 	void			*rlp_ptr; /* repcache_{entity,iter}_t */
565 	void			*rlp_data;	/* rc_node, for ENTITY only */
566 } request_log_ptr_t;
567 
568 #define	MAX_PTRS	3
569 
570 /*
571  * rl_start through rl_client cannot move without changing start_log()
572  */
573 typedef struct request_log_entry {
574 	hrtime_t		rl_start;
575 	hrtime_t		rl_end;
576 	pthread_t		rl_tid;
577 	uint32_t		rl_clientid;
578 	repcache_client_t	*rl_client;
579 	enum rep_protocol_requestid rl_request;
580 	rep_protocol_responseid_t rl_response;
581 	int			rl_num_ptrs;
582 	request_log_ptr_t	rl_ptrs[MAX_PTRS];
583 } request_log_entry_t;
584 
585 /*
586  * thread information
587  */
588 typedef enum thread_state {
589 	TI_CREATED,
590 	TI_DOOR_RETURN,
591 	TI_SIGNAL_WAIT,
592 	TI_MAIN_DOOR_CALL,
593 	TI_CLIENT_CALL
594 } thread_state_t;
595 
596 typedef struct thread_info {
597 	pthread_t	ti_thread;
598 	uu_list_node_t	ti_node;		/* for list of all thread */
599 
600 	/*
601 	 * per-thread globals
602 	 */
603 	ucred_t		*ti_ucred;		/* for credential lookups */
604 	int		ti_ucred_read;		/* ucred holds current creds */
605 
606 	/*
607 	 * per-thread state information, for debuggers
608 	 */
609 	hrtime_t	ti_lastchange;
610 
611 	thread_state_t	ti_state;
612 	thread_state_t	ti_prev_state;
613 
614 	repcache_client_t *ti_active_client;
615 	request_log_entry_t	ti_log;
616 
617 	struct rep_protocol_request *ti_client_request;
618 	repository_door_request_t *ti_main_door_request;
619 
620 } thread_info_t;
621 
622 /*
623  * Backend layer
624  */
625 typedef struct backend_query backend_query_t;
626 typedef struct backend_tx backend_tx_t;
627 
628 /*
629  * configd.c
630  */
631 int create_connection(ucred_t *cred, repository_door_request_t *rp,
632     size_t rp_size, int *out_fd);
633 
634 thread_info_t *thread_self(void);
635 void thread_newstate(thread_info_t *, thread_state_t);
636 ucred_t *get_ucred(void);
637 int ucred_is_privileged(ucred_t *);
638 
639 adt_session_data_t *get_audit_session(void);
640 
641 void configd_critical(const char *, ...);
642 void configd_vcritical(const char *, va_list);
643 void configd_info(const char *, ...);
644 
645 extern int is_main_repository;
646 extern int max_repository_backups;
647 
648 /*
649  * maindoor.c
650  */
651 int setup_main_door(const char *);
652 
653 /*
654  * client.c
655  */
656 int client_annotation_needed(char *, size_t, char *, size_t);
657 void client_annotation_finished(void);
658 int create_client(pid_t, uint32_t, int, int *);
659 int client_init(void);
660 int client_is_privileged(void);
661 void log_enter(request_log_entry_t *);
662 
663 /*
664  * rc_node.c, backend/cache interfaces (rc_node_t)
665  */
666 int rc_node_init();
667 int rc_check_type_name(uint32_t, const char *);
668 
669 void rc_node_ptr_free_mem(rc_node_ptr_t *);
670 void rc_node_rele(rc_node_t *);
671 rc_node_t *rc_node_setup(rc_node_t *, rc_node_lookup_t *,
672     const char *, rc_node_t *);
673 rc_node_t *rc_node_setup_pg(rc_node_t *, rc_node_lookup_t *, const char *,
674     const char *, uint32_t, uint32_t, rc_node_t *);
675 rc_node_t *rc_node_setup_snapshot(rc_node_t *, rc_node_lookup_t *, const char *,
676     uint32_t, rc_node_t *);
677 rc_node_t *rc_node_setup_snaplevel(rc_node_t *, rc_node_lookup_t *,
678     rc_snaplevel_t *, rc_node_t *);
679 int rc_node_create_property(rc_node_t *, rc_node_lookup_t *,
680     const char *, rep_protocol_value_type_t, const char *, size_t, size_t);
681 
682 rc_node_t *rc_node_alloc(void);
683 void rc_node_destroy(rc_node_t *);
684 
685 /*
686  * rc_node.c, client interface (rc_node_ptr_t, rc_node_iter_t)
687  */
688 void rc_node_ptr_init(rc_node_ptr_t *);
689 int rc_local_scope(uint32_t, rc_node_ptr_t *);
690 
691 void rc_node_clear(rc_node_ptr_t *, int);
692 void rc_node_ptr_assign(rc_node_ptr_t *, const rc_node_ptr_t *);
693 int rc_node_name(rc_node_ptr_t *, char *, size_t, uint32_t, size_t *);
694 int rc_node_fmri(rc_node_ptr_t *, char *, size_t, size_t *);
695 int rc_node_parent_type(rc_node_ptr_t *, uint32_t *);
696 int rc_node_get_child(rc_node_ptr_t *, const char *, uint32_t, rc_node_ptr_t *);
697 int rc_node_get_parent(rc_node_ptr_t *, uint32_t, rc_node_ptr_t *);
698 int rc_node_get_property_type(rc_node_ptr_t *, rep_protocol_value_type_t *);
699 int rc_node_get_property_value(rc_node_ptr_t *,
700     struct rep_protocol_value_response *, size_t *);
701 int rc_node_create_child(rc_node_ptr_t *, uint32_t, const char *,
702     rc_node_ptr_t *);
703 int rc_node_create_child_pg(rc_node_ptr_t *, uint32_t, const char *,
704     const char *, uint32_t, rc_node_ptr_t *);
705 int rc_node_update(rc_node_ptr_t *);
706 int rc_node_delete(rc_node_ptr_t *);
707 int rc_node_next_snaplevel(rc_node_ptr_t *, rc_node_ptr_t *);
708 
709 int rc_node_setup_iter(rc_node_ptr_t *, rc_node_iter_t **, uint32_t,
710     size_t, const char *);
711 
712 int rc_iter_next(rc_node_iter_t *, rc_node_ptr_t *, uint32_t);
713 int rc_iter_next_value(rc_node_iter_t *, struct rep_protocol_value_response *,
714     size_t *, int);
715 void rc_iter_destroy(rc_node_iter_t **);
716 
717 int rc_node_setup_tx(rc_node_ptr_t *, rc_node_ptr_t *);
718 int rc_tx_commit(rc_node_ptr_t *, const void *, size_t);
719 
720 void rc_pg_notify_init(rc_node_pg_notify_t *);
721 int rc_pg_notify_setup(rc_node_pg_notify_t *, rc_node_ptr_t *, int);
722 void rc_pg_notify_fini(rc_node_pg_notify_t *);
723 
724 void rc_notify_info_init(rc_notify_info_t *);
725 int rc_notify_info_add_name(rc_notify_info_t *, const char *);
726 int rc_notify_info_add_type(rc_notify_info_t *, const char *);
727 int rc_notify_info_wait(rc_notify_info_t *, rc_node_ptr_t *, char *, size_t);
728 void rc_notify_info_fini(rc_notify_info_t *);
729 
730 int rc_snapshot_take_new(rc_node_ptr_t *, const char *,
731     const char *, const char *, rc_node_ptr_t *);
732 int rc_snapshot_take_attach(rc_node_ptr_t *, rc_node_ptr_t *);
733 int rc_snapshot_attach(rc_node_ptr_t *, rc_node_ptr_t *);
734 
735 /*
736  * file_object.c
737  */
738 int object_fill_children(rc_node_t *);
739 int object_create(rc_node_t *, uint32_t, const char *, rc_node_t **);
740 int object_create_pg(rc_node_t *, uint32_t, const char *, const char *,
741     uint32_t, rc_node_t **);
742 
743 int object_delete(rc_node_t *);
744 void object_free_values(const char *, uint32_t, size_t, size_t);
745 
746 int object_fill_snapshot(rc_snapshot_t *);
747 
748 int object_snapshot_take_new(rc_node_t *, const char *, const char *,
749     const char *, rc_node_t **);
750 int object_snapshot_attach(rc_node_lookup_t *, uint32_t *, int);
751 
752 /*
753  * object.c
754  */
755 int object_tx_commit(rc_node_lookup_t *, tx_commit_data_t *, uint32_t *);
756 
757 /* Functions to access transaction commands. */
758 int tx_cmd_action(tx_commit_data_t *, size_t,
759     enum rep_protocol_transaction_action *);
760 size_t tx_cmd_count(tx_commit_data_t *);
761 int tx_cmd_nvalues(tx_commit_data_t *, size_t, uint32_t *);
762 int tx_cmd_prop(tx_commit_data_t *, size_t, const char **);
763 int tx_cmd_prop_type(tx_commit_data_t *, size_t, uint32_t *);
764 int tx_cmd_value(tx_commit_data_t *, size_t, uint32_t, const char **);
765 void tx_commit_data_free(tx_commit_data_t *);
766 int tx_commit_data_new(const void *, size_t, tx_commit_data_t **);
767 
768 /*
769  * snapshot.c
770  */
771 int rc_snapshot_get(uint32_t, rc_snapshot_t **);
772 void rc_snapshot_rele(rc_snapshot_t *);
773 void rc_snaplevel_hold(rc_snaplevel_t *);
774 void rc_snaplevel_rele(rc_snaplevel_t *);
775 
776 /*
777  * backend.c
778  */
779 int backend_init(const char *, const char *, int);
780 boolean_t backend_is_upgraded(backend_tx_t *);
781 void backend_fini(void);
782 
783 rep_protocol_responseid_t backend_create_backup(const char *);
784 rep_protocol_responseid_t backend_switch(int);
785 
786 /*
787  * call on any database inconsistency -- cleans up state as best it can,
788  * and exits with a "Database Bad" error code.
789  */
790 void backend_panic(const char *, ...) __NORETURN;
791 #pragma rarely_called(backend_panic)
792 
793 backend_query_t *backend_query_alloc(void);
794 void backend_query_append(backend_query_t *, const char *);
795 void backend_query_add(backend_query_t *, const char *, ...);
796 void backend_query_free(backend_query_t *);
797 
798 typedef int backend_run_callback_f(void *data, int columns, char **vals,
799     char **names);
800 #define	BACKEND_CALLBACK_CONTINUE	0
801 #define	BACKEND_CALLBACK_ABORT		1
802 
803 backend_run_callback_f backend_fail_if_seen;	/* aborts TX if called */
804 
805 int backend_run(backend_type_t, backend_query_t *,
806     backend_run_callback_f *, void *);
807 
808 int backend_tx_begin(backend_type_t, backend_tx_t **);
809 int backend_tx_begin_ro(backend_type_t, backend_tx_t **);
810 void backend_tx_end_ro(backend_tx_t *);
811 
812 enum id_space {
813 	BACKEND_ID_SERVICE_INSTANCE,
814 	BACKEND_ID_PROPERTYGRP,
815 	BACKEND_ID_GENERATION,
816 	BACKEND_ID_PROPERTY,
817 	BACKEND_ID_VALUE,
818 	BACKEND_ID_SNAPNAME,
819 	BACKEND_ID_SNAPSHOT,
820 	BACKEND_ID_SNAPLEVEL,
821 	BACKEND_ID_INVALID	/* always illegal */
822 };
823 
824 uint32_t backend_new_id(backend_tx_t *, enum id_space);
825 int backend_tx_run_update(backend_tx_t *, const char *, ...);
826 int backend_tx_run_update_changed(backend_tx_t *, const char *, ...);
827 int backend_tx_run_single_int(backend_tx_t *tx, backend_query_t *q,
828     uint32_t *buf);
829 int backend_tx_run(backend_tx_t *, backend_query_t *,
830     backend_run_callback_f *, void *);
831 
832 int backend_tx_commit(backend_tx_t *);
833 void backend_tx_rollback(backend_tx_t *);
834 
835 #ifdef	__cplusplus
836 }
837 #endif
838 
839 #endif	/* _CONFIGD_H */
840