PERFORCE change 188692 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Thu Feb 10 19:41:09 UTC 2011


http://p4web.freebsd.org/@@188692?ac=10

Change 188692 by trasz at 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 */
 
 /*


More information about the p4-projects mailing list