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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_CONTRACT_IMPL_H
28 #define	_SYS_CONTRACT_IMPL_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/types.h>
33 #include <sys/list.h>
34 #include <sys/poll.h>
35 #include <sys/condvar.h>
36 #include <sys/contract.h>
37 #include <sys/model.h>
38 #include <sys/cred.h>
39 #include <sys/mutex.h>
40 #include <sys/list.h>
41 #include <sys/avl.h>
42 #include <sys/nvpair.h>
43 #include <sys/time.h>
44 #include <sys/vnode.h>
45 #include <sys/vfs.h>
46 #include <sys/zone.h>
47 #include <sys/project.h>
48 
49 #ifdef	__cplusplus
50 extern "C" {
51 #endif
52 
53 #ifdef _SYSCALL32
54 
55 /*
56  * 32-bit versions of the event and status structures, for use (only)
57  * by the 64-bit kernel.  See sys/contract.h for the normal versions.
58  * Use pack(4) to get offsets and structure size correct on amd64.
59  */
60 
61 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
62 #pragma pack(4)
63 #endif
64 
65 typedef struct ct_event32 {
66 	ctid_t	ctev_id;
67 	uint32_t ctev_pad1;
68 	ctevid_t ctev_evid;
69 	ct_typeid_t ctev_cttype;
70 	uint32_t ctev_flags;
71 	uint32_t ctev_type;
72 	uint32_t ctev_nbytes;
73 	uint32_t ctev_goffset;
74 	uint32_t ctev_pad2;
75 	caddr32_t ctev_buffer;
76 } ct_event32_t;
77 
78 typedef struct ct_status32 {
79 	ctid_t	ctst_id;
80 	zoneid_t ctst_zoneid;
81 	ct_typeid_t ctst_type;
82 	pid_t	ctst_holder;
83 	ctstate_t ctst_state;
84 	int	ctst_nevents;
85 	int	ctst_ntime;
86 	int	ctst_qtime;
87 	uint64_t ctst_nevid;
88 	uint_t	ctst_detail;
89 	uint_t	ctst_nbytes;
90 	uint_t	ctst_critical;
91 	uint_t	ctst_informative;
92 	uint64_t ctst_cookie;
93 	caddr32_t ctst_buffer;
94 } ct_status32_t;
95 
96 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
97 #pragma pack()
98 #endif
99 
100 #endif /* _SYSCALL32 */
101 
102 struct proc;
103 
104 /*
105  * Contract template ops vector
106  */
107 typedef struct ctmplops {
108 	struct ct_template	*(*ctop_dup)(struct ct_template *);
109 	void		(*ctop_free)(struct ct_template *);
110 	int		(*ctop_set)(struct ct_template *, ct_param_t *,
111 			const cred_t *);
112 	int		(*ctop_get)(struct ct_template *, ct_param_t *);
113 	int		(*ctop_create)(struct ct_template *);
114 	uint_t		allevents;
115 } ctmplops_t;
116 
117 /*
118  * Contract template
119  */
120 typedef struct ct_template {
121 	kmutex_t	ctmpl_lock;
122 	ctmplops_t	*ctmpl_ops;
123 	struct ct_type	*ctmpl_type;
124 	void		*ctmpl_data;
125 	uint64_t	ctmpl_cookie;	/* term: contract cookie */
126 	uint_t		ctmpl_ev_crit;	/* term: critical events */
127 	uint_t		ctmpl_ev_info;	/* term: informative events */
128 } ct_template_t;
129 
130 typedef enum ct_listnum {
131 	CTEL_CONTRACT,			/* ../contracts/type/<id>/events */
132 	CTEL_BUNDLE,			/* ../contracts/type/bundle */
133 	CTEL_PBUNDLE,			/* ../contracts/type/pbundle */
134 	CTEL_MAX
135 } ct_listnum_t;
136 
137 typedef enum ctqflags {
138 	CTQ_DEAD = 1,	/* contract explicitly cancelled */
139 	CTQ_REFFED = 2	/* queue is reference counted */
140 } ctqflags_t;
141 
142 /*
143  * Contract event queue
144  */
145 typedef struct ct_equeue {
146 	kmutex_t ctq_lock;
147 	timespec_t ctq_atime;		/* access time */
148 	ct_listnum_t ctq_listno;	/* which list node */
149 	list_t	ctq_events;		/* list of events */
150 	list_t	ctq_listeners;		/* list of all listeners */
151 	list_t	ctq_tail;		/* list of tail listeners */
152 	int	ctq_nlisteners;		/* number of listeners */
153 	int	ctq_nreliable;		/* number of reliable listeners */
154 	int	ctq_ninf;		/* number of informative events */
155 	int	ctq_max;		/* max informative events */
156 	ctqflags_t ctq_flags;		/* queue flags */
157 } ct_equeue_t;
158 
159 typedef struct ct_member {
160 	list_node_t	ctm_node;	/* list membership */
161 	int		ctm_refs;	/* number of references per list */
162 	int		ctm_trimmed;	/* membership has been trimmed */
163 	int		ctm_nreliable;	/* reliable listeners */
164 } ct_member_t;
165 
166 typedef struct ct_kevent {
167 	kmutex_t	cte_lock;
168 	uint64_t	cte_id;		/* event id */
169 	uint_t		cte_type;	/* event type */
170 	int		cte_refs;
171 	ct_member_t	cte_nodes[CTEL_MAX]; /* event queue membership */
172 	int		cte_flags;	/* see above */
173 	nvlist_t 	*cte_data;	/* event data */
174 	nvlist_t 	*cte_gdata;	/* global-zone only data */
175 
176 	struct contract	*cte_contract;	/* contract */
177 } ct_kevent_t;
178 
179 /*
180  * Contract vnode linkage.
181  * Avoid having too much knowledge about the FS.
182  */
183 typedef struct contract_vnode {
184 	list_node_t	ctv_node;
185 	vnode_t		*ctv_vnode;
186 } contract_vnode_t;
187 
188 /*
189  * Contract ops vector
190  *   free - when reference count drops to zero
191  *   abandon - when holding process dies or relinquishes interest
192  *   destroy - when contract is to be completely destroyed
193  *   status - when contractfs needs to return detailed status information
194  */
195 typedef struct contops {
196 	void	(*contop_free)(struct contract *);
197 	void	(*contop_abandon)(struct contract *);
198 	void	(*contop_destroy)(struct contract *);
199 	void	(*contop_status)(struct contract *, zone_t *, int, nvlist_t *,
200 	    void *, model_t);
201 } contops_t;
202 
203 typedef ct_template_t *(ct_f_default_t)(void);
204 
205 /*
206  * Contract type information.
207  */
208 typedef struct ct_type {
209 	uint64_t	ct_type_evid;	/* last event id */
210 	ct_typeid_t	ct_type_index;	/* index in ct_types array */
211 	const char	*ct_type_name;	/* type as a string */
212 	kmutex_t	ct_type_lock;	/* protects ct_type_avl */
213 	avl_tree_t	ct_type_avl;	/* ordered list of type contracts */
214 	timestruc_t	ct_type_timestruc; /* time last contract was written */
215 	ct_equeue_t	ct_type_events;	/* bundle queue */
216 	contops_t	*ct_type_ops;
217 	ct_f_default_t	*ct_type_default; /* creates a fresh template */
218 } ct_type_t;
219 
220 typedef enum ctflags {
221 	CTF_INHERIT = 0x1
222 } ctflags_t;
223 
224 /*
225  * Contract
226  */
227 typedef struct contract {
228 	uint64_t	ct_ref;		/* reference count */
229 	kmutex_t	ct_reflock;	/* reference count lock */
230 	kmutex_t	ct_evtlock;	/* event dispatch lock */
231 
232 					/* Static data */
233 	kproject_t	*ct_proj;	/* project of creator */
234 	uid_t		ct_cuid;	/* uid of contract author */
235 	zoneid_t	ct_zoneid;	/* zoneid of creator */
236 	uint64_t	ct_czuniqid;	/* unique id of creator's zone */
237 	timespec_t	ct_ctime;	/* creation time */
238 	ct_type_t	*ct_type;	/* contract type information */
239 	void		*ct_data;	/* contract type data */
240 	ctid_t		ct_id;		/* contract ID */
241 	uint64_t	ct_cookie;	/* term: contract cookie */
242 	uint_t		ct_ev_crit;	/* term: critical events */
243 	uint_t		ct_ev_info;	/* term: informative events */
244 
245 					/* Protected by other locks */
246 	uint64_t	ct_mzuniqid;	/* unique id of members' zone */
247 	avl_node_t	ct_ctavl;	/* avl membership */
248 	avl_node_t	ct_cttavl;	/* type avl membership */
249 	avl_node_t	ct_ctlist;	/* position in holder's list */
250 
251 	kmutex_t	ct_lock;	/* lock for everything below */
252 	ctstate_t	ct_state;	/* contract's state */
253 	list_t		ct_vnodes;	/* vnodes list */
254 	ctflags_t	ct_flags;	/* contract flags */
255 	ct_equeue_t	ct_events;	/* contract event queue */
256 	struct proc	*ct_owner;	/* contract owner (if owned) */
257 	struct contract	*ct_regent;	/* [prospective] regent contract */
258 	int		ct_evcnt;	/* number of critical events */
259 	ct_kevent_t	*ct_nevent;	/* negotiation event */
260 } contract_t;
261 
262 #define	CTLF_COPYOUT	0x1		/* performing copyout */
263 #define	CTLF_RESET	0x2		/* event pointer reset or moved */
264 #define	CTLF_DEAD	0x4		/* dead listener */
265 #define	CTLF_RELIABLE	0x8		/* reliable listener */
266 #define	CTLF_CRITICAL	0x10		/* waiting for critical event */
267 
268 typedef struct ct_listener {
269 	list_node_t	ctl_allnode;	/* entry in list of all listeners */
270 	list_node_t	ctl_tailnode;	/* entry in list of tail listeners */
271 	ct_equeue_t	*ctl_equeue;	/* queue */
272 	ct_kevent_t	*ctl_position;	/* position in queue */
273 	int		ctl_flags;	/* state flags */
274 	kcondvar_t	ctl_cv;		/* for waiting for an event */
275 	pollhead_t	ctl_pollhead;	/* so we can poll(2) */
276 } ct_listener_t;
277 
278 /*
279  * Contract template interfaces
280  */
281 void ctmpl_free(ct_template_t *);
282 int ctmpl_set(ct_template_t *, ct_param_t *, const cred_t *);
283 int ctmpl_get(ct_template_t *, ct_param_t *);
284 ct_template_t *ctmpl_dup(ct_template_t *);
285 void ctmpl_activate(ct_template_t *);
286 void ctmpl_clear(ct_template_t *);
287 int ctmpl_create(ct_template_t *);
288 
289 /*
290  * Contract functions
291  */
292 void contract_init(void);
293 int contract_abandon(contract_t *, struct proc *, int);
294 int contract_adopt(contract_t *, struct proc *);
295 void contract_destroy(contract_t *);
296 void contract_exit(struct proc *);
297 int contract_ack(contract_t *, uint64_t);
298 
299 /*
300  * Event interfaces
301  */
302 void cte_publish_all(contract_t *, ct_kevent_t *, nvlist_t *, nvlist_t *);
303 void cte_add_listener(ct_equeue_t *, ct_listener_t *);
304 void cte_remove_listener(ct_listener_t *);
305 void cte_reset_listener(ct_listener_t *);
306 int cte_get_event(ct_listener_t *, int, void *, const cred_t *, uint64_t, int);
307 int cte_next_event(ct_listener_t *, uint64_t);
308 int cte_set_reliable(ct_listener_t *, const cred_t *);
309 
310 /*
311  * Contract implementation interfaces
312  */
313 int contract_compar(const void *, const void *);
314 void ctmpl_init(ct_template_t *, ctmplops_t *, ct_type_t *, void *);
315 void ctmpl_copy(ct_template_t *, ct_template_t *);
316 int ctmpl_create_inval(ct_template_t *);
317 int contract_ctor(contract_t *, ct_type_t *, ct_template_t *, void *, ctflags_t,
318     struct proc *, int);
319 void contract_hold(contract_t *);
320 void contract_rele(contract_t *);
321 uint64_t contract_getzuniqid(contract_t *);
322 void contract_setzuniqid(contract_t *, uint64_t);
323 void contract_rele_unlocked(contract_t *);
324 void contract_status_common(contract_t *, zone_t *, void *, model_t);
325 void contract_orphan(contract_t *);
326 ctid_t contract_lookup(uint64_t, ctid_t);
327 ctid_t contract_plookup(struct proc *, ctid_t, uint64_t);
328 contract_t *contract_ptr(id_t, uint64_t);
329 ctid_t contract_max(void);
330 int contract_owned(contract_t *, const cred_t *, int);
331 
332 /*
333  * Type interfaces
334  */
335 extern int ct_ntypes;
336 extern ct_type_t **ct_types;
337 
338 ct_type_t *contract_type_init(ct_typeid_t, const char *, contops_t *,
339     ct_f_default_t *);
340 int contract_type_count(ct_type_t *);
341 ctid_t contract_type_max(ct_type_t *);
342 ctid_t contract_type_lookup(ct_type_t *, uint64_t, ctid_t);
343 contract_t *contract_type_ptr(ct_type_t *, ctid_t, uint64_t);
344 void contract_type_time(ct_type_t *, timestruc_t *);
345 ct_equeue_t *contract_type_bundle(ct_type_t *);
346 ct_equeue_t *contract_type_pbundle(ct_type_t *, struct proc *);
347 
348 /*
349  * FS interfaces
350  */
351 vnode_t *contract_vnode_get(contract_t *, vfs_t *);
352 void contract_vnode_set(contract_t *, contract_vnode_t *, vnode_t *);
353 int contract_vnode_clear(contract_t *, contract_vnode_t *);
354 
355 #ifdef	__cplusplus
356 }
357 #endif
358 
359 #endif	/* _SYS_CONTRACT_IMPL_H */
360