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