PERFORCE change 169386 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Sun Oct 11 12:18:47 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=169386
Change 169386 by trasz at trasz_victim on 2009/10/11 12:17:57
First step in removing strict 1:1 relationship between subjects
(uidinfo, prison etc) and resource containers: a little renaming.
What was hrl_usage becomes hrl_container.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#66 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_jail.c#15 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_loginclass.c#14 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#26 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#37 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#10 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/loginclass.h#5 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#13 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#13 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#66 (text+ko) ====
@@ -128,18 +128,18 @@
cred = p->p_ucred;
mtx_assert(&hrl_lock, MA_OWNED);
for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++)
- KASSERT(p->p_usage.hu_resources[resource] >= 0,
+ KASSERT(p->p_container.hc_resources[resource] >= 0,
("resource usage propagation meltdown"));
- KASSERT(cred->cr_ruidinfo->ui_usage.hu_resources[resource] >= 0,
+ KASSERT(cred->cr_ruidinfo->ui_container.hc_resources[resource] >= 0,
("resource usage propagation meltdown"));
- KASSERT(cred->cr_ruidinfo->ui_usage.hu_resources[resource] >=
- p->p_usage.hu_resources[resource],
+ KASSERT(cred->cr_ruidinfo->ui_container.hc_resources[resource] >=
+ p->p_container.hc_resources[resource],
("resource usage propagation meltdown"));
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) {
- KASSERT(pr->pr_usage.hu_resources[resource] >= 0,
+ KASSERT(pr->pr_container.hc_resources[resource] >= 0,
("resource usage propagation meltdown"));
- KASSERT(pr->pr_usage.hu_resources[resource] >=
- p->p_usage.hu_resources[resource],
+ KASSERT(pr->pr_container.hc_resources[resource] >=
+ p->p_container.hc_resources[resource],
("resource usage propagation meltdown"));
}
}
@@ -159,7 +159,7 @@
mtx_lock(&hrl_lock);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- KASSERT(p->p_usage.hu_resources[i] == 0,
+ KASSERT(p->p_container.hc_resources[i] == 0,
("dead process still holding resources"));
}
mtx_unlock(&hrl_lock);
@@ -251,20 +251,20 @@
switch (rule->hr_per) {
case HRL_SUBJECT_TYPE_PROCESS:
available = rule->hr_amount -
- p->p_usage.hu_resources[resource];
+ p->p_container.hc_resources[resource];
break;
case HRL_SUBJECT_TYPE_USER:
available = rule->hr_amount -
- cred->cr_ruidinfo->ui_usage.hu_resources[resource];
+ cred->cr_ruidinfo->ui_container.hc_resources[resource];
break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
available = rule->hr_amount -
- cred->cr_loginclass->lc_usage.hu_resources[resource];
+ cred->cr_loginclass->lc_container.hc_resources[resource];
available = INT64_MAX; /* XXX */
break;
case HRL_SUBJECT_TYPE_JAIL:
available = rule->hr_amount -
- cred->cr_prison->pr_usage.hu_resources[resource];
+ cred->cr_prison->pr_container.hc_resources[resource];
break;
default:
panic("hrl_compute_available: unknown per %d",
@@ -437,6 +437,31 @@
}
}
+void
+hrl_container_create(struct hrl_container *container)
+{
+ int i;
+
+ for (i = 0; i <= HRL_RESOURCE_MAX; i++)
+ KASSERT(container->hc_resources[i] == 0,
+ ("container not zeroed"));
+}
+
+void
+hrl_container_destroy(struct hrl_container *container)
+{
+ int i;
+
+ for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
+ if (container->hc_resources[i] != 0)
+ printf("destroying non-empty container: "
+ "%ju allocated for resource %s",
+ container->hc_resources[i],
+ hrl_resource_name(i));
+ container->hc_resources[i] = 0;
+ }
+}
+
/*
* Increase allocation of 'resource' by 'amount' for process 'p'.
* Return 0 if it's below limits, or errno, if it's not.
@@ -461,12 +486,12 @@
mtx_unlock(&hrl_lock);
return (error);
}
- p->p_usage.hu_resources[resource] += amount;
+ p->p_container.hc_resources[resource] += amount;
cred = p->p_ucred;
- cred->cr_ruidinfo->ui_usage.hu_resources[resource] += amount;
+ cred->cr_ruidinfo->ui_container.hc_resources[resource] += amount;
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
- pr->pr_usage.hu_resources[resource] += amount;
- cred->cr_loginclass->lc_usage.hu_resources[resource] += amount;
+ pr->pr_container.hc_resources[resource] += amount;
+ cred->cr_loginclass->lc_container.hc_resources[resource] += amount;
#ifdef DIAGNOSTIC
hrl_assert_proc(p);
#endif
@@ -498,7 +523,7 @@
#endif
mtx_lock(&hrl_lock);
- diff = amount - p->p_usage.hu_resources[resource];
+ diff = amount - p->p_container.hc_resources[resource];
if (diff > 0) {
error = hrl_enforce_proc(p, resource, diff);
if (error) {
@@ -506,12 +531,12 @@
return (error);
}
}
- p->p_usage.hu_resources[resource] = amount;
+ p->p_container.hc_resources[resource] = amount;
cred = p->p_ucred;
- cred->cr_ruidinfo->ui_usage.hu_resources[resource] += diff;
+ cred->cr_ruidinfo->ui_container.hc_resources[resource] += diff;
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
- pr->pr_usage.hu_resources[resource] += diff;
- cred->cr_loginclass->lc_usage.hu_resources[resource] += diff;
+ pr->pr_container.hc_resources[resource] += diff;
+ cred->cr_loginclass->lc_container.hc_resources[resource] += diff;
#ifdef DIAGNOSTIC
hrl_assert_proc(p);
#endif
@@ -537,16 +562,16 @@
#endif
mtx_lock(&hrl_lock);
- KASSERT(amount <= p->p_usage.hu_resources[resource],
+ KASSERT(amount <= p->p_container.hc_resources[resource],
("hrl_free: freeing %ju of %s, which is more than allocated "
"%ld for %s (pid %d)", amount, hrl_resource_name(resource),
- p->p_usage.hu_resources[resource], p->p_comm, p->p_pid));
- p->p_usage.hu_resources[resource] -= amount;
+ p->p_container.hc_resources[resource], p->p_comm, p->p_pid));
+ p->p_container.hc_resources[resource] -= amount;
cred = p->p_ucred;
- cred->cr_ruidinfo->ui_usage.hu_resources[resource] -= amount;
+ cred->cr_ruidinfo->ui_container.hc_resources[resource] -= amount;
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
- pr->pr_usage.hu_resources[resource] -= amount;
- cred->cr_loginclass->lc_usage.hu_resources[resource] -= amount;
+ pr->pr_container.hc_resources[resource] -= amount;
+ cred->cr_loginclass->lc_container.hc_resources[resource] -= amount;
#ifdef DIAGNOSTIC
hrl_assert_proc(p);
#endif
@@ -554,38 +579,38 @@
}
static void
-hrl_usage_add(struct hrl_usage *dest, const struct hrl_usage *src)
+hrl_container_add(struct hrl_container *dest, const struct hrl_container *src)
{
int i;
mtx_lock(&hrl_lock);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- KASSERT(dest->hu_resources[i] >= 0,
+ KASSERT(dest->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
- KASSERT(src->hu_resources[i] >= 0,
+ KASSERT(src->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
- dest->hu_resources[i] += src->hu_resources[i];
- KASSERT(dest->hu_resources[i] >= 0,
+ dest->hc_resources[i] += src->hc_resources[i];
+ KASSERT(dest->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
}
mtx_unlock(&hrl_lock);
}
static void
-hrl_usage_subtract(struct hrl_usage *dest, const struct hrl_usage *src)
+hrl_container_subtract(struct hrl_container *dest, const struct hrl_container *src)
{
int i;
mtx_lock(&hrl_lock);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- KASSERT(dest->hu_resources[i] >= 0,
+ KASSERT(dest->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
- KASSERT(src->hu_resources[i] >= 0,
+ KASSERT(src->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
- KASSERT(src->hu_resources[i] <= dest->hu_resources[i],
+ KASSERT(src->hc_resources[i] <= dest->hc_resources[i],
("resource usage propagation meltdown"));
- dest->hu_resources[i] -= src->hu_resources[i];
- KASSERT(dest->hu_resources[i] >= 0,
+ dest->hc_resources[i] -= src->hc_resources[i];
+ KASSERT(dest->hc_resources[i] >= 0,
("resource usage propagation meltdown"));
}
mtx_unlock(&hrl_lock);
@@ -1314,7 +1339,7 @@
}
static struct sbuf *
-hrl_usage_to_sbuf(struct hrl_usage *usage)
+hrl_container_to_sbuf(struct hrl_container *container)
{
int i;
struct sbuf *sb;
@@ -1322,7 +1347,7 @@
sb = sbuf_new_auto();
for (i = 1; i <= HRL_RESOURCE_MAX; i++) {
sbuf_printf(sb, "%s=%jd,", hrl_resource_name(i),
- usage->hu_resources[i]);
+ container->hc_resources[i]);
}
sbuf_setpos(sb, sbuf_len(sb) - 1);
return (sb);
@@ -1357,7 +1382,7 @@
error = EINVAL;
goto out;
}
- outputsbuf = hrl_usage_to_sbuf(&p->p_usage);
+ outputsbuf = hrl_container_to_sbuf(&p->p_container);
break;
case HRL_SUBJECT_TYPE_USER:
uip = filter->hr_subject.hs_uip;
@@ -1365,7 +1390,7 @@
error = EINVAL;
goto out;
}
- outputsbuf = hrl_usage_to_sbuf(&uip->ui_usage);
+ outputsbuf = hrl_container_to_sbuf(&uip->ui_container);
break;
case HRL_SUBJECT_TYPE_GROUP:
gip = filter->hr_subject.hs_gip;
@@ -1373,7 +1398,7 @@
error = EINVAL;
goto out;
}
- outputsbuf = hrl_usage_to_sbuf(&gip->gi_usage);
+ outputsbuf = hrl_container_to_sbuf(&gip->gi_container);
break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
lc = filter->hr_subject.hs_loginclass;
@@ -1381,7 +1406,7 @@
error = EINVAL;
goto out;
}
- outputsbuf = hrl_usage_to_sbuf(&lc->lc_usage);
+ outputsbuf = hrl_container_to_sbuf(&lc->lc_container);
break;
case HRL_SUBJECT_TYPE_JAIL:
pr = filter->hr_subject.hs_prison;
@@ -1389,7 +1414,7 @@
error = EINVAL;
goto out;
}
- outputsbuf = hrl_usage_to_sbuf(&pr->pr_usage);
+ outputsbuf = hrl_container_to_sbuf(&pr->pr_container);
break;
default:
error = EINVAL;
@@ -1692,8 +1717,8 @@
newuip = newcred->cr_ruidinfo;
olduip = p->p_ucred->cr_ruidinfo;
if (newuip != olduip) {
- hrl_usage_subtract(&olduip->ui_usage, &p->p_usage);
- hrl_usage_add(&newuip->ui_usage, &p->p_usage);
+ hrl_container_subtract(&olduip->ui_container, &p->p_container);
+ hrl_container_add(&newuip->ui_container, &p->p_container);
}
/*
@@ -1702,8 +1727,8 @@
newlc = newcred->cr_loginclass;
oldlc = p->p_ucred->cr_loginclass;
if (newlc != oldlc) {
- hrl_usage_subtract(&oldlc->lc_usage, &p->p_usage);
- hrl_usage_add(&newlc->lc_usage, &p->p_usage);
+ hrl_container_subtract(&oldlc->lc_container, &p->p_container);
+ hrl_container_add(&newlc->lc_container, &p->p_container);
}
}
@@ -1724,10 +1749,10 @@
mtx_lock(&hrl_lock);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- if (parent->p_usage.hu_resources[i] != 0 &&
+ if (parent->p_container.hc_resources[i] != 0 &&
hrl_resource_inheritable(i))
hrl_allocated(child, i,
- parent->p_usage.hu_resources[i]);
+ parent->p_container.hc_resources[i]);
}
LIST_FOREACH(limit, &parent->p_limits, hl_next) {
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_jail.c#15 (text+ko) ====
@@ -1156,6 +1156,7 @@
root = mypr->pr_root;
vref(root);
}
+ hrl_container_create(&pr->pr_container);
strlcpy(pr->pr_hostuuid, DEFAULT_HOSTUUID, HOSTUUIDLEN);
pr->pr_flags |= PR_HOST;
#if defined(INET) || defined(INET6)
@@ -2408,7 +2409,7 @@
prison_deref(struct prison *pr, int flags)
{
struct prison *ppr, *tpr;
- int vfslocked, i;
+ int vfslocked;
if (!(flags & PD_LOCKED))
mtx_lock(&pr->pr_mtx);
@@ -2485,11 +2486,7 @@
if (pr->pr_cpuset != NULL)
cpuset_rel(pr->pr_cpuset);
osd_jail_exit(pr);
- for (i = 0; i < HRL_RESOURCE_MAX; i++) {
- if (pr->pr_usage.hu_resources[i] != 0)
- printf("prison_deref: resource %d = %ju\n",
- i, pr->pr_usage.hu_resources[i]);
- }
+ hrl_container_destroy(&pr->pr_container);
free(pr, M_PRISON);
/* Removing a prison frees a reference on its parent. */
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_loginclass.c#14 (text+ko) ====
@@ -83,16 +83,10 @@
void
loginclass_release(struct loginclass *lc)
{
- int i;
mtx_lock(&loginclasses_lock);
if (refcount_release(&lc->lc_refcount)) {
- for (i = 0; i < HRL_RESOURCE_MAX; i++) {
- KASSERT(lc->lc_usage.hu_resources[i] == 0,
- ("loginclass_release: freeing "
- "loginclass \"%s\", resource %d = %ju\n",
- lc->lc_name, i, lc->lc_usage.hu_resources[i]));
- }
+ hrl_container_destroy(&lc->lc_container);
LIST_REMOVE(lc, lc_next);
mtx_unlock(&loginclasses_lock);
free(lc, M_LOGINCLASS);
@@ -132,6 +126,7 @@
}
/* Add new loginclass. */
+ hrl_container_create(&newlc->lc_container);
strcpy(newlc->lc_name, name);
refcount_init(&newlc->lc_refcount, 1);
LIST_INSERT_HEAD(&loginclasses, newlc, lc_next);
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#26 (text+ko) ====
@@ -1320,6 +1320,7 @@
mtx_init(&uip->ui_vmsize_mtx, "ui_vmsize", NULL,
MTX_DEF);
LIST_INSERT_HEAD(UIHASH(uid), uip, ui_hash);
+ hrl_container_create(&uip->ui_container);
}
}
uihold(uip);
@@ -1357,7 +1358,7 @@
uifree(uip)
struct uidinfo *uip;
{
- int old, i;
+ int old;
/* Prepare for optimal case. */
old = uip->ui_ref;
@@ -1367,6 +1368,7 @@
/* Prepare for suboptimal case. */
rw_wlock(&uihashtbl_lock);
if (refcount_release(&uip->ui_ref)) {
+ hrl_container_destroy(&uip->ui_container);
LIST_REMOVE(uip, ui_hash);
rw_wunlock(&uihashtbl_lock);
if (uip->ui_sbsize != 0)
@@ -1379,12 +1381,6 @@
printf("freeing uidinfo: uid = %d, swapuse = %lld\n",
uip->ui_uid, (unsigned long long)uip->ui_vmsize);
mtx_destroy(&uip->ui_vmsize_mtx);
- for (i = 0; i < HRL_RESOURCE_MAX; i++) {
- KASSERT(uip->ui_usage.hu_resources[i] == 0,
- ("uifree: freeing uidinfo: uid = %d, "
- "resource %d = %ju\n", uip->ui_uid, i,
- uip->ui_usage.hu_resources[i]));
- }
free(uip, M_UIDINFO);
return;
}
@@ -1483,6 +1479,7 @@
refcount_init(&gip->gi_ref, 0);
gip->gi_gid = gid;
LIST_INSERT_HEAD(GIHASH(gid), gip, gi_hash);
+ hrl_container_create(&gip->gi_container);
}
}
gihold(gip);
@@ -1520,7 +1517,7 @@
gifree(gip)
struct gidinfo *gip;
{
- int old, i;
+ int old;
/* Prepare for optimal case. */
old = gip->gi_ref;
@@ -1530,14 +1527,9 @@
/* Prepare for suboptimal case. */
rw_wlock(&gihashtbl_lock);
if (refcount_release(&gip->gi_ref)) {
+ hrl_container_destroy(&gip->gi_container);
LIST_REMOVE(gip, gi_hash);
rw_wunlock(&gihashtbl_lock);
- for (i = 0; i < HRL_RESOURCE_MAX; i++) {
- KASSERT(gip->gi_usage.hu_resources[i] == 0,
- ("gifree: freeing gidinfo: gid = %d, "
- "resource %d = %ju\n", gip->gi_gid, i,
- gip->gi_usage.hu_resources[i]));
- }
free(gip, M_GIDINFO);
return;
}
==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#37 (text+ko) ====
@@ -38,6 +38,7 @@
struct gidinfo;
struct loginclass;
struct prison;
+struct ucred;
/*
* Hierarchical Resource Limits.
@@ -123,11 +124,22 @@
#define HRL_AMOUNT_UNDEFINED -1
/*
- * 'hrl_usage' defines resource consumption for a particular
- * object, such as process or user.
+ * 'hrl_container' defines resource consumption for a particular
+ * subject, such as process or jail. Containers form a graph - each
+ * container has zero or more subcontainers and zero or more
+ * "containing" containers (parents). For example, container for
+ * an uidinfo can have several subcontainers for processes for that
+ * user. On the other hand, each process can have several containing
+ * containers, one per every group this process belongs to.
+ *
+ * Every process has exactly one container assigned to it. Containers
+ * for other objects are created when there is a rule which requires it.
+ * For example, uidinfo will have container assigned only if there
+ * is a rule this uidinfo is subject to, and 'hr_per' for this rule
+ * is HRL_SUBJECT_TYPE_USER.
*/
-struct hrl_usage {
- int64_t hu_resources[HRL_RESOURCE_MAX + 1];
+struct hrl_container {
+ int64_t hc_resources[HRL_RESOURCE_MAX + 1];
};
/*
@@ -144,10 +156,6 @@
#ifdef _KERNEL
-struct loginclass;
-struct proc;
-struct ucred;
-
int hrl_alloc(struct proc *p, int object, uint64_t amount);
int hrl_allocated(struct proc *p, int object, uint64_t amount);
void hrl_free(struct proc *p, int object, uint64_t amount);
@@ -162,6 +170,10 @@
void hrl_rule_release(struct hrl_rule *rule);
int hrl_rule_add(struct hrl_rule *rule);
int hrl_rule_remove(const struct hrl_rule *filter);
+
+void hrl_container_create(struct hrl_container *container);
+void hrl_container_destroy(struct hrl_container *container);
+
#else /* !_KERNEL */
/*
==== //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#10 (text+ko) ====
@@ -181,7 +181,7 @@
char pr_hostname[MAXHOSTNAMELEN]; /* (p) jail hostname */
char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */
char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */
- struct hrl_usage pr_usage; /* (*) HRL resource accounting */
+ struct hrl_container pr_container; /* (*) HRL resource accounting */
struct hrl_limits_head pr_limits; /* (*) HRL rules applicable to the prison */
};
#endif /* _KERNEL || _WANT_PRISON */
==== //depot/projects/soc2009/trasz_limits/sys/sys/loginclass.h#5 (text+ko) ====
@@ -36,7 +36,7 @@
LIST_ENTRY(loginclass) lc_next;
char lc_name[MAXLOGNAME];
u_int lc_refcount;
- struct hrl_usage lc_usage;
+ struct hrl_container lc_container;
struct hrl_limits_head lc_limits;
};
==== //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#13 (text+ko) ====
@@ -511,7 +511,7 @@
int p_boundary_count;/* (c) Num threads at user boundary */
int p_pendingcnt; /* how many signals are pending */
struct itimers *p_itimers; /* (c) POSIX interval timers. */
- struct hrl_usage p_usage; /* (*) HRL resource accounting */
+ struct hrl_container p_container; /* (*) HRL resource accounting */
struct hrl_limits_head p_limits;/* (*) HRL rules applicable to the proccess */
/* End area that is zeroed on creation. */
#define p_endzero p_magic
==== //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#13 (text+ko) ====
@@ -98,7 +98,7 @@
long ui_ptscnt; /* (b) number of pseudo-terminals */
uid_t ui_uid; /* (a) uid */
u_int ui_ref; /* (b) reference count */
- struct hrl_usage ui_usage; /* (*) HRL resource accounting */
+ struct hrl_container ui_container; /* (*) HRL resource accounting */
struct hrl_limits_head ui_limits;/* (*) HRL rules applicable to the uid */
};
@@ -117,7 +117,7 @@
LIST_ENTRY(gidinfo) gi_hash; /* (c) hash chain of gidinfos */
gid_t gi_gid; /* (a) gid */
u_int gi_ref; /* (b) reference count */
- struct hrl_usage gi_usage; /* (*) HRL resource accounting */
+ struct hrl_container gi_container; /* (*) HRL resource accounting */
struct hrl_limits_head gi_limits;/* (*) HRL rules applicable to the gid */
};
More information about the p4-projects
mailing list