Skip site navigation (1)Skip section navigation (2)
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>