Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Oct 2009 14:53:56 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 169999 for review
Message-ID:  <200910311453.n9VEru0j077535@repoman.freebsd.org>

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

Change 169999 by trasz@trasz_victim on 2009/10/31 14:53:15

	Move list of limits into the container.  Reason for this is to make
	the code less ugly, and to make my next step (not updating resource
	usage in unused containers) much easier.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#72 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_loginclass.c#16 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#27 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#41 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#11 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/loginclass.h#6 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#14 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#14 edit

Differences ...

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

@@ -59,6 +59,16 @@
 #define	HRL_DEFAULT_BUFSIZE	4096
 #define	HRL_LOG_BUFSIZE		128
 
+/*
+ * 'hrl_limit' connects a rule with every container it's related to.
+ * For example, rule 'user:X:openfiles:deny=N/process' is linked
+ * with uidinfo for user X, and to each process of that user.
+ */
+struct hrl_limit {
+	LIST_ENTRY(hrl_limit)	hl_next;
+	struct hrl_rule		*hl_rule;
+};
+
 struct dict {
 	const char	*d_name;
 	int		d_value;
@@ -290,9 +300,9 @@
 	/*
 	 * XXX: We should sort the rules somewhat, so that 'log' and 'sig'
 	 * 	rules come before before 'deny', to spare iterations over
-	 * 	the p_limits.
+	 * 	the p_container.hc_limits.
 	 */
-	LIST_FOREACH(limit, &p->p_limits, hl_next) {
+	LIST_FOREACH(limit, &p->p_container.hc_limits, hl_next) {
 		rule = limit->hl_rule;
 		if (rule->hr_resource != resource)
 			continue;
@@ -370,7 +380,7 @@
 	for (i = 0; i <= HRL_RESOURCE_MAX; i++)
 		(*availablep)[i] = INT64_MAX;
 
-	LIST_FOREACH(limit, &p->p_limits, hl_next) {
+	LIST_FOREACH(limit, &p->p_container.hc_limits, hl_next) {
 		rule = limit->hl_rule;
 		resource = rule->hr_resource;
 		available = hrl_available_resource(p, rule);
@@ -768,10 +778,10 @@
 }
 
 /*
- * Add a new limit for a rule, increasing refcount for the rule.
+ * Connect the rule to the container, increasing refcount for the rule.
  */
 static void
-hrl_limit_add(struct hrl_limits_head *limits_head, struct hrl_rule *rule)
+hrl_container_add_rule(struct hrl_container *container, struct hrl_rule *rule)
 {
 	struct hrl_limit *limit;
 
@@ -782,12 +792,12 @@
 	limit->hl_rule = rule;
 
 	mtx_lock(&hrl_lock);
-	LIST_INSERT_HEAD(limits_head, limit, hl_next);
+	LIST_INSERT_HEAD(&container->hc_limits, limit, hl_next);
 	mtx_unlock(&hrl_lock);
 }
 
 static int
-hrl_limit_add_locked(struct hrl_limits_head *limits_head, struct hrl_rule *rule)
+hrl_container_add_rule_locked(struct hrl_container *container, struct hrl_rule *rule)
 {
 	struct hrl_limit *limit;
 
@@ -800,7 +810,7 @@
 	hrl_rule_acquire(rule);
 	limit->hl_rule = rule;
 
-	LIST_INSERT_HEAD(limits_head, limit, hl_next);
+	LIST_INSERT_HEAD(&container->hc_limits, limit, hl_next);
 	return (0);
 }
 
@@ -810,14 +820,14 @@
  * the number of limit structures removed.
  */
 static int
-hrl_limit_remove_matching(struct hrl_limits_head *limits_head,
+hrl_container_remove_rules(struct hrl_container *container,
     const struct hrl_rule *filter)
 {
 	int removed = 0;
 	struct hrl_limit *limit, *limittmp;
 
 	mtx_lock(&hrl_lock);
-	LIST_FOREACH_SAFE(limit, limits_head, hl_next, limittmp) {
+	LIST_FOREACH_SAFE(limit, &container->hc_limits, hl_next, limittmp) {
 		if (!hrl_rule_matches(limit->hl_rule, filter))
 			continue;
 
@@ -1156,39 +1166,41 @@
 	case HRL_SUBJECT_TYPE_PROCESS:
 		p = rule->hr_subject.hs_proc;
 		KASSERT(p != NULL, ("hrl_rule_add: NULL proc"));
-		hrl_limit_add(&p->p_limits, rule);
+		hrl_container_add_rule(&p->p_container, rule);
 		/*
 		 * In case of per-process rule, we don't have anything more
-		 * to do.
+		 * to do.  Also, there is no point in increasing reference
+		 * count, as the per-process containers never have
+		 * any subcontainers.
 		 */
 		return (0);
 
 	case HRL_SUBJECT_TYPE_USER:
 		uip = rule->hr_subject.hs_uip;
 		KASSERT(uip != NULL, ("hrl_rule_add: NULL uip"));
-		hrl_limit_add(&uip->ui_limits, rule);
+		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_limit_add(&gip->gi_limits, rule);
+		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"));
-		hrl_limit_add(&lc->lc_limits, rule);
+		hrl_container_add_rule(&lc->lc_container, rule);
 		break;
 
 	case HRL_SUBJECT_TYPE_JAIL:
 		pr = rule->hr_subject.hs_prison;
 		KASSERT(pr != NULL, ("hrl_rule_add: NULL pr"));
-		hrl_limit_add(&pr->pr_limits, rule);
+		hrl_container_add_rule(&pr->pr_container, rule);
 		break;
 
 	default:
-		panic("hrl_rule_add_limits: unknown subject type %d",
+		panic("hrl_rule_add: unknown subject type %d",
 		    rule->hr_subject_type);
 	}
 
@@ -1219,22 +1231,22 @@
 					break;
 			continue;
 		default:
-			panic("hrl_rule_add_limits: unknown subject type %d",
+			panic("hrl_rule_add: unknown subject type %d",
 			    rule->hr_subject_type);
 		}
 
-		hrl_limit_add(&p->p_limits, rule);
+		hrl_container_add_rule(&p->p_container, rule);
 	}
 
 	return (0);
 }
 
 static int
-hrl_rule_remove_callback(struct hrl_limits_head *limits, const struct hrl_rule *filter, void *arg3)
+hrl_rule_remove_callback(struct hrl_container *container, const struct hrl_rule *filter, void *arg3)
 {
 	int *found = (int *)arg3;
 
-	*found += hrl_limit_remove_matching(limits, filter);
+	*found += hrl_container_remove_rules(container, filter);
 	return (0);
 }
 
@@ -1250,25 +1262,25 @@
 	if (filter->hr_subject_type == HRL_SUBJECT_TYPE_PROCESS &&
 	    filter->hr_subject.hs_proc != NULL) {
 		p = filter->hr_subject.hs_proc;
-		found = hrl_limit_remove_matching(&p->p_limits, filter);
+		found = hrl_container_remove_rules(&p->p_container, filter);
 		if (found)
 			return (0);
 		return (ESRCH);
 	}
 
-	error = loginclass_limits_foreach(hrl_rule_remove_callback, filter,
+	error = loginclass_container_foreach(hrl_rule_remove_callback, filter,
 	    (void *)&found);
-	KASSERT(error == 0, ("loginclass_limits_foreach failed"));
-	error = ui_limits_foreach(hrl_rule_remove_callback, filter,
+	KASSERT(error == 0, ("loginclass_container_foreach failed"));
+	error = ui_container_foreach(hrl_rule_remove_callback, filter,
 	    (void *)&found);
-	KASSERT(error == 0, ("ui_limits_foreach failed"));
-	error = gi_limits_foreach(hrl_rule_remove_callback, filter,
+	KASSERT(error == 0, ("ui_container_foreach failed"));
+	error = gi_container_foreach(hrl_rule_remove_callback, filter,
 	    (void *)&found);
-	KASSERT(error == 0, ("gi_limits_foreach failed"));
+	KASSERT(error == 0, ("gi_container_foreach failed"));
 
 	sx_assert(&allproc_lock, SA_LOCKED);
 	FOREACH_PROC_IN_SYSTEM(p) {
-		found += hrl_limit_remove_matching(&p->p_limits, filter);
+		found += hrl_container_remove_rules(&p->p_container, filter);
 		if (error == 0)
 			found = 1;
 	}
@@ -1474,7 +1486,7 @@
 }
 
 static int
-hrl_get_rules_callback(struct hrl_limits_head *limits,
+hrl_get_rules_callback(struct hrl_container *container,
     const struct hrl_rule *filter, void *arg3)
 {
 	struct hrl_limit *limit;
@@ -1482,7 +1494,7 @@
 
 	mtx_assert(&hrl_lock, MA_OWNED);
 
-	LIST_FOREACH(limit, limits, hl_next) {
+	LIST_FOREACH(limit, &container->hc_limits, hl_next) {
 		if (!hrl_rule_matches(limit->hl_rule, filter))
 			continue;
 		hrl_rule_to_sbuf(sb, limit->hl_rule);
@@ -1523,7 +1535,7 @@
 	sx_assert(&allproc_lock, SA_LOCKED);
 	FOREACH_PROC_IN_SYSTEM(p) {
 		mtx_lock(&hrl_lock);
-		LIST_FOREACH(limit, &p->p_limits, hl_next) {
+		LIST_FOREACH(limit, &p->p_container.hc_limits, hl_next) {
 			/*
 			 * Non-process rules will be added to the buffer later.
 			 * Adding them here would result in duplicated output.
@@ -1539,9 +1551,9 @@
 	}
 
 	mtx_lock(&hrl_lock);
-	loginclass_limits_foreach(hrl_get_rules_callback, filter, sb);
-	ui_limits_foreach(hrl_get_rules_callback, filter, sb);
-	gi_limits_foreach(hrl_get_rules_callback, filter, sb);
+	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);
@@ -1608,7 +1620,7 @@
 	KASSERT(sb != NULL, ("sbuf_new failed"));
 
 	mtx_lock(&hrl_lock);
-	LIST_FOREACH(limit, &filter->hr_subject.hs_proc->p_limits, hl_next) {
+	LIST_FOREACH(limit, &filter->hr_subject.hs_proc->p_container.hc_limits, hl_next) {
 		hrl_rule_to_sbuf(sb, limit->hl_rule);
 		sbuf_printf(sb, ",");
 	}
@@ -1750,7 +1762,7 @@
 	/*
 	 * Remove rules that are no longer applicable with the new ucred.
 	 */
-	LIST_FOREACH(limit, &p->p_limits, hl_next) {
+	LIST_FOREACH(limit, &p->p_container.hc_limits, hl_next) {
 		switch (limit->hl_rule->hr_subject_type) {
 		case HRL_SUBJECT_TYPE_PROCESS:
 			continue;
@@ -1780,8 +1792,8 @@
 	 * 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);
+		LIST_FOREACH(limit, &newuip->ui_container.hc_limits, hl_next) {
+			error = hrl_container_add_rule_locked(&p->p_container, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
 
@@ -1789,8 +1801,8 @@
 		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);
+		LIST_FOREACH(limit, &newlc->lc_container.hc_limits, hl_next) {
+			error = hrl_container_add_rule_locked(&p->p_container, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
 
@@ -1798,8 +1810,8 @@
 		hrl_container_join(&p->p_container, &newlc->lc_container);
 	}
 	if (newpr != oldpr) {
-		LIST_FOREACH(limit, &newpr->pr_limits, hl_next) {
-			error = hrl_limit_add_locked(&p->p_limits, limit->hl_rule);
+		LIST_FOREACH(limit, &newpr->pr_container.hc_limits, hl_next) {
+			error = hrl_container_add_rule_locked(&p->p_container, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
 
@@ -1851,18 +1863,18 @@
 	 * Rules with 'process' subject have to be duplicated in order to make their
 	 * hr_subject point to the new process.
 	 */
-	LIST_FOREACH(limit, &parent->p_limits, hl_next) {
+	LIST_FOREACH(limit, &parent->p_container.hc_limits, hl_next) {
 		if (limit->hl_rule->hr_subject_type == HRL_SUBJECT_TYPE_PROCESS) {
 			rule = hrl_rule_duplicate(limit->hl_rule, M_NOWAIT);
 			KASSERT(rule != NULL, ("XXX: better error handling needed"));
 			KASSERT(rule->hr_subject.hs_proc == parent,
 			    ("rule->hr_subject.hs_proc == parent"));
 			rule->hr_subject.hs_proc = child;
-			error = hrl_limit_add_locked(&child->p_limits, rule);
+			error = hrl_container_add_rule_locked(&child->p_container, rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 			hrl_rule_release(rule);
 		} else {
-			error = hrl_limit_add_locked(&child->p_limits, limit->hl_rule);
+			error = hrl_container_add_rule_locked(&child->p_container, limit->hl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
 	}
@@ -1896,8 +1908,8 @@
 	struct hrl_limit *limit;
 
 	mtx_lock(&hrl_lock);
-	while (!LIST_EMPTY(&p->p_limits)) {
-		limit = LIST_FIRST(&p->p_limits);
+	while (!LIST_EMPTY(&p->p_container.hc_limits)) {
+		limit = LIST_FIRST(&p->p_container.hc_limits);
 		LIST_REMOVE(limit, hl_next);
 		hrl_rule_release(limit->hl_rule);
 		uma_zfree(hrl_limit_zone, limit);

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

@@ -208,7 +208,7 @@
 }
 
 int
-loginclass_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+loginclass_container_foreach(int (*callback)(struct hrl_container *container,
     const struct hrl_rule *filter, void *arg3),
     const struct hrl_rule *filter, void *arg3)
 {
@@ -216,7 +216,7 @@
 	struct loginclass *lc, *lctmp;
 
 	LIST_FOREACH_SAFE(lc, &loginclasses, lc_next, lctmp) {
-		error = (callback)(&lc->lc_limits, filter, arg3);
+		error = (callback)(&lc->lc_container, filter, arg3);
 		if (error)
 			return (error);
 	}

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

@@ -1392,7 +1392,7 @@
 }
 
 int
-ui_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+ui_container_foreach(int (*callback)(struct hrl_container *container,
     const struct hrl_rule *filter, void *arg3),
     const struct hrl_rule *filter, void *arg3)
 {
@@ -1404,7 +1404,7 @@
 	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);
+			error = (callback)(&uip->ui_container, filter, arg3);
 			if (error) {
 				rw_runlock(&uihashtbl_lock);
 				return (error);
@@ -1479,7 +1479,6 @@
 			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);
@@ -1541,7 +1540,7 @@
 }
 
 int
-gi_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+gi_container_foreach(int (*callback)(struct hrl_container *container,
     const struct hrl_rule *filter, void *arg3),
     const struct hrl_rule *filter, void *arg3)
 {
@@ -1553,7 +1552,7 @@
 	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);
+			error = (callback)(&gip->gi_container, filter, arg3);
 			if (error) {
 				rw_runlock(&gihashtbl_lock);
 				return (error);

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

@@ -147,24 +147,15 @@
  * 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.
+ *
+ * This structure must be filled with zeroes initially.
  */
 struct hrl_container {
 	int64_t				hc_resources[HRL_RESOURCE_MAX + 1];
 	struct hrl_container		*hc_parents[HRL_HC_PARENTS_MAX + 1];
+	LIST_HEAD(, hrl_limit)		hc_limits;
 };
 
-/*
- * 'hrl_limit' connects a rule with every subject it's related to.
- * For example, rule 'user:X:openfiles:deny=N/process' is linked
- * with uidinfo for user X, and to each process of that user.
- */
-struct hrl_limit {
-	LIST_ENTRY(hrl_limit)	hl_next;
-	struct hrl_rule		*hl_rule;
-};
-
-LIST_HEAD(hrl_limits_head, hrl_limit);
-
 #ifdef _KERNEL
 
 int	hrl_alloc(struct proc *p, int object, uint64_t amount);

==== //depot/projects/soc2009/trasz_limits/sys/sys/jail.h#11 (text+ko) ====

@@ -182,7 +182,6 @@
 	char		 pr_domainname[MAXHOSTNAMELEN];	/* (p) jail domainname */
 	char		 pr_hostuuid[HOSTUUIDLEN];	/* (p) jail hostuuid */
 	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#6 (text+ko) ====

@@ -37,13 +37,12 @@
 	char			lc_name[MAXLOGNAME];
 	u_int			lc_refcount;
 	struct hrl_container	lc_container;
-	struct hrl_limits_head	lc_limits;
 };
 
 void	loginclass_acquire(struct loginclass *lc);
 void	loginclass_release(struct loginclass *lc);
 struct loginclass	*loginclass_find(const char *name);
-int	loginclass_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+int	loginclass_container_foreach(int (*callback)(struct hrl_container *container,
 	    const struct hrl_rule *filter, void *arg3),
 	    const struct hrl_rule *filter, void *arg3);
 

==== //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#14 (text+ko) ====

@@ -512,7 +512,6 @@
 	int		p_pendingcnt;	/* how many signals are pending */
 	struct itimers	*p_itimers;	/* (c) POSIX interval timers. */
 	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#14 (text+ko) ====

@@ -99,7 +99,6 @@
 	uid_t	ui_uid;			/* (a) uid */
 	u_int	ui_ref;			/* (b) reference count */
 	struct hrl_container ui_container;	/* (*) HRL resource accounting */
-	struct hrl_limits_head	ui_limits;/* (*) HRL rules applicable to the uid */
 };
 
 #define	UIDINFO_VMSIZE_LOCK(ui)		mtx_lock(&((ui)->ui_vmsize_mtx))
@@ -118,7 +117,6 @@
 	gid_t	gi_gid;			/* (a) gid */
 	u_int	gi_ref;			/* (b) reference count */
 	struct hrl_container gi_container;	/* (*) HRL resource accounting */
-	struct hrl_limits_head	gi_limits;/* (*) HRL rules applicable to the gid */
 };
 
 struct proc;
@@ -157,7 +155,7 @@
 void	 uifree(struct uidinfo *uip);
 void	 uihashinit(void);
 void	 uihold(struct uidinfo *uip);
-int	 ui_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+int	 ui_container_foreach(int (*callback)(struct hrl_container *container,
 	    const struct hrl_rule *filter, void *arg3),
 	    const struct hrl_rule *filter, void *arg3);
 struct gidinfo
@@ -165,7 +163,7 @@
 void	 gifree(struct gidinfo *gip);
 void	 gihashinit(void);
 void	 gihold(struct gidinfo *gip);
-int	 gi_limits_foreach(int (*callback)(struct hrl_limits_head *limits,
+int	 gi_container_foreach(int (*callback)(struct hrl_container *container,
 	    const struct hrl_rule *filter, void *arg3),
 	    const struct hrl_rule *filter, void *arg3);
 



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