From owner-p4-projects@FreeBSD.ORG Mon Jul 13 17:21:05 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5C3AE1065674; Mon, 13 Jul 2009 17:21:05 +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 CCADA106566B for ; Mon, 13 Jul 2009 17:21:04 +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 B94B78FC0C for ; Mon, 13 Jul 2009 17:21:04 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n6DHL4xJ029521 for ; Mon, 13 Jul 2009 17:21:04 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n6DHL4jg029519 for perforce@freebsd.org; Mon, 13 Jul 2009 17:21:04 GMT (envelope-from trasz@freebsd.org) Date: Mon, 13 Jul 2009 17:21:04 GMT Message-Id: <200907131721.n6DHL4jg029519@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 Cc: Subject: PERFORCE change 166016 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Jul 2009 17:21:06 -0000 http://perforce.freebsd.org/chv.cgi?CH=166016 Change 166016 by trasz@trasz_victim on 2009/07/13 17:20:20 Add support for actions. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#30 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#30 (text+ko) ==== @@ -157,6 +157,7 @@ static void hrl_rule_add_limits(struct hrl_rule *rule); static void hrl_compute_available(struct proc *p, int64_t (*availablep)[], struct hrl_rule *(*rulesp)[]); +static struct sbuf *hrl_rules_to_sbuf(struct hrl_rule *usage, int nrules); MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits"); @@ -289,18 +290,93 @@ mtx_unlock(&hrl_lock); } +static void +hrl_deferred_psignal(struct proc *p, int signum) +{ + + PROC_LOCK(p); + psignal(p, signum); + PROC_UNLOCK(p); +} + /* + * Check whether the proc 'p' can allocate 'amount' of 'resource' in addition + * to what it has allocated now. Returns fake error code if the allocation + * should fail. + */ +static int +hrl_enforce_proc(struct proc *p, int resource, uint64_t amount) +{ + int64_t available[HRL_RESOURCE_MAX]; + struct hrl_rule *rules[HRL_RESOURCE_MAX]; + struct sbuf *sb; + + /* + * XXX: Check maxfilesperproc. + */ + /* + * XXX: Do this just before we start running on a CPU, not all the time. + */ + hrl_compute_available(p, &available, &rules); + + if (available[resource] >= amount) + return (0); + + switch (rules[resource]->hr_action) { + case HRL_ACTION_DENY: + /* + * Return fake error code; the caller should change it + * into proper one for the situation - EFSIZ, ENOMEM etc. + */ + return (EDOOFUS); + case HRL_ACTION_DELAY: + /* + * XXX: Think whether we actually can and want to do this. + */ + printf("hrl_enforce_proc: XXX, \"delay\" unimplemented.\n"); + return (0); + case HRL_ACTION_LOG: + sb = hrl_rules_to_sbuf(rules[resource], 1); + sbuf_finish(sb); + printf("resource limit \"%s\" exceeded by process %d (%s), " + "uid %d\n", sbuf_data(sb), p->p_pid, p->p_comm, + p->p_ucred->cr_uid); + sbuf_delete(sb); + return (0); + case HRL_ACTION_SIGHUP: + hrl_deferred_psignal(p, SIGHUP); + return (0); + case HRL_ACTION_SIGINT: + hrl_deferred_psignal(p, SIGINT); + return (0); + case HRL_ACTION_SIGKILL: + hrl_deferred_psignal(p, SIGKILL); + return (0); + case HRL_ACTION_SIGSEGV: + hrl_deferred_psignal(p, SIGSEGV); + return (0); + case HRL_ACTION_SIGXCPU: + hrl_deferred_psignal(p, SIGXCPU); + return (0); + case HRL_ACTION_SIGXFSZ: + hrl_deferred_psignal(p, SIGXFSZ); + return (0); + default: + panic("hrl_enforce_proc: unknown action %d", + rules[resource]->hr_action); + } +} + +/* * 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_proc(struct proc *p, int resource, uint64_t amount) { - int i, j; + int i, j, error; struct ucred *cred; struct prison *pr; - int64_t available[HRL_RESOURCE_MAX]; - struct hrl_rule *rules[HRL_RESOURCE_MAX]; KASSERT(amount > 0, ("hrl_alloc_proc: invalid amount for %s: %lld", hrl_resource_name(resource), amount)); @@ -310,20 +386,10 @@ #endif mtx_lock(&hrl_lock); - /* - * XXX: Check maxfilesperproc. - */ - /* - * XXX: Do this just before we start running on a CPU, not all the time. - */ - hrl_compute_available(p, &available, &rules); - /* - * Return fake error code; the caller should change it into proper - * one for the situation - EFSIZ, ENOMEM, EMFILE etc. - */ - if (available[resource] < 0 && rules[resource]->hr_action == HRL_ACTION_DENY) { + error = hrl_enforce_proc(p, resource, amount); + if (error) { mtx_unlock(&hrl_lock); - return (EDOOFUS); + return (error); } p->p_usage.hu_resources[resource] += amount; cred = p->p_ucred; @@ -368,12 +434,10 @@ int hrl_allocated_proc(struct proc *p, int resource, uint64_t amount) { - int i, j; + int i, j, error; int64_t diff; struct ucred *cred; struct prison *pr; - int64_t available[HRL_RESOURCE_MAX]; - struct hrl_rule *rules[HRL_RESOURCE_MAX]; KASSERT(amount >= 0, ("hrl_allocated_proc: invalid amount for %s: %lld", hrl_resource_name(resource), amount)); @@ -385,17 +449,10 @@ mtx_lock(&hrl_lock); diff = amount - p->p_usage.hu_resources[resource]; if (diff > 0) { - /* - * XXX: Do this just before we start running on a CPU, not all the time. - */ - hrl_compute_available(p, &available, &rules); - /* - * Return fake error code; the caller should change it into proper - * one for the situation - EFSIZ, ENOMEM, EMFILE etc. - */ - if (available[resource] < 0 && rules[resource]->hr_action == HRL_ACTION_DENY) { + error = hrl_enforce_proc(p, resource, diff); + if (error) { mtx_unlock(&hrl_lock); - return (EDOOFUS); + return (error); } } p->p_usage.hu_resources[resource] = amount; @@ -1111,6 +1168,8 @@ * copy it directly to the userland because of the mutex. */ for (i = 0; i < HRL_RESOURCE_MAX; i++) { + if (rules[i] == NULL) + continue; *(buf + copied) = *(rules[i]); copied++; }