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