xref: /illumos-gate/usr/src/uts/common/sys/rctl.h (revision 4e5b757f)
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_RCTL_H
27 #define	_SYS_RCTL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <sys/kmem.h>
32 #include <sys/resource.h>
33 #include <sys/types.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 /*
40  * Available local actions and flags.
41  */
42 #define	RCTL_LOCAL_NOACTION		0x00000000
43 #define	RCTL_LOCAL_SIGNAL		0x00000001
44 #define	RCTL_LOCAL_DENY			0x00000002
45 
46 #define	RCTL_LOCAL_MAXIMAL		0x80000000
47 #define	RCTL_LOCAL_PROJDB		0x40000000
48 
49 #define	RCTL_LOCAL_ACTION_MASK		0xffff0000
50 #define	RCTL_LOCAL_MASK			0xc0000003
51 
52 /*
53  * Available global actions and flags.
54  */
55 #define	RCTL_GLOBAL_NOACTION		0x00000000
56 #define	RCTL_GLOBAL_SYSLOG		0x00000001
57 
58 #define	RCTL_GLOBAL_NOBASIC		0x80000000
59 #define	RCTL_GLOBAL_LOWERABLE		0x40000000
60 #define	RCTL_GLOBAL_DENY_ALWAYS		0x20000000
61 #define	RCTL_GLOBAL_DENY_NEVER		0x10000000
62 #define	RCTL_GLOBAL_FILE_SIZE		0x08000000
63 #define	RCTL_GLOBAL_CPU_TIME		0x04000000
64 #define	RCTL_GLOBAL_SIGNAL_NEVER	0x02000000
65 #define	RCTL_GLOBAL_NOLOCALACTION	RCTL_GLOBAL_SIGNAL_NEVER
66 #define	RCTL_GLOBAL_INFINITE		0x01000000
67 #define	RCTL_GLOBAL_UNOBSERVABLE	0x00800000
68 #define	RCTL_GLOBAL_SYSLOG_NEVER	0x00080000
69 
70 #define	RCTL_GLOBAL_BYTES		0x00400000
71 #define	RCTL_GLOBAL_SECONDS		0x00200000
72 #define	RCTL_GLOBAL_COUNT		0x00100000
73 
74 #define	RCTL_GLOBAL_ACTION_MASK		0xffff0000
75 #define	RCTL_GLOBAL_MASK		0xfff80001
76 
77 /*
78  * getrctl(2) flag values
79  */
80 #define	RCTL_FIRST		0x00000000
81 #define	RCTL_NEXT		0x00000001
82 #define	RCTL_USAGE		0x00000002
83 
84 /*
85  * setrctl(2) flag values
86  */
87 
88 #define	RCTL_INSERT		0x00000000
89 #define	RCTL_DELETE		0x00000001
90 #define	RCTL_REPLACE		0x00000002
91 
92 #define	RCTL_USE_RECIPIENT_PID	0x10000000
93 
94 #define	RCTLSYS_ACTION_MASK 	0xffff0000
95 #define	RCTLSYS_MASK		0x10000003
96 
97 /*
98  * rctl_priv_t: rctl privilege defined values
99  *   A large amount of space has been deliberately left between these privileges
100  *   to permit future enrichment of the control privilege value.
101  */
102 #define	RCPRIV_BASIC		0x01000000
103 #define	RCPRIV_PRIVILEGED	0x04000000
104 #define	RCPRIV_SYSTEM		0x07000000
105 
106 typedef u_longlong_t rctl_qty_t; /* resource control numerical values   */
107 typedef int rctl_priv_t;
108 
109 typedef struct rctlblk rctlblk_t;
110 
111 extern int setrctl(const char *, rctlblk_t *, rctlblk_t *, int);
112 extern int getrctl(const char *, rctlblk_t *, rctlblk_t *, int);
113 
114 typedef enum {
115 	RCENTITY_PROCESS,
116 	RCENTITY_TASK,
117 	RCENTITY_PROJECT,
118 	RCENTITY_ZONE
119 } rctl_entity_t;
120 #define	RC_MAX_ENTITY RCENTITY_ZONE
121 
122 #ifndef _KERNEL
123 
124 typedef struct rctl_set rctl_set_t;
125 
126 #else /* _KERNEL */
127 
128 #include <sys/mutex.h>
129 
130 /*
131  * rctl_test return bitfield
132  */
133 #define	RCT_NONE		0x00000000
134 #define	RCT_DENY		0x00000001
135 #define	RCT_SIGNAL		0x00000002
136 #define	RCT_STRLOG		0x00000004
137 
138 #define	RCT_LK_ABANDONED	0x80000000
139 
140 /*
141  * rctl_set_dup flags
142  */
143 #define	RCD_DUP			0x1
144 #define	RCD_CALLBACK		0x2
145 
146 /*
147  * rctl_action/rctl_test action safety states
148  */
149 #define	RCA_SAFE		0x0 /* safe for signal and siginfo delivery */
150 #define	RCA_UNSAFE_SIGINFO	0x1 /* not safe to allocate for siginfo */
151 #define	RCA_UNSAFE_ALL		0x2 /* not safe to send signal */
152 
153 typedef struct rctl_val {
154 	struct rctl_val *rcv_prev;		/* previous (lower) value */
155 	struct rctl_val *rcv_next;		/* next (higher) value */
156 	rctl_priv_t	rcv_privilege;		/* appropriate RCPRIV_* cst */
157 	rctl_qty_t	rcv_value;		/* enforced value of control */
158 	uint_t		rcv_flagaction;		/* properties and actions */
159 	int		rcv_action_signal;	/* signal to send as action */
160 	struct proc	*rcv_action_recipient;	/* process to receive signal */
161 	id_t		rcv_action_recip_pid;	/* pid of that process */
162 	hrtime_t	rcv_firing_time;	/* time rctl_val last fired */
163 } rctl_val_t;
164 
165 typedef int rctl_hndl_t;
166 
167 struct rctl;
168 struct proc;
169 struct task;
170 struct kproject;
171 struct zone;
172 struct kstat;
173 
174 typedef struct rctl_entity_p_struct {
175 	rctl_entity_t rcep_t;
176 	union {
177 		struct proc *proc;
178 		struct task *task;
179 		struct kproject *proj;
180 		struct zone *zone;
181 	} rcep_p;
182 } rctl_entity_p_t;
183 
184 typedef struct rctl_ops {
185 	void		(*rco_action)(struct rctl *, struct proc *,
186 	    rctl_entity_p_t *);
187 	rctl_qty_t	(*rco_get_usage)(struct rctl *, struct proc *);
188 	int		(*rco_set)(struct rctl *, struct proc *,
189 	    rctl_entity_p_t *, rctl_qty_t);
190 	int		(*rco_test)(struct rctl *, struct proc *,
191 	    rctl_entity_p_t *, rctl_val_t *, rctl_qty_t, uint_t);
192 } rctl_ops_t;
193 
194 #define	RCTLOP_ACTION(r, p, e) (r->rc_dict_entry->rcd_ops->rco_action(r, p, e))
195 #define	RCTLOP_GET_USAGE(r, p) (r->rc_dict_entry->rcd_ops->rco_get_usage(r, p))
196 #define	RCTLOP_SET(r, p, e, v) (r->rc_dict_entry->rcd_ops->rco_set(r, p, e, v))
197 #define	RCTLOP_TEST(r, p, e, v, i, f) \
198 	(r->rc_dict_entry->rcd_ops->rco_test(r, p, e, v, i, f))
199 
200 /*
201  * Default resource control callback functions.
202  */
203 void rcop_no_action(struct rctl *, struct proc *, rctl_entity_p_t *);
204 rctl_qty_t rcop_no_usage(struct rctl *, struct proc *);
205 int rcop_no_set(struct rctl *, struct proc *, rctl_entity_p_t *, rctl_qty_t);
206 int rcop_no_test(struct rctl *, struct proc *, rctl_entity_p_t *,
207     struct rctl_val *, rctl_qty_t, uint_t);
208 int rcop_absolute_test(struct rctl *, struct proc *, rctl_entity_p_t *,
209     struct rctl_val *, rctl_qty_t, uint_t);
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_alloc_gp_t *rctl_set_init_prealloc(rctl_entity_t);
295 rctl_set_t *rctl_set_init(rctl_entity_t, struct proc *, rctl_entity_p_t *,
296     rctl_set_t *, rctl_alloc_gp_t *);
297 rctl_alloc_gp_t *rctl_set_dup_prealloc(rctl_set_t *);
298 int rctl_set_dup_ready(rctl_set_t *, rctl_alloc_gp_t *);
299 rctl_set_t *rctl_set_dup(rctl_set_t *, struct proc *, struct proc *,
300     rctl_entity_p_t *, rctl_set_t *, rctl_alloc_gp_t *, int);
301 void rctl_set_reset(rctl_set_t *, struct proc *, rctl_entity_p_t *);
302 void rctl_set_tearoff(rctl_set_t *, struct proc *);
303 void rctl_set_free(rctl_set_t *);
304 
305 void rctl_prealloc_destroy(rctl_alloc_gp_t *);
306 
307 size_t rctl_build_name_buf(char **);
308 
309 int rctl_global_get(const char *name, rctl_dict_entry_t *);
310 int rctl_global_set(const char *name, rctl_dict_entry_t *);
311 
312 int rctl_local_delete(rctl_hndl_t, rctl_val_t *, struct proc *p);
313 int rctl_local_insert(rctl_hndl_t, rctl_val_t *, struct proc *p);
314 int rctl_local_insert_all(rctl_hndl_t, rctl_val_t *, rctl_val_t *,
315     struct proc *p);
316 int rctl_local_replace_all(rctl_hndl_t, rctl_val_t *, rctl_val_t *,
317     struct proc *p);
318 int rctl_local_get(rctl_hndl_t, rctl_val_t *, rctl_val_t *, struct proc *p);
319 int rctl_local_replace(rctl_hndl_t, rctl_val_t *, rctl_val_t *,
320     struct proc *p);
321 
322 /* tag declaration to appease the compiler */
323 struct cred;
324 rctl_alloc_gp_t *rctl_rlimit_set_prealloc(uint_t);
325 int rctl_rlimit_set(rctl_hndl_t, struct proc *, struct rlimit64 *,
326     rctl_alloc_gp_t *, int, int, const struct cred *);
327 int rctl_rlimit_get(rctl_hndl_t, struct proc *, struct rlimit64 *);
328 
329 /* specific rctl utility functions */
330 int rctl_incr_locked_mem(struct proc *, struct kproject *, rctl_qty_t,
331     int);
332 void rctl_decr_locked_mem(struct proc *, struct kproject *, rctl_qty_t,
333     int);
334 int rctl_incr_swap(struct proc *, struct zone *, size_t);
335 void rctl_decr_swap(struct zone *, size_t);
336 
337 struct kstat *rctl_kstat_create_zone(struct zone *, char *, uchar_t, uint_t,
338     uchar_t);
339 
340 struct kstat *rctl_kstat_create_project(struct kproject *, char *, uchar_t,
341     uint_t, uchar_t);
342 
343 #endif /* _KERNEL */
344 
345 #ifdef	__cplusplus
346 }
347 #endif
348 
349 #endif	/* _SYS_RCTL_H */
350