PERFORCE change 180961 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Wed Jul 14 19:48:48 UTC 2010
http://p4web.freebsd.org/@@180961?ac=10
Change 180961 by trasz at trasz_victim on 2010/07/14 19:48:20
Get rid of 'struct gidinfo'. Per-group resource limits are not going
to happen; it would be bad performance-wise and would complicate
the code (right now each container can have at most three containing
containers, so we can store parents in a simple, fixed size array;
this wouldn't work with per-group limits). Besides, in most cases
you want to use per-group or per-loginclass limits anyway.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#87 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_proc.c#14 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#37 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#47 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#20 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#87 (text+ko) ====
@@ -85,7 +85,6 @@
static struct dict subjectnames[] = {
{ "process", HRL_SUBJECT_TYPE_PROCESS },
{ "user", HRL_SUBJECT_TYPE_USER },
- { "group", HRL_SUBJECT_TYPE_GROUP },
{ "loginclass", HRL_SUBJECT_TYPE_LOGINCLASS },
{ "jail", HRL_SUBJECT_TYPE_JAIL },
{ NULL, -1 }};
@@ -359,11 +358,6 @@
filter->hr_subject.hs_uip)
return (0);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- if (filter->hr_subject.hs_gip !=
- filter->hr_subject.hs_gip)
- return (0);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (filter->hr_subject.hs_loginclass !=
filter->hr_subject.hs_loginclass)
@@ -526,10 +520,6 @@
if (rule->hr_subject.hs_uip != NULL)
uihold(rule->hr_subject.hs_uip);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- if (rule->hr_subject.hs_gip != NULL)
- gihold(rule->hr_subject.hs_gip);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (rule->hr_subject.hs_loginclass != NULL)
loginclass_acquire(rule->hr_subject.hs_loginclass);
@@ -556,10 +546,6 @@
if (rule->hr_subject.hs_uip != NULL)
uifree(rule->hr_subject.hs_uip);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- if (rule->hr_subject.hs_gip != NULL)
- gifree(rule->hr_subject.hs_gip);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (rule->hr_subject.hs_loginclass != NULL)
loginclass_release(rule->hr_subject.hs_loginclass);
@@ -588,7 +574,6 @@
rule->hr_subject_type = HRL_SUBJECT_TYPE_UNDEFINED;
rule->hr_subject.hs_proc = NULL;
rule->hr_subject.hs_uip = NULL;
- rule->hr_subject.hs_gip = NULL;
rule->hr_subject.hs_loginclass = NULL;
rule->hr_subject.hs_prison = NULL;
rule->hr_per = HRL_SUBJECT_TYPE_UNDEFINED;
@@ -611,7 +596,6 @@
copy->hr_subject_type = rule->hr_subject_type;
copy->hr_subject.hs_proc = rule->hr_subject.hs_proc;
copy->hr_subject.hs_uip = rule->hr_subject.hs_uip;
- copy->hr_subject.hs_gip = rule->hr_subject.hs_gip;
copy->hr_subject.hs_loginclass = rule->hr_subject.hs_loginclass;
copy->hr_subject.hs_prison = rule->hr_subject.hs_prison;
copy->hr_per = rule->hr_per;
@@ -660,10 +644,6 @@
if (rule->hr_subject.hs_uip == NULL)
return (0);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- if (rule->hr_subject.hs_gip == NULL)
- return (0);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (rule->hr_subject.hs_loginclass == NULL)
return (0);
@@ -717,7 +697,6 @@
if (subject_idstr == NULL || subject_idstr[0] == '\0') {
rule->hr_subject.hs_proc = NULL;
rule->hr_subject.hs_uip = NULL;
- rule->hr_subject.hs_gip = NULL;
rule->hr_subject.hs_loginclass = NULL;
rule->hr_subject.hs_prison = NULL;
} else {
@@ -746,9 +725,6 @@
case HRL_SUBJECT_TYPE_USER:
rule->hr_subject.hs_uip = uifind(id);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- rule->hr_subject.hs_gip = gifind(id);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
rule->hr_subject.hs_loginclass = loginclass_find(subject_idstr);
break;
@@ -818,16 +794,11 @@
struct proc *p;
struct ucred *cred;
struct uidinfo *uip;
- struct gidinfo *gip;
struct prison *pr;
struct loginclass *lc;
KASSERT(hrl_rule_fully_specified(rule), ("rule not fully specified"));
- if (rule->hr_subject_type == HRL_SUBJECT_TYPE_GROUP ||
- rule->hr_per == HRL_SUBJECT_TYPE_GROUP)
- return (EOPNOTSUPP);
-
if (rule->hr_action == HRL_ACTION_DELAY)
return (EOPNOTSUPP);
@@ -855,12 +826,6 @@
hrl_container_add_rule(&uip->ui_container, rule);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- gip = rule->hr_subject.hs_gip;
- KASSERT(gip != NULL, ("hrl_rule_add: NULL gip"));
- hrl_container_add_rule(&gip->gi_container, rule);
- break;
-
case HRL_SUBJECT_TYPE_LOGINCLASS:
lc = rule->hr_subject.hs_loginclass;
KASSERT(lc != NULL, ("hrl_rule_add: NULL loginclass"));
@@ -891,10 +856,6 @@
cred->cr_ruidinfo == rule->hr_subject.hs_uip)
break;
continue;
- case HRL_SUBJECT_TYPE_GROUP:
- if (groupmember(rule->hr_subject.hs_gip->gi_gid, cred))
- break;
- continue;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (cred->cr_loginclass == rule->hr_subject.hs_loginclass)
break;
@@ -948,9 +909,6 @@
error = ui_container_foreach(hrl_rule_remove_callback, filter,
(void *)&found);
KASSERT(error == 0, ("ui_container_foreach failed"));
- error = gi_container_foreach(hrl_rule_remove_callback, filter,
- (void *)&found);
- KASSERT(error == 0, ("gi_container_foreach failed"));
sx_assert(&allproc_lock, SA_LOCKED);
FOREACH_PROC_IN_SYSTEM(p) {
@@ -986,12 +944,6 @@
else
sbuf_printf(sb, "%d:", rule->hr_subject.hs_uip->ui_uid);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- if (rule->hr_subject.hs_gip == NULL)
- sbuf_printf(sb, ":");
- else
- sbuf_printf(sb, "%d:", rule->hr_subject.hs_gip->gi_gid);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
if (rule->hr_subject.hs_loginclass == NULL)
sbuf_printf(sb, ":");
@@ -1088,7 +1040,6 @@
struct sbuf *outputsbuf = NULL;
struct proc *p;
struct uidinfo *uip;
- struct gidinfo *gip;
struct loginclass *lc;
struct prison *pr;
@@ -1121,14 +1072,6 @@
}
outputsbuf = hrl_container_to_sbuf(&uip->ui_container);
break;
- case HRL_SUBJECT_TYPE_GROUP:
- gip = filter->hr_subject.hs_gip;
- if (gip == NULL) {
- error = EINVAL;
- goto out;
- }
- outputsbuf = hrl_container_to_sbuf(&gip->gi_container);
- break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
lc = filter->hr_subject.hs_loginclass;
if (lc == NULL) {
@@ -1227,7 +1170,6 @@
mtx_lock(&hrl_lock);
loginclass_container_foreach(hrl_get_rules_callback, filter, sb);
ui_container_foreach(hrl_get_rules_callback, filter, sb);
- gi_container_foreach(hrl_get_rules_callback, filter, sb);
mtx_unlock(&hrl_lock);
if (sbuf_overflowed(sb)) {
sbuf_delete(sb);
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_proc.c#14 (text+ko) ====
@@ -173,7 +173,6 @@
proc_ctor, proc_dtor, proc_init, proc_fini,
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uihashinit();
- gihashinit();
}
/*
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#37 (text+ko) ====
@@ -73,18 +73,12 @@
static struct rwlock uihashtbl_lock;
static LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
static u_long uihash; /* size of hash table - 1 */
-static MALLOC_DEFINE(M_GIDINFO, "gidinfo", "gidinfo structures");
-#define GIHASH(gid) (&gihashtbl[(gid) & gihash])
-static struct rwlock gihashtbl_lock;
-static LIST_HEAD(gihashhead, gidinfo) *gihashtbl;
-static u_long gihash; /* size of hash table - 1 */
static void calcru1(struct proc *p, struct rusage_ext *ruxp,
struct timeval *up, struct timeval *sp);
static int donice(struct thread *td, struct proc *chgp, int n);
static struct uidinfo *uilookup(uid_t uid);
static void ruxagg_locked(struct rusage_ext *rux, struct thread *td);
-static struct gidinfo *gilookup(gid_t gid);
/*
* Resource controls and accounting.
@@ -1446,158 +1440,6 @@
#endif
/*
- * Find the gidinfo structure for a gid. This structure is used to
- * track the total resource consumption (process count, socket buffer
- * size, etc.) for the gid and impose limits.
- */
-void
-gihashinit()
-{
-
- gihashtbl = hashinit(maxproc / 16, M_GIDINFO, &gihash);
- rw_init(&gihashtbl_lock, "gidinfo hash");
-}
-
-/*
- * Look up a gidinfo struct for the parameter gid.
- * gihashtbl_lock must be locked.
- */
-static struct gidinfo *
-gilookup(gid)
- gid_t gid;
-{
- struct gihashhead *gipp;
- struct gidinfo *gip;
-
- rw_assert(&gihashtbl_lock, RA_LOCKED);
- gipp = GIHASH(gid);
- LIST_FOREACH(gip, gipp, gi_hash)
- if (gip->gi_gid == gid)
- break;
-
- return (gip);
-}
-
-/*
- * Find or allocate a struct gidinfo for a particular gid.
- * Increase refcount on gidinfo struct returned.
- * gifree() should be called on a struct gidinfo when released.
- */
-struct gidinfo *
-gifind(gid)
- gid_t gid;
-{
- struct gidinfo *old_gip, *gip;
-
- rw_rlock(&gihashtbl_lock);
- gip = gilookup(gid);
- if (gip == NULL) {
- rw_runlock(&gihashtbl_lock);
- gip = malloc(sizeof(*gip), M_GIDINFO, M_WAITOK | M_ZERO);
- rw_wlock(&gihashtbl_lock);
- /*
- * There's a chance someone created our gidinfo while we
- * were in malloc and not holding the lock, so we have to
- * make sure we don't insert a duplicate gidinfo.
- */
- if ((old_gip = gilookup(gid)) != NULL) {
- /* Someone else beat us to it. */
- free(gip, M_GIDINFO);
- gip = old_gip;
- } else {
- refcount_init(&gip->gi_ref, 0);
- gip->gi_gid = gid;
- LIST_INSERT_HEAD(GIHASH(gid), gip, gi_hash);
- }
- }
- gihold(gip);
- rw_unlock(&gihashtbl_lock);
- return (gip);
-}
-
-/*
- * Place another refcount on a gidinfo struct.
- */
-void
-gihold(gip)
- struct gidinfo *gip;
-{
-
- refcount_acquire(&gip->gi_ref);
-}
-
-/*-
- * Since gidinfo structs have a long lifetime, we use an
- * opportunistic refcounting scheme to avoid locking the lookup hash
- * for each release.
- *
- * If the refcount hits 0, we need to free the structure,
- * which means we need to lock the hash.
- * Optimal case:
- * After locking the struct and lowering the refcount, if we find
- * that we don't need to free, simply unlock and return.
- * Suboptimal case:
- * If refcount lowering results in need to free, bump the count
- * back up, lose the lock and acquire the locks in the proper
- * order to try again.
- */
-void
-gifree(gip)
- struct gidinfo *gip;
-{
- int old;
-
- /* Prepare for optimal case. */
- old = gip->gi_ref;
- if (old > 1 && atomic_cmpset_int(&gip->gi_ref, old, old - 1))
- return;
-
- /* Prepare for suboptimal case. */
- rw_wlock(&gihashtbl_lock);
- if (refcount_release(&gip->gi_ref)) {
-#ifdef HRL
- container_destroy(&gip->gi_container);
-#endif
- LIST_REMOVE(gip, gi_hash);
- rw_wunlock(&gihashtbl_lock);
- free(gip, M_GIDINFO);
- return;
- }
- /*
- * Someone added a reference between atomic_cmpset_int() and
- * rw_wlock(&gihashtbl_lock).
- */
- rw_wunlock(&gihashtbl_lock);
-}
-
-#ifdef HRL
-int
-gi_container_foreach(int (*callback)(struct container *container,
- const struct hrl_rule *filter, void *arg3),
- const struct hrl_rule *filter, void *arg3)
-{
- int error;
- struct gidinfo *gip, *nextgip;
- struct gihashhead *gih;
-
- 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_container, filter, arg3);
- if (error) {
- rw_runlock(&gihashtbl_lock);
- return (error);
- }
- }
- }
- rw_runlock(&gihashtbl_lock);
-
- return (0);
-}
-#endif
-
-/*
* Change the count associated with number of processes
* a given user is using. When 'max' is 0, don't enforce a limit
*/
==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#47 (text+ko) ====
@@ -35,7 +35,6 @@
struct proc;
struct uidinfo;
-struct gidinfo;
struct loginclass;
struct prison;
struct ucred;
@@ -71,7 +70,6 @@
#endif
struct proc *hs_proc;
struct uidinfo *hs_uip;
- struct gidinfo *hs_gip;
struct loginclass *hs_loginclass;
struct prison *hs_prison;
} hr_subject;
@@ -85,7 +83,6 @@
#define HRL_SUBJECT_TYPE_UNDEFINED -1
#define HRL_SUBJECT_TYPE_PROCESS 0x0000
#define HRL_SUBJECT_TYPE_USER 0x0001
-#define HRL_SUBJECT_TYPE_GROUP 0x0002
#define HRL_SUBJECT_TYPE_LOGINCLASS 0x0003
#define HRL_SUBJECT_TYPE_JAIL 0x0004
#define HRL_SUBJECT_TYPE_MAX HRL_SUBJECT_TYPE_JAIL
==== //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#20 (text+ko) ====
@@ -104,21 +104,6 @@
#define UIDINFO_VMSIZE_LOCK(ui) mtx_lock(&((ui)->ui_vmsize_mtx))
#define UIDINFO_VMSIZE_UNLOCK(ui) mtx_unlock(&((ui)->ui_vmsize_mtx))
-/*
- * Per gid resource consumption
- *
- * Locking guide:
- * (a) Constant from inception
- * (b) Lockless, updated using atomics
- * (c) Locked by global uihashtbl_mtx
- */
-struct gidinfo {
- LIST_ENTRY(gidinfo) gi_hash; /* (c) hash chain of gidinfos */
- gid_t gi_gid; /* (a) gid */
- u_int gi_ref; /* (b) reference count */
- struct container gi_container; /* (*) resource usage accounting */
-};
-
struct proc;
struct rusage_ext;
struct thread;
@@ -159,14 +144,6 @@
int ui_container_foreach(int (*callback)(struct container *container,
const struct hrl_rule *filter, void *arg3),
const struct hrl_rule *filter, void *arg3);
-struct gidinfo
- *gifind(gid_t gid);
-void gifree(struct gidinfo *gip);
-void gihashinit(void);
-void gihold(struct gidinfo *gip);
-int gi_container_foreach(int (*callback)(struct container *container,
- const struct hrl_rule *filter, void *arg3),
- const struct hrl_rule *filter, void *arg3);
#endif /* _KERNEL */
#endif /* !_SYS_RESOURCEVAR_H_ */
More information about the p4-projects
mailing list