From owner-p4-projects@FreeBSD.ORG Fri Sep 22 18:47:20 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 816C416A4E8; Fri, 22 Sep 2006 18:47:20 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2CC4716A40F for ; Fri, 22 Sep 2006 18:47:20 +0000 (UTC) (envelope-from als@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E268743D46 for ; Fri, 22 Sep 2006 18:47:19 +0000 (GMT) (envelope-from als@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8MIlJ59045863 for ; Fri, 22 Sep 2006 18:47:19 GMT (envelope-from als@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8MIlJ20045860 for perforce@freebsd.org; Fri, 22 Sep 2006 18:47:19 GMT (envelope-from als@FreeBSD.org) Date: Fri, 22 Sep 2006 18:47:19 GMT Message-Id: <200609221847.k8MIlJ20045860@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to als@FreeBSD.org using -f From: Alex Lyashkov To: Perforce Change Reviews Cc: Subject: PERFORCE change 106514 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Sep 2006 18:47:20 -0000 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); }