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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to