From a7ad07bff3f0501e3ea483955122f5da37519674 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 3 May 2011 07:32:58 +0000 Subject: [PATCH] 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. --- sys/kern/kern_jail.c | 116 ++++++++++++++++++++++++++++++++++++++---- sys/kern/kern_racct.c | 14 +++-- sys/kern/kern_rctl.c | 95 ++++++++++++++-------------------- sys/sys/jail.h | 13 ++++- sys/sys/rctl.h | 4 +- usr.bin/rctl/rctl.8 | 8 +-- 6 files changed, 171 insertions(+), 79 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 22b97e854ad1..5850ad1b512b 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -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 *context, int pending); 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 uio *optuio, int flags) 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 uio *optuio, int flags) 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 flags) 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 diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 5778bfe54d77..98bd9c56a0ed 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -313,7 +313,8 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) 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, int resource, uint64_t amount) 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, struct ucred *oldcred, } 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); diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c index 88a971c932e8..2d43bdce521c 100644 --- a/sys/kern/kern_rctl.c +++ b/sys/kern/kern_rctl.c @@ -241,7 +241,8 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) 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 resource, uint64_t amount) 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 resource, uint64_t amount) 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 *rule, const struct rctl_rule *filter) 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_rule *rule) 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_rule *rule) 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_rule *rule, int flags) 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 rctl_rule *rule) 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, struct rctl_rule **rulep) 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, struct rctl_rule **rulep) } 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 struct rctl_rule *rule) 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 rctl_get_racct_args *uap) 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 rctl_get_racct_args *uap) 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 rctl_get_racct_args *uap) 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 rctl_get_rules_args *uap) 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 @@ rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) 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, struct rctl_get_limits_args *uap) 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 @@ rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) 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 rctl_add_rule_args *uap) 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 rctl_add_rule_args *uap) 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, struct rctl_remove_rule_args *uap) 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 ucred *newcred) 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 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) 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 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) 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); diff --git a/sys/sys/jail.h b/sys/sys/jail.h index b83ac1b8a3c9..bbaf38162e7c 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -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 priv); 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_ */ diff --git a/sys/sys/rctl.h b/sys/sys/rctl.h index d61defd8e427..1e0342732b80 100644 --- a/sys/sys/rctl.h +++ b/sys/sys/rctl.h @@ -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; diff --git a/usr.bin/rctl/rctl.8 b/usr.bin/rctl/rctl.8 index f30f4c3f024f..bddd3130ff25 100644 --- a/usr.bin/rctl/rctl.8 +++ b/usr.bin/rctl/rctl.8 @@ -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 rule applies to. 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 than 1GB of virtual memory. .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