#ifndef _SYS_CONTRACT_IMPL_H
#define _SYS_CONTRACT_IMPL_H
#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
extern int ct_debug;
#define CT_DEBUG(args) if (ct_debug) cmn_err args
#ifdef _SYSCALL32
#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;
typedef struct ct_param32 {
uint32_t ctpm_id;
uint32_t ctpm_size;
caddr32_t ctpm_value;
} ct_param32_t;
#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif
#endif
typedef struct ct_kparam {
ct_param_t param;
void *ctpm_kbuf;
uint32_t ret_size;
} ct_kparam_t;
struct proc;
typedef struct ctmplops {
struct ct_template *(*ctop_dup)(struct ct_template *);
void (*ctop_free)(struct ct_template *);
int (*ctop_set)(struct ct_template *, ct_kparam_t *,
const cred_t *);
int (*ctop_get)(struct ct_template *, ct_kparam_t *);
int (*ctop_create)(struct ct_template *, ctid_t *);
uint_t allevents;
} ctmplops_t;
typedef struct ct_template {
kmutex_t ctmpl_lock;
ctmplops_t *ctmpl_ops;
struct ct_type *ctmpl_type;
void *ctmpl_data;
uint64_t ctmpl_cookie;
uint_t ctmpl_ev_crit;
uint_t ctmpl_ev_info;
} ct_template_t;
typedef enum ct_listnum {
CTEL_CONTRACT,
CTEL_BUNDLE,
CTEL_PBUNDLE,
CTEL_MAX
} ct_listnum_t;
typedef enum ctqflags {
CTQ_DEAD = 1,
CTQ_REFFED = 2
} ctqflags_t;
typedef enum ct_ack {
CT_ACK = 1,
CT_NACK,
CT_NONE
} ct_ack_t;
typedef struct ct_equeue {
kmutex_t ctq_lock;
timespec_t ctq_atime;
ct_listnum_t ctq_listno;
list_t ctq_events;
list_t ctq_listeners;
list_t ctq_tail;
int ctq_nlisteners;
int ctq_nreliable;
int ctq_ninf;
int ctq_max;
ctqflags_t ctq_flags;
} ct_equeue_t;
typedef struct ct_member {
list_node_t ctm_node;
int ctm_refs;
int ctm_trimmed;
int ctm_nreliable;
} ct_member_t;
typedef struct ct_kevent {
kmutex_t cte_lock;
uint64_t cte_id;
uint_t cte_type;
int cte_refs;
ct_member_t cte_nodes[CTEL_MAX];
int cte_flags;
nvlist_t *cte_data;
nvlist_t *cte_gdata;
struct contract *cte_contract;
} ct_kevent_t;
typedef struct contract_vnode {
list_node_t ctv_node;
vnode_t *ctv_vnode;
} contract_vnode_t;
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);
int (*contop_ack)(struct contract *, uint_t evtype,
uint64_t evid);
int (*contop_nack)(struct contract *, uint_t evtype,
uint64_t evid);
int (*contop_qack)(struct contract *, uint_t, uint64_t);
int (*contop_newct)(struct contract *);
} contops_t;
typedef ct_template_t *(ct_f_default_t)(void);
typedef struct ct_type {
uint64_t ct_type_evid;
ct_typeid_t ct_type_index;
const char *ct_type_name;
kmutex_t ct_type_lock;
avl_tree_t ct_type_avl;
timestruc_t ct_type_timestruc;
ct_equeue_t ct_type_events;
contops_t *ct_type_ops;
ct_f_default_t *ct_type_default;
} ct_type_t;
typedef enum ctflags {
CTF_INHERIT = 0x1
} ctflags_t;
typedef struct ct_time {
long ctm_total;
clock_t ctm_start;
} ct_time_t;
typedef struct contract {
uint64_t ct_ref;
kmutex_t ct_reflock;
kmutex_t ct_evtlock;
kproject_t *ct_proj;
uid_t ct_cuid;
zoneid_t ct_zoneid;
uint64_t ct_czuniqid;
timespec_t ct_ctime;
ct_type_t *ct_type;
void *ct_data;
ctid_t ct_id;
uint64_t ct_cookie;
uint_t ct_ev_crit;
uint_t ct_ev_info;
uint64_t ct_mzuniqid;
avl_node_t ct_ctavl;
avl_node_t ct_cttavl;
avl_node_t ct_ctlist;
kmutex_t ct_lock;
ctstate_t ct_state;
list_t ct_vnodes;
ctflags_t ct_flags;
ct_equeue_t ct_events;
struct proc *ct_owner;
struct contract *ct_regent;
int ct_evcnt;
ct_kevent_t *ct_nevent;
ct_time_t ct_ntime;
ct_time_t ct_qtime;
} contract_t;
#define CTLF_COPYOUT 0x1
#define CTLF_RESET 0x2
#define CTLF_DEAD 0x4
#define CTLF_RELIABLE 0x8
#define CTLF_CRITICAL 0x10
typedef struct ct_listener {
list_node_t ctl_allnode;
list_node_t ctl_tailnode;
ct_equeue_t *ctl_equeue;
ct_kevent_t *ctl_position;
int ctl_flags;
kcondvar_t ctl_cv;
pollhead_t ctl_pollhead;
} ct_listener_t;
void ctmpl_free(ct_template_t *);
int ctmpl_set(ct_template_t *, ct_kparam_t *, const cred_t *);
int ctmpl_get(ct_template_t *, ct_kparam_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 *, ctid_t *);
int ctparam_copyin(const void *, ct_kparam_t *, int, int);
int ctparam_copyout(ct_kparam_t *, void *, int);
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 *ct, uint64_t evid, int cmd);
int contract_qack(contract_t *ct, uint64_t evid);
int contract_newct(contract_t *ct);
uint64_t 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 *);
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 *, ctid_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);
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 *);
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 *);
int contract_ack_inval(contract_t *, uint_t, uint64_t);
int contract_qack_inval(contract_t *, uint_t, uint64_t);
int contract_qack_notsup(contract_t *, uint_t, uint64_t);
#ifdef __cplusplus
}
#endif
#endif