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