diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2018-08-23 01:45:18 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2018-08-23 01:45:18 +0000 |
| commit | db9db0e790be3439ca443caa2e4484a4339d1f8f (patch) | |
| tree | f23cc42b88d6499579475a8a60ed282715dad4a7 /sbin | |
| parent | b6c7d9c345d1427f37e2ead6076b04fefc768c5f (diff) | |
Notes
Diffstat (limited to 'sbin')
| -rw-r--r-- | sbin/bectl/bectl.8 | 12 | ||||
| -rw-r--r-- | sbin/bectl/bectl.c | 2 | ||||
| -rw-r--r-- | sbin/bectl/bectl_jail.c | 43 |
3 files changed, 44 insertions, 13 deletions
diff --git a/sbin/bectl/bectl.8 b/sbin/bectl/bectl.8 index 5cd4e0ed01be..21aba5da597f 100644 --- a/sbin/bectl/bectl.8 +++ b/sbin/bectl/bectl.8 @@ -18,7 +18,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 17, 2018 +.Dd August 22, 2018 .Dt BECTL 8 .Os .Sh NAME @@ -50,7 +50,7 @@ import .Ao Ar targetBe Ac .Nm jail -.Op Fl b +.Op Fl b | Fl U .Oo Fl o Ar key Ns = Ns Ar value | Fl u Ar key Oc Ns ... .Ao Ar jailID | jailName Ac .Ao Ar bootenv Ac @@ -148,6 +148,7 @@ Import from .Dv stdin . .It Ic jail +.Op Fl b | Fl U .Oo Fl o Ar key Ns = Ns Ar value | Fl u Ar key Oc Ns ... .Ao Ar jailID | jailName Ac .Ao Ar bootenv Ac @@ -172,10 +173,17 @@ If .Ar utility is specified, it will be executed instead of .Pa /bin/sh . +The jail will be destroyed and the boot environment unmounted when the command +finishes executing, unless the +.Fl U +argument is specified. .Pp The .Fl b argument enables batch mode, thereby disabling interactive mode. +The +.Fl U +argument will be ignored in batch mode. .Pp The .Va name , diff --git a/sbin/bectl/bectl.c b/sbin/bectl/bectl.c index 9a0f398aa30c..5b179bef8a9a 100644 --- a/sbin/bectl/bectl.c +++ b/sbin/bectl/bectl.c @@ -77,7 +77,7 @@ usage(bool explicit) #if SOON "\tbectl add (path)*\n" #endif - "\tbectl jail [-b] [ -o key=value | -u key ]... bootenv [utility [argument ...]]\n" + "\tbectl jail [-b | -U] [ -o key=value | -u key ]... bootenv [utility [argument ...]]\n" "\tbectl list [-a] [-D] [-H] [-s]\n" "\tbectl mount beName [mountpoint]\n" "\tbectl rename origBeName newBeName\n" diff --git a/sbin/bectl/bectl_jail.c b/sbin/bectl/bectl_jail.c index f0ea74c3177e..c60cec5fa683 100644 --- a/sbin/bectl/bectl_jail.c +++ b/sbin/bectl/bectl_jail.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/jail.h> #include <sys/mount.h> +#include <sys/wait.h> #include <err.h> #include <jail.h> #include <stdbool.h> @@ -179,10 +180,11 @@ int bectl_cmd_jail(int argc, char *argv[]) { char *bootenv, *mountpoint; - int jflags, jid, opt, ret; - bool default_hostname, default_name, interactive; + int jid, opt, ret; + bool default_hostname, default_name, interactive, unjail; + pid_t pid; - default_hostname = default_name = interactive = true; + default_hostname = default_name = interactive = unjail = true; jpcnt = INIT_PARAMCOUNT; jp = malloc(jpcnt * sizeof(*jp)); if (jp == NULL) @@ -193,7 +195,7 @@ bectl_cmd_jail(int argc, char *argv[]) jailparam_add("allow.mount.devfs", "true"); jailparam_add("enforce_statfs", "1"); - while ((opt = getopt(argc, argv, "bo:u:")) != -1) { + while ((opt = getopt(argc, argv, "bo:Uu:")) != -1) { switch (opt) { case 'b': interactive = false; @@ -210,6 +212,9 @@ bectl_cmd_jail(int argc, char *argv[]) default_hostname = false; } break; + case 'U': + unjail = false; + break; case 'u': if ((ret = jailparam_delarg(optarg)) == 0) { if (strcmp(optarg, "name") == 0) @@ -259,16 +264,14 @@ bectl_cmd_jail(int argc, char *argv[]) if (default_hostname) jailparam_add("host.hostname", bootenv); - jflags = JAIL_CREATE; - if (interactive) - jflags |= JAIL_ATTACH; /* * This is our indicator that path was not set by the user, so we'll use * the path that libbe generated for us. */ if (mountpoint == NULL) jailparam_add("path", mnt_loc); - jid = jailparam_set(jp, jpused, jflags); + /* Create the jail for now, attach later as-needed */ + jid = jailparam_set(jp, jpused, JAIL_CREATE); if (jid == -1) { fprintf(stderr, "unable to create jail. error: %d\n", errno); return (1); @@ -277,14 +280,34 @@ bectl_cmd_jail(int argc, char *argv[]) jailparam_free(jp, jpused); free(jp); - if (interactive) { + /* We're not interactive, nothing more to do here. */ + if (!interactive) + return (0); + + pid = fork(); + switch(pid) { + case -1: + perror("fork"); + return (1); + case 0: + jail_attach(jid); /* We're attached within the jail... good bye! */ chdir("/"); if (argc > 1) execve(argv[1], &argv[1], NULL); else execl("/bin/sh", "/bin/sh", NULL); - return (1); + fprintf(stderr, "bectl jail: failed to execute %s\n", + (argc > 1 ? argv[1] : "/bin/sh")); + _exit(1); + default: + /* Wait for the child to get back, see if we need to unjail */ + waitpid(pid, NULL, 0); + } + + if (unjail) { + jail_remove(jid); + unmount(mnt_loc, 0); } return (0); |
