Index: sys/kern/kern_jail.c =================================================================== --- sys/kern/kern_jail.c +++ sys/kern/kern_jail.c @@ -514,6 +514,9 @@ struct prison *tppr; void *op; #endif +#ifdef VIMAGE + struct vnet *pr_vnet; +#endif unsigned long hid; size_t namelen, onamelen, pnamelen; int born, created, cuflags, descend, enforce; @@ -559,6 +562,9 @@ error = vfs_buildopts(optuio, &opts); if (error) return (error); +#ifdef VIMAGE + pr_vnet = NULL; +#endif #ifdef INET ip4 = NULL; #endif @@ -981,6 +987,14 @@ if (*p != '\0') jid = 0; } +#ifdef VIMAGE + /* + * Allocate a new vnet if specified. + * Do this early to avoid deadlocks after taking the allprison sx lock. + */ + if ((pr_flags & PR_VNET) != 0) + pr_vnet = vnet_alloc(); +#endif sx_xlock(&allprison_lock); if (jid != 0) { /* @@ -1287,9 +1301,12 @@ TASK_INIT(&pr->pr_task, 0, prison_complete, pr); #ifdef VIMAGE - /* Allocate a new vnet if specified. */ - pr->pr_vnet = (pr_flags & PR_VNET) - ? vnet_alloc() : ppr->pr_vnet; + /* Assign a new vnet if specified. */ + if ((pr_flags & PR_VNET) != 0) { + pr->pr_vnet = pr_vnet; + pr_vnet = NULL; + } else + pr->pr_vnet = ppr->pr_vnet; #endif /* * Allocate a dedicated cpuset for each jail. @@ -1904,6 +1921,10 @@ #endif #ifdef INET6 free(ip6, M_PRISON); +#endif +#ifdef VIMAGE + if (error && pr_vnet != NULL) + vnet_destroy(pr_vnet); #endif if (g_path != NULL) free(g_path, M_TEMP);