Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Sep 2006 18:47:19 GMT
From:      Alex Lyashkov <als@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 106514 for review
Message-ID:  <200609221847.k8MIlJ20045860@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106514

Change 106514 by als@als_head on 2006/09/22 18:46:51

	reimplement all jail1 code via jail2 functions for avoid promlems with locking.

Affected files ...

.. //depot/projects/jail2/sys/kern/kern_jail.c#7 edit

Differences ...

==== //depot/projects/jail2/sys/kern/kern_jail.c#7 (text+ko) ====

@@ -64,8 +64,9 @@
 static void		 init_prison(void *);
 static void		 prison_complete(void *context, int pending);
 static int		 sysctl_jail_list(SYSCTL_HANDLER_ARGS);
+static int		 find_empty_prid(void);
 
-#define jprint(a...)
+#define jprint(a...) 
 /* printf(a) */
 
 static void
@@ -97,86 +98,34 @@
 static int
 jail_1(struct thread *td, struct jail_args *uap)
 {
-	struct nameidata nd;
-	struct prison *pr, *tpr;
 	struct jail j;
-	struct jail_attach_args jaa;
-	int vfslocked, error, tryprid;
+	struct prison *pr;
+	int error;
 
 	error = copyin(uap->jail, &j, sizeof(j));
 	if (error)
 		return (error);
 
-	MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO);
-	mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF);
-	refcount_init(&pr->pr_refcnt,1);
-	error = copyinstr(j.path, &pr->pr_disk.pr_path, sizeof(pr->pr_disk.pr_path), 0);
-	if (error)
-		goto e_killmtx;
-	NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF, UIO_SYSSPACE,
-	    pr->pr_disk.pr_path, td);
-	error = namei(&nd);
-	if (error)
-		goto e_killmtx;
-	vfslocked = NDHASGIANT(&nd);
-	JAIL_VROOT(pr) = nd.ni_vp;
-	VOP_UNLOCK(nd.ni_vp, 0, td);
-	NDFREE(&nd, NDF_ONLY_PNBUF);
-	VFS_UNLOCK_GIANT(vfslocked);
+	pr = prison_alloc(0);
+	if (pr == NULL)
+		return (EAGAIN);
+
 	error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0);
 	if (error)
-		goto e_dropvnref;
-	pr->pr_network.pr_ip = htonl(j.ip_number);
-	pr->pr_linux = NULL;
-	pr->pr_securelevel = -1;
-	pr_uihashinit(pr);
-	JAIL_DISKS_INIT(pr);
-	JAIL_TASKS_INIT(pr);
-	JAIL_IPC_INIT(pr);
-	JAIL_LIMITS_INIT(pr);
+		goto e_dropref;
 
-	/* Determine next pr_id and add prison to allprison list. */
-	mtx_lock(&allprison_mtx);
-	tryprid = lastprid + 1;
-	if (tryprid == JAIL_MAX)
-		tryprid = 1;
-next:
-	LIST_FOREACH(tpr, &allprison, pr_list) {
-		if (tpr->pr_id == tryprid) {
-			tryprid++;
-			if (tryprid == JAIL_MAX) {
-				mtx_unlock(&allprison_mtx);
-				error = EAGAIN;
-				goto e_dropvnref;
-			}
-			goto next;
-		}
-	}
+	error = jail_setvroot(pr, td, j.path);
+	if (error)
+		goto e_dropref;
 
-	pr->pr_id = jaa.jid = lastprid = tryprid;
-	LIST_INSERT_HEAD(&allprison, pr, pr_list);
-	prisoncount++;
-	mtx_unlock(&allprison_mtx);
-	pr->pr_flags |= J_START_FL;
-	error = jail_attach(td, &jaa);
+	JAIL_SET_STARTED(pr);
+	error = jail_migrate(td, pr);
 	if (error)
-		goto e_dropprref;
+		goto e_dropref;
 
+	td->td_retval[0] = pr->pr_id;
+e_dropref:
 	prison_free(pr);
-	td->td_retval[0] = jaa.jid;
-	return (0);
-e_dropprref:
-	mtx_lock(&allprison_mtx);
-	LIST_REMOVE(pr, pr_list);
-	prisoncount--;
-	mtx_unlock(&allprison_mtx);
-e_dropvnref:
-	vfslocked = VFS_LOCK_GIANT(JAIL_VROOT(pr)->v_mount);
-	vrele(JAIL_VROOT(pr));
-	VFS_UNLOCK_GIANT(vfslocked);
-e_killmtx:
-	mtx_destroy(&pr->pr_mtx);
-	FREE(pr, M_PRISON);
 	return (error);
 }
 
@@ -301,8 +250,7 @@
 int
 jail_attach(struct thread *td, struct jail_attach_args *uap)
 {
-	struct prison *pr;
-	int error;
+	struct jail_2 j;
 
 	/*
 	 * XXX: Note that there is a slight race here if two threads
@@ -312,20 +260,36 @@
 	 * a process root from one prison, but attached to the jail
 	 * of another.
 	 */
-	error = suser(td);
-	if (error)
-		return (error);
+	j.cmd = JAIL2_COMMAND(J_COMMON,J_ENTER);
+	j.ctx_id = uap->jid;
+	return jail2_common(td,&j);
+}
 
-	mtx_lock(&allprison_mtx);
-	pr = prison_find(uap->jid);
-	if (pr == NULL) {
-		return (ESRCH);
-	}
+static
+int find_empty_prid(void)
+{
+	int tryprid;
+	struct prison *tpr;
 
-	error = jail_migrate(td, pr);
-	prison_free(pr);
+	mtx_assert(&allprison_mtx, MA_OWNED);
 
-	return (error);
+	tryprid = lastprid + 1;
+	if (tryprid == JAIL_MAX)
+		tryprid = 1;
+next:
+	LIST_FOREACH(tpr, &allprison, pr_list) {
+		if (tpr->pr_id != tryprid) {
+			break;
+		}
+		tryprid++;
+		if (tryprid == JAIL_MAX) {
+			tryprid = 0;
+			goto exit;
+		}
+		goto next;
+	}
+exit:
+	return (tryprid);
 }
 
 struct prison *
@@ -338,9 +302,15 @@
 	pr->pr_id = ctx_id;
 	refcount_init(&pr->pr_refcnt,1);
 	mtx_lock(&allprison_mtx);
-	if((old_pr=prison_find(ctx_id)) != NULL) {
-	    jprint("Already have prisons");
-	    goto found;
+	if (ctx_id != 0) {
+		if ((old_pr=prison_find(ctx_id)) != NULL) {
+			jprint("Already have prisons");
+			goto found;
+		}
+	} else {
+		pr->pr_id = find_empty_prid();
+		if (pr->pr_id == 0)
+			goto err_exit;
 	}
 
 	LIST_INSERT_HEAD(&allprison, pr, pr_list);
@@ -360,6 +330,7 @@
 found:
 	mtx_unlock(&allprison_mtx);
 	prison_free(old_pr);
+err_exit:
 	FREE(pr, M_PRISON);
 	return (NULL);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609221847.k8MIlJ20045860>