PERFORCE change 106514 for review
Alex Lyashkov
als at FreeBSD.org
Fri Sep 22 11:47:20 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=106514
Change 106514 by als at 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);
}
More information about the p4-projects
mailing list