Date: Thu, 10 Feb 2011 19:41:08 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 188692 for review Message-ID: <201102101941.p1AJf8rE033058@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@188692?ac=10 Change 188692 by trasz@trasz_victim on 2011/02/10 19:40:25 Jails are not like uidinfo structures - we can't just increase their refcount when rules get linked to them, because it would leave them hanging in "dead" state after all the jailed processes died. Instead, treat them like we do with processes - instead of bumping their reference counts, just hold allprison_lock. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#73 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_jail.c#36 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#28 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/rctl.h#12 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#73 (text+ko) ==== @@ -615,7 +615,7 @@ PROC_UNLOCK(p); #ifdef RCTL - rctl_proc_exit(p); + rctl_container_release(p->p_container); #endif container_destroy(&p->p_container); } ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_jail.c#36 (text+ko) ==== @@ -50,6 +50,7 @@ #include <sys/jail.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/rctl.h> #include <sys/sx.h> #include <sys/sysent.h> #include <sys/namei.h> @@ -2532,6 +2533,9 @@ if (pr->pr_cpuset != NULL) cpuset_rel(pr->pr_cpuset); osd_jail_exit(pr); +#ifdef RCTL + rctl_container_release(pr->pr_container); +#endif container_destroy(&pr->pr_container); free(pr, M_PRISON); ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#28 (text+ko) ==== @@ -607,6 +607,7 @@ switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: + case RCTL_SUBJECT_TYPE_JAIL: break; case RCTL_SUBJECT_TYPE_USER: if (rule->rr_subject.rs_uip != NULL) @@ -616,10 +617,6 @@ if (rule->rr_subject.hr_loginclass != NULL) loginclass_acquire(rule->rr_subject.hr_loginclass); break; - case RCTL_SUBJECT_TYPE_JAIL: - if (rule->rr_subject.hr_loginclass != NULL) - prison_hold(rule->rr_subject.rs_prison); - break; default: panic("rctl_rule_acquire_subject: unknown subject type %d", rule->rr_subject_type); @@ -633,6 +630,7 @@ switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: + case RCTL_SUBJECT_TYPE_JAIL: break; case RCTL_SUBJECT_TYPE_USER: if (rule->rr_subject.rs_uip != NULL) @@ -642,10 +640,6 @@ if (rule->rr_subject.hr_loginclass != NULL) loginclass_release(rule->rr_subject.hr_loginclass); break; - case RCTL_SUBJECT_TYPE_JAIL: - if (rule->rr_subject.rs_prison != NULL) - prison_free(rule->rr_subject.rs_prison); - break; default: panic("rctl_rule_release_subject: unknown subject type %d", rule->rr_subject_type); @@ -842,17 +836,13 @@ rule->rr_subject.hr_loginclass = loginclass_find(subject_idstr); break; case RCTL_SUBJECT_TYPE_JAIL: - sx_slock(&allprison_lock); rule->rr_subject.rs_prison = prison_find(id); if (rule->rr_subject.rs_prison == NULL) { - sx_sunlock(&allprison_lock); error = ESRCH; goto out; } - prison_hold_locked(rule->rr_subject.rs_prison); /* prison_find() returns with mutex held. */ mtx_unlock(&rule->rr_subject.rs_prison->pr_mtx); - sx_sunlock(&allprison_lock); break; default: panic("rctl_rule_from_string: unknown subject type %d", @@ -1222,9 +1212,11 @@ return (error); sx_slock(&allproc_lock); + sx_slock(&allprison_lock); filter = rctl_rule_from_string(inputstr); free(inputstr, M_RCTL); if (filter == NULL) { + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } @@ -1271,6 +1263,7 @@ } out: rctl_rule_release(filter); + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); if (error != 0) return (error); @@ -1317,9 +1310,11 @@ return (error); sx_slock(&allproc_lock); + sx_slock(&allprison_lock); filter = rctl_rule_from_string(inputstr); free(inputstr, M_RCTL); if (filter == NULL) { + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } @@ -1366,6 +1361,7 @@ 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); @@ -1390,25 +1386,30 @@ return (error); sx_slock(&allproc_lock); + sx_slock(&allprison_lock); filter = rctl_rule_from_string(inputstr); free(inputstr, M_RCTL); if (filter == NULL) { + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } 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); } @@ -1439,6 +1440,7 @@ 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); @@ -1460,9 +1462,11 @@ return (error); sx_slock(&allproc_lock); + sx_slock(&allprison_lock); rule = rctl_rule_from_string(inputstr); free(inputstr, M_RCTL); if (rule == NULL) { + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } @@ -1482,6 +1486,7 @@ out: rctl_rule_release(rule); + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } @@ -1502,15 +1507,18 @@ return (error); sx_slock(&allproc_lock); + sx_slock(&allprison_lock); filter = rctl_rule_from_string(inputstr); free(inputstr, M_RCTL); if (filter == NULL) { + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } error = rctl_rule_remove(filter); rctl_rule_release(filter); + sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); @@ -1725,16 +1733,16 @@ } /* - * Go through the process' limits, freeing them. + * Release rules attached to the container. */ void -rctl_proc_exit(struct proc *p) +rctl_container_release(struct container *container) { struct rctl_rule_link *link; rw_wlock(&rctl_lock); - while (!LIST_EMPTY(&p->p_container->c_rule_links)) { - link = LIST_FIRST(&p->p_container->c_rule_links); + while (!LIST_EMPTY(&container->c_rule_links)) { + link = LIST_FIRST(&container->c_rule_links); LIST_REMOVE(link, rrl_next); rctl_rule_release(link->rrl_rule); uma_zfree(rctl_rule_link_zone, link); ==== //depot/projects/soc2009/trasz_limits/sys/sys/rctl.h#12 (text+ko) ==== @@ -132,7 +132,6 @@ #define RCTL_AMOUNT_UNDEFINED -1 -void rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred); struct rctl_rule *rctl_rule_alloc(int flags); struct rctl_rule *rctl_rule_duplicate(const struct rctl_rule *rule, int flags); void rctl_rule_acquire(struct rctl_rule *rule); @@ -144,8 +143,9 @@ uint64_t rctl_get_limit(struct proc *p, int resource); uint64_t rctl_get_available(struct proc *p, int resource); const char *rctl_resource_name(int resource); +void rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred); int rctl_proc_fork(struct proc *parent, struct proc *child); -void rctl_proc_exit(struct proc *p); +void rctl_container_release(struct container *container); #else /* !_KERNEL */ /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102101941.p1AJf8rE033058>