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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_CONTRACT_IMPL_H
27 #define _SYS_CONTRACT_IMPL_H
29 #include <sys/types.h>
32 #include <sys/condvar.h>
33 #include <sys/contract.h>
34 #include <sys/model.h>
36 #include <sys/mutex.h>
39 #include <sys/nvpair.h>
41 #include <sys/vnode.h>
44 #include <sys/project.h>
52 #define CT_DEBUG(args) if (ct_debug) cmn_err args
57 * 32-bit versions of the event, status and parameter structures, for use
58 * (only) by the 64-bit kernel. See sys/contract.h for the normal versions.
59 * Use pack(4) to get offsets and structure size correct on amd64.
62 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
66 typedef struct ct_event32
{
70 ct_typeid_t ctev_cttype
;
74 uint32_t ctev_goffset
;
76 caddr32_t ctev_buffer
;
79 typedef struct ct_status32
{
82 ct_typeid_t ctst_type
;
92 uint_t ctst_informative
;
94 caddr32_t ctst_buffer
;
97 typedef struct ct_param32
{
100 caddr32_t ctpm_value
;
103 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
107 #endif /* _SYSCALL32 */
110 * in kernel version of parameter structure.
112 typedef struct ct_kparam
{
113 ct_param_t param
; /* copy of user ct_param_t */
114 void *ctpm_kbuf
; /* kernel buffer for parameter value */
115 uint32_t ret_size
; /* parameter value size for copyout */
121 * Contract template ops vector
123 typedef struct ctmplops
{
124 struct ct_template
*(*ctop_dup
)(struct ct_template
*);
125 void (*ctop_free
)(struct ct_template
*);
126 int (*ctop_set
)(struct ct_template
*, ct_kparam_t
*,
128 int (*ctop_get
)(struct ct_template
*, ct_kparam_t
*);
129 int (*ctop_create
)(struct ct_template
*, ctid_t
*);
136 typedef struct ct_template
{
138 ctmplops_t
*ctmpl_ops
;
139 struct ct_type
*ctmpl_type
;
141 uint64_t ctmpl_cookie
; /* term: contract cookie */
142 uint_t ctmpl_ev_crit
; /* term: critical events */
143 uint_t ctmpl_ev_info
; /* term: informative events */
147 typedef enum ct_listnum
{
148 CTEL_CONTRACT
, /* ../contracts/type/<id>/events */
149 CTEL_BUNDLE
, /* ../contracts/type/bundle */
150 CTEL_PBUNDLE
, /* ../contracts/type/pbundle */
154 typedef enum ctqflags
{
155 CTQ_DEAD
= 1, /* contract explicitly cancelled */
156 CTQ_REFFED
= 2 /* queue is reference counted */
159 typedef enum ct_ack
{
160 CT_ACK
= 1, /* accept break */
161 CT_NACK
, /* disallow break */
162 CT_NONE
/* no matching contracts */
166 * Contract event queue
168 typedef struct ct_equeue
{
170 timespec_t ctq_atime
; /* access time */
171 ct_listnum_t ctq_listno
; /* which list node */
172 list_t ctq_events
; /* list of events */
173 list_t ctq_listeners
; /* list of all listeners */
174 list_t ctq_tail
; /* list of tail listeners */
175 int ctq_nlisteners
; /* number of listeners */
176 int ctq_nreliable
; /* number of reliable listeners */
177 int ctq_ninf
; /* number of informative events */
178 int ctq_max
; /* max informative events */
179 ctqflags_t ctq_flags
; /* queue flags */
182 typedef struct ct_member
{
183 list_node_t ctm_node
; /* list membership */
184 int ctm_refs
; /* number of references per list */
185 int ctm_trimmed
; /* membership has been trimmed */
186 int ctm_nreliable
; /* reliable listeners */
189 typedef struct ct_kevent
{
191 uint64_t cte_id
; /* event id */
192 uint_t cte_type
; /* event type */
194 ct_member_t cte_nodes
[CTEL_MAX
]; /* event queue membership */
195 int cte_flags
; /* see above */
196 nvlist_t
*cte_data
; /* event data */
197 nvlist_t
*cte_gdata
; /* global-zone only data */
199 struct contract
*cte_contract
; /* contract */
203 * Contract vnode linkage.
204 * Avoid having too much knowledge about the FS.
206 typedef struct contract_vnode
{
207 list_node_t ctv_node
;
212 * Contract ops vector
213 * free - when reference count drops to zero
214 * abandon - when holding process dies or relinquishes interest
215 * destroy - when contract is to be completely destroyed
216 * status - when contractfs needs to return detailed status information
218 typedef struct contops
{
219 void (*contop_free
)(struct contract
*);
220 void (*contop_abandon
)(struct contract
*);
221 void (*contop_destroy
)(struct contract
*);
222 void (*contop_status
)(struct contract
*, zone_t
*, int, nvlist_t
*,
224 int (*contop_ack
)(struct contract
*, uint_t evtype
,
226 int (*contop_nack
)(struct contract
*, uint_t evtype
,
228 int (*contop_qack
)(struct contract
*, uint_t
, uint64_t);
229 int (*contop_newct
)(struct contract
*);
232 typedef ct_template_t
*(ct_f_default_t
)(void);
235 * Contract type information.
237 typedef struct ct_type
{
238 uint64_t ct_type_evid
; /* last event id */
239 ct_typeid_t ct_type_index
; /* index in ct_types array */
240 const char *ct_type_name
; /* type as a string */
241 kmutex_t ct_type_lock
; /* protects ct_type_avl */
242 avl_tree_t ct_type_avl
; /* ordered list of type contracts */
243 timestruc_t ct_type_timestruc
; /* time last contract was written */
244 ct_equeue_t ct_type_events
; /* bundle queue */
245 contops_t
*ct_type_ops
;
246 ct_f_default_t
*ct_type_default
; /* creates a fresh template */
249 typedef enum ctflags
{
253 typedef struct ct_time
{
254 long ctm_total
; /* Total time allowed for event */
255 clock_t ctm_start
; /* starting lbolt for event */
261 typedef struct contract
{
262 uint64_t ct_ref
; /* reference count */
263 kmutex_t ct_reflock
; /* reference count lock */
264 kmutex_t ct_evtlock
; /* event dispatch lock */
267 kproject_t
*ct_proj
; /* project of creator */
268 uid_t ct_cuid
; /* uid of contract author */
269 zoneid_t ct_zoneid
; /* zoneid of creator */
270 uint64_t ct_czuniqid
; /* unique id of creator's zone */
271 timespec_t ct_ctime
; /* creation time */
272 ct_type_t
*ct_type
; /* contract type information */
273 void *ct_data
; /* contract type data */
274 ctid_t ct_id
; /* contract ID */
275 uint64_t ct_cookie
; /* term: contract cookie */
276 uint_t ct_ev_crit
; /* term: critical events */
277 uint_t ct_ev_info
; /* term: informative events */
279 /* Protected by other locks */
280 uint64_t ct_mzuniqid
; /* unique id of members' zone */
281 avl_node_t ct_ctavl
; /* avl membership */
282 avl_node_t ct_cttavl
; /* type avl membership */
283 avl_node_t ct_ctlist
; /* position in holder's list */
285 kmutex_t ct_lock
; /* lock for everything below */
286 ctstate_t ct_state
; /* contract's state */
287 list_t ct_vnodes
; /* vnodes list */
288 ctflags_t ct_flags
; /* contract flags */
289 ct_equeue_t ct_events
; /* contract event queue */
290 struct proc
*ct_owner
; /* contract owner (if owned) */
291 struct contract
*ct_regent
; /* [prospective] regent contract */
292 int ct_evcnt
; /* number of critical events */
293 ct_kevent_t
*ct_nevent
; /* negotiation event */
294 ct_time_t ct_ntime
; /* negotiation time tracker */
295 ct_time_t ct_qtime
; /* quantum time tracker */
298 #define CTLF_COPYOUT 0x1 /* performing copyout */
299 #define CTLF_RESET 0x2 /* event pointer reset or moved */
300 #define CTLF_DEAD 0x4 /* dead listener */
301 #define CTLF_RELIABLE 0x8 /* reliable listener */
302 #define CTLF_CRITICAL 0x10 /* waiting for critical event */
304 typedef struct ct_listener
{
305 list_node_t ctl_allnode
; /* entry in list of all listeners */
306 list_node_t ctl_tailnode
; /* entry in list of tail listeners */
307 ct_equeue_t
*ctl_equeue
; /* queue */
308 ct_kevent_t
*ctl_position
; /* position in queue */
309 int ctl_flags
; /* state flags */
310 kcondvar_t ctl_cv
; /* for waiting for an event */
311 pollhead_t ctl_pollhead
; /* so we can poll(2) */
315 * Contract template interfaces
317 void ctmpl_free(ct_template_t
*);
318 int ctmpl_set(ct_template_t
*, ct_kparam_t
*, const cred_t
*);
319 int ctmpl_get(ct_template_t
*, ct_kparam_t
*);
320 ct_template_t
*ctmpl_dup(ct_template_t
*);
321 void ctmpl_activate(ct_template_t
*);
322 void ctmpl_clear(ct_template_t
*);
323 int ctmpl_create(ct_template_t
*, ctid_t
*);
326 * Contract parameter functions
328 int ctparam_copyin(const void *, ct_kparam_t
*, int, int);
329 int ctparam_copyout(ct_kparam_t
*, void *, int);
334 void contract_init(void);
335 int contract_abandon(contract_t
*, struct proc
*, int);
336 int contract_adopt(contract_t
*, struct proc
*);
337 void contract_destroy(contract_t
*);
338 void contract_exit(struct proc
*);
339 int contract_ack(contract_t
*ct
, uint64_t evid
, int cmd
);
340 int contract_qack(contract_t
*ct
, uint64_t evid
);
341 int contract_newct(contract_t
*ct
);
346 uint64_t cte_publish_all(contract_t
*, ct_kevent_t
*, nvlist_t
*, nvlist_t
*);
347 void cte_add_listener(ct_equeue_t
*, ct_listener_t
*);
348 void cte_remove_listener(ct_listener_t
*);
349 void cte_reset_listener(ct_listener_t
*);
350 int cte_get_event(ct_listener_t
*, int, void *, const cred_t
*, uint64_t, int);
351 int cte_next_event(ct_listener_t
*, uint64_t);
352 int cte_set_reliable(ct_listener_t
*, const cred_t
*);
355 * Contract implementation interfaces
357 int contract_compar(const void *, const void *);
358 void ctmpl_init(ct_template_t
*, ctmplops_t
*, ct_type_t
*, void *);
359 void ctmpl_copy(ct_template_t
*, ct_template_t
*);
360 int ctmpl_create_inval(ct_template_t
*, ctid_t
*);
361 int contract_ctor(contract_t
*, ct_type_t
*, ct_template_t
*, void *, ctflags_t
,
363 void contract_hold(contract_t
*);
364 void contract_rele(contract_t
*);
365 uint64_t contract_getzuniqid(contract_t
*);
366 void contract_setzuniqid(contract_t
*, uint64_t);
367 void contract_rele_unlocked(contract_t
*);
368 void contract_status_common(contract_t
*, zone_t
*, void *, model_t
);
369 void contract_orphan(contract_t
*);
370 ctid_t
contract_lookup(uint64_t, ctid_t
);
371 ctid_t
contract_plookup(struct proc
*, ctid_t
, uint64_t);
372 contract_t
*contract_ptr(id_t
, uint64_t);
373 ctid_t
contract_max(void);
374 int contract_owned(contract_t
*, const cred_t
*, int);
379 extern int ct_ntypes
;
380 extern ct_type_t
**ct_types
;
382 ct_type_t
*contract_type_init(ct_typeid_t
, const char *, contops_t
*,
384 int contract_type_count(ct_type_t
*);
385 ctid_t
contract_type_max(ct_type_t
*);
386 ctid_t
contract_type_lookup(ct_type_t
*, uint64_t, ctid_t
);
387 contract_t
*contract_type_ptr(ct_type_t
*, ctid_t
, uint64_t);
388 void contract_type_time(ct_type_t
*, timestruc_t
*);
389 ct_equeue_t
*contract_type_bundle(ct_type_t
*);
390 ct_equeue_t
*contract_type_pbundle(ct_type_t
*, struct proc
*);
395 vnode_t
*contract_vnode_get(contract_t
*, vfs_t
*);
396 void contract_vnode_set(contract_t
*, contract_vnode_t
*, vnode_t
*);
397 int contract_vnode_clear(contract_t
*, contract_vnode_t
*);
402 int contract_ack_inval(contract_t
*, uint_t
, uint64_t);
403 int contract_qack_inval(contract_t
*, uint_t
, uint64_t);
404 int contract_qack_notsup(contract_t
*, uint_t
, uint64_t);
410 #endif /* _SYS_CONTRACT_IMPL_H */