Date: Sat, 8 Aug 2009 17:38:35 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 167111 for review Message-ID: <200908081738.n78HcZ97057924@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167111 Change 167111 by trasz@trasz_anger on 2009/08/08 17:37:52 Make enforcement code a little saner. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#49 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#49 (text+ko) ==== @@ -248,9 +248,13 @@ 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 hrl_rule *rules[HRL_RESOURCE_MAX], *rule; + struct hrl_limit *limit; struct sbuf *sb; + int should_deny = 0; + mtx_assert(&hrl_lock, MA_OWNED); + /* * XXX: Do this just before we start running on a CPU, not all the time. */ @@ -259,44 +263,74 @@ if (available[resource] >= amount) return (0); - switch (rules[resource]->hr_action) { - case HRL_ACTION_DENY: + /* + * It seems we've hit a limit. Figure out what to do. There may + * be more than one matching limit; go through all of them. Denial + * should be done last, after logging and sending signals. + */ + /* + * XXX: We should sort the rules somewhat, so that 'log' and 'sig' + * rules come before before 'deny', to spare iterations over + * the p_limits. + */ + LIST_FOREACH(limit, &p->p_limits, hl_next) { + rule = limit->hl_rule; + if (rule->hr_resource != resource) + continue; + if (rule->hr_amount < available[resource]); + continue; + if (rule->hr_amount > available[resource] + amount); + continue; + + /* + * This rule should apply to us. Behave accordingly. + */ + switch (rule->hr_action) { + case HRL_ACTION_DENY: + should_deny = 1; + break; + case HRL_ACTION_LOG: + sb = sbuf_new_auto(); + hrl_rule_to_sbuf(sb, rule); + 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); + break; + case HRL_ACTION_SIGHUP: + hrl_deferred_psignal(p, SIGHUP); + break; + case HRL_ACTION_SIGINT: + hrl_deferred_psignal(p, SIGINT); + break; + case HRL_ACTION_SIGKILL: + hrl_deferred_psignal(p, SIGKILL); + break; + case HRL_ACTION_SIGSEGV: + hrl_deferred_psignal(p, SIGSEGV); + break; + case HRL_ACTION_SIGXCPU: + hrl_deferred_psignal(p, SIGXCPU); + break; + case HRL_ACTION_SIGXFSZ: + hrl_deferred_psignal(p, SIGXFSZ); + break; + default: + panic("hrl_enforce_proc: unknown action %d", + rule->hr_action); + } + } + + if (should_deny) { /* * Return fake error code; the caller should change it - * into proper one for the situation - EFSIZ, ENOMEM etc. + * into one proper for the situation - EFSIZ, ENOMEM etc. */ return (EDOOFUS); - case HRL_ACTION_LOG: - sb = sbuf_new_auto(); - hrl_rule_to_sbuf(sb, rules[resource]); - 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); } + + return (0); } /* @@ -304,10 +338,6 @@ * with amount of resource left before hitting next limit, and the second * with pointers to the limit to be hit. */ -/* - * XXX: We should sort the rules somewhat, so that 'log' rules are enforced - * before 'deny', if both are for the same subject, resource and amount. - */ static void hrl_compute_available(struct proc *p, int64_t (*availablep)[], struct hrl_rule *(*rulesp)[]) @@ -323,8 +353,6 @@ (*rulesp)[i] = NULL; } - mtx_assert(&hrl_lock, MA_OWNED); - LIST_FOREACH(limit, &p->p_limits, hl_next) { resource = limit->hl_rule->hr_resource; available = limit->hl_rule->hr_amount -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908081738.n78HcZ97057924>