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 (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #ifndef _SYS_RCTL_H 26 #define _SYS_RCTL_H 27 28 #include <sys/kmem.h> 29 #include <sys/resource.h> 30 #include <sys/types.h> 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * Available local actions and flags. 38 */ 39 #define RCTL_LOCAL_NOACTION 0x00000000 40 #define RCTL_LOCAL_SIGNAL 0x00000001 41 #define RCTL_LOCAL_DENY 0x00000002 42 43 #define RCTL_LOCAL_MAXIMAL 0x80000000 44 #define RCTL_LOCAL_PROJDB 0x40000000 45 46 #define RCTL_LOCAL_ACTION_MASK 0xffff0000 47 #define RCTL_LOCAL_MASK 0xc0000003 48 49 /* 50 * Available global actions and flags. 51 */ 52 #define RCTL_GLOBAL_NOACTION 0x00000000 53 #define RCTL_GLOBAL_SYSLOG 0x00000001 54 55 #define RCTL_GLOBAL_NOBASIC 0x80000000 56 #define RCTL_GLOBAL_LOWERABLE 0x40000000 57 #define RCTL_GLOBAL_DENY_ALWAYS 0x20000000 58 #define RCTL_GLOBAL_DENY_NEVER 0x10000000 59 #define RCTL_GLOBAL_FILE_SIZE 0x08000000 60 #define RCTL_GLOBAL_CPU_TIME 0x04000000 61 #define RCTL_GLOBAL_SIGNAL_NEVER 0x02000000 62 #define RCTL_GLOBAL_NOLOCALACTION RCTL_GLOBAL_SIGNAL_NEVER 63 #define RCTL_GLOBAL_INFINITE 0x01000000 64 #define RCTL_GLOBAL_UNOBSERVABLE 0x00800000 65 #define RCTL_GLOBAL_SYSLOG_NEVER 0x00080000 66 67 #define RCTL_GLOBAL_BYTES 0x00400000 68 #define RCTL_GLOBAL_SECONDS 0x00200000 69 #define RCTL_GLOBAL_COUNT 0x00100000 70 71 #define RCTL_GLOBAL_ACTION_MASK 0xffff0000 72 #define RCTL_GLOBAL_MASK 0xfff80001 73 74 /* 75 * getrctl(2) flag values 76 */ 77 #define RCTL_FIRST 0x00000000 78 #define RCTL_NEXT 0x00000001 79 #define RCTL_USAGE 0x00000002 80 81 /* 82 * setrctl(2) flag values 83 */ 84 85 #define RCTL_INSERT 0x00000000 86 #define RCTL_DELETE 0x00000001 87 #define RCTL_REPLACE 0x00000002 88 89 #define RCTL_USE_RECIPIENT_PID 0x10000000 90 91 #define RCTLSYS_ACTION_MASK 0xffff0000 92 #define RCTLSYS_MASK 0x10000003 93 94 /* 95 * rctl_priv_t: rctl privilege defined values 96 * A large amount of space has been deliberately left between these privileges 97 * to permit future enrichment of the control privilege value. 98 */ 99 #define RCPRIV_BASIC 0x01000000 100 #define RCPRIV_PRIVILEGED 0x04000000 101 #define RCPRIV_SYSTEM 0x07000000 102 103 typedef u_longlong_t rctl_qty_t; /* resource control numerical values */ 104 typedef int rctl_priv_t; 105 106 typedef struct rctlblk rctlblk_t; 107 108 extern int setrctl(const char *, rctlblk_t *, rctlblk_t *, int); 109 extern int getrctl(const char *, rctlblk_t *, rctlblk_t *, int); 110 111 typedef enum { 112 RCENTITY_PROCESS, 113 RCENTITY_TASK, 114 RCENTITY_PROJECT, 115 RCENTITY_ZONE 116 } rctl_entity_t; 117 #define RC_MAX_ENTITY RCENTITY_ZONE 118 119 #ifndef _KERNEL 120 121 typedef struct rctl_set rctl_set_t; 122 123 #else /* _KERNEL */ 124 125 #include <sys/mutex.h> 126 127 /* 128 * rctl_test return bitfield 129 */ 130 #define RCT_NONE 0x00000000 131 #define RCT_DENY 0x00000001 132 #define RCT_SIGNAL 0x00000002 133 #define RCT_STRLOG 0x00000004 134 135 #define RCT_LK_ABANDONED 0x80000000 136 137 /* 138 * rctl_set_dup flags 139 */ 140 #define RCD_DUP 0x1 141 #define RCD_CALLBACK 0x2 142 143 /* 144 * rctl_action/rctl_test action safety states 145 */ 146 #define RCA_SAFE 0x0 /* safe for signal and siginfo delivery */ 147 #define RCA_UNSAFE_SIGINFO 0x1 /* not safe to allocate for siginfo */ 148 #define RCA_UNSAFE_ALL 0x2 /* not safe to send signal */ 149 150 typedef struct rctl_val { 151 struct rctl_val *rcv_prev; /* previous (lower) value */ 152 struct rctl_val *rcv_next; /* next (higher) value */ 153 rctl_priv_t rcv_privilege; /* appropriate RCPRIV_* cst */ 154 rctl_qty_t rcv_value; /* enforced value of control */ 155 uint_t rcv_flagaction; /* properties and actions */ 156 int rcv_action_signal; /* signal to send as action */ 157 struct proc *rcv_action_recipient; /* process to receive signal */ 158 id_t rcv_action_recip_pid; /* pid of that process */ 159 hrtime_t rcv_firing_time; /* time rctl_val last fired */ 160 } rctl_val_t; 161 162 typedef int rctl_hndl_t; 163 164 struct rctl; 165 struct proc; 166 struct task; 167 struct kproject; 168 struct zone; 169 struct kstat; 170 171 typedef struct rctl_entity_p_struct { 172 rctl_entity_t rcep_t; 173 union { 174 struct proc *proc; 175 struct task *task; 176 struct kproject *proj; 177 struct zone *zone; 178 } rcep_p; 179 } rctl_entity_p_t; 180 181 typedef struct rctl_ops { 182 void (*rco_action)(struct rctl *, struct proc *, 183 rctl_entity_p_t *); 184 rctl_qty_t (*rco_get_usage)(struct rctl *, struct proc *); 185 int (*rco_set)(struct rctl *, struct proc *, 186 rctl_entity_p_t *, rctl_qty_t); 187 int (*rco_test)(struct rctl *, struct proc *, 188 rctl_entity_p_t *, rctl_val_t *, rctl_qty_t, uint_t); 189 } rctl_ops_t; 190 191 #define RCTLOP_ACTION(r, p, e) (r->rc_dict_entry->rcd_ops->rco_action(r, p, e)) 192 #define RCTLOP_GET_USAGE(r, p) (r->rc_dict_entry->rcd_ops->rco_get_usage(r, p)) 193 #define RCTLOP_SET(r, p, e, v) (r->rc_dict_entry->rcd_ops->rco_set(r, p, e, v)) 194 #define RCTLOP_TEST(r, p, e, v, i, f) \ 195 (r->rc_dict_entry->rcd_ops->rco_test(r, p, e, v, i, f)) 196 197 /* 198 * Default resource control callback functions. 199 */ 200 void rcop_no_action(struct rctl *, struct proc *, rctl_entity_p_t *); 201 rctl_qty_t rcop_no_usage(struct rctl *, struct proc *); 202 int rcop_no_set(struct rctl *, struct proc *, rctl_entity_p_t *, rctl_qty_t); 203 int rcop_no_test(struct rctl *, struct proc *, rctl_entity_p_t *, 204 struct rctl_val *, rctl_qty_t, uint_t); 205 int rcop_absolute_test(struct rctl *, struct proc *, rctl_entity_p_t *, 206 struct rctl_val *, rctl_qty_t, uint_t); 207 208 #define RCTLOP_NO_USAGE(r) \ 209 (r->rc_dict_entry->rcd_ops->rco_get_usage == rcop_no_usage) 210 211 extern rctl_ops_t rctl_default_ops; 212 extern rctl_ops_t rctl_absolute_ops; 213 214 typedef struct rctl { 215 struct rctl *rc_next; /* next in set hash chain */ 216 rctl_val_t *rc_values; /* list of enforced value */ 217 rctl_val_t *rc_cursor; /* currently enforced value */ 218 struct rctl_dict_entry *rc_dict_entry; /* global control properties */ 219 rctl_hndl_t rc_id; /* control handle (hash key) */ 220 rctl_val_t *rc_projdb; /* project database rctls */ 221 } rctl_t; 222 223 /* 224 * The rctl_set is the collection of resource controls associated with an 225 * individual entity within the system. All of the controls are applicable to 226 * the same entity, which we call out explicitly in rcs_entity. 227 */ 228 typedef struct rctl_set { 229 kmutex_t rcs_lock; /* global set lock */ 230 rctl_entity_t rcs_entity; /* entity type */ 231 rctl_t **rcs_ctls; /* hash table of controls */ 232 } rctl_set_t; 233 234 typedef struct rctl_dict_entry { 235 struct rctl_dict_entry *rcd_next; /* next in dict hash chain */ 236 char *rcd_name; /* resource control name */ 237 rctl_val_t *rcd_default_value; /* system control value */ 238 rctl_ops_t *rcd_ops; /* callback operations */ 239 rctl_hndl_t rcd_id; /* control handle */ 240 rctl_entity_t rcd_entity; /* entity type */ 241 int rcd_flagaction; /* global properties/actions */ 242 int rcd_syslog_level; /* event syslog level */ 243 int rcd_strlog_flags; /* derived from syslog level */ 244 rctl_qty_t rcd_max_native; /* native model "infinity" */ 245 rctl_qty_t rcd_max_ilp32; /* ILP32 model "infinity" */ 246 } rctl_dict_entry_t; 247 248 typedef struct rctl_alloc_gp { 249 uint_t rcag_nctls; /* number of rctls needed/allocated */ 250 uint_t rcag_nvals; /* number of rctl values needed/allocated */ 251 rctl_t *rcag_ctls; /* list of allocated rctls */ 252 rctl_val_t *rcag_vals; /* list of allocated rctl values */ 253 } rctl_alloc_gp_t; 254 255 extern kmem_cache_t *rctl_cache; /* kmem cache for rctl structures */ 256 extern kmem_cache_t *rctl_val_cache; /* kmem cache for rctl values */ 257 258 extern rctl_hndl_t rctlproc_legacy[]; 259 extern uint_t rctlproc_flags[]; 260 extern int rctlproc_signals[]; 261 262 void rctl_init(void); 263 void rctlproc_init(void); 264 void rctlproc_default_init(struct proc *, rctl_alloc_gp_t *); 265 266 rctl_hndl_t rctl_register(const char *, rctl_entity_t, int, rctl_qty_t, 267 rctl_qty_t, rctl_ops_t *); 268 269 rctl_hndl_t rctl_hndl_lookup(const char *); 270 rctl_dict_entry_t *rctl_dict_lookup(const char *); 271 rctl_dict_entry_t *rctl_dict_lookup_hndl(rctl_hndl_t); 272 void rctl_add_default_limit(const char *, rctl_qty_t, rctl_priv_t, uint_t); 273 void rctl_add_legacy_limit(const char *, const char *, const char *, 274 rctl_qty_t, rctl_qty_t); 275 276 rctl_qty_t rctl_model_maximum(rctl_dict_entry_t *, struct proc *); 277 rctl_qty_t rctl_model_value(rctl_dict_entry_t *, struct proc *, rctl_qty_t); 278 279 int rctl_invalid_value(rctl_dict_entry_t *, rctl_val_t *); 280 rctl_qty_t rctl_enforced_value(rctl_hndl_t, rctl_set_t *, struct proc *); 281 282 int rctl_test(rctl_hndl_t, rctl_set_t *, struct proc *, rctl_qty_t, uint_t); 283 int rctl_action(rctl_hndl_t, rctl_set_t *, struct proc *, uint_t); 284 285 int rctl_test_entity(rctl_hndl_t, rctl_set_t *, struct proc *, 286 rctl_entity_p_t *, rctl_qty_t, uint_t); 287 int rctl_action_entity(rctl_hndl_t, rctl_set_t *, struct proc *, 288 rctl_entity_p_t *, uint_t); 289 290 int rctl_val_cmp(rctl_val_t *, rctl_val_t *, int); 291 int rctl_val_list_insert(rctl_val_t **, rctl_val_t *); 292 293 rctl_set_t *rctl_set_create(void); 294 rctl_set_t *rctl_entity_obtain_rset(rctl_dict_entry_t *, struct proc *); 295 rctl_alloc_gp_t *rctl_set_init_prealloc(rctl_entity_t); 296 rctl_set_t *rctl_set_init(rctl_entity_t, struct proc *, rctl_entity_p_t *, 297 rctl_set_t *, rctl_alloc_gp_t *); 298 rctl_alloc_gp_t *rctl_set_dup_prealloc(rctl_set_t *); 299 int rctl_set_dup_ready(rctl_set_t *, rctl_alloc_gp_t *); 300 rctl_set_t *rctl_set_dup(rctl_set_t *, struct proc *, struct proc *, 301 rctl_entity_p_t *, rctl_set_t *, rctl_alloc_gp_t *, int); 302 void rctl_set_reset(rctl_set_t *, struct proc *, rctl_entity_p_t *); 303 void rctl_set_tearoff(rctl_set_t *, struct proc *); 304 int rctl_set_find(rctl_set_t *, rctl_hndl_t, rctl_t **); 305 void rctl_set_free(rctl_set_t *); 306 307 void rctl_prealloc_destroy(rctl_alloc_gp_t *); 308 309 size_t rctl_build_name_buf(char **); 310 311 int rctl_global_get(const char *name, rctl_dict_entry_t *); 312 int rctl_global_set(const char *name, rctl_dict_entry_t *); 313 314 int rctl_local_delete(rctl_hndl_t, rctl_val_t *, struct proc *p); 315 int rctl_local_insert(rctl_hndl_t, rctl_val_t *, struct proc *p); 316 int rctl_local_insert_all(rctl_hndl_t, rctl_val_t *, rctl_val_t *, 317 struct proc *p); 318 int rctl_local_replace_all(rctl_hndl_t, rctl_val_t *, rctl_val_t *, 319 struct proc *p); 320 int rctl_local_get(rctl_hndl_t, rctl_val_t *, rctl_val_t *, struct proc *p); 321 int rctl_local_replace(rctl_hndl_t, rctl_val_t *, rctl_val_t *, 322 struct proc *p); 323 324 /* tag declaration to appease the compiler */ 325 struct cred; 326 rctl_alloc_gp_t *rctl_rlimit_set_prealloc(uint_t); 327 int rctl_rlimit_set(rctl_hndl_t, struct proc *, struct rlimit64 *, 328 rctl_alloc_gp_t *, int, int, const struct cred *); 329 int rctl_rlimit_get(rctl_hndl_t, struct proc *, struct rlimit64 *); 330 331 /* specific rctl utility functions */ 332 int rctl_incr_locked_mem(struct proc *, struct kproject *, rctl_qty_t, 333 int); 334 void rctl_decr_locked_mem(struct proc *, struct kproject *, rctl_qty_t, 335 int); 336 int rctl_incr_swap(struct proc *, struct zone *, size_t); 337 void rctl_decr_swap(struct zone *, size_t); 338 339 int rctl_incr_lofi(struct proc *, struct zone *, size_t); 340 void rctl_decr_lofi(struct zone *, size_t); 341 342 struct kstat *rctl_kstat_create_zone(struct zone *, char *, uchar_t, uint_t, 343 uchar_t); 344 345 struct kstat *rctl_kstat_create_project(struct kproject *, char *, uchar_t, 346 uint_t, uchar_t); 347 348 struct kstat *rctl_kstat_create_task(struct task *, char *, uchar_t, 349 uint_t, uchar_t); 350 351 #endif /* _KERNEL */ 352 353 #ifdef __cplusplus 354 } 355 #endif 356 357 #endif /* _SYS_RCTL_H */ 358