From owner-p4-projects@FreeBSD.ORG Mon Jun 21 17:49:31 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 171F91065673; Mon, 21 Jun 2010 17:49:31 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B7561106566B for ; Mon, 21 Jun 2010 17:49:30 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A413B8FC17 for ; Mon, 21 Jun 2010 17:49:30 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o5LHnUMf056883 for ; Mon, 21 Jun 2010 17:49:30 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o5LHnUlq056881 for perforce@freebsd.org; Mon, 21 Jun 2010 17:49:30 GMT (envelope-from trasz@freebsd.org) Date: Mon, 21 Jun 2010 17:49:30 GMT Message-Id: <201006211749.o5LHnUlq056881@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 180042 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jun 2010 17:49:31 -0000 http://p4web.freebsd.org/@@180042?ac=10 Change 180042 by trasz@trasz_victim on 2010/06/21 17:48:38 Begin work on splitting HRL into HRL and containers. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/conf/files#28 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#1 add .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#74 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/container.h#1 add .. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#43 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#14 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/loginclass.h#7 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#20 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#17 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/conf/files#28 (text+ko) ==== @@ -2079,6 +2079,7 @@ kern/kern_condvar.c standard kern/kern_conf.c standard kern/kern_cons.c standard +kern/kern_container.c standard kern/kern_cpu.c standard kern/kern_cpuset.c standard kern/kern_context.c standard ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#74 (text+ko) ==== @@ -27,6 +27,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -110,13 +111,12 @@ { "sigxfsz", HRL_ACTION_SIGXFSZ }, { NULL, -1 }}; -static const char * hrl_resource_name(int resource); static void hrl_init(void); SYSINIT(hrl, SI_SUB_CPU, SI_ORDER_FIRST, hrl_init, NULL); static uma_zone_t hrl_rule_link_zone; static uma_zone_t hrl_rule_zone; -static struct mtx hrl_lock; +struct mtx hrl_lock; static void hrl_compute_available(struct proc *p, int64_t (*availablep)[]); static int hrl_rule_fully_specified(const struct hrl_rule *rule); @@ -162,7 +162,7 @@ panic("hrl_action_name: unknown action %d", action); } -static const char * +const char * hrl_resource_name(int resource) { int i; @@ -268,7 +268,7 @@ * to what it keeps allocated now. Returns non-zero if the allocation should * be denied, 0 otherwise. */ -static int +int hrl_enforce_proc(struct proc *p, int resource, uint64_t amount) { int64_t available[HRL_RESOURCE_MAX]; @@ -396,276 +396,6 @@ } } -static void -hrl_container_add(struct hrl_container *dest, const struct hrl_container *src) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - - for (i = 0; i <= HRL_RESOURCE_MAX; i++) { - KASSERT(dest->hc_resources[i] >= 0, - ("resource usage propagation meltdown: dest < 0")); - KASSERT(src->hc_resources[i] >= 0, - ("resource usage propagation meltdown: src < 0")); - dest->hc_resources[i] += src->hc_resources[i]; - KASSERT(dest->hc_resources[i] >= 0, - ("resource usage propagation meltdown: dest < 0 after addition")); - } -} - -static void -hrl_container_subtract(struct hrl_container *dest, const struct hrl_container *src) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - - for (i = 0; i <= HRL_RESOURCE_MAX; i++) { - KASSERT(dest->hc_resources[i] >= 0, - ("resource usage propagation meltdown: dest < 0")); - KASSERT(src->hc_resources[i] >= 0, - ("resource usage propagation meltdown: src < 0")); - KASSERT(src->hc_resources[i] <= dest->hc_resources[i], - ("resource usage propagation meltdown: src > dest")); - dest->hc_resources[i] -= src->hc_resources[i]; - KASSERT(dest->hc_resources[i] >= 0, - ("resource usage propagation meltdown: dest < 0 after subtraction")); - } -} - -static void -hrl_container_join(struct hrl_container *child, struct hrl_container *parent) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - KASSERT(child != NULL, ("child != NULL")); - KASSERT(parent != NULL, ("parent != NULL")); - - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) { - KASSERT(child->hc_parents[i] != parent, - ("container already joined")); - if (child->hc_parents[i] == NULL) { - child->hc_parents[i] = parent; - hrl_container_add(parent, child); - return; - } - } - panic("container has too many parents"); -} - -static void -hrl_container_leave(struct hrl_container *child, struct hrl_container *parent) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - KASSERT(child != NULL, ("child != NULL")); - KASSERT(parent != NULL, ("parent != NULL")); - - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) { - if (child->hc_parents[i] == parent) { - hrl_container_subtract(parent, child); - child->hc_parents[i] = NULL; - return; - } - } - panic("container not joined"); -} - -static void -hrl_container_leave_parents(struct hrl_container *child) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - KASSERT(child != NULL, ("child != NULL")); - - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) { - if (child->hc_parents[i] == NULL) - continue; - hrl_container_subtract(child->hc_parents[i], child); - child->hc_parents[i] = NULL; - } -} - -void -hrl_container_create(struct hrl_container *container) -{ - int i; - - for (i = 0; i <= HRL_RESOURCE_MAX; i++) - KASSERT(container->hc_resources[i] == 0, - ("container->hc_resources[%d] != NULL", i)); - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) - KASSERT(container->hc_parents[i] == NULL, - ("container->hc_parents[%d] != NULL", i)); -} - -void -hrl_container_destroy(struct hrl_container *container) -{ - int i; - - mtx_lock(&hrl_lock); - for (i = 0; i <= HRL_RESOURCE_MAX; i++) { - if (container->hc_resources[i] != 0) - printf("destroying non-empty container: " - "%ju allocated for resource %s", - container->hc_resources[i], - hrl_resource_name(i)); - container->hc_resources[i] = 0; - } - - hrl_container_leave_parents(container); - mtx_unlock(&hrl_lock); -} - -#ifdef DIAGNOSTIC -/* - * Go through the resource consumption information and make sure it makes sense. - */ -static void -hrl_container_assert(const struct hrl_container *container) -{ - int i, resource; - struct hrl_container *parent; - - mtx_assert(&hrl_lock, MA_OWNED); - KASSERT(container != NULL, ("NULL container")); - - for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++) { - KASSERT(container->hc_resources[resource] >= 0, - ("resource usage propagation meltdown: resource < 0")); - } - - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) { - parent = container->hc_parents[i]; - if (parent == NULL); - continue; - hrl_container_assert(parent); - for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++) { - KASSERT(parent->hc_resources[resource] >= - container->hc_resources[resource], - ("resource usage propagation meltdown: child > parent")); - } - } -} -#endif /* DIAGNOSTIC */ - -/* - * Increase consumption of 'resource' by 'amount' for 'container' - * and all its parents. Differently from other cases, 'amount' here - * may be less than zero. - */ -static void -hrl_container_alloc_resource(struct hrl_container *container, int resource, - uint64_t amount) -{ - int i; - - mtx_assert(&hrl_lock, MA_OWNED); - KASSERT(container != NULL, ("NULL container")); - - container->hc_resources[resource] += amount; - for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) { - if (container->hc_parents[i] == NULL) - continue; - hrl_container_alloc_resource(container->hc_parents[i], resource, amount); - } -#ifdef DIAGNOSTIC - hrl_container_assert(container); -#endif -} - -/* - * Increase allocation of 'resource' by 'amount' for process 'p'. - * Return 0 if it's below limits, or errno, if it's not. - */ -int -hrl_alloc(struct proc *p, int resource, uint64_t amount) -{ - int error; - -#if 0 - printf("hrl_alloc: allocating %ju of %s for %s (pid %d)\n", amount, hrl_resource_name(resource), p->p_comm, p->p_pid); -#endif - - KASSERT(amount > 0, ("hrl_alloc: invalid amount for %s: %ju", - hrl_resource_name(resource), amount)); - - mtx_lock(&hrl_lock); - error = hrl_enforce_proc(p, resource, amount); - if (error) { - mtx_unlock(&hrl_lock); - return (error); - } - hrl_container_alloc_resource(&p->p_container, resource, amount); - mtx_unlock(&hrl_lock); - - return (0); -} - -/* - * Set allocation of 'resource' to 'amount' for process 'p'. - * Return 0 if it's below limits, or errno, if it's not. - * - * Note that decreasing the allocation always returns 0, - * even if it's above the limit. - */ -int -hrl_allocated(struct proc *p, int resource, uint64_t amount) -{ - int error; - int64_t diff; - -#if 0 - printf("hrl_allocated: allocated %lld of %s for %s (pid %d)\n", amount, hrl_resource_name(resource), p->p_comm, p->p_pid); -#endif - - KASSERT(amount >= 0, ("hrl_allocated: invalid amount for %s: %ju", - hrl_resource_name(resource), amount)); - - mtx_lock(&hrl_lock); - diff = amount - p->p_container.hc_resources[resource]; - if (diff > 0) { - error = hrl_enforce_proc(p, resource, diff); - if (error) { - mtx_unlock(&hrl_lock); - return (error); - } - } - hrl_container_alloc_resource(&p->p_container, resource, diff); - mtx_unlock(&hrl_lock); - - return (0); -} - -/* - * Decrease allocation of 'resource' by 'amount' for process 'p'. - */ -void -hrl_free(struct proc *p, int resource, uint64_t amount) -{ - -#if 0 - printf("hrl_free: freeing %lld of %s for %s (pid %d)\n", amount, hrl_resource_name(resource), p->p_comm, p->p_pid); -#endif - - KASSERT(amount > 0, ("hrl_free: invalid amount for %s: %ju", - hrl_resource_name(resource), amount)); - - mtx_lock(&hrl_lock); - KASSERT(amount <= p->p_container.hc_resources[resource], - ("hrl_free: freeing %ju of %s, which is more than allocated " - "%ld for %s (pid %d)", amount, hrl_resource_name(resource), - p->p_container.hc_resources[resource], p->p_comm, p->p_pid)); - - hrl_container_alloc_resource(&p->p_container, resource, -amount); - mtx_unlock(&hrl_lock); -} - static int hrl_rule_matches(const struct hrl_rule *rule, const struct hrl_rule *filter) { ==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#43 (text+ko) ==== @@ -94,22 +94,6 @@ * 'hr_per' takes the same flags as 'hr_subject_type'. */ -#define HRL_RESOURCE_UNDEFINED -1 -#define HRL_RESOURCE_CPUTIME 0x0000 -#define HRL_RESOURCE_FILESIZE 0x0001 -#define HRL_RESOURCE_DATASIZE 0x0002 -#define HRL_RESOURCE_STACKSIZE 0x0003 -#define HRL_RESOURCE_COREDUMPSIZE 0x0004 -#define HRL_RESOURCE_MEMORYUSE 0x0005 -#define HRL_RESOURCE_MEMORYLOCKED 0x0006 -#define HRL_RESOURCE_MAXPROCESSES 0x0007 -#define HRL_RESOURCE_FILEDESCRIPTORS 0x0008 -#define HRL_RESOURCE_SBSIZE 0x0009 -#define HRL_RESOURCE_VMEMORYUSE 0x000a -#define HRL_RESOURCE_PTY 0x000b -#define HRL_RESOURCE_SWAP 0x000c -#define HRL_RESOURCE_MAX HRL_RESOURCE_SWAP - #define HRL_ACTION_UNDEFINED -1 #define HRL_ACTION_DENY 0x0000 #define HRL_ACTION_DELAY 0x0001 @@ -124,45 +108,8 @@ #define HRL_AMOUNT_UNDEFINED -1 -/* - * Processes may have at most three parent containers - prison, uidinfo, - * and loginclass. Other subjects have less - struct prison may have only - * one parent container, loginclass and uidinfo structures have none. - * This may change when - and if - we add per-group resource limits. - */ -#define HRL_HC_PARENTS_MAX 3 - -/* - * 'hrl_container' defines resource consumption for a particular - * subject, such as process or jail. Containers form a graph - each - * container has zero or more subcontainers and zero or more - * "containing" containers (parents). For example, container for - * an uidinfo can have several subcontainers for processes of that - * user. On the other hand, each process can have several containing - * containers - one for jail the process is in, one for the user, - * one for every group this process belongs to (note that per-group - * limits are not implemented yet). - * - * Every process has exactly one container assigned to it. Containers - * for other objects are initialized when there is a rule which requires - * it. For example, uidinfo will have container assigned only if there - * is a rule this uidinfo is subject to, and 'hr_per' for this rule - * is HRL_SUBJECT_TYPE_USER. - * - * This structure must be filled with zeroes initially. - */ -struct hrl_container { - int64_t hc_resources[HRL_RESOURCE_MAX + 1]; - struct hrl_container *hc_parents[HRL_HC_PARENTS_MAX + 1]; - LIST_HEAD(, hrl_rule_link) hc_rule_links; -}; - #ifdef _KERNEL -int hrl_alloc(struct proc *p, int object, uint64_t amount); -int hrl_allocated(struct proc *p, int object, uint64_t amount); -void hrl_free(struct proc *p, int object, uint64_t amount); - void hrl_proc_exiting(struct proc *p); void hrl_proc_init(struct proc *p); @@ -175,8 +122,8 @@ int hrl_rule_add(struct hrl_rule *rule); int hrl_rule_remove(const struct hrl_rule *filter); -void hrl_container_create(struct hrl_container *container); -void hrl_container_destroy(struct hrl_container *container); +int hrl_enforce_proc(struct proc *p, int resource, uint64_t amount); +const char *hrl_resource_name(int resource); #else /* !_KERNEL */ ==== //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#14 (text+ko) ==== @@ -30,7 +30,7 @@ #ifndef _SYS_JAIL_H_ #define _SYS_JAIL_H_ -#include +#include #ifdef _KERNEL struct jail_v0 { ==== //depot/projects/soc2009/trasz_limits/sys/sys/loginclass.h#7 (text+ko) ==== @@ -27,7 +27,7 @@ #ifndef _SYS_LOGINCLASS_H_ #define _SYS_LOGINCLASS_H_ -#include +#include /* * Exactly one of these structures exists per login class. ==== //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#20 (text+ko) ==== @@ -44,7 +44,7 @@ #ifndef _KERNEL #include #endif -#include +#include #include #include #include ==== //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#17 (text+ko) ==== @@ -38,6 +38,7 @@ #ifdef _KERNEL #include #include +#include #include #endif