Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_jail.c
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
#include <sys/sysent.h> | #include <sys/sysent.h> | ||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/vps.h> | |||||
#ifdef VIMAGE | |||||
#include <sys/reboot.h> | |||||
#endif | |||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#ifdef DDB | #ifdef DDB | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
#endif /* DDB */ | #endif /* DDB */ | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#ifdef VIMAGE | |||||
FEATURE(vimage, "VIMAGE kernel virtualization"); | |||||
#endif | |||||
#define DEFAULT_HOSTUUID "00000000-0000-0000-0000-000000000000" | #define DEFAULT_HOSTUUID "00000000-0000-0000-0000-000000000000" | ||||
MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); | MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); | ||||
static MALLOC_DEFINE(M_PRISON_RACCT, "prison_racct", "Prison racct structures"); | static MALLOC_DEFINE(M_PRISON_RACCT, "prison_racct", "Prison racct structures"); | ||||
/* Keep struct prison prison0 and some code in kern_jail_set() readable. */ | /* Keep struct prison prison0 and some code in kern_jail_set() readable. */ | ||||
#ifdef INET | #ifdef INET | ||||
#ifdef INET6 | #ifdef INET6 | ||||
Show All 17 Lines | struct prison prison0 = { | ||||
.pr_uref = 1, | .pr_uref = 1, | ||||
.pr_path = "/", | .pr_path = "/", | ||||
.pr_securelevel = -1, | .pr_securelevel = -1, | ||||
.pr_devfs_rsnum = 0, | .pr_devfs_rsnum = 0, | ||||
.pr_childmax = JAIL_MAX, | .pr_childmax = JAIL_MAX, | ||||
.pr_hostuuid = DEFAULT_HOSTUUID, | .pr_hostuuid = DEFAULT_HOSTUUID, | ||||
.pr_children = LIST_HEAD_INITIALIZER(prison0.pr_children), | .pr_children = LIST_HEAD_INITIALIZER(prison0.pr_children), | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
.pr_flags = PR_HOST|PR_VNET|_PR_IP_SADDRSEL, | .pr_flags = PR_HOST|PR_VNET|PR_VPS|_PR_IP_SADDRSEL, | ||||
#else | #else | ||||
.pr_flags = PR_HOST|_PR_IP_SADDRSEL, | .pr_flags = PR_HOST|_PR_IP_SADDRSEL, | ||||
#endif | #endif | ||||
.pr_allow = PR_ALLOW_ALL_STATIC, | .pr_allow = PR_ALLOW_ALL_STATIC, | ||||
}; | }; | ||||
MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); | MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); | ||||
struct bool_flags { | struct bool_flags { | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
}; | }; | ||||
const size_t pr_flag_bool_size = sizeof(pr_flag_bool); | const size_t pr_flag_bool_size = sizeof(pr_flag_bool); | ||||
static struct jailsys_flags pr_flag_jailsys[] = { | static struct jailsys_flags pr_flag_jailsys[] = { | ||||
{"host", 0, PR_HOST}, | {"host", 0, PR_HOST}, | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
{"vnet", 0, PR_VNET}, | {"vnet", 0, PR_VNET}, | ||||
#ifdef ENABLE_VPS | |||||
{"vps", 0, PR_VPS }, | |||||
#endif | #endif | ||||
#endif | |||||
#ifdef INET | #ifdef INET | ||||
{"ip4", PR_IP4_USER, PR_IP4_USER}, | {"ip4", PR_IP4_USER, PR_IP4_USER}, | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
{"ip6", PR_IP6_USER, PR_IP6_USER}, | {"ip6", PR_IP6_USER, PR_IP6_USER}, | ||||
#endif | #endif | ||||
}; | }; | ||||
const size_t pr_flag_jailsys_size = sizeof(pr_flag_jailsys); | const size_t pr_flag_jailsys_size = sizeof(pr_flag_jailsys); | ||||
▲ Show 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | if ((flags & (JAIL_CREATE | JAIL_UPDATE | JAIL_ATTACH)) == JAIL_CREATE | ||||
goto done_errmsg; | goto done_errmsg; | ||||
} | } | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
if ((flags & JAIL_UPDATE) && (ch_flags & PR_VNET)) { | if ((flags & JAIL_UPDATE) && (ch_flags & PR_VNET)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
vfs_opterror(opts, "vnet cannot be changed after creation"); | vfs_opterror(opts, "vnet cannot be changed after creation"); | ||||
goto done_errmsg; | goto done_errmsg; | ||||
} | } | ||||
if ((flags & JAIL_UPDATE) && (ch_flags & PR_VPS)) { | |||||
error = EINVAL; | |||||
vfs_opterror(opts, "vps cannot be changed after creation"); | |||||
goto done_errmsg; | |||||
} | |||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
if ((flags & JAIL_UPDATE) && (ch_flags & PR_IP4_USER)) { | if ((flags & JAIL_UPDATE) && (ch_flags & PR_IP4_USER)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
vfs_opterror(opts, "ip4 cannot be changed after creation"); | vfs_opterror(opts, "ip4 cannot be changed after creation"); | ||||
goto done_errmsg; | goto done_errmsg; | ||||
} | } | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 1,158 Lines • ▼ Show 20 Lines | if (error) { | ||||
if (born) | if (born) | ||||
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); | (void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); | ||||
prison_deref(pr, created | prison_deref(pr, created | ||||
? PD_LIST_SLOCKED | ? PD_LIST_SLOCKED | ||||
: PD_DEREF | PD_LIST_SLOCKED); | : PD_DEREF | PD_LIST_SLOCKED); | ||||
goto done_errmsg; | goto done_errmsg; | ||||
} | } | ||||
#ifdef VIMAGE | |||||
/* Allocate a new vps if specified. */ | |||||
#ifdef ENABLE_VPS | |||||
if (pr_flags & PR_VPS) { | |||||
#else | |||||
if (0) { | |||||
#endif | |||||
vn_lock(pr->pr_root, LK_EXCLUSIVE | LK_RETRY); | |||||
if ((error = change_dir(pr->pr_root, td)) != 0) | |||||
goto c_unlock; | |||||
#ifdef MAC | |||||
if ((error = mac_vnode_check_chroot(td->td_ucred, pr->pr_root))) | |||||
goto c_unlock; | |||||
#endif | |||||
c_unlock: | |||||
VOP_UNLOCK(pr->pr_root, 0); | |||||
if (error || (error = pwd_chroot(td, pr->pr_root))) { | |||||
vfs_opterror(opts, "vps chroot failed"); | |||||
if (!created) | |||||
prison_deref(pr, PD_DEREF); | |||||
goto done_errmsg; | |||||
} | |||||
/* We temporary need a ref as otheriwse a prhold will panic. */ | |||||
mtx_lock(&pr->pr_mtx); | |||||
pr->pr_ref++; | |||||
pr->pr_uref++; | |||||
mtx_unlock(&pr->pr_mtx); | |||||
pr->pr_vps = vps_alloc(pr); | |||||
mtx_lock(&pr->pr_mtx); | |||||
pr->pr_ref--; | |||||
pr->pr_uref--; | |||||
mtx_unlock(&pr->pr_mtx); | |||||
} else { | |||||
pr->pr_vps = ppr->pr_vps; | |||||
} | |||||
#endif | |||||
/* Attach this process to the prison if requested. */ | /* Attach this process to the prison if requested. */ | ||||
if (flags & JAIL_ATTACH) { | if (flags & JAIL_ATTACH) { | ||||
mtx_lock(&pr->pr_mtx); | mtx_lock(&pr->pr_mtx); | ||||
error = do_jail_attach(td, pr); | error = do_jail_attach(td, pr); | ||||
if (error) { | if (error) { | ||||
vfs_opterror(opts, "attach failed"); | vfs_opterror(opts, "attach failed"); | ||||
if (!created) | if (!created) | ||||
prison_deref(pr, PD_DEREF); | prison_deref(pr, PD_DEREF); | ||||
▲ Show 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | if (pr->pr_ref == 1) { | ||||
return; | return; | ||||
} | } | ||||
mtx_unlock(&pr->pr_mtx); | mtx_unlock(&pr->pr_mtx); | ||||
sx_xunlock(&allprison_lock); | sx_xunlock(&allprison_lock); | ||||
/* | /* | ||||
* Kill all processes unfortunate enough to be attached to this prison. | * Kill all processes unfortunate enough to be attached to this prison. | ||||
*/ | */ | ||||
#ifdef VIMAGE | |||||
#ifdef ENABLE_VPS | |||||
if (pr->pr_vps) { | |||||
/* | |||||
* Send signal to init and let init do it's job. | |||||
* This should run rc.shutdown and processes should go away. | |||||
* All but init? We need to catch the tail-end of reboot(2) | |||||
* and handle appropriately for the non-default vpss. | |||||
* vps_destroy() will ensure init and swapper will also go | |||||
* away and might sleep. If they do not go something will | |||||
* hold refs on cred and prisons. | |||||
* XXX There are other places which might do that for a long | |||||
* time as well. | |||||
*/ | |||||
CURVPS_SET(pr->pr_vps); | |||||
shutdown_nice(RB_HALT|RB_POWEROFF); | |||||
vps_destroy(pr->pr_vps); | |||||
CURVPS_RESTORE(); | |||||
} else | |||||
#endif | |||||
#endif | |||||
{ | |||||
sx_slock(&allproc_lock); | sx_slock(&allproc_lock); | ||||
LIST_FOREACH(p, &allproc, p_list) { | LIST_FOREACH(p, &allproc, p_list) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (p->p_state != PRS_NEW && p->p_ucred && | if (p->p_state != PRS_NEW && p->p_ucred && | ||||
p->p_ucred->cr_prison == pr) | p->p_ucred->cr_prison == pr) | ||||
kern_psignal(p, SIGKILL); | kern_psignal(p, SIGKILL); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&allproc_lock); | ||||
} | |||||
/* Remove the temporary reference added by jail_remove. */ | /* Remove the temporary reference added by jail_remove. */ | ||||
prison_deref(pr, deuref | PD_DEREF); | prison_deref(pr, deuref | PD_DEREF); | ||||
} | } | ||||
/* | /* | ||||
* struct jail_attach_args { | * struct jail_attach_args { | ||||
* int jid; | * int jid; | ||||
Show All 30 Lines | sys_jail_attach(struct thread *td, struct jail_attach_args *uap) | ||||
if (pr->pr_uref == 0) { | if (pr->pr_uref == 0) { | ||||
mtx_unlock(&pr->pr_mtx); | mtx_unlock(&pr->pr_mtx); | ||||
sx_sunlock(&allprison_lock); | sx_sunlock(&allprison_lock); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
return (do_jail_attach(td, pr)); | return (do_jail_attach(td, pr)); | ||||
} | } | ||||
jamie: This takes out jail_attach(2), but not the JAIL_ATTACH flag to jail_set(2). Presumably, if we… | |||||
static int | static int | ||||
do_jail_attach(struct thread *td, struct prison *pr) | do_jail_attach(struct thread *td, struct prison *pr) | ||||
{ | { | ||||
struct proc *p; | struct proc *p; | ||||
struct ucred *newcred, *oldcred; | struct ucred *newcred, *oldcred; | ||||
int error; | int error; | ||||
#ifdef VIMAGE | |||||
/* | /* | ||||
* Do not allow to migrate a process between virtual process spaces. | |||||
* Use the console to attach to it. Getting all process spaces things | |||||
* right, including a new pid, progress group, session, terminal, | |||||
* tracing is one thing (with a lot of work) and may break apps if the | |||||
* pid changes, the pgrp no longer has the same (p)id; getting things | |||||
* restored to oriinal state and properly re-parented is virtually | |||||
* impossile. So do what we do on a normal machine, present a terminal | |||||
* to login to. | |||||
*/ | |||||
if (pr->pr_flags & PR_VPS) { | |||||
mtx_unlock(&pr->pr_mtx); | |||||
sx_sunlock(&allprison_lock); | |||||
return (EPERM); | |||||
} | |||||
#endif | |||||
/* | |||||
* XXX: Note that there is a slight race here if two threads | * XXX: Note that there is a slight race here if two threads | ||||
* in the same privileged process attempt to attach to two | * in the same privileged process attempt to attach to two | ||||
* different jails at the same time. It is important for | * different jails at the same time. It is important for | ||||
* user processes not to do this, or they might end up with | * user processes not to do this, or they might end up with | ||||
* a process root from one prison, but attached to the jail | * a process root from one prison, but attached to the jail | ||||
* of another. | * of another. | ||||
*/ | */ | ||||
pr->pr_ref++; | pr->pr_ref++; | ||||
▲ Show 20 Lines • Show All 263 Lines • ▼ Show 20 Lines | for (;;) { | ||||
ppr = pr->pr_parent; | ppr = pr->pr_parent; | ||||
for (tpr = ppr; tpr != NULL; tpr = tpr->pr_parent) | for (tpr = ppr; tpr != NULL; tpr = tpr->pr_parent) | ||||
tpr->pr_childcount--; | tpr->pr_childcount--; | ||||
sx_xunlock(&allprison_lock); | sx_xunlock(&allprison_lock); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
if (pr->pr_vnet != ppr->pr_vnet) | if (pr->pr_vnet != ppr->pr_vnet) | ||||
vnet_destroy(pr->pr_vnet); | vnet_destroy(pr->pr_vnet); | ||||
KASSERT(pr->pr_vps == NULL, ("%s: pr %p pr_vps %p != NULL\n", | |||||
__func__, pr, pr->pr_vps)); | |||||
#endif | #endif | ||||
if (pr->pr_root != NULL) | if (pr->pr_root != NULL) | ||||
vrele(pr->pr_root); | vrele(pr->pr_root); | ||||
mtx_destroy(&pr->pr_mtx); | mtx_destroy(&pr->pr_mtx); | ||||
#ifdef INET | #ifdef INET | ||||
free(pr->pr_ip4, M_PRISON); | free(pr->pr_ip4, M_PRISON); | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
Show All 16 Lines | |||||
} | } | ||||
void | void | ||||
prison_hold_locked(struct prison *pr) | prison_hold_locked(struct prison *pr) | ||||
{ | { | ||||
mtx_assert(&pr->pr_mtx, MA_OWNED); | mtx_assert(&pr->pr_mtx, MA_OWNED); | ||||
KASSERT(pr->pr_ref > 0, | KASSERT(pr->pr_ref > 0, | ||||
("Trying to hold dead prison %p (jid=%d).", pr, pr->pr_id)); | ("Trying to hold dead prison %p (jid=%d).", pr, pr->pr_id)); | ||||
Not Done Inline ActionsThis is in HEAD already; ignore. bz: This is in HEAD already; ignore. | |||||
pr->pr_ref++; | pr->pr_ref++; | ||||
} | } | ||||
void | void | ||||
prison_hold(struct prison *pr) | prison_hold(struct prison *pr) | ||||
{ | { | ||||
mtx_lock(&pr->pr_mtx); | mtx_lock(&pr->pr_mtx); | ||||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | getcredhostid(struct ucred *cred, unsigned long *hostid) | ||||
mtx_lock(&cred->cr_prison->pr_mtx); | mtx_lock(&cred->cr_prison->pr_mtx); | ||||
*hostid = cred->cr_prison->pr_hostid; | *hostid = cred->cr_prison->pr_hostid; | ||||
mtx_unlock(&cred->cr_prison->pr_mtx); | mtx_unlock(&cred->cr_prison->pr_mtx); | ||||
} | } | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
/* | /* | ||||
* Determine whether the prison represented by cred owns | * Determine whether the prison represented by cred owns | ||||
* its vnet rather than having it inherited. | * its vnet/vps rather than having it inherited. | ||||
* | * | ||||
* Returns 1 in case the prison owns the vnet, 0 otherwise. | * Returns 1 in case the prison owns the vnet/vps, 0 otherwise. | ||||
*/ | */ | ||||
int | int | ||||
prison_owns_vnet(struct ucred *cred) | prison_owns_vnet(struct ucred *cred) | ||||
{ | { | ||||
/* | /* | ||||
* vnets cannot be added/removed after jail creation, | * vnets cannot be added/removed after jail creation, | ||||
* so no need to lock here. | * so no need to lock here. | ||||
*/ | */ | ||||
return (cred->cr_prison->pr_flags & PR_VNET ? 1 : 0); | return (cred->cr_prison->pr_flags & PR_VNET ? 1 : 0); | ||||
} | } | ||||
int | |||||
prison_owns_vps(struct ucred *cred) | |||||
{ | |||||
/* | |||||
* vps cannot be added/removed after jail creation, | |||||
* so no need to lock here. | |||||
*/ | |||||
return (cred->cr_prison->pr_flags & PR_VPS ? 1 : 0); | |||||
} | |||||
#endif | #endif | ||||
/* | /* | ||||
* Determine whether the subject represented by cred can "see" | * Determine whether the subject represented by cred can "see" | ||||
* status of a mount point. | * status of a mount point. | ||||
* Returns: 0 for permitted, ENOENT otherwise. | * Returns: 0 for permitted, ENOENT otherwise. | ||||
* XXX: This function should be called cr_canseemount() and should be | * XXX: This function should be called cr_canseemount() and should be | ||||
* placed in kern_prot.c. | * placed in kern_prot.c. | ||||
▲ Show 20 Lines • Show All 598 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
error = SYSCTL_OUT(req, &havevnet, sizeof(havevnet)); | error = SYSCTL_OUT(req, &havevnet, sizeof(havevnet)); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_security_jail, OID_AUTO, vnet, | SYSCTL_PROC(_security_jail, OID_AUTO, vnet, | ||||
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | ||||
sysctl_jail_vnet, "I", "Jail owns vnet?"); | sysctl_jail_vnet, "I", "Jail owns vnet?"); | ||||
Not Done Inline ActionsThis line is in HEAD already as well; ignore. bz: This line is in HEAD already as well; ignore. | |||||
static int | |||||
sysctl_jail_vps(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
int error, havevps; | |||||
#ifdef VIMAGE | |||||
struct ucred *cred = req->td->td_ucred; | |||||
havevps = jailed(cred) && prison_owns_vps(cred); | |||||
#else | |||||
havevps = 0; | |||||
#endif | |||||
error = SYSCTL_OUT(req, &havevps, sizeof(havevps)); | |||||
return (error); | |||||
} | |||||
SYSCTL_PROC(_security_jail, OID_AUTO, vps, | |||||
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | |||||
sysctl_jail_vps, "I", "Jail owns vps?"); | |||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
SYSCTL_UINT(_security_jail, OID_AUTO, jail_max_af_ips, CTLFLAG_RW, | SYSCTL_UINT(_security_jail, OID_AUTO, jail_max_af_ips, CTLFLAG_RW, | ||||
&jail_max_af_ips, 0, | &jail_max_af_ips, 0, | ||||
"Number of IP addresses a jail may have at most per address family (deprecated)"); | "Number of IP addresses a jail may have at most per address family (deprecated)"); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Default parameters for jail(2) compatibility. For historical reasons, | * Default parameters for jail(2) compatibility. For historical reasons, | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | SYSCTL_JAIL_PARAM(, enforce_statfs, CTLTYPE_INT | CTLFLAG_RW, | ||||
"I", "Jail cannot see all mounted file systems"); | "I", "Jail cannot see all mounted file systems"); | ||||
SYSCTL_JAIL_PARAM(, devfs_ruleset, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(, devfs_ruleset, CTLTYPE_INT | CTLFLAG_RW, | ||||
"I", "Ruleset for in-jail devfs mounts"); | "I", "Ruleset for in-jail devfs mounts"); | ||||
SYSCTL_JAIL_PARAM(, persist, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(, persist, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail persistence"); | "B", "Jail persistence"); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
SYSCTL_JAIL_PARAM(, vnet, CTLTYPE_INT | CTLFLAG_RDTUN, | SYSCTL_JAIL_PARAM(, vnet, CTLTYPE_INT | CTLFLAG_RDTUN, | ||||
"E,jailsys", "Virtual network stack"); | "E,jailsys", "Virtual network stack"); | ||||
#ifdef ENABLE_VPS | |||||
SYSCTL_JAIL_PARAM(, vps, CTLTYPE_INT | CTLFLAG_RDTUN, | |||||
"E,jailsys", "Virtual process space"); | |||||
#endif | #endif | ||||
#endif | |||||
SYSCTL_JAIL_PARAM(, dying, CTLTYPE_INT | CTLFLAG_RD, | SYSCTL_JAIL_PARAM(, dying, CTLTYPE_INT | CTLFLAG_RD, | ||||
"B", "Jail is in the process of shutting down"); | "B", "Jail is in the process of shutting down"); | ||||
SYSCTL_JAIL_PARAM_NODE(children, "Number of child jails"); | SYSCTL_JAIL_PARAM_NODE(children, "Number of child jails"); | ||||
SYSCTL_JAIL_PARAM(_children, cur, CTLTYPE_INT | CTLFLAG_RD, | SYSCTL_JAIL_PARAM(_children, cur, CTLTYPE_INT | CTLFLAG_RD, | ||||
"I", "Current number of child jails"); | "I", "Current number of child jails"); | ||||
SYSCTL_JAIL_PARAM(_children, max, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_children, max, CTLTYPE_INT | CTLFLAG_RW, | ||||
"I", "Maximum number of child jails"); | "I", "Maximum number of child jails"); | ||||
▲ Show 20 Lines • Show All 360 Lines • ▼ Show 20 Lines | #endif | ||||
db_printf(" parent = %p\n", pr->pr_parent); | db_printf(" parent = %p\n", pr->pr_parent); | ||||
db_printf(" ref = %d\n", pr->pr_ref); | db_printf(" ref = %d\n", pr->pr_ref); | ||||
db_printf(" uref = %d\n", pr->pr_uref); | db_printf(" uref = %d\n", pr->pr_uref); | ||||
db_printf(" path = %s\n", pr->pr_path); | db_printf(" path = %s\n", pr->pr_path); | ||||
db_printf(" cpuset = %d\n", pr->pr_cpuset | db_printf(" cpuset = %d\n", pr->pr_cpuset | ||||
? pr->pr_cpuset->cs_id : -1); | ? pr->pr_cpuset->cs_id : -1); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
db_printf(" vnet = %p\n", pr->pr_vnet); | db_printf(" vnet = %p\n", pr->pr_vnet); | ||||
db_printf(" vps = %p\n", pr->pr_vps); | |||||
#endif | #endif | ||||
db_printf(" root = %p\n", pr->pr_root); | db_printf(" root = %p\n", pr->pr_root); | ||||
db_printf(" securelevel = %d\n", pr->pr_securelevel); | db_printf(" securelevel = %d\n", pr->pr_securelevel); | ||||
db_printf(" devfs_rsnum = %d\n", pr->pr_devfs_rsnum); | db_printf(" devfs_rsnum = %d\n", pr->pr_devfs_rsnum); | ||||
db_printf(" children.max = %d\n", pr->pr_childmax); | db_printf(" children.max = %d\n", pr->pr_childmax); | ||||
db_printf(" children.cur = %d\n", pr->pr_childcount); | db_printf(" children.cur = %d\n", pr->pr_childcount); | ||||
db_printf(" child = %p\n", LIST_FIRST(&pr->pr_children)); | db_printf(" child = %p\n", LIST_FIRST(&pr->pr_children)); | ||||
db_printf(" sibling = %p\n", LIST_NEXT(pr, pr_sibling)); | db_printf(" sibling = %p\n", LIST_NEXT(pr, pr_sibling)); | ||||
▲ Show 20 Lines • Show All 81 Lines • Show Last 20 Lines |
This takes out jail_attach(2), but not the JAIL_ATTACH flag to jail_set(2). Presumably, if we don't want to attach via one method we also don't want to via the other.
That implies that VPS jails will always need "persist" set. But we should probably relax that to allow for VPS jails that go away when their last process (init) dies in a virtual shutdown.