diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -990,7 +990,6 @@ * This abuses the file error codes ENOENT and EEXIST. */ pr = NULL; - ppr = mypr; inspr = NULL; if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) { namelc = strrchr(name, '.'); @@ -999,6 +998,12 @@ jid = 0; } sx_xlock(&allprison_lock); + ppr = mypr; + if (!prison_isalive(ppr)) { + /* This jail is dying. This process will surely follow. */ + error = EAGAIN; + goto done_deref; + } drflags = PD_LIST_XLOCKED; if (jid != 0) { if (jid < 0) { @@ -1022,7 +1027,6 @@ break; } if (pr != NULL) { - ppr = pr->pr_parent; /* Create: jid must not exist. */ if (cuflags == JAIL_CREATE) { /* @@ -1044,6 +1048,13 @@ vfs_opterror(opts, "jail %d not found", jid); goto done_deref; } + ppr = pr->pr_parent; + if (!prison_isalive(ppr)) { + error = ENOENT; + vfs_opterror(opts, "jail %d is dying", + ppr->pr_id); + goto done_deref; + } if (!prison_isalive(pr)) { if (!(flags & JAIL_DYING)) { error = ENOENT; @@ -1109,15 +1120,13 @@ "jail \"%s\" not found", name); goto done_deref; } - if (!(flags & JAIL_DYING) && - !prison_isalive(ppr)) { - mtx_unlock(&ppr->pr_mtx); + mtx_unlock(&ppr->pr_mtx); + if (!prison_isalive(ppr)) { error = ENOENT; vfs_opterror(opts, "jail \"%s\" is dying", name); goto done_deref; } - mtx_unlock(&ppr->pr_mtx); *namelc = '.'; } namelc++; @@ -1196,26 +1205,9 @@ vfs_opterror(opts, "prison limit exceeded"); goto done_deref; } - prison_hold(ppr); - if (!refcount_acquire_if_not_zero(&ppr->pr_uref)) { - /* This brings the parent back to life. */ - mtx_lock(&ppr->pr_mtx); - refcount_acquire(&ppr->pr_uref); - ppr->pr_state = PRISON_STATE_ALIVE; - mtx_unlock(&ppr->pr_mtx); - error = osd_jail_call(ppr, PR_METHOD_CREATE, opts); - if (error) { - pr = ppr; - drflags |= PD_DEREF | PD_DEUREF; - goto done_deref; - } - } - if (jid == 0 && (jid = get_next_prid(&inspr)) == 0) { error = EAGAIN; vfs_opterror(opts, "no available jail IDs"); - pr = ppr; - drflags |= PD_DEREF | PD_DEUREF; goto done_deref; } @@ -1235,6 +1227,8 @@ TAILQ_INSERT_TAIL(&allprison, pr, pr_list); pr->pr_parent = ppr; + prison_hold(ppr); + prison_proc_hold(ppr); LIST_INSERT_HEAD(&ppr->pr_children, pr, pr_sibling); for (tpr = ppr; tpr != NULL; tpr = tpr->pr_parent) tpr->pr_childcount++;