From owner-p4-projects@FreeBSD.ORG Thu Feb 10 19:41:09 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D2F1D1065674; Thu, 10 Feb 2011 19:41:08 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 94FAB1065672 for ; Thu, 10 Feb 2011 19:41:08 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 811158FC21 for ; Thu, 10 Feb 2011 19:41:08 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p1AJf8Uf033065 for ; Thu, 10 Feb 2011 19:41:08 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p1AJf8rE033058 for perforce@freebsd.org; Thu, 10 Feb 2011 19:41:08 GMT (envelope-from trasz@freebsd.org) Date: Thu, 10 Feb 2011 19:41:08 GMT Message-Id: <201102101941.p1AJf8rE033058@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 188692 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Feb 2011 19:41:09 -0000 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 #include #include +#include #include #include #include @@ -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 */ /*