Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Oct 2009 15:14:59 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 169398 for review
Message-ID:  <200910111514.n9BFEx45038982@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=169398

Change 169398 by trasz@trasz_victim on 2009/10/11 15:14:24

	Maintain containers hierarchy.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#68 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#38 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#68 (text+ko) ====

@@ -437,6 +437,93 @@
 	}
 }
 
+static void
+hrl_container_add(struct hrl_container *dest, const struct hrl_container *src)
+{
+	int i;
+
+	mtx_assert(&hrl_lock, MA_OWNED);
+
+	for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
+		KASSERT(dest->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+		KASSERT(src->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+		dest->hc_resources[i] += src->hc_resources[i];
+		KASSERT(dest->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+	}
+}
+
+static void
+hrl_container_subtract(struct hrl_container *dest, const struct hrl_container *src)
+{
+	int i;
+
+	mtx_assert(&hrl_lock, MA_OWNED);
+
+	for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
+		KASSERT(dest->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+		KASSERT(src->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+		KASSERT(src->hc_resources[i] <= dest->hc_resources[i],
+		    ("resource usage propagation meltdown"));
+		dest->hc_resources[i] -= src->hc_resources[i];
+		KASSERT(dest->hc_resources[i] >= 0,
+		    ("resource usage propagation meltdown"));
+	}
+}
+
+static void
+hrl_container_join(struct hrl_container *child, struct hrl_container *parent)
+{
+	struct hrl_container *container;
+
+	mtx_assert(&hrl_lock, MA_OWNED);
+	KASSERT(child != NULL, ("child != NULL"));
+	KASSERT(parent != NULL, ("parent != NULL"));
+
+	LIST_FOREACH(container, &child->hc_parents, hc_next)
+		KASSERT(container != parent, ("container already joined"));
+
+	LIST_INSERT_HEAD(&child->hc_parents, parent, hc_next);
+	hrl_container_add(parent, child);
+}
+
+static void
+hrl_container_leave(struct hrl_container *child, struct hrl_container *parent)
+{
+	struct hrl_container *container, *containertmp;
+
+	mtx_assert(&hrl_lock, MA_OWNED);
+	KASSERT(child != NULL, ("child != NULL"));
+	KASSERT(parent != NULL, ("parent != NULL"));
+
+	hrl_container_subtract(parent, child);
+	LIST_FOREACH_SAFE(container, &child->hc_parents, hc_next, containertmp) {
+		if (container != parent)
+			continue;
+		LIST_REMOVE(container, hc_next);
+		break;
+	}
+}
+
+static void
+hrl_container_leave_parents(struct hrl_container *child)
+{
+	struct hrl_container *parent;
+
+	mtx_assert(&hrl_lock, MA_OWNED);
+	KASSERT(child != NULL, ("child != NULL"));
+
+	while (!LIST_EMPTY(&child->hc_parents)) {
+		parent = LIST_FIRST(&child->hc_parents);
+		hrl_container_subtract(parent, child);
+		LIST_REMOVE(parent, hc_next);
+	}
+}
+
 void
 hrl_container_create(struct hrl_container *container)
 {
@@ -445,6 +532,8 @@
 	for (i = 0; i <= HRL_RESOURCE_MAX; i++)
 		KASSERT(container->hc_resources[i] == 0,
 		    ("container not zeroed"));
+
+	LIST_INIT(&container->hc_parents);
 }
 
 void
@@ -452,6 +541,7 @@
 {
 	int i;
 
+	mtx_lock(&hrl_lock);
 	for (i = 0; i <= HRL_RESOURCE_MAX; i++) {
 		if (container->hc_resources[i] != 0)
 			printf("destroying non-empty container: "
@@ -460,6 +550,9 @@
 			    hrl_resource_name(i));
 		container->hc_resources[i] = 0;
 	}
+
+	hrl_container_leave_parents(container);
+	mtx_unlock(&hrl_lock);
 }
 
 /*
@@ -578,44 +671,6 @@
 	mtx_unlock(&hrl_lock);
 }
 
-static void
-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->hc_resources[i] >= 0,
-		    ("resource usage propagation meltdown"));
-		KASSERT(src->hc_resources[i] >= 0,
-		    ("resource usage propagation meltdown"));
-		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_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->hc_resources[i] >= 0,
-		    ("resource usage propagation meltdown"));
-		KASSERT(src->hc_resources[i] >= 0,
-		    ("resource usage propagation meltdown"));
-		KASSERT(src->hc_resources[i] <= dest->hc_resources[i],
-		    ("resource usage propagation meltdown"));
-		dest->hc_resources[i] -= src->hc_resources[i];
-		KASSERT(dest->hc_resources[i] >= 0,
-		    ("resource usage propagation meltdown"));
-	}
-	mtx_unlock(&hrl_lock);
-}
-
 static int
 hrl_rule_matches(const struct hrl_rule *rule, const struct hrl_rule *filter)
 {
@@ -1715,48 +1770,37 @@
 	}
 	
 	/*
-	 * Add rules for the new ucred.
+	 * Add rules for the new ucred and move between containers where applicable.
 	 */
 	if (newuip != olduip) {
 		LIST_FOREACH(limit, &newuip->ui_limits, hl_next) {
 			error = hrl_limit_add_locked(&p->p_limits, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
+
+		hrl_container_leave(&p->p_container, &olduip->ui_container);
+		hrl_container_join(&p->p_container, &newuip->ui_container);
 	}
 	if (newlc != oldlc) {
 		LIST_FOREACH(limit, &newlc->lc_limits, hl_next) {
 			error = hrl_limit_add_locked(&p->p_limits, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
+
+		hrl_container_leave(&p->p_container, &oldlc->lc_container);
+		hrl_container_join(&p->p_container, &newlc->lc_container);
 	}
-	if (newpr != newpr) {
+	if (newpr != oldpr) {
 		LIST_FOREACH(limit, &newpr->pr_limits, hl_next) {
 			error = hrl_limit_add_locked(&p->p_limits, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
+
+		hrl_container_leave(&p->p_container, &oldpr->pr_container);
+		hrl_container_join(&p->p_container, &newpr->pr_container);
 	}
 
 	mtx_unlock(&hrl_lock);
-
-	/*
-	 * Fix up per-ruid resource consumption.
-	 */
-	if (newuip != olduip) {
-		hrl_container_subtract(&olduip->ui_container, &p->p_container);
-		hrl_container_add(&newuip->ui_container, &p->p_container);
-	}
-
-	/*
-	 * Adjust loginclass resource usage information.
-	 */
-	if (newlc != oldlc) {
-		hrl_container_subtract(&oldlc->lc_container, &p->p_container);
-		hrl_container_add(&newlc->lc_container, &p->p_container);
-	}
-
-	/*
-	 * XXX: Jail resource consumption.
-	 */
 }
 
 /*

==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#38 (text+ko) ====

@@ -139,7 +139,9 @@
  * is HRL_SUBJECT_TYPE_USER.
  */
 struct hrl_container {
-	int64_t	hc_resources[HRL_RESOURCE_MAX + 1];
+	LIST_ENTRY(hrl_container)	hc_next;
+	int64_t				hc_resources[HRL_RESOURCE_MAX + 1];
+	LIST_HEAD(, hrl_container)	hc_parents;
 };
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910111514.n9BFEx45038982>