PERFORCE change 166975 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Mon Aug 3 17:55:46 UTC 2009


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

Change 166975 by trasz at trasz_anger on 2009/08/03 17:55:17

	Add support for per-uid and per-gid rules.  Also,
	fix removing rules with 'per' different from 'subject'.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/TODO#7 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#41 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#19 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#10 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/TODO#7 (text+ko) ====

@@ -1,5 +1,6 @@
 
- - Rework rule storage.
+ - In hrl_rule, instead of keeping subject ids, keep links to a process,
+   uidinfo and gidinfo, the same way we do with loginclasses.
 
  - Make sure we have all the gidinfos we need in the 'struct ucred'.
 

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#41 (text+ko) ====

@@ -883,7 +883,7 @@
 	}
 
 	if (perstr == NULL || perstr[0] == '\0')
-		rule->hr_per = rule->hr_subject;
+		rule->hr_per = HRL_SUBJECT_UNDEFINED;
 	else {
 		error = str2value(perstr, &rule->hr_per, subjectnames);
 		if (error)
@@ -947,7 +947,7 @@
 
 	case HRL_SUBJECT_USER:
 		uip = uifind(rule->hr_subject_id);
-		KASSERT(uip == NULL, ("hrl_rule_add: uifind failed"));
+		KASSERT(uip != NULL, ("hrl_rule_add: uifind failed"));
 		hrl_limit_add(&uip->ui_limits, rule);
 		/*
 		 * Don't call uifree(2); we don't want the uidinfo
@@ -959,7 +959,7 @@
 
 	case HRL_SUBJECT_GROUP:
 		gip = gifind_existing(rule->hr_subject_id);
-		KASSERT(gip == NULL, ("hrl_rule_add: gifind failed"));
+		KASSERT(gip != NULL, ("hrl_rule_add: gifind failed"));
 		hrl_limit_add(&gip->gi_limits, rule);
 		break;
 
@@ -1292,8 +1292,10 @@
 	struct hrl_rule *buf = (struct hrl_rule *)arg3;
 	int copied = 0, *available = (int *)arg4;
 
+	mtx_assert(&hrl_lock, MA_OWNED);
+
 	LIST_FOREACH(limit, limits, hl_next) {
-		if (copied >= *available)
+		if (*available <= 0)
 			return (ERANGE);
 		if (!hrl_rule_matches(limit->hl_rule, filter))
 			continue;
@@ -1308,7 +1310,7 @@
 int
 hrl_get_rules(struct thread *td, struct hrl_get_rules_args *uap)
 {
-	int error, copied, maxcopied = HRL_MAX_RULES, available;
+	int error, copied, bufsize = HRL_MAX_RULES, available;
 	char *inputstr;
 	struct sbuf *outputsbuf;
 	struct hrl_rule *filter, *buf;
@@ -1325,16 +1327,17 @@
 		return (EINVAL);
 
 again:
-	buf = malloc(maxcopied * sizeof(*buf), M_HRL, M_WAITOK);
+	buf = malloc(bufsize * sizeof(*buf), M_HRL, M_WAITOK);
+	available = bufsize;
 	copied = 0;
 	sx_slock(&proctree_lock);
 	FOREACH_PROC_IN_SYSTEM(p) {
 		mtx_lock(&hrl_lock);
 		LIST_FOREACH(limit, &p->p_limits, hl_next) {
-			if (copied >= maxcopied) {
+			if (available <= 0) {
 				mtx_unlock(&hrl_lock);
 				sx_sunlock(&proctree_lock);
-				maxcopied *= 4;
+				bufsize *= 4;
 				free(buf, M_HRL);
 				goto again;
 			}
@@ -1348,39 +1351,32 @@
 				continue;
 			*(buf + copied) = *limit->hl_rule;
 			copied++;
+			available--;
 		}
 		mtx_unlock(&hrl_lock);
 	}
 	sx_sunlock(&proctree_lock);
-	if (error)
-		goto out;
 
-	available = maxcopied - copied;
+	mtx_lock(&hrl_lock);
 	loginclass_limits_foreach(hrl_get_rules_callback, filter,
 	    buf + copied, &available);
-	copied = maxcopied - available;
-	available = maxcopied - copied;
+	copied = bufsize - available;
 	ui_limits_foreach(hrl_get_rules_callback, filter,
 	    buf + copied, &available);
-	copied = maxcopied - available;
-	available = maxcopied - copied;
+	copied = bufsize - available;
 	gi_limits_foreach(hrl_get_rules_callback, filter,
 	    buf + copied, &available);
-	copied = maxcopied - available;
-	if (copied >= maxcopied) {
-		maxcopied *= 4;
+	mtx_unlock(&hrl_lock);
+	if (available <= 0) {
+		bufsize *= 4;
 		free(buf, M_HRL);
 		goto again;
 	}
 
-	/*
-	 * XXX: Iterate over the rest (other than per-process) of the rules.
-	 */
-
 	outputsbuf = hrl_rules_to_sbuf(buf, copied);
 
 	error = hrl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen);
