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