From owner-p4-projects@FreeBSD.ORG Mon Aug 3 17:55:45 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3A95D1065672; Mon, 3 Aug 2009 17:55:45 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B8BDB106566C for ; Mon, 3 Aug 2009 17:55:44 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 9BE0A8FC0A for ; Mon, 3 Aug 2009 17:55:44 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n73HtiSB083015 for ; Mon, 3 Aug 2009 17:55:44 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n73HtiIg083013 for perforce@freebsd.org; Mon, 3 Aug 2009 17:55:44 GMT (envelope-from trasz@freebsd.org) Date: Mon, 3 Aug 2009 17:55:44 GMT Message-Id: <200908031755.n73HtiIg083013@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 166975 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Aug 2009 17:55:46 -0000 http://perforce.freebsd.org/chv.cgi?CH=166975 Change 166975 by trasz@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) ====