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