xref: /onnv-gate/usr/src/cmd/svc/configd/configd.h (revision 471:fb6202c3da23)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23407Sjwadams  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef	_CONFIGD_H
280Sstevel@tonic-gate #define	_CONFIGD_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <door.h>
330Sstevel@tonic-gate #include <pthread.h>
340Sstevel@tonic-gate #include <string.h>
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include <libscf.h>
380Sstevel@tonic-gate #include <repcache_protocol.h>
390Sstevel@tonic-gate #include <libuutil.h>
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include <configd_exit.h>
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #ifdef	__cplusplus
440Sstevel@tonic-gate extern "C" {
450Sstevel@tonic-gate #endif
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * Lock order:
490Sstevel@tonic-gate  *
500Sstevel@tonic-gate  *	client lock
510Sstevel@tonic-gate  *		iter locks, in ID order
520Sstevel@tonic-gate  *		entity locks, in ID order
530Sstevel@tonic-gate  *
540Sstevel@tonic-gate  *		(any iter/entity locks)
550Sstevel@tonic-gate  *			backend locks (NORMAL, then NONPERSIST)
560Sstevel@tonic-gate  *				rc_node lock
570Sstevel@tonic-gate  *					children's rc_node lock
580Sstevel@tonic-gate  *				cache bucket lock
590Sstevel@tonic-gate  *					rc_node lock[*]
600Sstevel@tonic-gate  *
610Sstevel@tonic-gate  *	* only one node may be grabbed while holding a bucket lock
620Sstevel@tonic-gate  *
630Sstevel@tonic-gate  *	leaf locks:  (no other locks may be aquired while holding one)
640Sstevel@tonic-gate  *		rc_pg_notify_lock
650Sstevel@tonic-gate  */
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /*
680Sstevel@tonic-gate  * Returns the minimum size for a structure of type 't' such
690Sstevel@tonic-gate  * that it is safe to access field 'f'.
700Sstevel@tonic-gate  */
710Sstevel@tonic-gate #define	offsetofend(t, f)	(offsetof(t, f) + sizeof (((t *)0)->f))
720Sstevel@tonic-gate 
730Sstevel@tonic-gate /*
740Sstevel@tonic-gate  * We want MUTEX_HELD, but we also want pthreads.  So we're stuck with this.
750Sstevel@tonic-gate  */
760Sstevel@tonic-gate struct _lwp_mutex_t;
770Sstevel@tonic-gate extern int _mutex_held(struct _lwp_mutex_t *);
780Sstevel@tonic-gate #define	MUTEX_HELD(m)		_mutex_held((struct _lwp_mutex_t *)(m))
790Sstevel@tonic-gate 
800Sstevel@tonic-gate /*
810Sstevel@tonic-gate  * Maximum levels of composition.
820Sstevel@tonic-gate  */
830Sstevel@tonic-gate #define	COMPOSITION_DEPTH	2
840Sstevel@tonic-gate 
850Sstevel@tonic-gate /*
860Sstevel@tonic-gate  * The default locations of the repository dbs
870Sstevel@tonic-gate  */
880Sstevel@tonic-gate #define	REPOSITORY_DB	"/etc/svc/repository.db"
890Sstevel@tonic-gate #define	NONPERSIST_DB	"/etc/svc/volatile/svc_nonpersist.db"
900Sstevel@tonic-gate 
910Sstevel@tonic-gate #define	CONFIGD_CORE	"core.%f.%t.%p"
920Sstevel@tonic-gate 
930Sstevel@tonic-gate #ifndef NDEBUG
940Sstevel@tonic-gate #define	bad_error(f, e)							\
950Sstevel@tonic-gate 	uu_warn("%s:%d: %s() returned bad error %d.  Aborting.\n",	\
960Sstevel@tonic-gate 	    __FILE__, __LINE__, f, e);					\
970Sstevel@tonic-gate 	abort()
980Sstevel@tonic-gate #else
990Sstevel@tonic-gate #define	bad_error(f, e)		abort()
1000Sstevel@tonic-gate #endif
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate typedef enum backend_type {
1030Sstevel@tonic-gate 	BACKEND_TYPE_NORMAL		= 0,
1040Sstevel@tonic-gate 	BACKEND_TYPE_NONPERSIST,
1050Sstevel@tonic-gate 	BACKEND_TYPE_TOTAL			/* backend use only */
1060Sstevel@tonic-gate } backend_type_t;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate  * pre-declare rc_* types
1100Sstevel@tonic-gate  */
1110Sstevel@tonic-gate typedef struct rc_node rc_node_t;
1120Sstevel@tonic-gate typedef struct rc_snapshot rc_snapshot_t;
1130Sstevel@tonic-gate typedef struct rc_snaplevel rc_snaplevel_t;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate  * notification layer -- protected by rc_pg_notify_lock
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate typedef struct rc_notify_info rc_notify_info_t;
1190Sstevel@tonic-gate typedef struct rc_notify_delete rc_notify_delete_t;
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate #define	RC_NOTIFY_MAX_NAMES	4	/* enough for now */
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate typedef struct rc_notify {
1240Sstevel@tonic-gate 	uu_list_node_t	rcn_list_node;
1250Sstevel@tonic-gate 	rc_node_t	*rcn_node;
1260Sstevel@tonic-gate 	rc_notify_info_t *rcn_info;
1270Sstevel@tonic-gate 	rc_notify_delete_t *rcn_delete;
1280Sstevel@tonic-gate } rc_notify_t;
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate struct rc_notify_delete {
1310Sstevel@tonic-gate 	rc_notify_t rnd_notify;
1320Sstevel@tonic-gate 	char rnd_fmri[REP_PROTOCOL_FMRI_LEN];
1330Sstevel@tonic-gate };
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate struct rc_notify_info {
1360Sstevel@tonic-gate 	uu_list_node_t	rni_list_node;
1370Sstevel@tonic-gate 	rc_notify_t	rni_notify;
1380Sstevel@tonic-gate 	const char	*rni_namelist[RC_NOTIFY_MAX_NAMES];
1390Sstevel@tonic-gate 	const char	*rni_typelist[RC_NOTIFY_MAX_NAMES];
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	int		rni_flags;
1420Sstevel@tonic-gate 	int		rni_waiters;
1430Sstevel@tonic-gate 	pthread_cond_t	rni_cv;
1440Sstevel@tonic-gate };
1450Sstevel@tonic-gate #define	RC_NOTIFY_ACTIVE	0x00000001
1460Sstevel@tonic-gate #define	RC_NOTIFY_DRAIN		0x00000002
1470Sstevel@tonic-gate #define	RC_NOTIFY_EMPTYING	0x00000004
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate typedef struct rc_node_pg_notify {
1500Sstevel@tonic-gate 	uu_list_node_t	rnpn_node;
1510Sstevel@tonic-gate 	int		rnpn_fd;
1520Sstevel@tonic-gate 	rc_node_t	*rnpn_pg;
1530Sstevel@tonic-gate } rc_node_pg_notify_t;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate /*
1560Sstevel@tonic-gate  * cache layer
1570Sstevel@tonic-gate  */
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate /*
1600Sstevel@tonic-gate  * The 'key' for the main object hash.  main_id is the main object
1610Sstevel@tonic-gate  * identifier.  The rl_ids array contains:
1620Sstevel@tonic-gate  *
1630Sstevel@tonic-gate  *	TYPE		RL_IDS
1640Sstevel@tonic-gate  *	scope		unused
1650Sstevel@tonic-gate  *	service		unused
1660Sstevel@tonic-gate  *	instance	{service_id}
1670Sstevel@tonic-gate  *	snapshot	{service_id, instance_id}
1680Sstevel@tonic-gate  *	snaplevel	{service_id, instance_id, name_id, snapshot_id}
1690Sstevel@tonic-gate  *	propertygroup	{service_id, (instance_id or 0), (name_id or 0),
1700Sstevel@tonic-gate  *			    (snapshot_id or 0), (l_id or 0)}
1710Sstevel@tonic-gate  *	property	{service_id, (instance_id or 0), (name_id or 0),
1720Sstevel@tonic-gate  *			    (snapshot_id or 0), (l_id or 0), pg_id, gen_id}
1730Sstevel@tonic-gate  */
1740Sstevel@tonic-gate #define	ID_SERVICE	0
1750Sstevel@tonic-gate #define	ID_INSTANCE	1
1760Sstevel@tonic-gate #define	ID_NAME		2
1770Sstevel@tonic-gate #define	ID_SNAPSHOT	3
1780Sstevel@tonic-gate #define	ID_LEVEL	4
1790Sstevel@tonic-gate #define	ID_PG		5
1800Sstevel@tonic-gate #define	ID_GEN		6
1810Sstevel@tonic-gate #define	MAX_IDS	7
1820Sstevel@tonic-gate typedef struct rc_node_lookup {
1830Sstevel@tonic-gate 	uint16_t	rl_type;		/* REP_PROTOCOL_ENTITY_* */
1840Sstevel@tonic-gate 	uint16_t	rl_backend;		/* BACKEND_TYPE_* */
1850Sstevel@tonic-gate 	uint32_t	rl_main_id;		/* primary identifier */
1860Sstevel@tonic-gate 	uint32_t	rl_ids[MAX_IDS];	/* context */
1870Sstevel@tonic-gate } rc_node_lookup_t;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate struct rc_node {
1900Sstevel@tonic-gate 	/*
1910Sstevel@tonic-gate 	 * read-only data
1920Sstevel@tonic-gate 	 */
1930Sstevel@tonic-gate 	rc_node_lookup_t rn_id;			/* must be first */
1940Sstevel@tonic-gate 	uint32_t	rn_hash;
1950Sstevel@tonic-gate 	const char	*rn_name;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	/*
1980Sstevel@tonic-gate 	 * type-specific state
1990Sstevel@tonic-gate 	 * (if space becomes an issue, these can become a union)
2000Sstevel@tonic-gate 	 */
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	/*
2030Sstevel@tonic-gate 	 * Used by instances, snapshots, and "composed property groups" only.
2040Sstevel@tonic-gate 	 * These are the entities whose properties should appear composed when
2050Sstevel@tonic-gate 	 * this entity is traversed by a composed iterator.  0 is the top-most
2060Sstevel@tonic-gate 	 * entity, down to COMPOSITION_DEPTH - 1.
2070Sstevel@tonic-gate 	 */
2080Sstevel@tonic-gate 	rc_node_t	*rn_cchain[COMPOSITION_DEPTH];
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	/*
2110Sstevel@tonic-gate 	 * used by property groups only
2120Sstevel@tonic-gate 	 */
2130Sstevel@tonic-gate 	const char	*rn_type;
2140Sstevel@tonic-gate 	uint32_t	rn_pgflags;
2150Sstevel@tonic-gate 	uint32_t	rn_gen_id;
2160Sstevel@tonic-gate 	uu_list_t	*rn_pg_notify_list;	/* prot by rc_pg_notify_lock */
2170Sstevel@tonic-gate 	rc_notify_t	rn_notify;		/* prot by rc_pg_notify_lock */
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	/*
2200Sstevel@tonic-gate 	 * used by properties only
2210Sstevel@tonic-gate 	 */
2220Sstevel@tonic-gate 	rep_protocol_value_type_t rn_valtype;
2230Sstevel@tonic-gate 	const char	*rn_values;		/* protected by rn_lock */
2240Sstevel@tonic-gate 	size_t		rn_values_count;	/* protected by rn_lock */
2250Sstevel@tonic-gate 	size_t		rn_values_size;		/* protected by rn_lock */
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	/*
2280Sstevel@tonic-gate 	 * used by snapshots only
2290Sstevel@tonic-gate 	 */
2300Sstevel@tonic-gate 	uint32_t	rn_snapshot_id;
2310Sstevel@tonic-gate 	rc_snapshot_t	*rn_snapshot;		/* protected by rn_lock */
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 	/*
2340Sstevel@tonic-gate 	 * used by snaplevels only
2350Sstevel@tonic-gate 	 */
2360Sstevel@tonic-gate 	rc_snaplevel_t	*rn_snaplevel;
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate 	/*
2390Sstevel@tonic-gate 	 * mutable state
2400Sstevel@tonic-gate 	 */
2410Sstevel@tonic-gate 	pthread_mutex_t	rn_lock;
2420Sstevel@tonic-gate 	pthread_cond_t	rn_cv;
2430Sstevel@tonic-gate 	uint32_t	rn_flags;
2440Sstevel@tonic-gate 	uint32_t	rn_refs;		/* reference count */
2450Sstevel@tonic-gate 	uint32_t	rn_other_refs;		/* atomic refcount */
2460Sstevel@tonic-gate 	uint32_t	rn_other_refs_held;	/* for 1->0 transitions */
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 	uu_list_t	*rn_children;
2490Sstevel@tonic-gate 	uu_list_node_t	rn_sibling_node;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	rc_node_t	*rn_parent;		/* set if on child list */
2520Sstevel@tonic-gate 	rc_node_t	*rn_former;		/* next former node */
2530Sstevel@tonic-gate 	rc_node_t	*rn_parent_ref;		/* reference count target */
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	/*
2560Sstevel@tonic-gate 	 * external state (protected by hash chain lock)
2570Sstevel@tonic-gate 	 */
2580Sstevel@tonic-gate 	rc_node_t	*rn_hash_next;
2590Sstevel@tonic-gate };
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate /*
2620Sstevel@tonic-gate  * flag ordering:
2630Sstevel@tonic-gate  *	RC_DYING
2640Sstevel@tonic-gate  *		RC_NODE_CHILDREN_CHANGING
2650Sstevel@tonic-gate  *		RC_NODE_CREATING_CHILD
2660Sstevel@tonic-gate  *		RC_NODE_USING_PARENT
2670Sstevel@tonic-gate  *			RC_NODE_IN_TX
2680Sstevel@tonic-gate  *
2690Sstevel@tonic-gate  * RC_NODE_USING_PARENT is special, because it lets you proceed up the tree,
2700Sstevel@tonic-gate  * in the reverse of the usual locking order.  Because of this, there are
2710Sstevel@tonic-gate  * limitations on what you can do while holding it.  While holding
2720Sstevel@tonic-gate  * RC_NODE_USING_PARENT, you may:
2730Sstevel@tonic-gate  *	bump or release your parent's reference count
2740Sstevel@tonic-gate  *	access fields in your parent
2750Sstevel@tonic-gate  *	hold RC_NODE_USING_PARENT in the parent, proceeding recursively.
2760Sstevel@tonic-gate  *
2770Sstevel@tonic-gate  * If you are only holding *one* node's RC_NODE_USING_PARENT, and:
2780Sstevel@tonic-gate  *	you are *not* proceeding recursively, you can hold your
2790Sstevel@tonic-gate  *	    immediate parent's RC_NODE_CHILDREN_CHANGING flag.
2800Sstevel@tonic-gate  *	you hold your parent's RC_NODE_CHILDREN_CHANGING flag, you can add
2810Sstevel@tonic-gate  *	    RC_NODE_IN_TX to your flags.
2820Sstevel@tonic-gate  *	you want to grab a flag in your parent, you must lock your parent,
2830Sstevel@tonic-gate  *	    lock yourself, drop RC_NODE_USING_PARENT, unlock yourself,
2840Sstevel@tonic-gate  *	    then proceed to manipulate the parent.
2850Sstevel@tonic-gate  */
2860Sstevel@tonic-gate #define	RC_NODE_CHILDREN_CHANGING	0x00000001 /* child list in flux */
2870Sstevel@tonic-gate #define	RC_NODE_HAS_CHILDREN		0x00000002 /* child list is accurate */
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate #define	RC_NODE_IN_PARENT		0x00000004 /* I'm in my parent's list */
2900Sstevel@tonic-gate #define	RC_NODE_USING_PARENT		0x00000008 /* parent ptr in use */
2910Sstevel@tonic-gate #define	RC_NODE_CREATING_CHILD		0x00000010 /* a create is in progress */
2920Sstevel@tonic-gate #define	RC_NODE_IN_TX			0x00000020 /* a tx is in progess */
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate #define	RC_NODE_OLD			0x00000400 /* out-of-date object */
2950Sstevel@tonic-gate #define	RC_NODE_ON_FORMER		0x00000800 /* on an rn_former list */
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate #define	RC_NODE_PARENT_REF		0x00001000 /* parent_ref in use */
2980Sstevel@tonic-gate #define	RC_NODE_UNREFED			0x00002000 /* unref processing active */
2990Sstevel@tonic-gate #define	RC_NODE_DYING			0x00004000 /* node is being deleted */
3000Sstevel@tonic-gate #define	RC_NODE_DEAD			0x00008000 /* node has been deleted */
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate #define	RC_NODE_DYING_FLAGS						\
3030Sstevel@tonic-gate 	(RC_NODE_CHILDREN_CHANGING | RC_NODE_IN_TX | RC_NODE_DYING |	\
3040Sstevel@tonic-gate 	    RC_NODE_CREATING_CHILD)
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate #define	RC_NODE_WAITING_FLAGS						\
3070Sstevel@tonic-gate 	(RC_NODE_DYING_FLAGS | RC_NODE_USING_PARENT)
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate typedef struct rc_node_ptr {
3110Sstevel@tonic-gate 	rc_node_t	*rnp_node;
3120Sstevel@tonic-gate 	char		rnp_authorized;		/* transaction pre-authed */
3130Sstevel@tonic-gate 	char		rnp_deleted;		/* object was deleted */
3140Sstevel@tonic-gate } rc_node_ptr_t;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate #define	NODE_PTR_NOT_HELD(npp) \
3170Sstevel@tonic-gate 	    ((npp)->rnp_node == NULL || !MUTEX_HELD(&(npp)->rnp_node->rn_lock))
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate typedef int rc_iter_filter_func(rc_node_t *, void *);
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate typedef struct rc_node_iter {
3220Sstevel@tonic-gate 	rc_node_t	*rni_parent;
3230Sstevel@tonic-gate 	int		rni_clevel;	/* index into rni_parent->rn_cchain[] */
3240Sstevel@tonic-gate 	rc_node_t	*rni_iter_node;
3250Sstevel@tonic-gate 	uu_list_walk_t	*rni_iter;
3260Sstevel@tonic-gate 	uint32_t	rni_type;
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 	/*
3290Sstevel@tonic-gate 	 * for normal walks
3300Sstevel@tonic-gate 	 */
3310Sstevel@tonic-gate 	rc_iter_filter_func *rni_filter;
3320Sstevel@tonic-gate 	void		*rni_filter_arg;
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 	/*
3350Sstevel@tonic-gate 	 * for value walks
3360Sstevel@tonic-gate 	 */
3370Sstevel@tonic-gate 	uint32_t	rni_offset;		/* next value offset */
3380Sstevel@tonic-gate 	uint32_t	rni_last_offset;	/* previous value offset */
3390Sstevel@tonic-gate } rc_node_iter_t;
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate typedef struct rc_node_tx {
3420Sstevel@tonic-gate 	rc_node_ptr_t	rnt_ptr;
3430Sstevel@tonic-gate 	int		rnt_authorized;		/* No need to check anymore. */
3440Sstevel@tonic-gate } rc_node_tx_t;
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate typedef struct cache_bucket {
3480Sstevel@tonic-gate 	pthread_mutex_t	cb_lock;
3490Sstevel@tonic-gate 	rc_node_t	*cb_head;
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 	char		cb_pad[64 - sizeof (pthread_mutex_t) -
3520Sstevel@tonic-gate 			    2 * sizeof (rc_node_t *)];
3530Sstevel@tonic-gate } cache_bucket_t;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate /*
3560Sstevel@tonic-gate  * Snapshots
3570Sstevel@tonic-gate  */
3580Sstevel@tonic-gate struct rc_snapshot {
3590Sstevel@tonic-gate 	uint32_t	rs_snap_id;
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	pthread_mutex_t	rs_lock;
3620Sstevel@tonic-gate 	pthread_cond_t	rs_cv;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	uint32_t	rs_flags;
3650Sstevel@tonic-gate 	uint32_t	rs_refcnt;	/* references from rc_nodes */
3660Sstevel@tonic-gate 	uint32_t	rs_childref;	/* references to children */
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	rc_snaplevel_t	*rs_levels;	/* list of levels */
3690Sstevel@tonic-gate 	rc_snapshot_t	*rs_hash_next;
3700Sstevel@tonic-gate };
3710Sstevel@tonic-gate #define	RC_SNAPSHOT_FILLING	0x00000001	/* rs_levels changing */
3720Sstevel@tonic-gate #define	RC_SNAPSHOT_READY	0x00000002
3730Sstevel@tonic-gate #define	RC_SNAPSHOT_DEAD	0x00000004	/* no resources */
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate typedef struct rc_snaplevel_pgs {
3760Sstevel@tonic-gate 	uint32_t	rsp_pg_id;
3770Sstevel@tonic-gate 	uint32_t	rsp_gen_id;
3780Sstevel@tonic-gate } rc_snaplevel_pgs_t;
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate struct rc_snaplevel {
3810Sstevel@tonic-gate 	rc_snapshot_t	*rsl_parent;
3820Sstevel@tonic-gate 	uint32_t	rsl_level_num;
3830Sstevel@tonic-gate 	uint32_t	rsl_level_id;
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 	uint32_t	rsl_service_id;
3860Sstevel@tonic-gate 	uint32_t	rsl_instance_id;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	const char	*rsl_scope;
3890Sstevel@tonic-gate 	const char	*rsl_service;
3900Sstevel@tonic-gate 	const char	*rsl_instance;
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	rc_snaplevel_t	*rsl_next;
3930Sstevel@tonic-gate };
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate /*
3960Sstevel@tonic-gate  * Client layer -- the IDs fields must be first, in order for the search
3970Sstevel@tonic-gate  * routines to work correctly.
3980Sstevel@tonic-gate  */
3990Sstevel@tonic-gate enum repcache_txstate {
4000Sstevel@tonic-gate 	REPCACHE_TX_INIT,
4010Sstevel@tonic-gate 	REPCACHE_TX_SETUP,
4020Sstevel@tonic-gate 	REPCACHE_TX_COMMITTED
4030Sstevel@tonic-gate };
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate typedef struct repcache_entity {
4060Sstevel@tonic-gate 	uint32_t	re_id;
407407Sjwadams 	uu_avl_node_t	re_link;
4080Sstevel@tonic-gate 	uint32_t	re_changeid;
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	pthread_mutex_t	re_lock;
4110Sstevel@tonic-gate 	uint32_t	re_type;
4120Sstevel@tonic-gate 	rc_node_ptr_t	re_node;
4130Sstevel@tonic-gate 	enum repcache_txstate re_txstate;	/* property groups only */
4140Sstevel@tonic-gate } repcache_entity_t;
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate typedef struct repcache_iter {
4170Sstevel@tonic-gate 	uint32_t	ri_id;
418407Sjwadams 	uu_avl_node_t	ri_link;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	uint32_t	ri_type;	/* result type */
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	pthread_mutex_t	ri_lock;
4230Sstevel@tonic-gate 	uint32_t	ri_sequence;
4240Sstevel@tonic-gate 	rc_node_iter_t	*ri_iter;
4250Sstevel@tonic-gate } repcache_iter_t;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate typedef struct repcache_client {
4280Sstevel@tonic-gate 	/*
4290Sstevel@tonic-gate 	 * constants
4300Sstevel@tonic-gate 	 */
4310Sstevel@tonic-gate 	uint32_t	rc_id;		/* must be first */
4320Sstevel@tonic-gate 	int		rc_all_auths;	/* bypass auth checks */
4330Sstevel@tonic-gate 	uint32_t	rc_debug;	/* debug flags */
4340Sstevel@tonic-gate 	pid_t		rc_pid;		/* pid of opening process */
4350Sstevel@tonic-gate 	door_id_t	rc_doorid;	/* a globally unique identifier */
4360Sstevel@tonic-gate 	int		rc_doorfd;	/* our door's FD */
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	/*
4390Sstevel@tonic-gate 	 * client list linkage, protected by hash chain lock
4400Sstevel@tonic-gate 	 */
4410Sstevel@tonic-gate 	uu_list_node_t	rc_link;
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	/*
4440Sstevel@tonic-gate 	 * notification information, protected by rc_node layer
4450Sstevel@tonic-gate 	 */
4460Sstevel@tonic-gate 	rc_node_pg_notify_t	rc_pg_notify;
4470Sstevel@tonic-gate 	rc_notify_info_t	rc_notify_info;
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	/*
4500Sstevel@tonic-gate 	 * client_wait output, only usable by rc_notify_thr
4510Sstevel@tonic-gate 	 */
4520Sstevel@tonic-gate 	rc_node_ptr_t	rc_notify_ptr;
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	/*
455407Sjwadams 	 * register sets, protected by rc_lock
4560Sstevel@tonic-gate 	 */
457407Sjwadams 	uu_avl_t	*rc_entities;
458407Sjwadams 	uu_avl_t	*rc_iters;
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate 	/*
4610Sstevel@tonic-gate 	 * Variables, protected by rc_lock
4620Sstevel@tonic-gate 	 */
4630Sstevel@tonic-gate 	int		rc_refcnt;	/* in-progress door calls */
4640Sstevel@tonic-gate 	int		rc_flags;	/* state */
4650Sstevel@tonic-gate 	uint32_t	rc_changeid;	/* used to make backups idempotent */
4660Sstevel@tonic-gate 	pthread_t	rc_insert_thr;	/* single thread trying to insert */
4670Sstevel@tonic-gate 	pthread_t	rc_notify_thr;	/* single thread waiting for notify */
4680Sstevel@tonic-gate 	pthread_cond_t	rc_cv;
4690Sstevel@tonic-gate 	pthread_mutex_t	rc_lock;
4700Sstevel@tonic-gate } repcache_client_t;
4710Sstevel@tonic-gate #define	RC_CLIENT_DEAD			0x00000001
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate typedef struct client_bucket {
4740Sstevel@tonic-gate 	pthread_mutex_t	cb_lock;
4750Sstevel@tonic-gate 	uu_list_t	*cb_list;
4760Sstevel@tonic-gate 	char ch_pad[64 - sizeof (pthread_mutex_t) - sizeof (uu_list_t *)];
4770Sstevel@tonic-gate } client_bucket_t;
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate enum rc_ptr_type {
4800Sstevel@tonic-gate 	RC_PTR_TYPE_ENTITY = 1,
4810Sstevel@tonic-gate 	RC_PTR_TYPE_ITER
4820Sstevel@tonic-gate };
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate typedef struct request_log_ptr {
4850Sstevel@tonic-gate 	enum rc_ptr_type	rlp_type;
4860Sstevel@tonic-gate 	uint32_t		rlp_id;
4870Sstevel@tonic-gate 	void			*rlp_ptr; /* repcache_{entity,iter}_t */
4880Sstevel@tonic-gate 	void			*rlp_data;	/* rc_node, for ENTITY only */
4890Sstevel@tonic-gate } request_log_ptr_t;
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate #define	MAX_PTRS	3
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate /*
4940Sstevel@tonic-gate  * rl_start through rl_client cannot move without changing start_log()
4950Sstevel@tonic-gate  */
4960Sstevel@tonic-gate typedef struct request_log_entry {
4970Sstevel@tonic-gate 	hrtime_t		rl_start;
4980Sstevel@tonic-gate 	hrtime_t		rl_end;
4990Sstevel@tonic-gate 	pthread_t		rl_tid;
5000Sstevel@tonic-gate 	uint32_t		rl_clientid;
5010Sstevel@tonic-gate 	repcache_client_t	*rl_client;
5020Sstevel@tonic-gate 	enum rep_protocol_requestid rl_request;
5030Sstevel@tonic-gate 	rep_protocol_responseid_t rl_response;
5040Sstevel@tonic-gate 	int			rl_num_ptrs;
5050Sstevel@tonic-gate 	request_log_ptr_t	rl_ptrs[MAX_PTRS];
5060Sstevel@tonic-gate } request_log_entry_t;
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate /*
5090Sstevel@tonic-gate  * thread information
5100Sstevel@tonic-gate  */
5110Sstevel@tonic-gate typedef enum thread_state {
5120Sstevel@tonic-gate 	TI_CREATED,
5130Sstevel@tonic-gate 	TI_DOOR_RETURN,
5140Sstevel@tonic-gate 	TI_SIGNAL_WAIT,
5150Sstevel@tonic-gate 	TI_MAIN_DOOR_CALL,
5160Sstevel@tonic-gate 	TI_CLIENT_CALL
5170Sstevel@tonic-gate } thread_state_t;
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate typedef struct thread_info {
5200Sstevel@tonic-gate 	pthread_t	ti_thread;
5210Sstevel@tonic-gate 	uu_list_node_t	ti_node;		/* for list of all thread */
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 	/*
5240Sstevel@tonic-gate 	 * per-thread globals
5250Sstevel@tonic-gate 	 */
5260Sstevel@tonic-gate 	ucred_t		*ti_ucred;		/* for credential lookups */
5270Sstevel@tonic-gate 	int		ti_ucred_read;		/* ucred holds current creds */
5280Sstevel@tonic-gate 
5290Sstevel@tonic-gate 	/*
5300Sstevel@tonic-gate 	 * per-thread state information, for debuggers
5310Sstevel@tonic-gate 	 */
5320Sstevel@tonic-gate 	hrtime_t	ti_lastchange;
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 	thread_state_t	ti_state;
5350Sstevel@tonic-gate 	thread_state_t	ti_prev_state;
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	repcache_client_t *ti_active_client;
5380Sstevel@tonic-gate 	request_log_entry_t	ti_log;
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate 	struct rep_protocol_request *ti_client_request;
5410Sstevel@tonic-gate 	repository_door_request_t *ti_main_door_request;
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate } thread_info_t;
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate /*
5460Sstevel@tonic-gate  * Backend layer
5470Sstevel@tonic-gate  */
5480Sstevel@tonic-gate typedef struct backend_query backend_query_t;
5490Sstevel@tonic-gate typedef struct backend_tx backend_tx_t;
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate /*
5520Sstevel@tonic-gate  * configd.c
5530Sstevel@tonic-gate  */
5540Sstevel@tonic-gate int create_connection(ucred_t *cred, repository_door_request_t *rp,
5550Sstevel@tonic-gate     size_t rp_size, int *out_fd);
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate thread_info_t *thread_self(void);
5580Sstevel@tonic-gate void thread_newstate(thread_info_t *, thread_state_t);
5590Sstevel@tonic-gate ucred_t *get_ucred(void);
5600Sstevel@tonic-gate int ucred_is_privileged(ucred_t *);
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate void configd_critical(const char *, ...);
5630Sstevel@tonic-gate void configd_vcritical(const char *, va_list);
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate extern int is_main_repository;
5660Sstevel@tonic-gate extern int max_repository_backups;
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate /*
5690Sstevel@tonic-gate  * maindoor.c
5700Sstevel@tonic-gate  */
5710Sstevel@tonic-gate int setup_main_door(const char *);
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate /*
5740Sstevel@tonic-gate  * client.c
5750Sstevel@tonic-gate  */
5760Sstevel@tonic-gate int create_client(pid_t, uint32_t, int, int *);
5770Sstevel@tonic-gate int client_init(void);
5780Sstevel@tonic-gate int client_is_privileged(void);
5790Sstevel@tonic-gate void log_enter(request_log_entry_t *);
5800Sstevel@tonic-gate 
5810Sstevel@tonic-gate /*
5820Sstevel@tonic-gate  * rc_node.c, backend/cache interfaces (rc_node_t)
5830Sstevel@tonic-gate  */
5840Sstevel@tonic-gate int rc_node_init();
5850Sstevel@tonic-gate int rc_check_type_name(uint32_t, const char *);
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate void rc_node_rele(rc_node_t *);
5880Sstevel@tonic-gate rc_node_t *rc_node_setup(rc_node_t *, rc_node_lookup_t *,
5890Sstevel@tonic-gate     const char *, rc_node_t *);
5900Sstevel@tonic-gate rc_node_t *rc_node_setup_pg(rc_node_t *, rc_node_lookup_t *, const char *,
5910Sstevel@tonic-gate     const char *, uint32_t, uint32_t, rc_node_t *);
5920Sstevel@tonic-gate rc_node_t *rc_node_setup_snapshot(rc_node_t *, rc_node_lookup_t *, const char *,
5930Sstevel@tonic-gate     uint32_t, rc_node_t *);
5940Sstevel@tonic-gate rc_node_t *rc_node_setup_snaplevel(rc_node_t *, rc_node_lookup_t *,
5950Sstevel@tonic-gate     rc_snaplevel_t *, rc_node_t *);
5960Sstevel@tonic-gate int rc_node_create_property(rc_node_t *, rc_node_lookup_t *,
5970Sstevel@tonic-gate     const char *, rep_protocol_value_type_t, const char *, size_t, size_t);
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate rc_node_t *rc_node_alloc(void);
6000Sstevel@tonic-gate void rc_node_destroy(rc_node_t *);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate /*
6030Sstevel@tonic-gate  * rc_node.c, client interface (rc_node_ptr_t, rc_node_iter_t)
6040Sstevel@tonic-gate  */
6050Sstevel@tonic-gate void rc_node_ptr_init(rc_node_ptr_t *);
6060Sstevel@tonic-gate int rc_local_scope(uint32_t, rc_node_ptr_t *);
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate void rc_node_clear(rc_node_ptr_t *, int);
6090Sstevel@tonic-gate void rc_node_ptr_assign(rc_node_ptr_t *, const rc_node_ptr_t *);
6100Sstevel@tonic-gate int rc_node_name(rc_node_ptr_t *, char *, size_t, uint32_t, size_t *);
6110Sstevel@tonic-gate int rc_node_fmri(rc_node_ptr_t *, char *, size_t, size_t *);
6120Sstevel@tonic-gate int rc_node_parent_type(rc_node_ptr_t *, uint32_t *);
6130Sstevel@tonic-gate int rc_node_get_child(rc_node_ptr_t *, const char *, uint32_t, rc_node_ptr_t *);
6140Sstevel@tonic-gate int rc_node_get_parent(rc_node_ptr_t *, uint32_t, rc_node_ptr_t *);
6150Sstevel@tonic-gate int rc_node_get_property_type(rc_node_ptr_t *, rep_protocol_value_type_t *);
6160Sstevel@tonic-gate int rc_node_get_property_value(rc_node_ptr_t *,
6170Sstevel@tonic-gate     struct rep_protocol_value_response *, size_t *);
6180Sstevel@tonic-gate int rc_node_create_child(rc_node_ptr_t *, uint32_t, const char *,
6190Sstevel@tonic-gate     rc_node_ptr_t *);
6200Sstevel@tonic-gate int rc_node_create_child_pg(rc_node_ptr_t *, uint32_t, const char *,
6210Sstevel@tonic-gate     const char *, uint32_t, rc_node_ptr_t *);
6220Sstevel@tonic-gate int rc_node_update(rc_node_ptr_t *);
6230Sstevel@tonic-gate int rc_node_delete(rc_node_ptr_t *);
6240Sstevel@tonic-gate int rc_node_next_snaplevel(rc_node_ptr_t *, rc_node_ptr_t *);
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate int rc_node_setup_iter(rc_node_ptr_t *, rc_node_iter_t **, uint32_t,
6270Sstevel@tonic-gate     size_t, const char *);
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate int rc_iter_next(rc_node_iter_t *, rc_node_ptr_t *, uint32_t);
6300Sstevel@tonic-gate int rc_iter_next_value(rc_node_iter_t *, struct rep_protocol_value_response *,
6310Sstevel@tonic-gate     size_t *, int);
6320Sstevel@tonic-gate void rc_iter_destroy(rc_node_iter_t **);
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate int rc_node_setup_tx(rc_node_ptr_t *, rc_node_ptr_t *);
6350Sstevel@tonic-gate int rc_tx_commit(rc_node_ptr_t *, const void *, size_t);
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate void rc_pg_notify_init(rc_node_pg_notify_t *);
6380Sstevel@tonic-gate int rc_pg_notify_setup(rc_node_pg_notify_t *, rc_node_ptr_t *, int);
6390Sstevel@tonic-gate void rc_pg_notify_fini(rc_node_pg_notify_t *);
6400Sstevel@tonic-gate 
6410Sstevel@tonic-gate void rc_notify_info_init(rc_notify_info_t *);
6420Sstevel@tonic-gate int rc_notify_info_add_name(rc_notify_info_t *, const char *);
6430Sstevel@tonic-gate int rc_notify_info_add_type(rc_notify_info_t *, const char *);
6440Sstevel@tonic-gate int rc_notify_info_wait(rc_notify_info_t *, rc_node_ptr_t *, char *, size_t);
6450Sstevel@tonic-gate void rc_notify_info_fini(rc_notify_info_t *);
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate int rc_snapshot_take_new(rc_node_ptr_t *, const char *,
6480Sstevel@tonic-gate     const char *, const char *, rc_node_ptr_t *);
6490Sstevel@tonic-gate int rc_snapshot_take_attach(rc_node_ptr_t *, rc_node_ptr_t *);
6500Sstevel@tonic-gate int rc_snapshot_attach(rc_node_ptr_t *, rc_node_ptr_t *);
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate /*
6530Sstevel@tonic-gate  * file_object.c
6540Sstevel@tonic-gate  */
6550Sstevel@tonic-gate int object_fill_children(rc_node_t *);
6560Sstevel@tonic-gate int object_create(rc_node_t *, uint32_t, const char *, rc_node_t **);
6570Sstevel@tonic-gate int object_create_pg(rc_node_t *, uint32_t, const char *, const char *,
6580Sstevel@tonic-gate     uint32_t, rc_node_t **);
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate int object_delete(rc_node_t *);
6610Sstevel@tonic-gate void object_free_values(const char *, uint32_t, size_t, size_t);
6620Sstevel@tonic-gate 
663407Sjwadams int object_fill_snapshot(rc_snapshot_t *);
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate int object_snapshot_take_new(rc_node_t *, const char *, const char *,
6660Sstevel@tonic-gate     const char *, rc_node_t **);
6670Sstevel@tonic-gate int object_snapshot_attach(rc_node_lookup_t *, uint32_t *, int);
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate /*
6700Sstevel@tonic-gate  * object.c
6710Sstevel@tonic-gate  */
6720Sstevel@tonic-gate int object_tx_commit(rc_node_lookup_t *, const void *, size_t, uint32_t *);
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate /*
6750Sstevel@tonic-gate  * snapshot.c
6760Sstevel@tonic-gate  */
6770Sstevel@tonic-gate int rc_snapshot_get(uint32_t, rc_snapshot_t **);
6780Sstevel@tonic-gate void rc_snapshot_rele(rc_snapshot_t *);
6790Sstevel@tonic-gate void rc_snaplevel_hold(rc_snaplevel_t *);
6800Sstevel@tonic-gate void rc_snaplevel_rele(rc_snaplevel_t *);
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate /*
6830Sstevel@tonic-gate  * backend.c
6840Sstevel@tonic-gate  */
6850Sstevel@tonic-gate int backend_init(const char *, const char *, int);
6860Sstevel@tonic-gate void backend_fini(void);
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate rep_protocol_responseid_t backend_create_backup(const char *);
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate /*
6910Sstevel@tonic-gate  * call on any database inconsistency -- cleans up state as best it can,
6920Sstevel@tonic-gate  * and exits with a "Database Bad" error code.
6930Sstevel@tonic-gate  */
694*471Shg115875 void backend_panic(const char *, ...) __NORETURN;
6950Sstevel@tonic-gate #pragma rarely_called(backend_panic)
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate backend_query_t *backend_query_alloc(void);
6980Sstevel@tonic-gate void backend_query_append(backend_query_t *, const char *);
6990Sstevel@tonic-gate void backend_query_add(backend_query_t *, const char *, ...);
7000Sstevel@tonic-gate void backend_query_free(backend_query_t *);
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate typedef int backend_run_callback_f(void *data, int columns, char **vals,
7030Sstevel@tonic-gate     char **names);
7040Sstevel@tonic-gate #define	BACKEND_CALLBACK_CONTINUE	0
7050Sstevel@tonic-gate #define	BACKEND_CALLBACK_ABORT		1
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate backend_run_callback_f backend_fail_if_seen;	/* aborts TX if called */
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate int backend_run(backend_type_t, backend_query_t *,
7100Sstevel@tonic-gate     backend_run_callback_f *, void *);
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate int backend_tx_begin(backend_type_t, backend_tx_t **);
7130Sstevel@tonic-gate int backend_tx_begin_ro(backend_type_t, backend_tx_t **);
7140Sstevel@tonic-gate void backend_tx_end_ro(backend_tx_t *);
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate enum id_space {
7170Sstevel@tonic-gate 	BACKEND_ID_SERVICE_INSTANCE,
7180Sstevel@tonic-gate 	BACKEND_ID_PROPERTYGRP,
7190Sstevel@tonic-gate 	BACKEND_ID_GENERATION,
7200Sstevel@tonic-gate 	BACKEND_ID_PROPERTY,
7210Sstevel@tonic-gate 	BACKEND_ID_VALUE,
7220Sstevel@tonic-gate 	BACKEND_ID_SNAPNAME,
7230Sstevel@tonic-gate 	BACKEND_ID_SNAPSHOT,
7240Sstevel@tonic-gate 	BACKEND_ID_SNAPLEVEL,
7250Sstevel@tonic-gate 	BACKEND_ID_INVALID	/* always illegal */
7260Sstevel@tonic-gate };
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate uint32_t backend_new_id(backend_tx_t *, enum id_space);
7290Sstevel@tonic-gate int backend_tx_run_update(backend_tx_t *, const char *, ...);
7300Sstevel@tonic-gate int backend_tx_run_update_changed(backend_tx_t *, const char *, ...);
7310Sstevel@tonic-gate int backend_tx_run_single_int(backend_tx_t *tx, backend_query_t *q,
7320Sstevel@tonic-gate     uint32_t *buf);
7330Sstevel@tonic-gate int backend_tx_run(backend_tx_t *, backend_query_t *,
7340Sstevel@tonic-gate     backend_run_callback_f *, void *);
7350Sstevel@tonic-gate 
7360Sstevel@tonic-gate int backend_tx_commit(backend_tx_t *);
7370Sstevel@tonic-gate void backend_tx_rollback(backend_tx_t *);
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate #ifdef	__cplusplus
7400Sstevel@tonic-gate }
7410Sstevel@tonic-gate #endif
7420Sstevel@tonic-gate 
7430Sstevel@tonic-gate #endif	/* _CONFIGD_H */
744