-out:
+
 	hrl_rule_release(filter);
 	free(buf, M_HRL);
 	return (error);
@@ -1474,6 +1470,12 @@
 	free(inputstr, M_HRL);
 	if (rule == NULL)
 		return (EINVAL);
+	/*
+	 * The 'per' part of a rule is optional.
+	 */
+	if (rule->hr_per == HRL_SUBJECT_UNDEFINED &&
+	    rule->hr_subject != HRL_SUBJECT_UNDEFINED)
+		rule->hr_per = rule->hr_subject;
 
 	if (!hrl_rule_fully_specified(rule)) {
 		error = EINVAL;

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#19 (text+ko) ====

@@ -1417,11 +1417,23 @@
     const struct hrl_rule *filter, void *arg3, void *arg4),
     const struct hrl_rule *filter, void *arg3, void *arg4)
 {
+	int error;
+	struct uidinfo *uip, *nextuip;
+	struct uihashhead *uih;
+
+	rw_rlock(&uihashtbl_lock);
+	for (uih = &uihashtbl[uihash]; uih >= uihashtbl; uih--) {
+		for (uip = LIST_FIRST(uih); uip; uip = nextuip) {
+			nextuip = LIST_NEXT(uip, ui_hash);
+			error = (callback)(&uip->ui_limits, filter, arg3, arg4);
+			if (error) {
+				rw_runlock(&uihashtbl_lock);
+				return (error);
+			}
+		}
+	}
+	rw_runlock(&uihashtbl_lock);
 
-	callback = callback;
-	filter = filter;
-	arg3 = arg3;
-	arg4 = arg4;
 	return (0);
 }
 
@@ -1575,11 +1587,22 @@
     const struct hrl_rule *filter, void *arg3, void *arg4),
     const struct hrl_rule *filter, void *arg3, void *arg4)
 {
+	int error;
+	struct gidinfo *gip, *nextgip;
+	struct gihashhead *gih;
 
-	callback = callback;
-	filter = filter;
-	arg3 = arg3;
-	arg4 = arg4;
+	rw_rlock(&gihashtbl_lock);
+	for (gih = &gihashtbl[gihash]; gih >= gihashtbl; gih--) {
+		for (gip = LIST_FIRST(gih); gip; gip = nextgip) {
+			nextgip = LIST_NEXT(gip, gi_hash);
+			error = (callback)(&gip->gi_limits, filter, arg3, arg4);
+			if (error) {
+				rw_runlock(&gihashtbl_lock);
+				return (error);
+			}
+		}
+	}
+	rw_runlock(&gihashtbl_lock);
 
 	return (0);
 }

==== //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#10 (text+ko) ====



More information about the p4-projects mailing list