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