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