Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 May 2011 07:32:58 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221362 - in head: sys/kern sys/sys usr.bin/rctl
Message-ID:  <201105030732.p437Wwoa074933@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Tue May  3 07:32:58 2011
New Revision: 221362
URL: http://svn.freebsd.org/changeset/base/221362

Log:
  Change the way rctl interfaces with jails by introducing prison_racct
  structure, which acts as a proxy between them.  This makes jail rules
  persistent, i.e. they can be added before jail gets created, and they
  don't disappear when the jail gets destroyed.

Modified:
  head/sys/kern/kern_jail.c
  head/sys/kern/kern_racct.c
  head/sys/kern/kern_rctl.c
  head/sys/sys/jail.h
  head/sys/sys/rctl.h
  head/usr.bin/rctl/rctl.8

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Tue May  3 07:24:47 2011	(r221361)
+++ head/sys/kern/kern_jail.c	Tue May  3 07:32:58 2011	(r221362)
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/racct.h>
-#include <sys/rctl.h>
+#include <sys/refcount.h>
 #include <sys/sx.h>
 #include <sys/sysent.h>
 #include <sys/namei.h>
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
 #define	DEFAULT_HOSTUUID	"00000000-0000-0000-0000-000000000000"
 
 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
+MALLOC_DEFINE(M_PRISON_RACCT, "prison_racct", "Prison racct structures");
 
 /* Keep struct prison prison0 and some code in kern_jail_set() readable. */
 #ifdef INET
@@ -114,10 +115,11 @@ struct prison prison0 = {
 };
 MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
 
-/* allprison and lastprid are protected by allprison_lock. */
+/* allprison, allprison_racct and lastprid are protected by allprison_lock. */
 struct	sx allprison_lock;
 SX_SYSINIT(allprison_lock, &allprison_lock, "allprison");
 struct	prisonlist allprison = TAILQ_HEAD_INITIALIZER(allprison);
+LIST_HEAD(, prison_racct) allprison_racct;
 int	lastprid = 0;
 
 static int do_jail_attach(struct thread *td, struct prison *pr);
