PERFORCE change 180274 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Sun Jun 27 18:25:09 UTC 2010
http://p4web.freebsd.org/@@180274?ac=10
Change 180274 by trasz at trasz_victim on 2010/06/27 18:24:29
Divorce containers from hrl some more.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#3 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#18 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#14 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#76 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/container.h#3 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#45 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#3 (text+ko) ====
@@ -62,12 +62,12 @@
mtx_assert(&hrl_lock, MA_OWNED);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- KASSERT(dest->hc_resources[i] >= 0,
+ KASSERT(dest->c_resources[i] >= 0,
("resource usage propagation meltdown: dest < 0"));
- KASSERT(src->hc_resources[i] >= 0,
+ KASSERT(src->c_resources[i] >= 0,
("resource usage propagation meltdown: src < 0"));
- dest->hc_resources[i] += src->hc_resources[i];
- KASSERT(dest->hc_resources[i] >= 0,
+ dest->c_resources[i] += src->c_resources[i];
+ KASSERT(dest->c_resources[i] >= 0,
("resource usage propagation meltdown: dest < 0 after addition"));
}
}
@@ -80,14 +80,14 @@
mtx_assert(&hrl_lock, MA_OWNED);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- KASSERT(dest->hc_resources[i] >= 0,
+ KASSERT(dest->c_resources[i] >= 0,
("resource usage propagation meltdown: dest < 0"));
- KASSERT(src->hc_resources[i] >= 0,
+ KASSERT(src->c_resources[i] >= 0,
("resource usage propagation meltdown: src < 0"));
- KASSERT(src->hc_resources[i] <= dest->hc_resources[i],
+ KASSERT(src->c_resources[i] <= dest->c_resources[i],
("resource usage propagation meltdown: src > dest"));
- dest->hc_resources[i] -= src->hc_resources[i];
- KASSERT(dest->hc_resources[i] >= 0,
+ dest->c_resources[i] -= src->c_resources[i];
+ KASSERT(dest->c_resources[i] >= 0,
("resource usage propagation meltdown: dest < 0 after subtraction"));
}
}
@@ -101,11 +101,11 @@
KASSERT(child != NULL, ("child != NULL"));
KASSERT(parent != NULL, ("parent != NULL"));
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- KASSERT(child->hc_parents[i] != parent,
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ KASSERT(child->c_parents[i] != parent,
("container already joined"));
- if (child->hc_parents[i] == NULL) {
- child->hc_parents[i] = parent;
+ if (child->c_parents[i] == NULL) {
+ child->c_parents[i] = parent;
container_add(parent, child);
return;
}
@@ -122,10 +122,10 @@
KASSERT(child != NULL, ("child != NULL"));
KASSERT(parent != NULL, ("parent != NULL"));
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- if (child->hc_parents[i] == parent) {
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ if (child->c_parents[i] == parent) {
container_subtract(parent, child);
- child->hc_parents[i] = NULL;
+ child->c_parents[i] = NULL;
return;
}
}
@@ -140,11 +140,11 @@
mtx_assert(&hrl_lock, MA_OWNED);
KASSERT(child != NULL, ("child != NULL"));
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- if (child->hc_parents[i] == NULL)
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ if (child->c_parents[i] == NULL)
continue;
- container_subtract(child->hc_parents[i], child);
- child->hc_parents[i] = NULL;
+ container_subtract(child->c_parents[i], child);
+ child->c_parents[i] = NULL;
}
}
@@ -154,11 +154,11 @@
int i;
for (i = 0; i <= HRL_RESOURCE_MAX; i++)
- KASSERT(container->hc_resources[i] == 0,
- ("container->hc_resources[%d] != NULL", i));
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++)
- KASSERT(container->hc_parents[i] == NULL,
- ("container->hc_parents[%d] != NULL", i));
+ KASSERT(container->c_resources[i] == 0,
+ ("container->c_resources[%d] != NULL", i));
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++)
+ KASSERT(container->c_parents[i] == NULL,
+ ("container->c_parents[%d] != NULL", i));
}
void
@@ -168,12 +168,12 @@
mtx_lock(&hrl_lock);
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- if (container->hc_resources[i] != 0)
+ if (container->c_resources[i] != 0)
printf("destroying non-empty container: "
"%ju allocated for resource %s",
- container->hc_resources[i],
+ container->c_resources[i],
hrl_resource_name(i));
- container->hc_resources[i] = 0;
+ container->c_resources[i] = 0;
}
container_leave_parents(container);
@@ -194,18 +194,18 @@
KASSERT(container != NULL, ("NULL container"));
for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++) {
- KASSERT(container->hc_resources[resource] >= 0,
+ KASSERT(container->c_resources[resource] >= 0,
("resource usage propagation meltdown: resource < 0"));
}
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- parent = container->hc_parents[i];
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ parent = container->c_parents[i];
if (parent == NULL);
continue;
container_assert(parent);
for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++) {
- KASSERT(parent->hc_resources[resource] >=
- container->hc_resources[resource],
+ KASSERT(parent->c_resources[resource] >=
+ container->c_resources[resource],
("resource usage propagation meltdown: child > parent"));
}
}
@@ -226,11 +226,11 @@
mtx_assert(&hrl_lock, MA_OWNED);
KASSERT(container != NULL, ("NULL container"));
- container->hc_resources[resource] += amount;
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- if (container->hc_parents[i] == NULL)
+ container->c_resources[resource] += amount;
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ if (container->c_parents[i] == NULL)
continue;
- container_alloc_resource(container->hc_parents[i], resource, amount);
+ container_alloc_resource(container->c_parents[i], resource, amount);
}
#ifdef DIAGNOSTIC
container_assert(container);
@@ -286,7 +286,7 @@
hrl_resource_name(resource), amount));
mtx_lock(&hrl_lock);
- diff = amount - p->p_container.hc_resources[resource];
+ diff = amount - p->p_container.c_resources[resource];
if (diff > 0) {
error = hrl_enforce_proc(p, resource, diff);
if (error) {
@@ -315,11 +315,76 @@
hrl_resource_name(resource), amount));
mtx_lock(&hrl_lock);
- KASSERT(amount <= p->p_container.hc_resources[resource],
+ KASSERT(amount <= p->p_container.c_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_container.hc_resources[resource], p->p_comm, p->p_pid));
+ p->p_container.c_resources[resource], p->p_comm, p->p_pid));
container_alloc_resource(&p->p_container, resource, -amount);
mtx_unlock(&hrl_lock);
}
+
+static int
+container_resource_inheritable(int resource)
+{
+
+ switch (resource) {
+ case HRL_RESOURCE_MAXPROCESSES:
+ return (0);
+ default:
+ return (1);
+ }
+}
+
+void
+container_proc_exit(struct proc *p)
+{
+ /*
+ * XXX: Free these three some other way.
+ */
+ hrl_allocated(p, HRL_RESOURCE_FILESIZE, 0);
+ hrl_allocated(p, HRL_RESOURCE_COREDUMPSIZE, 0);
+ hrl_allocated(p, HRL_RESOURCE_PTY, 0);
+
+ mtx_lock(&hrl_lock);
+ container_destroy(&p->p_container);
+ mtx_unlock(&hrl_lock);
+}
+
+/*
+ * Inherit resource usage information and copy limits from the parent
+ * process to the child.
+ */
+void
+container_proc_fork(struct proc *parent, struct proc *child)
+{
+ int i;
+ struct container *container;
+
+ PROC_LOCK(parent);
+ PROC_LOCK(child);
+ mtx_lock(&hrl_lock);
+
+ /*
+ * Create container for the child process and inherit containing
+ * containers from the parent.
+ */
+ container_create(&child->p_container);
+ for (i = 0; i <= CONTAINER_PARENTS_MAX; i++) {
+ container = parent->p_container.c_parents[i];
+ if (container == NULL)
+ continue;
+ container_join(&child->p_container, container);
+ }
+
+ for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
+ if (parent->p_container.c_resources[i] != 0 &&
+ container_resource_inheritable(i))
+ hrl_allocated(child, i,
+ parent->p_container.c_resources[i]);
+ }
+
+ mtx_unlock(&hrl_lock);
+ PROC_UNLOCK(child);
+ PROC_UNLOCK(parent);
+}
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#18 (text+ko) ====
@@ -768,7 +768,11 @@
*/
(void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0);
hrl_free(p->p_pptr, HRL_RESOURCE_MAXPROCESSES, 1);
- hrl_proc_exiting(p);
+
+ /*
+ * Destroy resource container associated with the process.
+ */
+ container_proc_exit(p);
/*
* Free credentials, arguments, and sigacts.
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#14 (text+ko) ====
@@ -739,6 +739,11 @@
}
/*
+ * Initialize resource container for the child process.
+ */
+ container_proc_fork(p1, p2);
+
+ /*
* Both processes are set up, now check if any loadable modules want
* to adjust anything.
* What if they have an error? XXX
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#76 (text+ko) ====
@@ -124,18 +124,6 @@
MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits");
-static int
-hrl_resource_inheritable(int resource)
-{
-
- switch (resource) {
- case HRL_RESOURCE_MAXPROCESSES:
- return (0);
- default:
- return (1);
- }
-}
-
static const char *
hrl_subject_type_name(int subject)
{
@@ -210,20 +198,20 @@
switch (rule->hr_per) {
case HRL_SUBJECT_TYPE_PROCESS:
available = rule->hr_amount -
- p->p_container.hc_resources[resource];
+ p->p_container.c_resources[resource];
break;
case HRL_SUBJECT_TYPE_USER:
available = rule->hr_amount -
- cred->cr_ruidinfo->ui_container.hc_resources[resource];
+ cred->cr_ruidinfo->ui_container.c_resources[resource];
break;
case HRL_SUBJECT_TYPE_LOGINCLASS:
available = rule->hr_amount -
- cred->cr_loginclass->lc_container.hc_resources[resource];
+ cred->cr_loginclass->lc_container.c_resources[resource];
available = INT64_MAX; /* XXX */
break;
case HRL_SUBJECT_TYPE_JAIL:
available = rule->hr_amount -
- cred->cr_prison->pr_container.hc_resources[resource];
+ cred->cr_prison->pr_container.c_resources[resource];
break;
default:
panic("hrl_compute_available: unknown per %d",
@@ -300,9 +288,9 @@
/*
* XXX: We should sort the rules somewhat, so that 'log' and 'sig'
* rules come before before 'deny', to spare iterations over
- * the p_container.hc_rule_links.
+ * the p_container.c_rule_links.
*/
- LIST_FOREACH(link, &p->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &p->p_container.c_rule_links, hrl_next) {
rule = link->hrl_rule;
if (rule->hr_resource != resource)
continue;
@@ -380,7 +368,7 @@
for (i = 0; i <= HRL_RESOURCE_MAX; i++)
(*availablep)[i] = INT64_MAX;
- LIST_FOREACH(link, &p->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &p->p_container.c_rule_links, hrl_next) {
rule = link->hrl_rule;
resource = rule->hr_resource;
available = hrl_available_resource(p, rule);
@@ -522,7 +510,7 @@
link->hrl_rule = rule;
mtx_lock(&hrl_lock);
- LIST_INSERT_HEAD(&container->hc_rule_links, link, hrl_next);
+ LIST_INSERT_HEAD(&container->c_rule_links, link, hrl_next);
mtx_unlock(&hrl_lock);
}
@@ -540,7 +528,7 @@
hrl_rule_acquire(rule);
link->hrl_rule = rule;
- LIST_INSERT_HEAD(&container->hc_rule_links, link, hrl_next);
+ LIST_INSERT_HEAD(&container->c_rule_links, link, hrl_next);
return (0);
}
@@ -557,7 +545,7 @@
struct hrl_rule_link *link, *linktmp;
mtx_lock(&hrl_lock);
- LIST_FOREACH_SAFE(link, &container->hc_rule_links, hrl_next, linktmp) {
+ LIST_FOREACH_SAFE(link, &container->c_rule_links, hrl_next, linktmp) {
if (!hrl_rule_matches(link->hrl_rule, filter))
continue;
@@ -1129,7 +1117,7 @@
sb = sbuf_new_auto();
for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
sbuf_printf(sb, "%s=%jd,", hrl_resource_name(i),
- container->hc_resources[i]);
+ container->c_resources[i]);
}
sbuf_setpos(sb, sbuf_len(sb) - 1);
return (sb);
@@ -1224,7 +1212,7 @@
mtx_assert(&hrl_lock, MA_OWNED);
- LIST_FOREACH(link, &container->hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &container->c_rule_links, hrl_next) {
if (!hrl_rule_matches(link->hrl_rule, filter))
continue;
hrl_rule_to_sbuf(sb, link->hrl_rule);
@@ -1265,7 +1253,7 @@
sx_assert(&allproc_lock, SA_LOCKED);
FOREACH_PROC_IN_SYSTEM(p) {
mtx_lock(&hrl_lock);
- LIST_FOREACH(link, &p->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &p->p_container.c_rule_links, hrl_next) {
/*
* Non-process rules will be added to the buffer later.
* Adding them here would result in duplicated output.
@@ -1350,7 +1338,7 @@
KASSERT(sb != NULL, ("sbuf_new failed"));
mtx_lock(&hrl_lock);
- LIST_FOREACH(link, &filter->hr_subject.hs_proc->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &filter->hr_subject.hs_proc->p_container.c_rule_links, hrl_next) {
hrl_rule_to_sbuf(sb, link->hrl_rule);
sbuf_printf(sb, ",");
}
@@ -1492,7 +1480,7 @@
/*
* Remove rules that are no longer applicable with the new ucred.
*/
- LIST_FOREACH(link, &p->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &p->p_container.c_rule_links, hrl_next) {
switch (link->hrl_rule->hr_subject_type) {
case HRL_SUBJECT_TYPE_PROCESS:
continue;
@@ -1522,7 +1510,7 @@
* Add rules for the new ucred and move between containers where applicable.
*/
if (newuip != olduip) {
- LIST_FOREACH(link, &newuip->ui_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &newuip->ui_container.c_rule_links, hrl_next) {
error = hrl_container_add_rule_locked(&p->p_container, link->hrl_rule);
KASSERT(error == 0, ("XXX: better error handling needed"));
}
@@ -1531,7 +1519,7 @@
container_join(&p->p_container, &newuip->ui_container);
}
if (newlc != oldlc) {
- LIST_FOREACH(link, &newlc->lc_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &newlc->lc_container.c_rule_links, hrl_next) {
error = hrl_container_add_rule_locked(&p->p_container, link->hrl_rule);
KASSERT(error == 0, ("XXX: better error handling needed"));
}
@@ -1540,7 +1528,7 @@
container_join(&p->p_container, &newlc->lc_container);
}
if (newpr != oldpr) {
- LIST_FOREACH(link, &newpr->pr_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &newpr->pr_container.c_rule_links, hrl_next) {
error = hrl_container_add_rule_locked(&p->p_container, link->hrl_rule);
KASSERT(error == 0, ("XXX: better error handling needed"));
}
@@ -1553,47 +1541,26 @@
}
/*
- * Inherit resource usage information and copy limits from the parent
- * process to the child.
+ * Assign HRL rules to the newly created process.
*/
static void
hrl_proc_fork(void *arg __unused, struct proc *parent, struct proc *child,
int flags __unused)
{
- int error, i;
+ int error;
struct hrl_rule_link *link;
struct hrl_rule *rule;
- struct container *container;
PROC_LOCK(parent);
PROC_LOCK(child);
mtx_lock(&hrl_lock);
/*
- * Create container for the child process and inherit containing
- * containers from the parent.
- */
- container_create(&child->p_container);
- for (i = 0; i <= HRL_HC_PARENTS_MAX; i++) {
- container = parent->p_container.hc_parents[i];
- if (container == NULL)
- continue;
- container_join(&child->p_container, container);
- }
-
- for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
- if (parent->p_container.hc_resources[i] != 0 &&
- hrl_resource_inheritable(i))
- hrl_allocated(child, i,
- parent->p_container.hc_resources[i]);
- }
-
- /*
* Go through limits applicable to the parent and assign them to the child.
* Rules with 'process' subject have to be duplicated in order to make their
* hr_subject point to the new process.
*/
- LIST_FOREACH(link, &parent->p_container.hc_rule_links, hrl_next) {
+ LIST_FOREACH(link, &parent->p_container.c_rule_links, hrl_next) {
if (link->hrl_rule->hr_subject_type == HRL_SUBJECT_TYPE_PROCESS) {
rule = hrl_rule_duplicate(link->hrl_rule, M_NOWAIT);
KASSERT(rule != NULL, ("XXX: better error handling needed"));
@@ -1614,21 +1581,6 @@
PROC_UNLOCK(parent);
}
-void
-hrl_proc_exiting(struct proc *p)
-{
- /*
- * XXX: Free these three some other way.
- */
- hrl_allocated(p, HRL_RESOURCE_FILESIZE, 0);
- hrl_allocated(p, HRL_RESOURCE_COREDUMPSIZE, 0);
- hrl_allocated(p, HRL_RESOURCE_PTY, 0);
-
- mtx_lock(&hrl_lock);
- container_destroy(&p->p_container);
- mtx_unlock(&hrl_lock);
-}
-
/*
* Go through the process' limits, freeing them.
*/
@@ -1638,8 +1590,8 @@
struct hrl_rule_link *link;
mtx_lock(&hrl_lock);
- while (!LIST_EMPTY(&p->p_container.hc_rule_links)) {
- link = LIST_FIRST(&p->p_container.hc_rule_links);
+ while (!LIST_EMPTY(&p->p_container.c_rule_links)) {
+ link = LIST_FIRST(&p->p_container.c_rule_links);
LIST_REMOVE(link, hrl_next);
hrl_rule_release(link->hrl_rule);
uma_zfree(hrl_rule_link_zone, link);
==== //depot/projects/soc2009/trasz_limits/sys/sys/container.h#3 (text+ko) ====
@@ -46,7 +46,7 @@
* one parent container, loginclass and uidinfo structures have none.
* This may change when - and if - we add per-group resource limits.
*/
-#define HRL_HC_PARENTS_MAX 3
+#define CONTAINER_PARENTS_MAX 3
#define HRL_RESOURCE_UNDEFINED -1
#define HRL_RESOURCE_CPUTIME 0x0000
@@ -64,7 +64,6 @@
#define HRL_RESOURCE_SWAP 0x000c
#define HRL_RESOURCE_MAX HRL_RESOURCE_SWAP
-
/*
* 'container' defines resource consumption for a particular
* subject, such as process or jail. Containers form a graph - each
@@ -85,13 +84,11 @@
* This structure must be filled with zeroes initially.
*/
struct container {
- int64_t hc_resources[HRL_RESOURCE_MAX + 1];
- struct container *hc_parents[HRL_HC_PARENTS_MAX + 1];
- LIST_HEAD(, hrl_rule_link) hc_rule_links;
+ int64_t c_resources[HRL_RESOURCE_MAX + 1];
+ struct container *c_parents[CONTAINER_PARENTS_MAX + 1];
+ LIST_HEAD(, hrl_rule_link) c_rule_links;
};
-#ifdef _KERNEL
-
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);
@@ -102,6 +99,7 @@
void container_join(struct container *child, struct container *parent);
void container_leave(struct container *child, struct container *parent);
-#endif /* _KERNEL */
+void container_proc_exit(struct proc *p);
+void container_proc_fork(struct proc *parent, struct proc *child);
#endif /* !_CONTAINER_H_ */
==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#45 (text+ko) ====
@@ -110,8 +110,6 @@
#ifdef _KERNEL
-void hrl_proc_exiting(struct proc *p);
-
void hrl_proc_init(struct proc *p);
void hrl_proc_ucred_changing(struct proc *p, struct ucred *newcred);
More information about the p4-projects
mailing list