PERFORCE change 166016 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Mon Jul 13 17:21:06 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166016

Change 166016 by trasz at 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++;
 	}


More information about the p4-projects mailing list