Date: Mon, 13 Jul 2009 17:21:04 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 166016 for review Message-ID: <200907131721.n6DHL4jg029519@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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++; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907131721.n6DHL4jg029519>