Skip site navigation (1)Skip section navigation (2)
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>