xref: /titanic_52/usr/src/cmd/svc/configd/configd.h (revision 53f3aea0943e36e5fed2615ad5f9fd1f17de51d2)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55b7f77adStw21770  * Common Development and Distribution License (the "License").
65b7f77adStw21770  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*53f3aea0SRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
23*53f3aea0SRoger A. Faulkner  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #ifndef	_CONFIGD_H
287c478bd9Sstevel@tonic-gate #define	_CONFIGD_H
297c478bd9Sstevel@tonic-gate 
305b7f77adStw21770 #include <bsm/adt.h>
317c478bd9Sstevel@tonic-gate #include <door.h>
327c478bd9Sstevel@tonic-gate #include <pthread.h>
33*53f3aea0SRoger A. Faulkner #include <synch.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <libscf.h>
387c478bd9Sstevel@tonic-gate #include <repcache_protocol.h>
397c478bd9Sstevel@tonic-gate #include <libuutil.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <configd_exit.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
447c478bd9Sstevel@tonic-gate extern "C" {
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * Lock order:
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  *	client lock
517c478bd9Sstevel@tonic-gate  *		iter locks, in ID order
527c478bd9Sstevel@tonic-gate  *		entity locks, in ID order
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  *		(any iter/entity locks)
557c478bd9Sstevel@tonic-gate  *			backend locks (NORMAL, then NONPERSIST)
567c478bd9Sstevel@tonic-gate  *				rc_node lock
577c478bd9Sstevel@tonic-gate  *					children's rc_node lock
587c478bd9Sstevel@tonic-gate  *				cache bucket lock
597c478bd9Sstevel@tonic-gate  *					rc_node lock[*]
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  *	* only one node may be grabbed while holding a bucket lock
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  *	leaf locks:  (no other locks may be aquired while holding one)
647c478bd9Sstevel@tonic-gate  *		rc_pg_notify_lock
655b7f77adStw21770  *		rc_annotate_lock
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate  * Returns the minimum size for a structure of type 't' such
707c478bd9Sstevel@tonic-gate  * that it is safe to access field 'f'.
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate #define	offsetofend(t, f)	(offsetof(t, f) + sizeof (((t *)0)->f))
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
75*53f3aea0SRoger A. Faulkner  * We want MUTEX_HELD, but we also want pthreads.  So we're stuck with this
76*53f3aea0SRoger A. Faulkner  * for the native build, at least until the build machines can catch up
77*53f3aea0SRoger A. Faulkner  * with the latest version of MUTEX_HELD() in <synch.h>.
787c478bd9Sstevel@tonic-gate  */
79*53f3aea0SRoger A. Faulkner #if defined(NATIVE_BUILD)
80*53f3aea0SRoger A. Faulkner #undef	MUTEX_HELD
81*53f3aea0SRoger A. Faulkner #define	MUTEX_HELD(m)		_mutex_held((mutex_t *)(m))
82*53f3aea0SRoger A. Faulkner #endif
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate  * Maximum levels of composition.
867c478bd9Sstevel@tonic-gate  */
877c478bd9Sstevel@tonic-gate #define	COMPOSITION_DEPTH	2
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate #define	CONFIGD_CORE	"core.%f.%t.%p"
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #ifndef NDEBUG
927c478bd9Sstevel@tonic-gate #define	bad_error(f, e)							\
937c478bd9Sstevel@tonic-gate 	uu_warn("%s:%d: %s() returned bad error %d.  Aborting.\n",	\
947c478bd9Sstevel@tonic-gate 	    __FILE__, __LINE__, f, e);					\
957c478bd9Sstevel@tonic-gate 	abort()
967c478bd9Sstevel@tonic-gate #else
977c478bd9Sstevel@tonic-gate #define	bad_error(f, e)		abort()
987c478bd9Sstevel@tonic-gate #endif
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate typedef enum backend_type {
1017c478bd9Sstevel@tonic-gate 	BACKEND_TYPE_NORMAL		= 0,
1027c478bd9Sstevel@tonic-gate 	BACKEND_TYPE_NONPERSIST,
1037c478bd9Sstevel@tonic-gate 	BACKEND_TYPE_TOTAL			/* backend use only */
1047c478bd9Sstevel@tonic-gate } backend_type_t;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate  * pre-declare rc_* types
1087c478bd9Sstevel@tonic-gate  */
1097c478bd9Sstevel@tonic-gate typedef struct rc_node rc_node_t;
1107c478bd9Sstevel@tonic-gate typedef struct rc_snapshot rc_snapshot_t;
1117c478bd9Sstevel@tonic-gate typedef struct rc_snaplevel rc_snaplevel_t;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate  * notification layer -- protected by rc_pg_notify_lock
1157c478bd9Sstevel@tonic-gate  */
1167c478bd9Sstevel@tonic-gate typedef struct rc_notify_info rc_notify_info_t;
1177c478bd9Sstevel@tonic-gate typedef struct rc_notify_delete rc_notify_delete_t;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate #define	RC_NOTIFY_MAX_NAMES	4	/* enough for now */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate typedef struct rc_notify {
1227c478bd9Sstevel@tonic-gate 	uu_list_node_t	rcn_list_node;
1237c478bd9Sstevel@tonic-gate 	rc_node_t	*rcn_node;
1247c478bd9Sstevel@tonic-gate 	rc_notify_info_t *rcn_info;
1257c478bd9Sstevel@tonic-gate 	rc_notify_delete_t *rcn_delete;
1267c478bd9Sstevel@tonic-gate } rc_notify_t;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate struct rc_notify_delete {
1297c478bd9Sstevel@tonic-gate 	rc_notify_t rnd_notify;
1307c478bd9Sstevel@tonic-gate 	char rnd_fmri[REP_PROTOCOL_FMRI_LEN];
1317c478bd9Sstevel@tonic-gate };
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate struct rc_notify_info {
1347c478bd9Sstevel@tonic-gate 	uu_list_node_t	rni_list_node;
1357c478bd9Sstevel@tonic-gate 	rc_notify_t	rni_notify;
1367c478bd9Sstevel@tonic-gate 	const char	*rni_namelist[RC_NOTIFY_MAX_NAMES];
1377c478bd9Sstevel@tonic-gate 	const char	*rni_typelist[RC_NOTIFY_MAX_NAMES];
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	int		rni_flags;
1407c478bd9Sstevel@tonic-gate 	int		rni_waiters;
1417c478bd9Sstevel@tonic-gate 	pthread_cond_t	rni_cv;
1427c478bd9Sstevel@tonic-gate };
1437c478bd9Sstevel@tonic-gate #define	RC_NOTIFY_ACTIVE	0x00000001
1447c478bd9Sstevel@tonic-gate #define	RC_NOTIFY_DRAIN		0x00000002
1457c478bd9Sstevel@tonic-gate #define	RC_NOTIFY_EMPTYING	0x00000004
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate typedef struct rc_node_pg_notify {
1487c478bd9Sstevel@tonic-gate 	uu_list_node_t	rnpn_node;
1497c478bd9Sstevel@tonic-gate 	int		rnpn_fd;
1507c478bd9Sstevel@tonic-gate 	rc_node_t	*rnpn_pg;
1517c478bd9Sstevel@tonic-gate } rc_node_pg_notify_t;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate /*
1547c478bd9Sstevel@tonic-gate  * cache layer
1557c478bd9Sstevel@tonic-gate  */
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate  * The 'key' for the main object hash.  main_id is the main object
1597c478bd9Sstevel@tonic-gate  * identifier.  The rl_ids array contains:
1607c478bd9Sstevel@tonic-gate  *
1617c478bd9Sstevel@tonic-gate  *	TYPE		RL_IDS
1627c478bd9Sstevel@tonic-gate  *	scope		unused
1637c478bd9Sstevel@tonic-gate  *	service		unused
1647c478bd9Sstevel@tonic-gate  *	instance	{service_id}
1657c478bd9Sstevel@tonic-gate  *	snapshot	{service_id, instance_id}
1667c478bd9Sstevel@tonic-gate  *	snaplevel	{service_id, instance_id, name_id, snapshot_id}
1677c478bd9Sstevel@tonic-gate  *	propertygroup	{service_id, (instance_id or 0), (name_id or 0),
1687c478bd9Sstevel@tonic-gate  *			    (snapshot_id or 0), (l_id or 0)}
1697c478bd9Sstevel@tonic-gate  *	property	{service_id, (instance_id or 0), (name_id or 0),
1707c478bd9Sstevel@tonic-gate  *			    (snapshot_id or 0), (l_id or 0), pg_id, gen_id}
1717c478bd9Sstevel@tonic-gate  */
1727c478bd9Sstevel@tonic-gate #define	ID_SERVICE	0
1737c478bd9Sstevel@tonic-gate #define	ID_INSTANCE	1
1747c478bd9Sstevel@tonic-gate #define	ID_NAME		2
1757c478bd9Sstevel@tonic-gate #define	ID_SNAPSHOT	3
1767c478bd9Sstevel@tonic-gate #define	ID_LEVEL	4
1777c478bd9Sstevel@tonic-gate #define	ID_PG		5
1787c478bd9Sstevel@tonic-gate #define	ID_GEN		6
1797c478bd9Sstevel@tonic-gate #define	MAX_IDS	7
1807c478bd9Sstevel@tonic-gate typedef struct rc_node_lookup {
1817c478bd9Sstevel@tonic-gate 	uint16_t	rl_type;		/* REP_PROTOCOL_ENTITY_* */
1827c478bd9Sstevel@tonic-gate 	uint16_t	rl_backend;		/* BACKEND_TYPE_* */
1837c478bd9Sstevel@tonic-gate 	uint32_t	rl_main_id;		/* primary identifier */
1847c478bd9Sstevel@tonic-gate 	uint32_t	rl_ids[MAX_IDS];	/* context */
1857c478bd9Sstevel@tonic-gate } rc_node_lookup_t;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate struct rc_node {
1887c478bd9Sstevel@tonic-gate 	/*
1897c478bd9Sstevel@tonic-gate 	 * read-only data
1907c478bd9Sstevel@tonic-gate 	 */
1917c478bd9Sstevel@tonic-gate 	rc_node_lookup_t rn_id;			/* must be first */
1927c478bd9Sstevel@tonic-gate 	uint32_t	rn_hash;
1937c478bd9Sstevel@tonic-gate 	const char	*rn_name;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	/*
1967c478bd9Sstevel@tonic-gate 	 * type-specific state
1977c478bd9Sstevel@tonic-gate 	 * (if space becomes an issue, these can become a union)
1987c478bd9Sstevel@tonic-gate 	 */
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	/*
2017c478bd9Sstevel@tonic-gate 	 * Used by instances, snapshots, and "composed property groups" only.
2027c478bd9Sstevel@tonic-gate 	 * These are the entities whose properties should appear composed when
2037c478bd9Sstevel@tonic-gate 	 * this entity is traversed by a composed iterator.  0 is the top-most
2047c478bd9Sstevel@tonic-gate 	 * entity, down to COMPOSITION_DEPTH - 1.
2057c478bd9Sstevel@tonic-gate 	 */
2067c478bd9Sstevel@tonic-gate 	rc_node_t	*rn_cchain[COMPOSITION_DEPTH];
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	/*
2097c478bd9Sstevel@tonic-gate 	 * used by property groups only
2107c478bd9Sstevel@tonic-gate 	 */
2117c478bd9Sstevel@tonic-gate 	const char	*rn_type;
2127c478bd9Sstevel@tonic-gate 	uint32_t	rn_pgflags;
2137c478bd9Sstevel@tonic-gate 	uint32_t	rn_gen_id;
2147c478bd9Sstevel@tonic-gate 	uu_list_t	*rn_pg_notify_list;	/* prot by rc_pg_notify_lock */
2157c478bd9Sstevel@tonic-gate 	rc_notify_t	rn_notify;		/* prot by rc_pg_notify_lock */
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	/*
2187c478bd9Sstevel@tonic-gate 	 * used by properties only
2197c478bd9Sstevel@tonic-gate 	 */
2207c478bd9Sstevel@tonic-gate 	rep_protocol_value_type_t rn_valtype;
2217c478bd9Sstevel@tonic-gate 	const char	*rn_values;		/* protected by rn_lock */
2227c478bd9Sstevel@tonic-gate 	size_t		rn_values_count;	/* protected by rn_lock */
2237c478bd9Sstevel@tonic-gate 	size_t		rn_values_size;		/* protected by rn_lock */
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	/*
2267c478bd9Sstevel@tonic-gate 	 * used by snapshots only
2277c478bd9Sstevel@tonic-gate 	 */
2287c478bd9Sstevel@tonic-gate 	uint32_t	rn_snapshot_id;
2297c478bd9Sstevel@tonic-gate 	rc_snapshot_t	*rn_snapshot;		/* protected by rn_lock */
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	/*
2327c478bd9Sstevel@tonic-gate 	 * used by snaplevels only
2337c478bd9Sstevel@tonic-gate 	 */
2347c478bd9Sstevel@tonic-gate 	rc_snaplevel_t	*rn_snaplevel;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	/*
2377c478bd9Sstevel@tonic-gate 	 * mutable state
2387c478bd9Sstevel@tonic-gate 	 */
2397c478bd9Sstevel@tonic-gate 	pthread_mutex_t	rn_lock;
2407c478bd9Sstevel@tonic-gate 	pthread_cond_t	rn_cv;
2417c478bd9Sstevel@tonic-gate 	uint32_t	rn_flags;
2426643e1ffSbustos 	uint32_t	rn_refs;		/* client reference count */
2436643e1ffSbustos 	uint32_t	rn_erefs;		/* ephemeral ref count */
2447c478bd9Sstevel@tonic-gate 	uint32_t	rn_other_refs;		/* atomic refcount */
2457c478bd9Sstevel@tonic-gate 	uint32_t	rn_other_refs_held;	/* for 1->0 transitions */
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	uu_list_t	*rn_children;
2487c478bd9Sstevel@tonic-gate 	uu_list_node_t	rn_sibling_node;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	rc_node_t	*rn_parent;		/* set if on child list */
2517c478bd9Sstevel@tonic-gate 	rc_node_t	*rn_former;		/* next former node */
2527c478bd9Sstevel@tonic-gate 	rc_node_t	*rn_parent_ref;		/* reference count target */
2535b7f77adStw21770 	const char	*rn_fmri;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	/*
2567c478bd9Sstevel@tonic-gate 	 * external state (protected by hash chain lock)
2577c478bd9Sstevel@tonic-gate 	 */
2587c478bd9Sstevel@tonic-gate 	rc_node_t	*rn_hash_next;
2597c478bd9Sstevel@tonic-gate };
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate /*
2627c478bd9Sstevel@tonic-gate  * flag ordering:
2637c478bd9Sstevel@tonic-gate  *	RC_DYING
2647c478bd9Sstevel@tonic-gate  *		RC_NODE_CHILDREN_CHANGING
2657c478bd9Sstevel@tonic-gate  *		RC_NODE_CREATING_CHILD
2667c478bd9Sstevel@tonic-gate  *		RC_NODE_USING_PARENT
2677c478bd9Sstevel@tonic-gate  *			RC_NODE_IN_TX
2687c478bd9Sstevel@tonic-gate  *
2697c478bd9Sstevel@tonic-gate  * RC_NODE_USING_PARENT is special, because it lets you proceed up the tree,
2707c478bd9Sstevel@tonic-gate  * in the reverse of the usual locking order.  Because of this, there are
2717c478bd9Sstevel@tonic-gate  * limitations on what you can do while holding it.  While holding
2727c478bd9Sstevel@tonic-gate  * RC_NODE_USING_PARENT, you may:
2737c478bd9Sstevel@tonic-gate  *	bump or release your parent's reference count
2747c478bd9Sstevel@tonic-gate  *	access fields in your parent
2757c478bd9Sstevel@tonic-gate  *	hold RC_NODE_USING_PARENT in the parent, proceeding recursively.
2767c478bd9Sstevel@tonic-gate  *
2777c478bd9Sstevel@tonic-gate  * If you are only holding *one* node's RC_NODE_USING_PARENT, and:
2787c478bd9Sstevel@tonic-gate  *	you are *not* proceeding recursively, you can hold your
2797c478bd9Sstevel@tonic-gate  *	    immediate parent's RC_NODE_CHILDREN_CHANGING flag.
2807c478bd9Sstevel@tonic-gate  *	you hold your parent's RC_NODE_CHILDREN_CHANGING flag, you can add
2817c478bd9Sstevel@tonic-gate  *	    RC_NODE_IN_TX to your flags.
2827c478bd9Sstevel@tonic-gate  *	you want to grab a flag in your parent, you must lock your parent,
2837c478bd9Sstevel@tonic-gate  *	    lock yourself, drop RC_NODE_USING_PARENT, unlock yourself,
2847c478bd9Sstevel@tonic-gate  *	    then proceed to manipulate the parent.
2857c478bd9Sstevel@tonic-gate  */
2867c478bd9Sstevel@tonic-gate #define	RC_NODE_CHILDREN_CHANGING	0x00000001 /* child list in flux */
2877c478bd9Sstevel@tonic-gate #define	RC_NODE_HAS_CHILDREN		0x00000002 /* child list is accurate */
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate #define	RC_NODE_IN_PARENT		0x00000004 /* I'm in my parent's list */
2907c478bd9Sstevel@tonic-gate #define	RC_NODE_USING_PARENT		0x00000008 /* parent ptr in use */
2917c478bd9Sstevel@tonic-gate #define	RC_NODE_CREATING_CHILD		0x00000010 /* a create is in progress */
2927c478bd9Sstevel@tonic-gate #define	RC_NODE_IN_TX			0x00000020 /* a tx is in progess */
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate #define	RC_NODE_OLD			0x00000400 /* out-of-date object */
2957c478bd9Sstevel@tonic-gate #define	RC_NODE_ON_FORMER		0x00000800 /* on an rn_former list */
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate #define	RC_NODE_PARENT_REF		0x00001000 /* parent_ref in use */
2987c478bd9Sstevel@tonic-gate #define	RC_NODE_UNREFED			0x00002000 /* unref processing active */
2997c478bd9Sstevel@tonic-gate #define	RC_NODE_DYING			0x00004000 /* node is being deleted */
3007c478bd9Sstevel@tonic-gate #define	RC_NODE_DEAD			0x00008000 /* node has been deleted */
3017c478bd9Sstevel@tonic-gate 
3026643e1ffSbustos /*
3036643e1ffSbustos  * RC_NODE_DEAD means that the node no longer represents data in the
3046643e1ffSbustos  * backend, and we should return _DELETED errors to clients who try to use
3056643e1ffSbustos  * it.  Very much like a zombie process.
3066643e1ffSbustos  *
3076643e1ffSbustos  * RC_NODE_OLD also means that the node no longer represents data in the
3086643e1ffSbustos  * backend, but it's ok for clients to access it because we've loaded all of
3096643e1ffSbustos  * the children.  (This only happens for transactional objects such as
3106643e1ffSbustos  * property groups and snapshots, where we guarantee a stable view once
3116643e1ffSbustos  * a reference is obtained.)  When all client references are destroyed,
3126643e1ffSbustos  * however, the node should be destroyed.
3136643e1ffSbustos  *
3146643e1ffSbustos  * Though RC_NODE_DEAD is set by the rc_node_delete() code, it is also set
3156643e1ffSbustos  * by rc_node_no_client_refs() for RC_NODE_OLD nodes not long before
3166643e1ffSbustos  * they're destroyed.
3176643e1ffSbustos  */
3186643e1ffSbustos 
3197c478bd9Sstevel@tonic-gate #define	RC_NODE_DYING_FLAGS						\
3207c478bd9Sstevel@tonic-gate 	(RC_NODE_CHILDREN_CHANGING | RC_NODE_IN_TX | RC_NODE_DYING |	\
3217c478bd9Sstevel@tonic-gate 	    RC_NODE_CREATING_CHILD)
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate #define	RC_NODE_WAITING_FLAGS						\
3247c478bd9Sstevel@tonic-gate 	(RC_NODE_DYING_FLAGS | RC_NODE_USING_PARENT)
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 
3276643e1ffSbustos #define	NODE_LOCK(n)	(void) pthread_mutex_lock(&(n)->rn_lock)
3286643e1ffSbustos #define	NODE_UNLOCK(n)	(void) pthread_mutex_unlock(&(n)->rn_lock)
3296643e1ffSbustos 
3306643e1ffSbustos 
3315b7f77adStw21770 typedef enum rc_auth_state {
3325b7f77adStw21770 	RC_AUTH_UNKNOWN = 0,		/* No checks done yet. */
3335b7f77adStw21770 	RC_AUTH_FAILED,			/* Authorization checked & failed. */
3345b7f77adStw21770 	RC_AUTH_PASSED			/* Authorization succeeded. */
3355b7f77adStw21770 } rc_auth_state_t;
3365b7f77adStw21770 
3375b7f77adStw21770 /*
3385b7f77adStw21770  * Some authorization checks are performed in rc_node_setup_tx() in
3395b7f77adStw21770  * response to the REP_PROTOCOL_PROPERTYGRP_TX_START message.  Other checks
3405b7f77adStw21770  * must wait until the actual transaction operations are received in the
3415b7f77adStw21770  * REP_PROTOCOL_PROPERTYGRP_TX_COMMIT message.  This second set of checks
3425b7f77adStw21770  * is performed in rc_tx_commit().  rnp_auth_string and rnp_authorized in
3435b7f77adStw21770  * the following structure are used to hold the results of the
3445b7f77adStw21770  * authorization checking done in rc_node_setup_tx() for later use by
3455b7f77adStw21770  * rc_tx_commit().
3465b7f77adStw21770  *
3475b7f77adStw21770  * In client.c transactions are represented by rc_node_ptr structures which
3485b7f77adStw21770  * point to a property group rc_node_t.  Thus, this is an appropriate place
3495b7f77adStw21770  * to hold authorization state.
3505b7f77adStw21770  */
3517c478bd9Sstevel@tonic-gate typedef struct rc_node_ptr {
3527c478bd9Sstevel@tonic-gate 	rc_node_t	*rnp_node;
3535b7f77adStw21770 	const char	*rnp_auth_string;	/* authorization string */
3545b7f77adStw21770 	rc_auth_state_t	rnp_authorized;		/* transaction pre-auth rslt. */
3557c478bd9Sstevel@tonic-gate 	char		rnp_deleted;		/* object was deleted */
3567c478bd9Sstevel@tonic-gate } rc_node_ptr_t;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate #define	NODE_PTR_NOT_HELD(npp) \
3597c478bd9Sstevel@tonic-gate 	    ((npp)->rnp_node == NULL || !MUTEX_HELD(&(npp)->rnp_node->rn_lock))
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate typedef int rc_iter_filter_func(rc_node_t *, void *);
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate typedef struct rc_node_iter {
3647c478bd9Sstevel@tonic-gate 	rc_node_t	*rni_parent;
3657c478bd9Sstevel@tonic-gate 	int		rni_clevel;	/* index into rni_parent->rn_cchain[] */
3667c478bd9Sstevel@tonic-gate 	rc_node_t	*rni_iter_node;
3677c478bd9Sstevel@tonic-gate 	uu_list_walk_t	*rni_iter;
3687c478bd9Sstevel@tonic-gate 	uint32_t	rni_type;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	/*
3717c478bd9Sstevel@tonic-gate 	 * for normal walks
3727c478bd9Sstevel@tonic-gate 	 */
3737c478bd9Sstevel@tonic-gate 	rc_iter_filter_func *rni_filter;
3747c478bd9Sstevel@tonic-gate 	void		*rni_filter_arg;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	/*
3777c478bd9Sstevel@tonic-gate 	 * for value walks
3787c478bd9Sstevel@tonic-gate 	 */
3797c478bd9Sstevel@tonic-gate 	uint32_t	rni_offset;		/* next value offset */
3807c478bd9Sstevel@tonic-gate 	uint32_t	rni_last_offset;	/* previous value offset */
3817c478bd9Sstevel@tonic-gate } rc_node_iter_t;
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate typedef struct rc_node_tx {
3847c478bd9Sstevel@tonic-gate 	rc_node_ptr_t	rnt_ptr;
3857c478bd9Sstevel@tonic-gate 	int		rnt_authorized;		/* No need to check anymore. */
3867c478bd9Sstevel@tonic-gate } rc_node_tx_t;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate typedef struct cache_bucket {
3907c478bd9Sstevel@tonic-gate 	pthread_mutex_t	cb_lock;
3917c478bd9Sstevel@tonic-gate 	rc_node_t	*cb_head;
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	char		cb_pad[64 - sizeof (pthread_mutex_t) -
3947c478bd9Sstevel@tonic-gate 			    2 * sizeof (rc_node_t *)];
3957c478bd9Sstevel@tonic-gate } cache_bucket_t;
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate /*
3985b7f77adStw21770  * tx_commit_data_tx is an opaque structure which is defined in object.c.
3995b7f77adStw21770  * It contains the data of the transaction that is to be committed.
4005b7f77adStw21770  * Accessor functions in object.c allow other modules to retrieve
4015b7f77adStw21770  * information.
4025b7f77adStw21770  */
4035b7f77adStw21770 typedef struct tx_commit_data tx_commit_data_t;
4045b7f77adStw21770 
4055b7f77adStw21770 /*
4067c478bd9Sstevel@tonic-gate  * Snapshots
4077c478bd9Sstevel@tonic-gate  */
4087c478bd9Sstevel@tonic-gate struct rc_snapshot {
4097c478bd9Sstevel@tonic-gate 	uint32_t	rs_snap_id;
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	pthread_mutex_t	rs_lock;
4127c478bd9Sstevel@tonic-gate 	pthread_cond_t	rs_cv;
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	uint32_t	rs_flags;
4157c478bd9Sstevel@tonic-gate 	uint32_t	rs_refcnt;	/* references from rc_nodes */
4167c478bd9Sstevel@tonic-gate 	uint32_t	rs_childref;	/* references to children */
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	rc_snaplevel_t	*rs_levels;	/* list of levels */
4197c478bd9Sstevel@tonic-gate 	rc_snapshot_t	*rs_hash_next;
4207c478bd9Sstevel@tonic-gate };
4217c478bd9Sstevel@tonic-gate #define	RC_SNAPSHOT_FILLING	0x00000001	/* rs_levels changing */
4227c478bd9Sstevel@tonic-gate #define	RC_SNAPSHOT_READY	0x00000002
4237c478bd9Sstevel@tonic-gate #define	RC_SNAPSHOT_DEAD	0x00000004	/* no resources */
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate typedef struct rc_snaplevel_pgs {
4267c478bd9Sstevel@tonic-gate 	uint32_t	rsp_pg_id;
4277c478bd9Sstevel@tonic-gate 	uint32_t	rsp_gen_id;
4287c478bd9Sstevel@tonic-gate } rc_snaplevel_pgs_t;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate struct rc_snaplevel {
4317c478bd9Sstevel@tonic-gate 	rc_snapshot_t	*rsl_parent;
4327c478bd9Sstevel@tonic-gate 	uint32_t	rsl_level_num;
4337c478bd9Sstevel@tonic-gate 	uint32_t	rsl_level_id;
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	uint32_t	rsl_service_id;
4367c478bd9Sstevel@tonic-gate 	uint32_t	rsl_instance_id;
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	const char	*rsl_scope;
4397c478bd9Sstevel@tonic-gate 	const char	*rsl_service;
4407c478bd9Sstevel@tonic-gate 	const char	*rsl_instance;
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	rc_snaplevel_t	*rsl_next;
4437c478bd9Sstevel@tonic-gate };
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate /*
4467c478bd9Sstevel@tonic-gate  * Client layer -- the IDs fields must be first, in order for the search
4477c478bd9Sstevel@tonic-gate  * routines to work correctly.
4487c478bd9Sstevel@tonic-gate  */
4497c478bd9Sstevel@tonic-gate enum repcache_txstate {
4507c478bd9Sstevel@tonic-gate 	REPCACHE_TX_INIT,
4517c478bd9Sstevel@tonic-gate 	REPCACHE_TX_SETUP,
4527c478bd9Sstevel@tonic-gate 	REPCACHE_TX_COMMITTED
4537c478bd9Sstevel@tonic-gate };
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate typedef struct repcache_entity {
4567c478bd9Sstevel@tonic-gate 	uint32_t	re_id;
4578918dff3Sjwadams 	uu_avl_node_t	re_link;
4587c478bd9Sstevel@tonic-gate 	uint32_t	re_changeid;
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	pthread_mutex_t	re_lock;
4617c478bd9Sstevel@tonic-gate 	uint32_t	re_type;
4627c478bd9Sstevel@tonic-gate 	rc_node_ptr_t	re_node;
4637c478bd9Sstevel@tonic-gate 	enum repcache_txstate re_txstate;	/* property groups only */
4647c478bd9Sstevel@tonic-gate } repcache_entity_t;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate typedef struct repcache_iter {
4677c478bd9Sstevel@tonic-gate 	uint32_t	ri_id;
4688918dff3Sjwadams 	uu_avl_node_t	ri_link;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	uint32_t	ri_type;	/* result type */
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	pthread_mutex_t	ri_lock;
4737c478bd9Sstevel@tonic-gate 	uint32_t	ri_sequence;
4747c478bd9Sstevel@tonic-gate 	rc_node_iter_t	*ri_iter;
4757c478bd9Sstevel@tonic-gate } repcache_iter_t;
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate typedef struct repcache_client {
4787c478bd9Sstevel@tonic-gate 	/*
4797c478bd9Sstevel@tonic-gate 	 * constants
4807c478bd9Sstevel@tonic-gate 	 */
4817c478bd9Sstevel@tonic-gate 	uint32_t	rc_id;		/* must be first */
4827c478bd9Sstevel@tonic-gate 	int		rc_all_auths;	/* bypass auth checks */
4837c478bd9Sstevel@tonic-gate 	uint32_t	rc_debug;	/* debug flags */
4847c478bd9Sstevel@tonic-gate 	pid_t		rc_pid;		/* pid of opening process */
4857c478bd9Sstevel@tonic-gate 	door_id_t	rc_doorid;	/* a globally unique identifier */
4867c478bd9Sstevel@tonic-gate 	int		rc_doorfd;	/* our door's FD */
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	/*
4895b7f77adStw21770 	 * Constants used for security auditing
4905b7f77adStw21770 	 *
4915b7f77adStw21770 	 * rc_adt_session points to the audit session data that is used for
4925b7f77adStw21770 	 * the life of the client.  rc_adt_sessionid is the session ID that
4935b7f77adStw21770 	 * is initially assigned when the audit session is started.  See
4945b7f77adStw21770 	 * start_audit_session() in client.c.  This session id is used for
4955b7f77adStw21770 	 * audit events except when we are processing a set of annotated
4965b7f77adStw21770 	 * events.  Annotated events use a separate session id so that they
4975b7f77adStw21770 	 * can be grouped.  See set_annotation() in client.c.
4985b7f77adStw21770 	 */
4995b7f77adStw21770 	adt_session_data_t *rc_adt_session;	/* Session data. */
5005b7f77adStw21770 	au_asid_t	rc_adt_sessionid;	/* Main session ID for */
5015b7f77adStw21770 						/* auditing */
5025b7f77adStw21770 
5035b7f77adStw21770 	/*
5047c478bd9Sstevel@tonic-gate 	 * client list linkage, protected by hash chain lock
5057c478bd9Sstevel@tonic-gate 	 */
5067c478bd9Sstevel@tonic-gate 	uu_list_node_t	rc_link;
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/*
5097c478bd9Sstevel@tonic-gate 	 * notification information, protected by rc_node layer
5107c478bd9Sstevel@tonic-gate 	 */
5117c478bd9Sstevel@tonic-gate 	rc_node_pg_notify_t	rc_pg_notify;
5127c478bd9Sstevel@tonic-gate 	rc_notify_info_t	rc_notify_info;
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	/*
5157c478bd9Sstevel@tonic-gate 	 * client_wait output, only usable by rc_notify_thr
5167c478bd9Sstevel@tonic-gate 	 */
5177c478bd9Sstevel@tonic-gate 	rc_node_ptr_t	rc_notify_ptr;
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 	/*
5208918dff3Sjwadams 	 * register sets, protected by rc_lock
5217c478bd9Sstevel@tonic-gate 	 */
5228918dff3Sjwadams 	uu_avl_t	*rc_entities;
5238918dff3Sjwadams 	uu_avl_t	*rc_iters;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 	/*
5267c478bd9Sstevel@tonic-gate 	 * Variables, protected by rc_lock
5277c478bd9Sstevel@tonic-gate 	 */
5287c478bd9Sstevel@tonic-gate 	int		rc_refcnt;	/* in-progress door calls */
5295b7f77adStw21770 	int		rc_flags;	/* see RC_CLIENT_* symbols below */
5307c478bd9Sstevel@tonic-gate 	uint32_t	rc_changeid;	/* used to make backups idempotent */
5317c478bd9Sstevel@tonic-gate 	pthread_t	rc_insert_thr;	/* single thread trying to insert */
5327c478bd9Sstevel@tonic-gate 	pthread_t	rc_notify_thr;	/* single thread waiting for notify */
5337c478bd9Sstevel@tonic-gate 	pthread_cond_t	rc_cv;
5347c478bd9Sstevel@tonic-gate 	pthread_mutex_t	rc_lock;
5355b7f77adStw21770 
5365b7f77adStw21770 	/*
5375b7f77adStw21770 	 * Per-client audit information.  These fields must be protected by
5385b7f77adStw21770 	 * rc_annotate_lock separately from rc_lock because they may need
5395b7f77adStw21770 	 * to be accessed from rc_node.c with an entity or iterator lock
5405b7f77adStw21770 	 * held, and those must be taken after rc_lock.
5415b7f77adStw21770 	 */
5425b7f77adStw21770 	int		rc_annotate;	/* generate annotation event if set */
5435b7f77adStw21770 	const char	*rc_operation;	/* operation for audit annotation */
5445b7f77adStw21770 	const char	*rc_file;	/* file name for audit annotation */
5455b7f77adStw21770 	pthread_mutex_t	rc_annotate_lock;
5467c478bd9Sstevel@tonic-gate } repcache_client_t;
5475b7f77adStw21770 
5485b7f77adStw21770 /* Bit definitions for rc_flags. */
5497c478bd9Sstevel@tonic-gate #define	RC_CLIENT_DEAD			0x00000001
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate typedef struct client_bucket {
5527c478bd9Sstevel@tonic-gate 	pthread_mutex_t	cb_lock;
5537c478bd9Sstevel@tonic-gate 	uu_list_t	*cb_list;
5547c478bd9Sstevel@tonic-gate 	char ch_pad[64 - sizeof (pthread_mutex_t) - sizeof (uu_list_t *)];
5557c478bd9Sstevel@tonic-gate } client_bucket_t;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate enum rc_ptr_type {
5587c478bd9Sstevel@tonic-gate 	RC_PTR_TYPE_ENTITY = 1,
5597c478bd9Sstevel@tonic-gate 	RC_PTR_TYPE_ITER
5607c478bd9Sstevel@tonic-gate };
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate typedef struct request_log_ptr {
5637c478bd9Sstevel@tonic-gate 	enum rc_ptr_type	rlp_type;
5647c478bd9Sstevel@tonic-gate 	uint32_t		rlp_id;
5657c478bd9Sstevel@tonic-gate 	void			*rlp_ptr; /* repcache_{entity,iter}_t */
5667c478bd9Sstevel@tonic-gate 	void			*rlp_data;	/* rc_node, for ENTITY only */
5677c478bd9Sstevel@tonic-gate } request_log_ptr_t;
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate #define	MAX_PTRS	3
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate /*
5727c478bd9Sstevel@tonic-gate  * rl_start through rl_client cannot move without changing start_log()
5737c478bd9Sstevel@tonic-gate  */
5747c478bd9Sstevel@tonic-gate typedef struct request_log_entry {
5757c478bd9Sstevel@tonic-gate 	hrtime_t		rl_start;
5767c478bd9Sstevel@tonic-gate 	hrtime_t		rl_end;
5777c478bd9Sstevel@tonic-gate 	pthread_t		rl_tid;
5787c478bd9Sstevel@tonic-gate 	uint32_t		rl_clientid;
5797c478bd9Sstevel@tonic-gate 	repcache_client_t	*rl_client;
5807c478bd9Sstevel@tonic-gate 	enum rep_protocol_requestid rl_request;
5817c478bd9Sstevel@tonic-gate 	rep_protocol_responseid_t rl_response;
5827c478bd9Sstevel@tonic-gate 	int			rl_num_ptrs;
5837c478bd9Sstevel@tonic-gate 	request_log_ptr_t	rl_ptrs[MAX_PTRS];
5847c478bd9Sstevel@tonic-gate } request_log_entry_t;
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate /*
5877c478bd9Sstevel@tonic-gate  * thread information
5887c478bd9Sstevel@tonic-gate  */
5897c478bd9Sstevel@tonic-gate typedef enum thread_state {
5907c478bd9Sstevel@tonic-gate 	TI_CREATED,
5917c478bd9Sstevel@tonic-gate 	TI_DOOR_RETURN,
5927c478bd9Sstevel@tonic-gate 	TI_SIGNAL_WAIT,
5937c478bd9Sstevel@tonic-gate 	TI_MAIN_DOOR_CALL,
5947c478bd9Sstevel@tonic-gate 	TI_CLIENT_CALL
5957c478bd9Sstevel@tonic-gate } thread_state_t;
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate typedef struct thread_info {
5987c478bd9Sstevel@tonic-gate 	pthread_t	ti_thread;
5997c478bd9Sstevel@tonic-gate 	uu_list_node_t	ti_node;		/* for list of all thread */
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	/*
6027c478bd9Sstevel@tonic-gate 	 * per-thread globals
6037c478bd9Sstevel@tonic-gate 	 */
6047c478bd9Sstevel@tonic-gate 	ucred_t		*ti_ucred;		/* for credential lookups */
6057c478bd9Sstevel@tonic-gate 	int		ti_ucred_read;		/* ucred holds current creds */
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	/*
6087c478bd9Sstevel@tonic-gate 	 * per-thread state information, for debuggers
6097c478bd9Sstevel@tonic-gate 	 */
6107c478bd9Sstevel@tonic-gate 	hrtime_t	ti_lastchange;
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 	thread_state_t	ti_state;
6137c478bd9Sstevel@tonic-gate 	thread_state_t	ti_prev_state;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	repcache_client_t *ti_active_client;
6167c478bd9Sstevel@tonic-gate 	request_log_entry_t	ti_log;
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	struct rep_protocol_request *ti_client_request;
6197c478bd9Sstevel@tonic-gate 	repository_door_request_t *ti_main_door_request;
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate } thread_info_t;
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate /*
6247c478bd9Sstevel@tonic-gate  * Backend layer
6257c478bd9Sstevel@tonic-gate  */
6267c478bd9Sstevel@tonic-gate typedef struct backend_query backend_query_t;
6277c478bd9Sstevel@tonic-gate typedef struct backend_tx backend_tx_t;
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate /*
6307c478bd9Sstevel@tonic-gate  * configd.c
6317c478bd9Sstevel@tonic-gate  */
6327c478bd9Sstevel@tonic-gate int create_connection(ucred_t *cred, repository_door_request_t *rp,
6337c478bd9Sstevel@tonic-gate     size_t rp_size, int *out_fd);
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate thread_info_t *thread_self(void);
6367c478bd9Sstevel@tonic-gate void thread_newstate(thread_info_t *, thread_state_t);
6377c478bd9Sstevel@tonic-gate ucred_t *get_ucred(void);
6387c478bd9Sstevel@tonic-gate int ucred_is_privileged(ucred_t *);
6397c478bd9Sstevel@tonic-gate 
6405b7f77adStw21770 adt_session_data_t *get_audit_session(void);
6415b7f77adStw21770 
6427c478bd9Sstevel@tonic-gate void configd_critical(const char *, ...);
6437c478bd9Sstevel@tonic-gate void configd_vcritical(const char *, va_list);
6446e1d2b42Samaguire void configd_info(const char *, ...);
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate extern int is_main_repository;
6477c478bd9Sstevel@tonic-gate extern int max_repository_backups;
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate /*
6507c478bd9Sstevel@tonic-gate  * maindoor.c
6517c478bd9Sstevel@tonic-gate  */
6527c478bd9Sstevel@tonic-gate int setup_main_door(const char *);
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate /*
6557c478bd9Sstevel@tonic-gate  * client.c
6567c478bd9Sstevel@tonic-gate  */
6575b7f77adStw21770 int client_annotation_needed(char *, size_t, char *, size_t);
6585b7f77adStw21770 void client_annotation_finished(void);
6597c478bd9Sstevel@tonic-gate int create_client(pid_t, uint32_t, int, int *);
6607c478bd9Sstevel@tonic-gate int client_init(void);
6617c478bd9Sstevel@tonic-gate int client_is_privileged(void);
6627c478bd9Sstevel@tonic-gate void log_enter(request_log_entry_t *);
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate /*
6657c478bd9Sstevel@tonic-gate  * rc_node.c, backend/cache interfaces (rc_node_t)
6667c478bd9Sstevel@tonic-gate  */
6677c478bd9Sstevel@tonic-gate int rc_node_init();
6687c478bd9Sstevel@tonic-gate int rc_check_type_name(uint32_t, const char *);
6697c478bd9Sstevel@tonic-gate 
6705b7f77adStw21770 void rc_node_ptr_free_mem(rc_node_ptr_t *);
6717c478bd9Sstevel@tonic-gate void rc_node_rele(rc_node_t *);
6727c478bd9Sstevel@tonic-gate rc_node_t *rc_node_setup(rc_node_t *, rc_node_lookup_t *,
6737c478bd9Sstevel@tonic-gate     const char *, rc_node_t *);
6747c478bd9Sstevel@tonic-gate rc_node_t *rc_node_setup_pg(rc_node_t *, rc_node_lookup_t *, const char *,
6757c478bd9Sstevel@tonic-gate     const char *, uint32_t, uint32_t, rc_node_t *);
6767c478bd9Sstevel@tonic-gate rc_node_t *rc_node_setup_snapshot(rc_node_t *, rc_node_lookup_t *, const char *,
6777c478bd9Sstevel@tonic-gate     uint32_t, rc_node_t *);
6787c478bd9Sstevel@tonic-gate rc_node_t *rc_node_setup_snaplevel(rc_node_t *, rc_node_lookup_t *,
6797c478bd9Sstevel@tonic-gate     rc_snaplevel_t *, rc_node_t *);
6807c478bd9Sstevel@tonic-gate int rc_node_create_property(rc_node_t *, rc_node_lookup_t *,
6817c478bd9Sstevel@tonic-gate     const char *, rep_protocol_value_type_t, const char *, size_t, size_t);
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate rc_node_t *rc_node_alloc(void);
6847c478bd9Sstevel@tonic-gate void rc_node_destroy(rc_node_t *);
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate /*
6877c478bd9Sstevel@tonic-gate  * rc_node.c, client interface (rc_node_ptr_t, rc_node_iter_t)
6887c478bd9Sstevel@tonic-gate  */
6897c478bd9Sstevel@tonic-gate void rc_node_ptr_init(rc_node_ptr_t *);
6907c478bd9Sstevel@tonic-gate int rc_local_scope(uint32_t, rc_node_ptr_t *);
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate void rc_node_clear(rc_node_ptr_t *, int);
6937c478bd9Sstevel@tonic-gate void rc_node_ptr_assign(rc_node_ptr_t *, const rc_node_ptr_t *);
6947c478bd9Sstevel@tonic-gate int rc_node_name(rc_node_ptr_t *, char *, size_t, uint32_t, size_t *);
6957c478bd9Sstevel@tonic-gate int rc_node_fmri(rc_node_ptr_t *, char *, size_t, size_t *);
6967c478bd9Sstevel@tonic-gate int rc_node_parent_type(rc_node_ptr_t *, uint32_t *);
6977c478bd9Sstevel@tonic-gate int rc_node_get_child(rc_node_ptr_t *, const char *, uint32_t, rc_node_ptr_t *);
6987c478bd9Sstevel@tonic-gate int rc_node_get_parent(rc_node_ptr_t *, uint32_t, rc_node_ptr_t *);
6997c478bd9Sstevel@tonic-gate int rc_node_get_property_type(rc_node_ptr_t *, rep_protocol_value_type_t *);
7007c478bd9Sstevel@tonic-gate int rc_node_get_property_value(rc_node_ptr_t *,
7017c478bd9Sstevel@tonic-gate     struct rep_protocol_value_response *, size_t *);
7027c478bd9Sstevel@tonic-gate int rc_node_create_child(rc_node_ptr_t *, uint32_t, const char *,
7037c478bd9Sstevel@tonic-gate     rc_node_ptr_t *);
7047c478bd9Sstevel@tonic-gate int rc_node_create_child_pg(rc_node_ptr_t *, uint32_t, const char *,
7057c478bd9Sstevel@tonic-gate     const char *, uint32_t, rc_node_ptr_t *);
7067c478bd9Sstevel@tonic-gate int rc_node_update(rc_node_ptr_t *);
7077c478bd9Sstevel@tonic-gate int rc_node_delete(rc_node_ptr_t *);
7087c478bd9Sstevel@tonic-gate int rc_node_next_snaplevel(rc_node_ptr_t *, rc_node_ptr_t *);
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate int rc_node_setup_iter(rc_node_ptr_t *, rc_node_iter_t **, uint32_t,
7117c478bd9Sstevel@tonic-gate     size_t, const char *);
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate int rc_iter_next(rc_node_iter_t *, rc_node_ptr_t *, uint32_t);
7147c478bd9Sstevel@tonic-gate int rc_iter_next_value(rc_node_iter_t *, struct rep_protocol_value_response *,
7157c478bd9Sstevel@tonic-gate     size_t *, int);
7167c478bd9Sstevel@tonic-gate void rc_iter_destroy(rc_node_iter_t **);
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate int rc_node_setup_tx(rc_node_ptr_t *, rc_node_ptr_t *);
7197c478bd9Sstevel@tonic-gate int rc_tx_commit(rc_node_ptr_t *, const void *, size_t);
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate void rc_pg_notify_init(rc_node_pg_notify_t *);
7227c478bd9Sstevel@tonic-gate int rc_pg_notify_setup(rc_node_pg_notify_t *, rc_node_ptr_t *, int);
7237c478bd9Sstevel@tonic-gate void rc_pg_notify_fini(rc_node_pg_notify_t *);
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate void rc_notify_info_init(rc_notify_info_t *);
7267c478bd9Sstevel@tonic-gate int rc_notify_info_add_name(rc_notify_info_t *, const char *);
7277c478bd9Sstevel@tonic-gate int rc_notify_info_add_type(rc_notify_info_t *, const char *);
7287c478bd9Sstevel@tonic-gate int rc_notify_info_wait(rc_notify_info_t *, rc_node_ptr_t *, char *, size_t);
7297c478bd9Sstevel@tonic-gate void rc_notify_info_fini(rc_notify_info_t *);
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate int rc_snapshot_take_new(rc_node_ptr_t *, const char *,
7327c478bd9Sstevel@tonic-gate     const char *, const char *, rc_node_ptr_t *);
7337c478bd9Sstevel@tonic-gate int rc_snapshot_take_attach(rc_node_ptr_t *, rc_node_ptr_t *);
7347c478bd9Sstevel@tonic-gate int rc_snapshot_attach(rc_node_ptr_t *, rc_node_ptr_t *);
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate /*
7377c478bd9Sstevel@tonic-gate  * file_object.c
7387c478bd9Sstevel@tonic-gate  */
7397c478bd9Sstevel@tonic-gate int object_fill_children(rc_node_t *);
7407c478bd9Sstevel@tonic-gate int object_create(rc_node_t *, uint32_t, const char *, rc_node_t **);
7417c478bd9Sstevel@tonic-gate int object_create_pg(rc_node_t *, uint32_t, const char *, const char *,
7427c478bd9Sstevel@tonic-gate     uint32_t, rc_node_t **);
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate int object_delete(rc_node_t *);
7457c478bd9Sstevel@tonic-gate void object_free_values(const char *, uint32_t, size_t, size_t);
7467c478bd9Sstevel@tonic-gate 
7478918dff3Sjwadams int object_fill_snapshot(rc_snapshot_t *);
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate int object_snapshot_take_new(rc_node_t *, const char *, const char *,
7507c478bd9Sstevel@tonic-gate     const char *, rc_node_t **);
7517c478bd9Sstevel@tonic-gate int object_snapshot_attach(rc_node_lookup_t *, uint32_t *, int);
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate /*
7547c478bd9Sstevel@tonic-gate  * object.c
7557c478bd9Sstevel@tonic-gate  */
7565b7f77adStw21770 int object_tx_commit(rc_node_lookup_t *, tx_commit_data_t *, uint32_t *);
7575b7f77adStw21770 
7585b7f77adStw21770 /* Functions to access transaction commands. */
7595b7f77adStw21770 int tx_cmd_action(tx_commit_data_t *, size_t,
7605b7f77adStw21770     enum rep_protocol_transaction_action *);
7615b7f77adStw21770 size_t tx_cmd_count(tx_commit_data_t *);
7625b7f77adStw21770 int tx_cmd_nvalues(tx_commit_data_t *, size_t, uint32_t *);
7635b7f77adStw21770 int tx_cmd_prop(tx_commit_data_t *, size_t, const char **);
7645b7f77adStw21770 int tx_cmd_prop_type(tx_commit_data_t *, size_t, uint32_t *);
7655b7f77adStw21770 int tx_cmd_value(tx_commit_data_t *, size_t, uint32_t, const char **);
7665b7f77adStw21770 void tx_commit_data_free(tx_commit_data_t *);
7675b7f77adStw21770 int tx_commit_data_new(const void *, size_t, tx_commit_data_t **);
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate /*
7707c478bd9Sstevel@tonic-gate  * snapshot.c
7717c478bd9Sstevel@tonic-gate  */
7727c478bd9Sstevel@tonic-gate int rc_snapshot_get(uint32_t, rc_snapshot_t **);
7737c478bd9Sstevel@tonic-gate void rc_snapshot_rele(rc_snapshot_t *);
7747c478bd9Sstevel@tonic-gate void rc_snaplevel_hold(rc_snaplevel_t *);
7757c478bd9Sstevel@tonic-gate void rc_snaplevel_rele(rc_snaplevel_t *);
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate /*
7787c478bd9Sstevel@tonic-gate  * backend.c
7797c478bd9Sstevel@tonic-gate  */
7807c478bd9Sstevel@tonic-gate int backend_init(const char *, const char *, int);
7816e1d2b42Samaguire boolean_t backend_is_upgraded(backend_tx_t *);
7827c478bd9Sstevel@tonic-gate void backend_fini(void);
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate rep_protocol_responseid_t backend_create_backup(const char *);
785c0889d7aSstevep rep_protocol_responseid_t backend_switch(int);
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate /*
7887c478bd9Sstevel@tonic-gate  * call on any database inconsistency -- cleans up state as best it can,
7897c478bd9Sstevel@tonic-gate  * and exits with a "Database Bad" error code.
7907c478bd9Sstevel@tonic-gate  */
7910b5c9250Shg115875 void backend_panic(const char *, ...) __NORETURN;
7927c478bd9Sstevel@tonic-gate #pragma rarely_called(backend_panic)
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate backend_query_t *backend_query_alloc(void);
7957c478bd9Sstevel@tonic-gate void backend_query_append(backend_query_t *, const char *);
7967c478bd9Sstevel@tonic-gate void backend_query_add(backend_query_t *, const char *, ...);
7977c478bd9Sstevel@tonic-gate void backend_query_free(backend_query_t *);
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate typedef int backend_run_callback_f(void *data, int columns, char **vals,
8007c478bd9Sstevel@tonic-gate     char **names);
8017c478bd9Sstevel@tonic-gate #define	BACKEND_CALLBACK_CONTINUE	0
8027c478bd9Sstevel@tonic-gate #define	BACKEND_CALLBACK_ABORT		1
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate backend_run_callback_f backend_fail_if_seen;	/* aborts TX if called */
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate int backend_run(backend_type_t, backend_query_t *,
8077c478bd9Sstevel@tonic-gate     backend_run_callback_f *, void *);
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate int backend_tx_begin(backend_type_t, backend_tx_t **);
8107c478bd9Sstevel@tonic-gate int backend_tx_begin_ro(backend_type_t, backend_tx_t **);
8117c478bd9Sstevel@tonic-gate void backend_tx_end_ro(backend_tx_t *);
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate enum id_space {
8147c478bd9Sstevel@tonic-gate 	BACKEND_ID_SERVICE_INSTANCE,
8157c478bd9Sstevel@tonic-gate 	BACKEND_ID_PROPERTYGRP,
8167c478bd9Sstevel@tonic-gate 	BACKEND_ID_GENERATION,
8177c478bd9Sstevel@tonic-gate 	BACKEND_ID_PROPERTY,
8187c478bd9Sstevel@tonic-gate 	BACKEND_ID_VALUE,
8197c478bd9Sstevel@tonic-gate 	BACKEND_ID_SNAPNAME,
8207c478bd9Sstevel@tonic-gate 	BACKEND_ID_SNAPSHOT,
8217c478bd9Sstevel@tonic-gate 	BACKEND_ID_SNAPLEVEL,
8227c478bd9Sstevel@tonic-gate 	BACKEND_ID_INVALID	/* always illegal */
8237c478bd9Sstevel@tonic-gate };
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate uint32_t backend_new_id(backend_tx_t *, enum id_space);
8267c478bd9Sstevel@tonic-gate int backend_tx_run_update(backend_tx_t *, const char *, ...);
8277c478bd9Sstevel@tonic-gate int backend_tx_run_update_changed(backend_tx_t *, const char *, ...);
8287c478bd9Sstevel@tonic-gate int backend_tx_run_single_int(backend_tx_t *tx, backend_query_t *q,
8297c478bd9Sstevel@tonic-gate     uint32_t *buf);
8307c478bd9Sstevel@tonic-gate int backend_tx_run(backend_tx_t *, backend_query_t *,
8317c478bd9Sstevel@tonic-gate     backend_run_callback_f *, void *);
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate int backend_tx_commit(backend_tx_t *);
8347c478bd9Sstevel@tonic-gate void backend_tx_rollback(backend_tx_t *);
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate #endif
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate #endif	/* _CONFIGD_H */
841