summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/contract_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys/contract_impl.h')
-rw-r--r--usr/src/uts/common/sys/contract_impl.h359
1 files changed, 359 insertions, 0 deletions
diff --git a/usr/src/uts/common/sys/contract_impl.h b/usr/src/uts/common/sys/contract_impl.h
new file mode 100644
index 0000000000..c45cf06e60
--- /dev/null
+++ b/usr/src/uts/common/sys/contract_impl.h
@@ -0,0 +1,359 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_CONTRACT_IMPL_H
+#define _SYS_CONTRACT_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/list.h>
+#include <sys/poll.h>
+#include <sys/condvar.h>
+#include <sys/contract.h>
+#include <sys/model.h>
+#include <sys/cred.h>
+#include <sys/mutex.h>
+#include <sys/list.h>
+#include <sys/avl.h>
+#include <sys/nvpair.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
+#include <sys/vfs.h>
+#include <sys/zone.h>
+#include <sys/project.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _SYSCALL32
+
+/*
+ * 32-bit versions of the event and status structures, for use (only)
+ * by the 64-bit kernel. See sys/contract.h for the normal versions.
+ * Use pack(4) to get offsets and structure size correct on amd64.
+ */
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+typedef struct ct_event32 {
+ ctid_t ctev_id;
+ uint32_t ctev_pad1;
+ ctevid_t ctev_evid;
+ ct_typeid_t ctev_cttype;
+ uint32_t ctev_flags;
+ uint32_t ctev_type;
+ uint32_t ctev_nbytes;
+ uint32_t ctev_goffset;
+ uint32_t ctev_pad2;
+ caddr32_t ctev_buffer;
+} ct_event32_t;
+
+typedef struct ct_status32 {
+ ctid_t ctst_id;
+ zoneid_t ctst_zoneid;
+ ct_typeid_t ctst_type;
+ pid_t ctst_holder;
+ ctstate_t ctst_state;
+ int ctst_nevents;
+ int ctst_ntime;
+ int ctst_qtime;
+ uint64_t ctst_nevid;
+ uint_t ctst_detail;
+ uint_t ctst_nbytes;
+ uint_t ctst_critical;
+ uint_t ctst_informative;
+ uint64_t ctst_cookie;
+ caddr32_t ctst_buffer;
+} ct_status32_t;
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif
+
+#endif /* _SYSCALL32 */
+
+struct proc;
+
+/*
+ * Contract template ops vector
+ */
+typedef struct ctmplops {
+ struct ct_template *(*ctop_dup)(struct ct_template *);
+ void (*ctop_free)(struct ct_template *);
+ int (*ctop_set)(struct ct_template *, ct_param_t *,
+ const cred_t *);
+ int (*ctop_get)(struct ct_template *, ct_param_t *);
+ int (*ctop_create)(struct ct_template *);
+ uint_t allevents;
+} ctmplops_t;
+
+/*
+ * Contract template
+ */
+typedef struct ct_template {
+ kmutex_t ctmpl_lock;
+ ctmplops_t *ctmpl_ops;
+ struct ct_type *ctmpl_type;
+ void *ctmpl_data;
+ uint64_t ctmpl_cookie; /* term: contract cookie */
+ uint_t ctmpl_ev_crit; /* term: critical events */
+ uint_t ctmpl_ev_info; /* term: informative events */
+} ct_template_t;
+
+typedef enum ct_listnum {
+ CTEL_CONTRACT, /* ../contracts/type/<id>/events */
+ CTEL_BUNDLE, /* ../contracts/type/bundle */
+ CTEL_PBUNDLE, /* ../contracts/type/pbundle */
+ CTEL_MAX
+} ct_listnum_t;
+
+typedef enum ctqflags {
+ CTQ_DEAD = 1, /* contract explicitly cancelled */
+ CTQ_REFFED = 2 /* queue is reference counted */
+} ctqflags_t;
+
+/*
+ * Contract event queue
+ */
+typedef struct ct_equeue {
+ kmutex_t ctq_lock;
+ timespec_t ctq_atime; /* access time */
+ ct_listnum_t ctq_listno; /* which list node */
+ list_t ctq_events; /* list of events */
+ list_t ctq_listeners; /* list of all listeners */
+ list_t ctq_tail; /* list of tail listeners */
+ int ctq_nlisteners; /* number of listeners */
+ int ctq_nreliable; /* number of reliable listeners */
+ int ctq_ninf; /* number of informative events */
+ int ctq_max; /* max informative events */
+ ctqflags_t ctq_flags; /* queue flags */
+} ct_equeue_t;
+
+typedef struct ct_member {
+ list_node_t ctm_node; /* list membership */
+ int ctm_refs; /* number of references per list */
+ int ctm_trimmed; /* membership has been trimmed */
+ int ctm_nreliable; /* reliable listeners */
+} ct_member_t;
+
+typedef struct ct_kevent {
+ kmutex_t cte_lock;
+ uint64_t cte_id; /* event id */
+ uint_t cte_type; /* event type */
+ int cte_refs;
+ ct_member_t cte_nodes[CTEL_MAX]; /* event queue membership */
+ int cte_flags; /* see above */
+ nvlist_t *cte_data; /* event data */
+ nvlist_t *cte_gdata; /* global-zone only data */
+
+ struct contract *cte_contract; /* contract */
+} ct_kevent_t;
+
+/*
+ * Contract vnode linkage.
+ * Avoid having too much knowledge about the FS.
+ */
+typedef struct contract_vnode {
+ list_node_t ctv_node;
+ vnode_t *ctv_vnode;
+} contract_vnode_t;
+
+/*
+ * Contract ops vector
+ * free - when reference count drops to zero
+ * abandon - when holding process dies or relinquishes interest
+ * destroy - when contract is to be completely destroyed
+ * status - when contractfs needs to return detailed status information
+ */
+typedef struct contops {
+ void (*contop_free)(struct contract *);
+ void (*contop_abandon)(struct contract *);
+ void (*contop_destroy)(struct contract *);
+ void (*contop_status)(struct contract *, zone_t *, int, nvlist_t *,
+ void *, model_t);
+} contops_t;
+
+typedef ct_template_t *(ct_f_default_t)(void);
+
+/*
+ * Contract type information.
+ */
+typedef struct ct_type {
+ uint64_t ct_type_evid; /* last event id */
+ ct_typeid_t ct_type_index; /* index in ct_types array */
+ const char *ct_type_name; /* type as a string */
+ kmutex_t ct_type_lock; /* protects ct_type_avl */
+ avl_tree_t ct_type_avl; /* ordered list of type contracts */
+ timestruc_t ct_type_timestruc; /* time last contract was written */
+ ct_equeue_t ct_type_events; /* bundle queue */
+ contops_t *ct_type_ops;
+ ct_f_default_t *ct_type_default; /* creates a fresh template */
+} ct_type_t;
+
+typedef enum ctflags {
+ CTF_INHERIT = 0x1
+} ctflags_t;
+
+/*
+ * Contract
+ */
+typedef struct contract {
+ uint64_t ct_ref; /* reference count */
+ kmutex_t ct_reflock; /* reference count lock */
+ kmutex_t ct_evtlock; /* event dispatch lock */
+
+ /* Static data */
+ kproject_t *ct_proj; /* project of creator */
+ uid_t ct_cuid; /* uid of contract author */
+ zoneid_t ct_zoneid; /* zoneid of creator */
+ uint64_t ct_czuniqid; /* unique id of creator's zone */
+ timespec_t ct_ctime; /* creation time */
+ ct_type_t *ct_type; /* contract type information */
+ void *ct_data; /* contract type data */
+ ctid_t ct_id; /* contract ID */
+ uint64_t ct_cookie; /* term: contract cookie */
+ uint_t ct_ev_crit; /* term: critical events */
+ uint_t ct_ev_info; /* term: informative events */
+
+ /* Protected by other locks */
+ uint64_t ct_mzuniqid; /* unique id of members' zone */
+ avl_node_t ct_ctavl; /* avl membership */
+ avl_node_t ct_cttavl; /* type avl membership */
+ avl_node_t ct_ctlist; /* position in holder's list */
+
+ kmutex_t ct_lock; /* lock for everything below */
+ ctstate_t ct_state; /* contract's state */
+ list_t ct_vnodes; /* vnodes list */
+ ctflags_t ct_flags; /* contract flags */
+ ct_equeue_t ct_events; /* contract event queue */
+ struct proc *ct_owner; /* contract owner (if owned) */
+ struct contract *ct_regent; /* [prospective] regent contract */
+ int ct_evcnt; /* number of critical events */
+ ct_kevent_t *ct_nevent; /* negotiation event */
+} contract_t;
+
+#define CTLF_COPYOUT 0x1 /* performing copyout */
+#define CTLF_RESET 0x2 /* event pointer reset or moved */
+#define CTLF_DEAD 0x4 /* dead listener */
+#define CTLF_RELIABLE 0x8 /* reliable listener */
+#define CTLF_CRITICAL 0x10 /* waiting for critical event */
+
+typedef struct ct_listener {
+ list_node_t ctl_allnode; /* entry in list of all listeners */
+ list_node_t ctl_tailnode; /* entry in list of tail listeners */
+ ct_equeue_t *ctl_equeue; /* queue */
+ ct_kevent_t *ctl_position; /* position in queue */
+ int ctl_flags; /* state flags */
+ kcondvar_t ctl_cv; /* for waiting for an event */
+ pollhead_t ctl_pollhead; /* so we can poll(2) */
+} ct_listener_t;
+
+/*
+ * Contract template interfaces
+ */
+void ctmpl_free(ct_template_t *);
+int ctmpl_set(ct_template_t *, ct_param_t *, const cred_t *);
+int ctmpl_get(ct_template_t *, ct_param_t *);
+ct_template_t *ctmpl_dup(ct_template_t *);
+void ctmpl_activate(ct_template_t *);
+void ctmpl_clear(ct_template_t *);
+int ctmpl_create(ct_template_t *);
+
+/*
+ * Contract functions
+ */
+void contract_init(void);
+int contract_abandon(contract_t *, struct proc *, int);
+int contract_adopt(contract_t *, struct proc *);
+void contract_destroy(contract_t *);
+void contract_exit(struct proc *);
+int contract_ack(contract_t *, uint64_t);
+
+/*
+ * Event interfaces
+ */
+void cte_publish_all(contract_t *, ct_kevent_t *, nvlist_t *, nvlist_t *);
+void cte_add_listener(ct_equeue_t *, ct_listener_t *);
+void cte_remove_listener(ct_listener_t *);
+void cte_reset_listener(ct_listener_t *);
+int cte_get_event(ct_listener_t *, int, void *, const cred_t *, uint64_t, int);
+int cte_next_event(ct_listener_t *, uint64_t);
+int cte_set_reliable(ct_listener_t *, const cred_t *);
+
+/*
+ * Contract implementation interfaces
+ */
+int contract_compar(const void *, const void *);
+void ctmpl_init(ct_template_t *, ctmplops_t *, ct_type_t *, void *);
+void ctmpl_copy(ct_template_t *, ct_template_t *);
+int ctmpl_create_inval(ct_template_t *);
+int contract_ctor(contract_t *, ct_type_t *, ct_template_t *, void *, ctflags_t,
+ struct proc *, int);
+void contract_hold(contract_t *);
+void contract_rele(contract_t *);
+uint64_t contract_getzuniqid(contract_t *);
+void contract_setzuniqid(contract_t *, uint64_t);
+void contract_rele_unlocked(contract_t *);
+void contract_status_common(contract_t *, zone_t *, void *, model_t);
+void contract_orphan(contract_t *);
+ctid_t contract_lookup(uint64_t, ctid_t);
+ctid_t contract_plookup(struct proc *, ctid_t, uint64_t);
+contract_t *contract_ptr(id_t, uint64_t);
+ctid_t contract_max(void);
+int contract_owned(contract_t *, const cred_t *, int);
+
+/*
+ * Type interfaces
+ */
+extern int ct_ntypes;
+extern ct_type_t **ct_types;
+
+ct_type_t *contract_type_init(ct_typeid_t, const char *, contops_t *,
+ ct_f_default_t *);
+int contract_type_count(ct_type_t *);
+ctid_t contract_type_max(ct_type_t *);
+ctid_t contract_type_lookup(ct_type_t *, uint64_t, ctid_t);
+contract_t *contract_type_ptr(ct_type_t *, ctid_t, uint64_t);
+void contract_type_time(ct_type_t *, timestruc_t *);
+ct_equeue_t *contract_type_bundle(ct_type_t *);
+ct_equeue_t *contract_type_pbundle(ct_type_t *, struct proc *);
+
+/*
+ * FS interfaces
+ */
+vnode_t *contract_vnode_get(contract_t *, vfs_t *);
+void contract_vnode_set(contract_t *, contract_vnode_t *, vnode_t *);
+int contract_vnode_clear(contract_t *, contract_vnode_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_CONTRACT_IMPL_H */