@@ -125,6 +127,10 @@ static void prison_complete(void *contex
 static void prison_deref(struct prison *pr, int flags);
 static char *prison_path(struct prison *pr1, struct prison *pr2);
 static void prison_remove_one(struct prison *pr);
+#ifdef RACCT
+static void prison_racct_attach(struct prison *pr);
+static void prison_racct_detach(struct prison *pr);
+#endif
 #ifdef INET
 static int _prison_check_ip4(struct prison *pr, struct in_addr *ia);
 static int prison_restrict_ip4(struct prison *pr, struct in_addr *newip4);
@@ -1197,7 +1203,6 @@ kern_jail_set(struct thread *td, struct 
 			root = mypr->pr_root;
 			vref(root);
 		}
-		racct_create(&pr->pr_racct);
 		strlcpy(pr->pr_hostuuid, DEFAULT_HOSTUUID, HOSTUUIDLEN);
 		pr->pr_flags |= PR_HOST;
 #if defined(INET) || defined(INET6)
@@ -1657,6 +1662,11 @@ kern_jail_set(struct thread *td, struct 
 	pr->pr_flags = (pr->pr_flags & ~ch_flags) | pr_flags;
 	mtx_unlock(&pr->pr_mtx);
 
+#ifdef RACCT
+	if (created)
+		prison_racct_attach(pr);
+#endif
+
 	/* Locks may have prevented a complete restriction of child IP
 	 * addresses.  If so, allocate some more memory and try again.
 	 */
@@ -2533,10 +2543,9 @@ prison_deref(struct prison *pr, int flag
 		if (pr->pr_cpuset != NULL)
 			cpuset_rel(pr->pr_cpuset);
 		osd_jail_exit(pr);
-#ifdef RCTL
-		rctl_racct_release(pr->pr_racct);
+#ifdef RACCT
+		prison_racct_detach(pr);
 #endif
-		racct_destroy(&pr->pr_racct);
 		free(pr, M_PRISON);
 
 		/* Removing a prison frees a reference on its parent. */
@@ -4277,14 +4286,103 @@ void
 prison_racct_foreach(void (*callback)(struct racct *racct,
     void *arg2, void *arg3), void *arg2, void *arg3)
 {
-	struct prison *pr;
+	struct prison_racct *prr;
 
 	sx_slock(&allprison_lock);
-	TAILQ_FOREACH(pr, &allprison, pr_list)
-		(callback)(pr->pr_racct, arg2, arg3);
+	LIST_FOREACH(prr, &allprison_racct, prr_next)
+		(callback)(prr->prr_racct, arg2, arg3);
 	sx_sunlock(&allprison_lock);
 }
 
+static struct prison_racct *
+prison_racct_find_locked(const char *name)
+{
+	struct prison_racct *prr;
+
+	sx_assert(&allprison_lock, SA_XLOCKED);
+
+	if (name[0] == '\0' || strlen(name) >= MAXHOSTNAMELEN)
+		return (NULL);
+
+	LIST_FOREACH(prr, &allprison_racct, prr_next) {
+		if (strcmp(name, prr->prr_name) != 0)
+			continue;
+
+		/* Found prison_racct with a matching name? */
+		prison_racct_hold(prr);
+		return (prr);
+	}
+
+	/* Add new prison_racct. */
+	prr = malloc(sizeof(*prr), M_PRISON_RACCT, M_ZERO | M_WAITOK);
+	racct_create(&prr->prr_racct);
+
+	strcpy(prr->prr_name, name);
+	refcount_init(&prr->prr_refcount, 1);
+	LIST_INSERT_HEAD(&allprison_racct, prr, prr_next);
+
+	return (prr);
+}
+
+struct prison_racct *
+prison_racct_find(const char *name)
+{
+	struct prison_racct *prr;
+
+	sx_xlock(&allprison_lock);
+	prr = prison_racct_find_locked(name);
+	sx_xunlock(&allprison_lock);
+	return (prr);
+}
+
+void
+prison_racct_hold(struct prison_racct *prr)
+{
+
+	refcount_acquire(&prr->prr_refcount);
+}
+
+void
+prison_racct_free(struct prison_racct *prr)
+{
+	int old;
+
+	old = prr->prr_refcount;
+	if (old > 1 && atomic_cmpset_int(&prr->prr_refcount, old, old - 1))
+		return;
+
+	sx_xlock(&allprison_lock);
+	if (refcount_release(&prr->prr_refcount)) {
+		racct_destroy(&prr->prr_racct);
+		LIST_REMOVE(prr, prr_next);
+		sx_xunlock(&allprison_lock);
+		free(prr, M_PRISON_RACCT);
+
+		return;
+	}
+	sx_xunlock(&allprison_lock);
+}
+
+#ifdef RACCT
+static void
+prison_racct_attach(struct prison *pr)
+{
+	struct prison_racct *prr;
+
+	prr = prison_racct_find_locked(pr->pr_name);
+	KASSERT(prr != NULL, ("cannot find prison_racct"));
+
+	pr->pr_prison_racct = prr;
+}
+
+static void
+prison_racct_detach(struct prison *pr)
+{
+	prison_racct_free(pr->pr_prison_racct);
+	pr->pr_prison_racct = NULL;
+}
+#endif /* RACCT */
+
 #ifdef DDB
 
 static void

Modified: head/sys/kern/kern_racct.c
==============================================================================
--- head/sys/kern/kern_racct.c	Tue May  3 07:24:47 2011	(r221361)
+++ head/sys/kern/kern_racct.c	Tue May  3 07:32:58 2011	(r221362)
@@ -313,7 +313,8 @@ racct_add_cred_locked(struct ucred *cred
 
 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
-		racct_alloc_resource(pr->pr_racct, resource, amount);
+		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
+		    amount);
 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
 }
 
@@ -522,7 +523,8 @@ racct_sub_cred_locked(struct ucred *cred
 
 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
-		racct_alloc_resource(pr->pr_racct, resource, -amount);
+		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
+		    -amount);
 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
 }
 
@@ -669,9 +671,11 @@ racct_proc_ucred_changed(struct proc *p,
 	}
 	if (newpr != oldpr) {
 		for (pr = oldpr; pr != NULL; pr = pr->pr_parent)
-			racct_sub_racct(pr->pr_racct, p->p_racct);
+			racct_sub_racct(pr->pr_prison_racct->prr_racct,
+			    p->p_racct);
 		for (pr = newpr; pr != NULL; pr = pr->pr_parent)
-			racct_add_racct(pr->pr_racct, p->p_racct);
+			racct_add_racct(pr->pr_prison_racct->prr_racct,
+			    p->p_racct);
 	}
 	mtx_unlock(&racct_lock);
 
@@ -744,7 +748,7 @@ racct_init(void)
 	/*
 	 * XXX: Move this somewhere.
 	 */
-	racct_create(&prison0.pr_racct);
+	prison0.pr_prison_racct = prison_racct_find("0");
 }
 SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
 

