diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/uts/common/sys/rctl.h | |
download | illumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/uts/common/sys/rctl.h')
-rw-r--r-- | usr/src/uts/common/sys/rctl.h | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/usr/src/uts/common/sys/rctl.h b/usr/src/uts/common/sys/rctl.h new file mode 100644 index 0000000000..d67edb2d99 --- /dev/null +++ b/usr/src/uts/common/sys/rctl.h @@ -0,0 +1,328 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_RCTL_H +#define _SYS_RCTL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/kmem.h> +#include <sys/resource.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Available local actions and flags. + */ +#define RCTL_LOCAL_NOACTION 0x00000000 +#define RCTL_LOCAL_SIGNAL 0x00000001 +#define RCTL_LOCAL_DENY 0x00000002 + +#define RCTL_LOCAL_MAXIMAL 0x80000000 + +#define RCTL_LOCAL_ACTION_MASK 0xffff0000 +#define RCTL_LOCAL_MASK 0x80000003 + +/* + * Available global actions and flags. + */ +#define RCTL_GLOBAL_NOACTION 0x00000000 +#define RCTL_GLOBAL_SYSLOG 0x00000001 + +#define RCTL_GLOBAL_NOBASIC 0x80000000 +#define RCTL_GLOBAL_LOWERABLE 0x40000000 +#define RCTL_GLOBAL_DENY_ALWAYS 0x20000000 +#define RCTL_GLOBAL_DENY_NEVER 0x10000000 +#define RCTL_GLOBAL_FILE_SIZE 0x08000000 +#define RCTL_GLOBAL_CPU_TIME 0x04000000 +#define RCTL_GLOBAL_SIGNAL_NEVER 0x02000000 +#define RCTL_GLOBAL_NOLOCALACTION RCTL_GLOBAL_SIGNAL_NEVER +#define RCTL_GLOBAL_INFINITE 0x01000000 +#define RCTL_GLOBAL_UNOBSERVABLE 0x00800000 + +#define RCTL_GLOBAL_BYTES 0x00400000 +#define RCTL_GLOBAL_SECONDS 0x00200000 +#define RCTL_GLOBAL_COUNT 0x00100000 + +#define RCTL_GLOBAL_ACTION_MASK 0xffff0000 +#define RCTL_GLOBAL_MASK 0xff700001 + +/* + * getrctl(2) flag values + */ +#define RCTL_FIRST 0x00000000 +#define RCTL_NEXT 0x00000001 +#define RCTL_USAGE 0x00000002 + +/* + * setrctl(2) flag values + */ + +#define RCTL_INSERT 0x00000000 +#define RCTL_DELETE 0x00000001 +#define RCTL_REPLACE 0x00000002 + +#define RCTL_USE_RECIPIENT_PID 0x10000000 + +#define RCTLSYS_ACTION_MASK 0xffff0000 +#define RCTLSYS_MASK 0x10000003 + +/* + * rctl_priv_t: rctl privilege defined values + * A large amount of space has been deliberately left between these privileges + * to permit future enrichment of the control privilege value. + */ +#define RCPRIV_BASIC 0x01000000 +#define RCPRIV_PRIVILEGED 0x04000000 +#define RCPRIV_SYSTEM 0x07000000 + +typedef u_longlong_t rctl_qty_t; /* resource control numerical values */ +typedef int rctl_priv_t; + +typedef struct rctlblk rctlblk_t; + +extern int setrctl(const char *, rctlblk_t *, rctlblk_t *, int); +extern int getrctl(const char *, rctlblk_t *, rctlblk_t *, int); + +typedef enum { + RCENTITY_PROCESS, + RCENTITY_TASK, + RCENTITY_PROJECT, + RCENTITY_ZONE +} rctl_entity_t; +#define RC_MAX_ENTITY RCENTITY_ZONE + +#ifndef _KERNEL + +typedef struct rctl_set rctl_set_t; + +#else /* _KERNEL */ + +#include <sys/mutex.h> + +/* + * rctl_test return bitfield + */ +#define RCT_NONE 0x00000000 +#define RCT_DENY 0x00000001 +#define RCT_SIGNAL 0x00000002 +#define RCT_STRLOG 0x00000004 + +#define RCT_LK_ABANDONED 0x80000000 + +/* + * rctl_set_dup flags + */ +#define RCD_DUP 0x1 +#define RCD_CALLBACK 0x2 + +/* + * rctl_action/rctl_test action safety states + */ +#define RCA_SAFE 0x0 /* safe for signal and siginfo delivery */ +#define RCA_UNSAFE_SIGINFO 0x1 /* not safe to allocate for siginfo */ +#define RCA_UNSAFE_ALL 0x2 /* not safe to send signal */ + +typedef struct rctl_val { + struct rctl_val *rcv_prev; /* previous (lower) value */ + struct rctl_val *rcv_next; /* next (higher) value */ + rctl_priv_t rcv_privilege; /* appropriate RCPRIV_* cst */ + rctl_qty_t rcv_value; /* enforced value of control */ + uint_t rcv_flagaction; /* properties and actions */ + int rcv_action_signal; /* signal to send as action */ + struct proc *rcv_action_recipient; /* process to receive signal */ + id_t rcv_action_recip_pid; /* pid of that process */ + hrtime_t rcv_firing_time; /* time rctl_val last fired */ +} rctl_val_t; + +typedef int rctl_hndl_t; + +struct rctl; +struct proc; +struct task; +struct kproject; +struct zone; + +typedef struct rctl_entity_p_struct { + rctl_entity_t rcep_t; + union { + struct proc *proc; + struct task *task; + struct kproject *proj; + struct zone *zone; + } rcep_p; +} rctl_entity_p_t; + +typedef struct rctl_ops { + void (*rco_action)(struct rctl *, struct proc *, + rctl_entity_p_t *); + rctl_qty_t (*rco_get_usage)(struct rctl *, struct proc *); + int (*rco_set)(struct rctl *, struct proc *, + rctl_entity_p_t *, rctl_qty_t); + int (*rco_test)(struct rctl *, struct proc *, + rctl_entity_p_t *, rctl_val_t *, rctl_qty_t, uint_t); +} rctl_ops_t; + +#define RCTLOP_ACTION(r, p, e) (r->rc_dict_entry->rcd_ops->rco_action(r, p, e)) +#define RCTLOP_GET_USAGE(r, p) (r->rc_dict_entry->rcd_ops->rco_get_usage(r, p)) +#define RCTLOP_SET(r, p, e, v) (r->rc_dict_entry->rcd_ops->rco_set(r, p, e, v)) +#define RCTLOP_TEST(r, p, e, v, i, f) \ + (r->rc_dict_entry->rcd_ops->rco_test(r, p, e, v, i, f)) + +/* + * Default resource control callback functions. + */ +void rcop_no_action(struct rctl *, struct proc *, rctl_entity_p_t *); +rctl_qty_t rcop_no_usage(struct rctl *, struct proc *); +int rcop_no_set(struct rctl *, struct proc *, rctl_entity_p_t *, rctl_qty_t); +int rcop_no_test(struct rctl *, struct proc *, rctl_entity_p_t *, + struct rctl_val *, rctl_qty_t, uint_t); +int rcop_absolute_test(struct rctl *, struct proc *, rctl_entity_p_t *, + struct rctl_val *, rctl_qty_t, uint_t); + +extern rctl_ops_t rctl_default_ops; +extern rctl_ops_t rctl_absolute_ops; + +typedef struct rctl { + struct rctl *rc_next; /* next in set hash chain */ + rctl_val_t *rc_values; /* list of enforced value */ + rctl_val_t *rc_cursor; /* currently enforced value */ + struct rctl_dict_entry *rc_dict_entry; /* global control properties */ + rctl_hndl_t rc_id; /* control handle (hash key) */ +} rctl_t; + +/* + * The rctl_set is the collection of resource controls associated with an + * individual entity within the system. All of the controls are applicable to + * the same entity, which we call out explicitly in rcs_entity. + */ +typedef struct rctl_set { + kmutex_t rcs_lock; /* global set lock */ + rctl_entity_t rcs_entity; /* entity type */ + rctl_t **rcs_ctls; /* hash table of controls */ +} rctl_set_t; + +typedef struct rctl_dict_entry { + struct rctl_dict_entry *rcd_next; /* next in dict hash chain */ + char *rcd_name; /* resource control name */ + rctl_val_t *rcd_default_value; /* system control value */ + rctl_ops_t *rcd_ops; /* callback operations */ + rctl_hndl_t rcd_id; /* control handle */ + rctl_entity_t rcd_entity; /* entity type */ + int rcd_flagaction; /* global properties/actions */ + int rcd_syslog_level; /* event syslog level */ + int rcd_strlog_flags; /* derived from syslog level */ + rctl_qty_t rcd_max_native; /* native model "infinity" */ + rctl_qty_t rcd_max_ilp32; /* ILP32 model "infinity" */ +} rctl_dict_entry_t; + +typedef struct rctl_alloc_gp { + uint_t rcag_nctls; /* number of rctls needed/allocated */ + uint_t rcag_nvals; /* number of rctl values needed/allocated */ + rctl_t *rcag_ctls; /* list of allocated rctls */ + rctl_val_t *rcag_vals; /* list of allocated rctl values */ +} rctl_alloc_gp_t; + +extern kmem_cache_t *rctl_cache; /* kmem cache for rctl structures */ +extern kmem_cache_t *rctl_val_cache; /* kmem cache for rctl values */ + +extern rctl_hndl_t rctlproc_legacy[]; +extern uint_t rctlproc_flags[]; +extern int rctlproc_signals[]; + +void rctl_init(void); +void rctlproc_init(void); +void rctlproc_default_init(struct proc *, rctl_alloc_gp_t *); + +rctl_hndl_t rctl_register(const char *, rctl_entity_t, int, rctl_qty_t, + rctl_qty_t, rctl_ops_t *); + +rctl_hndl_t rctl_hndl_lookup(const char *); +rctl_dict_entry_t *rctl_dict_lookup(const char *); +rctl_dict_entry_t *rctl_dict_lookup_hndl(rctl_hndl_t); +void rctl_add_default_limit(const char *, rctl_qty_t, rctl_priv_t, uint_t); +void rctl_add_legacy_limit(const char *, const char *, const char *, + rctl_qty_t, rctl_qty_t); + +rctl_qty_t rctl_model_maximum(rctl_dict_entry_t *, struct proc *); +rctl_qty_t rctl_model_value(rctl_dict_entry_t *, struct proc *, rctl_qty_t); + +int rctl_invalid_value(rctl_dict_entry_t *, rctl_val_t *); +rctl_qty_t rctl_enforced_value(rctl_hndl_t, rctl_set_t *, struct proc *); + +int rctl_test(rctl_hndl_t, rctl_set_t *, struct proc *, rctl_qty_t, uint_t); +int rctl_action(rctl_hndl_t, rctl_set_t *, struct proc *, uint_t); + +int rctl_test_entity(rctl_hndl_t, rctl_set_t *, struct proc *, + rctl_entity_p_t *, rctl_qty_t, uint_t); +int rctl_action_entity(rctl_hndl_t, rctl_set_t *, struct proc *, + rctl_entity_p_t *, uint_t); + +int rctl_val_cmp(rctl_val_t *, rctl_val_t *, int); +int rctl_val_list_insert(rctl_val_t **, rctl_val_t *); + +rctl_set_t *rctl_set_create(void); +rctl_alloc_gp_t *rctl_set_init_prealloc(rctl_entity_t); +rctl_set_t *rctl_set_init(rctl_entity_t, struct proc *, rctl_entity_p_t *, + rctl_set_t *, rctl_alloc_gp_t *); +rctl_alloc_gp_t *rctl_set_dup_prealloc(rctl_set_t *); +int rctl_set_dup_ready(rctl_set_t *, rctl_alloc_gp_t *); +rctl_set_t *rctl_set_dup(rctl_set_t *, struct proc *, struct proc *, + rctl_entity_p_t *, rctl_set_t *, rctl_alloc_gp_t *, int); +void rctl_set_reset(rctl_set_t *, struct proc *, rctl_entity_p_t *); +void rctl_set_tearoff(rctl_set_t *, struct proc *); +void rctl_set_free(rctl_set_t *); + +void rctl_prealloc_destroy(rctl_alloc_gp_t *); + +size_t rctl_build_name_buf(char **); + +int rctl_global_get(const char *name, rctl_dict_entry_t *); +int rctl_global_set(const char *name, rctl_dict_entry_t *); + +int rctl_local_delete(rctl_hndl_t, rctl_val_t *, struct proc *p); +int rctl_local_insert(rctl_hndl_t, rctl_val_t *, struct proc *p); +int rctl_local_get(rctl_hndl_t, rctl_val_t *, rctl_val_t *, struct proc *p); +int rctl_local_replace(rctl_hndl_t, rctl_val_t *, rctl_val_t *, + struct proc *p); + +/* tag declaration to appease the compiler */ +struct cred; +rctl_alloc_gp_t *rctl_rlimit_set_prealloc(uint_t); +int rctl_rlimit_set(rctl_hndl_t, struct proc *, struct rlimit64 *, + rctl_alloc_gp_t *, int, int, const struct cred *); +int rctl_rlimit_get(rctl_hndl_t, struct proc *, struct rlimit64 *); + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_RCTL_H */ |