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 (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <sys/resource.h>
30 #include <sys/types.h>
37 * Available local actions and flags.
39 #define RCTL_LOCAL_NOACTION 0x00000000
40 #define RCTL_LOCAL_SIGNAL 0x00000001
41 #define RCTL_LOCAL_DENY 0x00000002
43 #define RCTL_LOCAL_MAXIMAL 0x80000000
44 #define RCTL_LOCAL_PROJDB 0x40000000
46 #define RCTL_LOCAL_ACTION_MASK 0xffff0000
47 #define RCTL_LOCAL_MASK 0xc0000003
50 * Available global actions and flags.
52 #define RCTL_GLOBAL_NOACTION 0x00000000
53 #define RCTL_GLOBAL_SYSLOG 0x00000001
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
67 #define RCTL_GLOBAL_BYTES 0x00400000
68 #define RCTL_GLOBAL_SECONDS 0x00200000
69 #define RCTL_GLOBAL_COUNT 0x00100000
71 #define RCTL_GLOBAL_ACTION_MASK 0xffff0000
72 #define RCTL_GLOBAL_MASK 0xfff80001
75 * getrctl(2) flag values
77 #define RCTL_FIRST 0x00000000
78 #define RCTL_NEXT 0x00000001
79 #define RCTL_USAGE 0x00000002
82 * setrctl(2) flag values
85 #define RCTL_INSERT 0x00000000
86 #define RCTL_DELETE 0x00000001
87 #define RCTL_REPLACE 0x00000002
89 #define RCTL_USE_RECIPIENT_PID 0x10000000
91 #define RCTLSYS_ACTION_MASK 0xffff0000
92 #define RCTLSYS_MASK 0x10000003
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.
99 #define RCPRIV_BASIC 0x01000000
100 #define RCPRIV_PRIVILEGED 0x04000000
101 #define RCPRIV_SYSTEM 0x07000000
103 typedef u_longlong_t rctl_qty_t
; /* resource control numerical values */
104 typedef int rctl_priv_t
;
106 typedef struct rctlblk rctlblk_t
;
108 extern int setrctl(const char *, rctlblk_t
*, rctlblk_t
*, int);
109 extern int getrctl(const char *, rctlblk_t
*, rctlblk_t
*, int);
117 #define RC_MAX_ENTITY RCENTITY_ZONE
121 typedef struct rctl_set rctl_set_t
;
125 #include <sys/mutex.h>
128 * rctl_test return bitfield
130 #define RCT_NONE 0x00000000
131 #define RCT_DENY 0x00000001
132 #define RCT_SIGNAL 0x00000002
133 #define RCT_STRLOG 0x00000004
135 #define RCT_LK_ABANDONED 0x80000000
141 #define RCD_CALLBACK 0x2
144 * rctl_action/rctl_test action safety states
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 */
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 */
162 typedef int rctl_hndl_t
;
171 typedef struct rctl_entity_p_struct
{
172 rctl_entity_t rcep_t
;
176 struct kproject
*proj
;
181 typedef struct rctl_ops
{
182 void (*rco_action
)(struct rctl
*, struct proc
*,
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
);
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))
198 * Default resource control callback functions.
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
);
208 #define RCTLOP_NO_USAGE(r) \
209 (r->rc_dict_entry->rcd_ops->rco_get_usage == rcop_no_usage)
211 extern rctl_ops_t rctl_default_ops
;
212 extern rctl_ops_t rctl_absolute_ops
;
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 */
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.
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 */
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" */
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 */
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 */
258 extern rctl_hndl_t rctlproc_legacy
[];
259 extern uint_t rctlproc_flags
[];
260 extern int rctlproc_signals
[];
262 void rctl_init(void);
263 void rctlproc_init(void);
264 void rctlproc_default_init(struct proc
*, rctl_alloc_gp_t
*);
266 rctl_hndl_t
rctl_register(const char *, rctl_entity_t
, int, rctl_qty_t
,
267 rctl_qty_t
, rctl_ops_t
*);
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
);
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
);
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
*);
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
);
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
);
290 int rctl_val_cmp(rctl_val_t
*, rctl_val_t
*, int);
291 int rctl_val_list_insert(rctl_val_t
**, rctl_val_t
*);
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
*);
307 void rctl_prealloc_destroy(rctl_alloc_gp_t
*);
309 size_t rctl_build_name_buf(char **);
311 int rctl_global_get(const char *name
, rctl_dict_entry_t
*);
312 int rctl_global_set(const char *name
, rctl_dict_entry_t
*);
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
*,
318 int rctl_local_replace_all(rctl_hndl_t
, rctl_val_t
*, rctl_val_t
*,
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
*,
324 /* tag declaration to appease the compiler */
326 rctl_alloc_gp_t
*rctl_rlimit_set_prealloc(uint_t
);
327 int rctl_rlimit_set(rctl_hndl_t
, struct proc
*, struct rlimit
*,
328 rctl_alloc_gp_t
*, int, int, const struct cred
*);
329 int rctl_rlimit_get(rctl_hndl_t
, struct proc
*, struct rlimit
*);
331 /* specific rctl utility functions */
332 int rctl_incr_locked_mem(struct proc
*, struct kproject
*, rctl_qty_t
,
334 void rctl_decr_locked_mem(struct proc
*, struct kproject
*, rctl_qty_t
,
336 int rctl_incr_swap(struct proc
*, struct zone
*, size_t);
337 void rctl_decr_swap(struct zone
*, size_t);
339 int rctl_incr_lofi(struct proc
*, struct zone
*, size_t);
340 void rctl_decr_lofi(struct zone
*, size_t);
342 struct kstat
*rctl_kstat_create_zone(struct zone
*, char *, uchar_t
, uint_t
,
345 struct kstat
*rctl_kstat_create_project(struct kproject
*, char *, uchar_t
,
348 struct kstat
*rctl_kstat_create_task(struct task
*, char *, uchar_t
,
357 #endif /* _SYS_RCTL_H */