Modified: head/sys/kern/kern_rctl.c
==============================================================================
--- head/sys/kern/kern_rctl.c	Tue May  3 07:24:47 2011	(r221361)
+++ head/sys/kern/kern_rctl.c	Tue May  3 07:32:58 2011	(r221362)
@@ -241,7 +241,8 @@ rctl_available_resource(const struct pro
 		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
 		available = rule->rr_amount -
-		    cred->cr_prison->pr_racct->r_resources[resource];
+		    cred->cr_prison->pr_prison_racct->prr_racct->
+		        r_resources[resource];
 		break;
 	default:
 		panic("rctl_compute_available: unknown per %d",
@@ -327,7 +328,7 @@ rctl_enforce(struct proc *p, int resourc
 			printf("rctl: rule \"%s\" matched by pid %d "
 			    "(%s), uid %d, jail %s\n", sbuf_data(&sb),
 			    p->p_pid, p->p_comm, p->p_ucred->cr_uid,
-			    p->p_ucred->cr_prison->pr_name);
+			    p->p_ucred->cr_prison->pr_prison_racct->prr_name);
 			sbuf_delete(&sb);
 			free(buf, M_RCTL);
 			link->rrl_exceeded = 1;
@@ -346,7 +347,7 @@ rctl_enforce(struct proc *p, int resourc
 			rctl_rule_to_sbuf(&sb, rule);
 			sbuf_printf(&sb, " pid=%d ruid=%d jail=%s",
 			    p->p_pid, p->p_ucred->cr_ruid,
-			    p->p_ucred->cr_prison->pr_name);
+			    p->p_ucred->cr_prison->pr_prison_racct->prr_name);
 			sbuf_finish(&sb);
 			devctl_notify_f("RCTL", "rule", "matched",
 			    sbuf_data(&sb), M_NOWAIT);
@@ -481,9 +482,9 @@ rctl_rule_matches(const struct rctl_rule
 				return (0);
 			break;
 		case RCTL_SUBJECT_TYPE_JAIL:
-			if (filter->rr_subject.rs_prison != NULL &&
-			    rule->rr_subject.rs_prison !=
-			    filter->rr_subject.rs_prison)
+			if (filter->rr_subject.rs_prison_racct != NULL &&
+			    rule->rr_subject.rs_prison_racct !=
+			    filter->rr_subject.rs_prison_racct)
 				return (0);
 			break;
 		default:
@@ -635,7 +636,10 @@ rctl_rule_acquire_subject(struct rctl_ru
 	switch (rule->rr_subject_type) {
 	case RCTL_SUBJECT_TYPE_UNDEFINED:
 	case RCTL_SUBJECT_TYPE_PROCESS:
+		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
+		if (rule->rr_subject.rs_prison_racct != NULL)
+			prison_racct_hold(rule->rr_subject.rs_prison_racct);
 		break;
 	case RCTL_SUBJECT_TYPE_USER:
 		if (rule->rr_subject.rs_uip != NULL)
@@ -658,7 +662,10 @@ rctl_rule_release_subject(struct rctl_ru
 	switch (rule->rr_subject_type) {
 	case RCTL_SUBJECT_TYPE_UNDEFINED:
 	case RCTL_SUBJECT_TYPE_PROCESS:
+		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
+		if (rule->rr_subject.rs_prison_racct != NULL)
+			prison_racct_free(rule->rr_subject.rs_prison_racct);
 		break;
 	case RCTL_SUBJECT_TYPE_USER:
 		if (rule->rr_subject.rs_uip != NULL)
@@ -686,7 +693,7 @@ rctl_rule_alloc(int flags)
 	rule->rr_subject.rs_proc = NULL;
 	rule->rr_subject.rs_uip = NULL;
 	rule->rr_subject.rs_loginclass = NULL;
-	rule->rr_subject.rs_prison = NULL;
+	rule->rr_subject.rs_prison_racct = NULL;
 	rule->rr_per = RCTL_SUBJECT_TYPE_UNDEFINED;
 	rule->rr_resource = RACCT_UNDEFINED;
 	rule->rr_action = RCTL_ACTION_UNDEFINED;
@@ -708,7 +715,7 @@ rctl_rule_duplicate(const struct rctl_ru
 	copy->rr_subject.rs_proc = rule->rr_subject.rs_proc;
 	copy->rr_subject.rs_uip = rule->rr_subject.rs_uip;
 	copy->rr_subject.rs_loginclass = rule->rr_subject.rs_loginclass;
-	copy->rr_subject.rs_prison = rule->rr_subject.rs_prison;
+	copy->rr_subject.rs_prison_racct = rule->rr_subject.rs_prison_racct;
 	copy->rr_per = rule->rr_per;
 	copy->rr_resource = rule->rr_resource;
 	copy->rr_action = rule->rr_action;
@@ -784,7 +791,7 @@ rctl_rule_fully_specified(const struct r
 			return (0);
 		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
-		if (rule->rr_subject.rs_prison == NULL)
+		if (rule->rr_subject.rs_prison_racct == NULL)
 			return (0);
 		break;
 	default:
@@ -833,7 +840,7 @@ rctl_string_to_rule(char *rulestr, struc
 		rule->rr_subject.rs_proc = NULL;
 		rule->rr_subject.rs_uip = NULL;
 		rule->rr_subject.rs_loginclass = NULL;
-		rule->rr_subject.rs_prison = NULL;
+		rule->rr_subject.rs_prison_racct = NULL;
 	} else {
 		switch (rule->rr_subject_type) {
 		case RCTL_SUBJECT_TYPE_UNDEFINED:
@@ -866,23 +873,12 @@ rctl_string_to_rule(char *rulestr, struc
 			}
 			break;
 		case RCTL_SUBJECT_TYPE_JAIL:
-			rule->rr_subject.rs_prison =
-			    prison_find_name(&prison0, subject_idstr);
-			if (rule->rr_subject.rs_prison == NULL) {
-				/*
-				 * No jail with that name; try with the JID.
-				 */
-				error = str2id(subject_idstr, &id);
-				if (error != 0)
-					goto out;
-				rule->rr_subject.rs_prison = prison_find(id);
-				if (rule->rr_subject.rs_prison == NULL) {
-					error = ESRCH;
-					goto out;
-				}
+			rule->rr_subject.rs_prison_racct =
+			    prison_racct_find(subject_idstr);
+			if (rule->rr_subject.rs_prison_racct == NULL) {
+				error = ENAMETOOLONG;
+				goto out;
 			}
-			/* prison_find() returns with mutex held. */
-			mtx_unlock(&rule->rr_subject.rs_prison->pr_mtx);
 			break;
                default:
                        panic("rctl_string_to_rule: unknown subject type %d",
@@ -944,6 +940,7 @@ rctl_rule_add(struct rctl_rule *rule)
 	struct ucred *cred;
 	struct uidinfo *uip;
 	struct prison *pr;
+	struct prison_racct *prr;
 	struct loginclass *lc;
 	struct rctl_rule *rule2;
 	int match;
@@ -1008,9 +1005,9 @@ rctl_rule_add(struct rctl_rule *rule)
 		break;
 
 	case RCTL_SUBJECT_TYPE_JAIL:
-		pr = rule->rr_subject.rs_prison;
-		KASSERT(pr != NULL, ("rctl_rule_add: NULL pr"));
-		rctl_racct_add_rule(pr->pr_racct, rule);
+		prr = rule->rr_subject.rs_prison_racct;
+		KASSERT(prr != NULL, ("rctl_rule_add: NULL pr"));
+		rctl_racct_add_rule(prr->prr_racct, rule);
 		break;
 
 	default:
@@ -1040,7 +1037,7 @@ rctl_rule_add(struct rctl_rule *rule)
 		case RCTL_SUBJECT_TYPE_JAIL:
 			match = 0;
 			for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) {
-				if (pr == rule->rr_subject.rs_prison) {
+				if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) {
 					match = 1;
 					break;
 				}
@@ -1144,11 +1141,11 @@ rctl_rule_to_sbuf(struct sbuf *sb, const
 			    rule->rr_subject.rs_loginclass->lc_name);
 		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
-		if (rule->rr_subject.rs_prison == NULL)
+		if (rule->rr_subject.rs_prison_racct == NULL)
 			sbuf_printf(sb, ":");
 		else
 			sbuf_printf(sb, "%s:",
-			    rule->rr_subject.rs_prison->pr_name);
+			    rule->rr_subject.rs_prison_racct->prr_name);
 		break;
 	default:
 		panic("rctl_rule_to_sbuf: unknown subject type %d",
@@ -1245,7 +1242,7 @@ rctl_get_racct(struct thread *td, struct
 	struct proc *p;
 	struct uidinfo *uip;
 	struct loginclass *lc;
-	struct prison *pr;
+	struct prison_racct *prr;
 
 	error = priv_check(td, PRIV_RCTL_GET_RACCT);
 	if (error != 0)
@@ -1256,11 +1253,9 @@ rctl_get_racct(struct thread *td, struct
 		return (error);
 
 	sx_slock(&allproc_lock);
-	sx_slock(&allprison_lock);
 	error = rctl_string_to_rule(inputstr, &filter);
 	free(inputstr, M_RCTL);
 	if (error != 0) {
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (error);
 	}
@@ -1295,19 +1290,18 @@ rctl_get_racct(struct thread *td, struct
 		outputsbuf = rctl_racct_to_sbuf(lc->lc_racct, 1);
 		break;
 	case RCTL_SUBJECT_TYPE_JAIL:
-		pr = filter->rr_subject.rs_prison;
-		if (pr == NULL) {
+		prr = filter->rr_subject.rs_prison_racct;
+		if (prr == NULL) {
 			error = EINVAL;
 			goto out;
 		}
-		outputsbuf = rctl_racct_to_sbuf(pr->pr_racct, 1);
+		outputsbuf = rctl_racct_to_sbuf(prr->prr_racct, 1);
 		break;
 	default:
 		error = EINVAL;
 	}
 out:
 	rctl_rule_release(filter);
-	sx_sunlock(&allprison_lock);
 	sx_sunlock(&allproc_lock);
 	if (error != 0)
 		return (error);
@@ -1354,11 +1348,9 @@ rctl_get_rules(struct thread *td, struct
 		return (error);
 
 	sx_slock(&allproc_lock);
-	sx_slock(&allprison_lock);
 	error = rctl_string_to_rule(inputstr, &filter);
 	free(inputstr, M_RCTL);
 	if (error != 0) {
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (error);
 	}
@@ -1406,7 +1398,6 @@ again:
 	error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
 
 	rctl_rule_release(filter);
-	sx_sunlock(&allprison_lock);
 	sx_sunlock(&allproc_lock);
 	free(buf, M_RCTL);
 	return (error);
@@ -1431,30 +1422,25 @@ rctl_get_limits(struct thread *td, struc
 		return (error);
 
 	sx_slock(&allproc_lock);
-	sx_slock(&allprison_lock);
 	error = rctl_string_to_rule(inputstr, &filter);
 	free(inputstr, M_RCTL);
 	if (error != 0) {
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (error);
 	}
 
 	if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_UNDEFINED) {
 		rctl_rule_release(filter);
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (EINVAL);
 	}
 	if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_PROCESS) {
 		rctl_rule_release(filter);
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (EOPNOTSUPP);
 	}
 	if (filter->rr_subject.rs_proc == NULL) {
 		rctl_rule_release(filter);
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (EINVAL);
 	}
@@ -1486,7 +1472,6 @@ again:
 
 	error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
 	rctl_rule_release(filter);
-	sx_sunlock(&allprison_lock);
 	sx_sunlock(&allproc_lock);
 	free(buf, M_RCTL);
 	return (error);
@@ -1508,11 +1493,9 @@ rctl_add_rule(struct thread *td, struct 
 		return (error);
 
 	sx_slock(&allproc_lock);
-	sx_slock(&allprison_lock);
 	error = rctl_string_to_rule(inputstr, &rule);
 	free(inputstr, M_RCTL);
 	if (error != 0) {
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (error);
 	}
@@ -1532,7 +1515,6 @@ rctl_add_rule(struct thread *td, struct 
 
 out:
 	rctl_rule_release(rule);
-	sx_sunlock(&allprison_lock);
 	sx_sunlock(&allproc_lock);
 	return (error);
 }
@@ -1553,18 +1535,15 @@ rctl_remove_rule(struct thread *td, stru
 		return (error);
 
 	sx_slock(&allproc_lock);
-	sx_slock(&allprison_lock);
 	error = rctl_string_to_rule(inputstr, &filter);
 	free(inputstr, M_RCTL);
 	if (error != 0) {
-		sx_sunlock(&allprison_lock);
 		sx_sunlock(&allproc_lock);
 		return (error);
 	}
 
 	error = rctl_rule_remove(filter);
 	rctl_rule_release(filter);
-	sx_sunlock(&allprison_lock);
 	sx_sunlock(&allproc_lock);
 
 	return (error);
@@ -1580,12 +1559,12 @@ rctl_proc_ucred_changed(struct proc *p, 
 	struct rctl_rule_link *link, *newlink;
 	struct uidinfo *newuip;
 	struct loginclass *newlc;
-	struct prison *newpr;
+	struct prison_racct *newprr;
 	LIST_HEAD(, rctl_rule_link) newrules;
 
 	newuip = newcred->cr_ruidinfo;
 	newlc = newcred->cr_loginclass;
-	newpr = newcred->cr_prison;
+	newprr = newcred->cr_prison->pr_prison_racct;
 	
 	LIST_INIT(&newrules);
 
@@ -1605,7 +1584,7 @@ again:
 		rulecnt++;
 	LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next)
 		rulecnt++;
-	LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next)
+	LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next)
 		rulecnt++;
 	rw_runlock(&rctl_lock);
 
@@ -1655,7 +1634,7 @@ again:
 		rulecnt--;
 	}
 
-	LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next) {
+	LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) {
 		if (newlink == NULL)
 			goto goaround;
 		rctl_rule_acquire(link->rrl_rule);

Modified: head/sys/sys/jail.h
==============================================================================
--- head/sys/sys/jail.h	Tue May  3 07:24:47 2011	(r221361)
+++ head/sys/sys/jail.h	Tue May  3 07:32:58 2011	(r221362)
@@ -136,6 +136,7 @@ MALLOC_DECLARE(M_PRISON);
 #define	HOSTUUIDLEN	64
 
 struct racct;
+struct prison_racct;
 
 /*
  * This structure describes a prison.  It is pointed to by all struct
@@ -168,7 +169,7 @@ struct prison {
 	int		 pr_ip6s;			/* (p) number of v6 IPs */
 	struct in_addr	*pr_ip4;			/* (p) v4 IPs of jail */
 	struct in6_addr	*pr_ip6;			/* (p) v6 IPs of jail */
-	struct racct	*pr_racct;			/* (c) resource accounting */
+	struct prison_racct *pr_prison_racct;		/* (c) racct jail proxy */
 	void		*pr_sparep[3];
 	int		 pr_childcount;			/* (a) number of child jails */
 	int		 pr_childmax;			/* (p) maximum child jails */
@@ -183,6 +184,13 @@ struct prison {
 	char		 pr_domainname[MAXHOSTNAMELEN];	/* (p) jail domainname */
 	char		 pr_hostuuid[HOSTUUIDLEN];	/* (p) jail hostuuid */
 };
+
+struct prison_racct {
+	LIST_ENTRY(prison_racct) prr_next;
+	char		prr_name[MAXHOSTNAMELEN];
+	u_int		prr_refcount;
+	struct racct	*prr_racct;
+};
 #endif /* _KERNEL || _WANT_PRISON */
 
 #ifdef _KERNEL
@@ -385,6 +393,9 @@ int prison_priv_check(struct ucred *cred
 int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
 void prison_racct_foreach(void (*callback)(struct racct *racct,
     void *arg2, void *arg3), void *arg2, void *arg3);
+struct prison_racct *prison_racct_find(const char *name);
+void prison_racct_hold(struct prison_racct *prr);
+void prison_racct_free(struct prison_racct *prr);
 
 #endif /* _KERNEL */
 #endif /* !_SYS_JAIL_H_ */

Modified: head/sys/sys/rctl.h
==============================================================================
--- head/sys/sys/rctl.h	Tue May  3 07:24:47 2011	(r221361)
+++ head/sys/sys/rctl.h	Tue May  3 07:32:58 2011	(r221362)
@@ -44,7 +44,7 @@
 struct proc;
 struct uidinfo;
 struct loginclass;
-struct prison;
+struct prison_racct;
 struct ucred;
 struct rctl_rule_link;
 
@@ -70,7 +70,7 @@ struct rctl_rule {
 		struct proc		*rs_proc;
 		struct uidinfo		*rs_uip;
 		struct loginclass	*rs_loginclass;
-		struct prison		*rs_prison;
+		struct prison_racct	*rs_prison_racct;
 	} rr_subject;
 	int		rr_per;
 	int		rr_resource;

Modified: head/usr.bin/rctl/rctl.8
==============================================================================
--- head/usr.bin/rctl/rctl.8	Tue May  3 07:24:47 2011	(r221361)
+++ head/usr.bin/rctl/rctl.8	Tue May  3 07:32:58 2011	(r221362)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 14, 2011
+.Dd May 3, 2011
 .Dt RCTL 8
 .Os
 .Sh NAME
@@ -90,7 +90,7 @@ Subject defines the kind of entity the r
 It can be either process, user, login class, or jail.
 .Pp
 Subject ID identifies the subject.  It can be user name,
-numerical user ID, login class name, jail name, or numerical jail ID.
+numerical user ID, login class name, or jail name.
 .Pp
 Resource identifies the resource the rule controls.
 .Pp
@@ -177,9 +177,9 @@ Prevent user "joe" from allocating more 
 .Pp
 Remove all RCTL rules.
 .Pp
-.Dl rctl -hu jail:5
+.Dl rctl -hu jail:www
 .Pp
-Display resource usage information for jail with JID 5.
+Display resource usage information for jail named "www".
 .Pp
 .Dl rctl -l process:512
 .Pp



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