vimage(8) is a legacy CLI interface for managing jails associated with
network stack instances, which is provided for compatibility with older applications. This change brings it back to life in a followup to the initial conversion of vimage to use the new jail(4) userland-kernel API: - when creating vimages via "vimage -c", by default turn on a few options expected by legacy applications, such as allow operations on raw sockets, FS mounts etc, and allow jail-related parameters to be optionally configured. - introduce the "-m" modifier which allows for configuring jail parameters of existing vimages / vnet-jails. - make "vimage name command ..." actually work. - when reassigning ifnets to vnets using "vimage -i", attempt to rename the ifnet as "ethXXX" on arrival in the target vnet. Several legacy applications are known to depend heavily on such behavior. - vimage -l lists only jails associated with vnets. The output is sorted using vimage / jail names as keys. - vimage -l by default searches only the current level in the jail hierarchy. Recursive listing can be requested via -r switch. - vimage -l by default prints only jail names on each line, making such output suitable for pipelining to other commands. More verbose output can be obtained via -v switch, and even more jail specific information will be displayed if -j switch is turned on. - there's no need to build vimage as statically linked, so update the Makefile accordingly. - update the vimage.8 man page. Approved by: re (rwatson), julian (mentor) MFC after: immediately
This commit is contained in:
parent
0cef25aeb2
commit
ad3764ac1d
@ -10,6 +10,5 @@ CFLAGS+= -I../../../sys
|
||||
MAN= vimage.8
|
||||
|
||||
BINDIR?= /usr/sbin
|
||||
NO_SHARED?= YES
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2002, 2003 Marko Zec <zec@tel.fer.hr>
|
||||
.\" Copyright (c) 2002, 2003 Marko Zec <zec@fer.hr>
|
||||
.\" Copyright (c) 2009 University of Zagreb
|
||||
.\" Copyright (c) 2009 FreeBSD Foundation
|
||||
.\"
|
||||
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 6, 2009
|
||||
.Dd August 25, 2009
|
||||
.Dt VIMAGE 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -35,35 +35,46 @@
|
||||
.Nd manage virtual network stacks
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar vi_name
|
||||
.Op command
|
||||
.Nm
|
||||
.Fl c
|
||||
.Ar vi_name
|
||||
.Op Fl c | m
|
||||
.Ar vname
|
||||
.Op Ar param=value ...
|
||||
.Nm
|
||||
.Fl d
|
||||
.Ar vi_name
|
||||
.Ar vname
|
||||
.Nm
|
||||
.Fl l
|
||||
.Op Ar vi_name
|
||||
.Op Fl rvj
|
||||
.Op Ar vname
|
||||
.Nm
|
||||
.Fl i
|
||||
.Ar vi_name interface
|
||||
.Sh DESCRIPTION
|
||||
.Ar vname ifname
|
||||
.Op Ar newifname
|
||||
.Nm
|
||||
command is an interm user interface for controlling the virtual network
|
||||
stacks in FreeBSD.
|
||||
.Ar vi_name
|
||||
.Op command ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is an alternative user interface for controlling virtual network
|
||||
stacks in FreeBSD, aimed primarily at supporting legacy applications
|
||||
which are not yet converted to using
|
||||
.Xr jail 8 ,
|
||||
.Xr jexec 8 ,
|
||||
and
|
||||
.Xr jls 8 .
|
||||
.
|
||||
.Ss Overview
|
||||
A virtual image reprepresents an isolated operating environment with its
|
||||
own independent network stack instance. Every process, socket and network
|
||||
interface present in the system is always attached to one, and only one,
|
||||
virtual image i.e. virtual network stack instance.
|
||||
During the system bootup sequence default virtual image is created to
|
||||
which all the configured interfaces and user processes are initially
|
||||
assigned.
|
||||
Assuming that enough system resources and per virtual image privileges
|
||||
are provided, the super-user can create and manage a hierarchy of
|
||||
subordinated virtual images. The
|
||||
A virtual image or vimage is a jail with its own independent network
|
||||
stack instance. Every process, socket and network interface present
|
||||
in the system is always attached to one, and only one, virtual network
|
||||
stack instance (vnet).
|
||||
During system bootup sequence a default vnet
|
||||
is created to which all the configured interfaces and user processes
|
||||
are initially attached.
|
||||
Assuming that enough system resources are
|
||||
are available, a user with sufficient privileges can create and manage
|
||||
a hierarchy of subordinated virtual images.
|
||||
The
|
||||
.Nm
|
||||
command allows for creation, deletion and monitoring of virtual images,
|
||||
as well as for execution of arbitrary processes in a targeted virtual
|
||||
@ -71,59 +82,72 @@ image.
|
||||
.Ss Invocation
|
||||
If invoked with no modifiers, the
|
||||
.Nm
|
||||
command spawns a new shell process in virtual image
|
||||
.Ar vi_name .
|
||||
If provided, the optional arguments following the virtual image name
|
||||
.Ar vi_name
|
||||
are interpreted as a standard command line issued at a shell,
|
||||
otherwise an interactive shell is started in the target virtual image.
|
||||
command spawns a new interactive shell in virtual image
|
||||
.Ar vname .
|
||||
If optional additional arguments following
|
||||
.Ar vname
|
||||
are provided, the first of those will be executed in place of the
|
||||
interactive shell, and the rest of the arguments will be passed as
|
||||
arguments to the executed command.
|
||||
.Pp
|
||||
The following parameters are available:
|
||||
The following modifiers are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl c
|
||||
Create a new virtual image named
|
||||
.So
|
||||
.Ar vi_name
|
||||
.Sc .
|
||||
.Ar vname .
|
||||
Additional arguments, if provided, may be used to specify operating
|
||||
parameters different from defaults, in format
|
||||
.Ar param=value .
|
||||
See
|
||||
.Xr jail 8
|
||||
for an extensive list of available parameters.
|
||||
.It Fl m
|
||||
Modify the parameters of a virtual image named
|
||||
.Ar vname ,
|
||||
using the same syntax as with the -c form of the command.
|
||||
.It Fl d
|
||||
Delete the virtual image
|
||||
.Ar vi_name .
|
||||
.Ar vname .
|
||||
No processes and/or sockets should exist in the target virtual image
|
||||
in order for the delete request to succeed. Non-loopback interfaces
|
||||
in order for the delete request to succeed. Non-loopback interfaces
|
||||
residing in the target virtual image will be reassigned to the virtual
|
||||
image's parent.
|
||||
.It Fl l
|
||||
List the properties and statistics for virtual images one level
|
||||
below the current one in the hierarchy. If an optional argument
|
||||
.Ar vi_name
|
||||
.Ar vname
|
||||
is provided, only the information regarding the target virtual image
|
||||
.Ar vi_name
|
||||
.Ar vname
|
||||
is displayed.
|
||||
.It Fl lr
|
||||
List the properties and statistics for all virtual images in
|
||||
the hierarchy of subordinated vimages. If an optional argument
|
||||
.Ar vi_name
|
||||
is provided, the hierarchy will be traversed at and below the
|
||||
.Ar vi_name
|
||||
level.
|
||||
With the optional
|
||||
.Op Ar -r
|
||||
switch enabled the list will include all virtual images below the
|
||||
current level in the vimage hierarchy.
|
||||
Enabling the optional
|
||||
.Op Ar -v
|
||||
or
|
||||
.Op Ar -j
|
||||
switches results in a more detailed output.
|
||||
.It Fl i
|
||||
Move the interface
|
||||
.Ar interface
|
||||
Move interface
|
||||
.Ar ifname
|
||||
to the target virtual image
|
||||
.Ar vi_name .
|
||||
If the value of
|
||||
.Ar vi_name
|
||||
argument is
|
||||
.So ..
|
||||
.Ar vname .
|
||||
Interfaces will be automatically renamed to
|
||||
.So
|
||||
ethXX
|
||||
.Sc ,
|
||||
the interface is returned to the parent of the current virtual image.
|
||||
unless an optional argument specifying the desired interface name
|
||||
.Op Ar newifname
|
||||
is provided.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
Create a new virtual image named
|
||||
.So v1
|
||||
.Sc :
|
||||
.Sc ,
|
||||
which is allowed to create and manage an own subhierarchy of vimages:
|
||||
.Pp
|
||||
.Dl vimage -c v1
|
||||
.Dl vimage -c v1 children.max=100
|
||||
.Pp
|
||||
Execute the
|
||||
.So ifconfig
|
||||
@ -137,28 +161,35 @@ Move the interface
|
||||
.So vlan0
|
||||
.Sc to the virtual image
|
||||
.So v1
|
||||
.Sc while renaming the interface as
|
||||
.So
|
||||
ve0
|
||||
.Sc :
|
||||
.Pp
|
||||
.Dl vimage -i v1 vlan0
|
||||
.Dl vimage -i v1 vlan0 ve0
|
||||
.Pp
|
||||
Show the status information for virtual image
|
||||
.So v1
|
||||
.Sc :
|
||||
.Pp
|
||||
.Dl vimage -l v1
|
||||
.Dl vimage -lv v1
|
||||
.Sh DIAGNOSTICS
|
||||
The
|
||||
.Nm
|
||||
command exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr jail 8
|
||||
.Xr jexec 8
|
||||
.Xr jls 8
|
||||
.Sh BUGS
|
||||
If memory allocation failure occurs during the vimage creation, it will remain
|
||||
undetected/ignored in the current implementation, thus latently scheduling
|
||||
an almost imminent system crash in the future.
|
||||
Deletion of vimages / vnets is known to leak kernel memory and fail at
|
||||
stopping various timers, hence may lead to system crashes.
|
||||
.Sh AUTHOR
|
||||
.An "Marko Zec" Aq zec@fer.hr
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
facility first appeared as a patch against FreeBSD 4.7-RELEASE in 2002.
|
||||
Network stack virtualization framework first appeared as a patchset
|
||||
against the FreeBSD 4.7 kernel in 2002, and was maintained outside
|
||||
of the main FreeBSD tree.
|
||||
As a result of a project sponsored by the FreeBSD Foundation and
|
||||
Stiching NLNet, integrated virtualized network stack first appeared
|
||||
in FreeBSD 8.0.
|
||||
|
@ -28,142 +28,294 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <jail.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define VI_CREATE 0x00000001
|
||||
#define VI_DESTROY 0x00000002
|
||||
#define VI_SWITCHTO 0x00000008
|
||||
#define VI_IFACE 0x00000010
|
||||
#define VI_GET 0x00000100
|
||||
#define VI_GETNEXT 0x00000200
|
||||
typedef enum {
|
||||
VI_SWITCHTO,
|
||||
VI_CREATE,
|
||||
VI_MODIFY,
|
||||
VI_DESTROY,
|
||||
VI_IFMOVE,
|
||||
VI_GET
|
||||
} vi_cmd_t;
|
||||
|
||||
static int getjail(char *name, int lastjid, int *vnet);
|
||||
typedef struct vimage_status {
|
||||
char name[MAXPATHLEN]; /* Must be first field for strcmp(). */
|
||||
char path[MAXPATHLEN];
|
||||
char hostname[MAXPATHLEN];
|
||||
char domainname[MAXPATHLEN];
|
||||
int jid;
|
||||
int parentjid;
|
||||
int vnet;
|
||||
int childcnt;
|
||||
int childmax;
|
||||
int cpuset;
|
||||
int rawsock;
|
||||
int socket_af;
|
||||
int mount;
|
||||
} vstat_t;
|
||||
|
||||
#define VST_SIZE_STEP 1024
|
||||
#define MAXPARAMS 32
|
||||
|
||||
static int getjail(vstat_t *, int, int);
|
||||
|
||||
static char *invocname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-c | -m] vname [param=value ...]\n"
|
||||
" %s -d vname\n"
|
||||
" %s -l[rvj] [vname]\n"
|
||||
" %s -i vname ifname [newifname]\n"
|
||||
" %s vname [command ...]\n",
|
||||
invocname, invocname, invocname, invocname, invocname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int s;
|
||||
char *shell;
|
||||
int cmd;
|
||||
int jid, vnet;
|
||||
struct jailparam params[MAXPARAMS];
|
||||
char ifname[IFNAMSIZ];
|
||||
struct ifreq ifreq;
|
||||
char name[MAXHOSTNAMELEN];
|
||||
vi_cmd_t newcmd, cmd;
|
||||
int recurse = 0;
|
||||
int verbose = 0;
|
||||
int jid, i, s, namelen;
|
||||
int vst_size, vst_last;
|
||||
vstat_t *vst;
|
||||
char *str;
|
||||
char ch;
|
||||
|
||||
switch (argc) {
|
||||
invocname = argv[0];
|
||||
|
||||
case 1:
|
||||
cmd = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (strcmp(argv[1], "-l") == 0)
|
||||
cmd = VI_GETNEXT;
|
||||
else if (strcmp(argv[1], "-lr") == 0)
|
||||
cmd = VI_GETNEXT;
|
||||
else {
|
||||
strcpy(name, argv[1]);
|
||||
cmd = VI_SWITCHTO;
|
||||
newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */
|
||||
while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
newcmd = VI_CREATE;
|
||||
break;
|
||||
case 'm':
|
||||
newcmd = VI_MODIFY;
|
||||
break;
|
||||
case 'd':
|
||||
newcmd = VI_DESTROY;
|
||||
break;
|
||||
case 'l':
|
||||
newcmd = VI_GET;
|
||||
break;
|
||||
case 'i':
|
||||
newcmd = VI_IFMOVE;
|
||||
break;
|
||||
case 'r':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'j':
|
||||
verbose = 2;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
strcpy(name, argv[2]);
|
||||
if (strcmp(argv[1], "-l") == 0)
|
||||
cmd = VI_GET;
|
||||
if (strcmp(argv[1], "-c") == 0)
|
||||
cmd = VI_CREATE;
|
||||
if (strcmp(argv[1], "-d") == 0)
|
||||
cmd = VI_DESTROY;
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(name, argv[2]);
|
||||
if (strcmp(argv[1], "-c") == 0)
|
||||
cmd = VI_CREATE;
|
||||
if (strcmp(argv[1], "-i") == 0)
|
||||
cmd = VI_IFACE;
|
||||
if (cmd == VI_SWITCHTO || cmd == newcmd)
|
||||
cmd = newcmd;
|
||||
else
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) ||
|
||||
(cmd == VI_IFMOVE && (argc < 2 || argc > 3)) ||
|
||||
(cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS)
|
||||
usage();
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case VI_GET:
|
||||
jid = getjail(name, -1, &vnet);
|
||||
if (jid < 0)
|
||||
goto abort;
|
||||
printf("%d: %s%s\n", jid, name, vnet ? "" : " (no vnet)");
|
||||
exit(0);
|
||||
|
||||
case VI_GETNEXT:
|
||||
vst_last = 0;
|
||||
vst_size = VST_SIZE_STEP;
|
||||
if ((vst = malloc(vst_size * sizeof(*vst))) == NULL)
|
||||
break;
|
||||
if (argc == 1)
|
||||
namelen = strlen(argv[0]);
|
||||
else
|
||||
namelen = 0;
|
||||
jid = 0;
|
||||
while ((jid = getjail(name, jid, &vnet)) > 0)
|
||||
printf("%d: %s%s\n", jid, name,
|
||||
vnet ? "" : " (no vnet)");
|
||||
while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) {
|
||||
/* Skip jails which do not own vnets. */
|
||||
if (vst[vst_last].vnet != 1)
|
||||
continue;
|
||||
/* Skip non-matching vnames / hierarchies. */
|
||||
if (namelen &&
|
||||
((strlen(vst[vst_last].name) < namelen ||
|
||||
strncmp(vst[vst_last].name, argv[0], namelen) != 0)
|
||||
|| (strlen(vst[vst_last].name) > namelen &&
|
||||
vst[vst_last].name[namelen] != '.')))
|
||||
continue;
|
||||
/* Skip any sub-trees if -r not requested. */
|
||||
if (!recurse &&
|
||||
(strlen(vst[vst_last].name) < namelen ||
|
||||
strchr(&vst[vst_last].name[namelen], '.') != NULL))
|
||||
continue;
|
||||
/* Grow vst table if necessary. */
|
||||
if (++vst_last == vst_size) {
|
||||
vst_size += VST_SIZE_STEP;
|
||||
vst = realloc(vst, vst_size * sizeof(*vst));
|
||||
if (vst == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vst == NULL)
|
||||
break;
|
||||
/* Sort: the key is the 1st field in *vst, i.e. vimage name. */
|
||||
qsort(vst, vst_last, sizeof(*vst), (void *) strcmp);
|
||||
for (i = 0; i < vst_last; i++) {
|
||||
if (!verbose) {
|
||||
printf("%s\n", vst[i].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%s:\n", vst[i].name);
|
||||
printf(" Path: %s\n", vst[i].path);
|
||||
printf(" Hostname: %s\n", vst[i].hostname);
|
||||
printf(" Domainname: %s\n", vst[i].domainname);
|
||||
printf(" Children: %d\n", vst[i].childcnt);
|
||||
|
||||
if (verbose < 2)
|
||||
continue;
|
||||
|
||||
printf(" Children limit: %d\n", vst[i].childmax);
|
||||
printf(" CPUsetID: %d\n", vst[i].cpuset);
|
||||
printf(" JID: %d\n", vst[i].jid);
|
||||
printf(" PJID: %d\n", vst[i].parentjid);
|
||||
printf(" Raw sockets allowed: %d\n", vst[i].rawsock);
|
||||
printf(" All AF allowed: %d\n", vst[i].socket_af);
|
||||
printf(" Mount allowed: %d\n", vst[i].mount);
|
||||
}
|
||||
free(vst);
|
||||
exit(0);
|
||||
|
||||
case VI_IFACE:
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1)
|
||||
goto abort;
|
||||
jid = jail_getid(name);
|
||||
if (jid < 0)
|
||||
goto abort;
|
||||
case VI_IFMOVE:
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
break;
|
||||
if ((jid = jail_getid(argv[0])) < 0)
|
||||
break;
|
||||
ifreq.ifr_jid = jid;
|
||||
strncpy(ifreq.ifr_name, argv[3], sizeof(ifreq.ifr_name));
|
||||
strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name));
|
||||
if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
|
||||
goto abort;
|
||||
printf("%s@%s\n", ifreq.ifr_name, name);
|
||||
break;
|
||||
close(s);
|
||||
if (argc == 3)
|
||||
snprintf(ifname, sizeof(ifname), "%s", argv[2]);
|
||||
else
|
||||
snprintf(ifname, sizeof(ifname), "eth0");
|
||||
ifreq.ifr_data = ifname;
|
||||
/* Do we need to rename the ifnet? */
|
||||
if (strcmp(ifreq.ifr_name, ifname) != 0) {
|
||||
/* Switch to the context of the target vimage. */
|
||||
if (jail_attach(jid) < 0)
|
||||
break;
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
break;
|
||||
for (namelen = 0; isalpha(ifname[namelen]); namelen++);
|
||||
i = 0;
|
||||
/* Search for a free ifunit in target vnet. Unsafe. */
|
||||
while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) {
|
||||
snprintf(&ifname[namelen],
|
||||
sizeof(ifname) - namelen, "%d", i);
|
||||
/* Emergency brake. */
|
||||
if (i++ == IF_MAXUNIT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < IF_MAXUNIT)
|
||||
printf("%s@%s\n", ifname, argv[0]);
|
||||
else
|
||||
printf("%s@%s\n", ifreq.ifr_name, argv[0]);
|
||||
exit(0);
|
||||
|
||||
case VI_CREATE:
|
||||
if (jail_setv(JAIL_CREATE, "name", name, "vnet", NULL,
|
||||
"host", NULL, "persist", NULL, NULL) < 0)
|
||||
goto abort;
|
||||
if ((jid = jail_setv(JAIL_CREATE,
|
||||
"name", argv[0],
|
||||
"vnet", NULL,
|
||||
"host", NULL,
|
||||
"persist", NULL,
|
||||
"allow.raw_sockets", "true",
|
||||
"allow.socket_af", "true",
|
||||
"allow.mount", "true",
|
||||
NULL)) >= 0)
|
||||
break;
|
||||
if (jid < 0)
|
||||
break;
|
||||
if (argc == 1)
|
||||
exit(0);
|
||||
/* Not done yet, proceed to apply non-default parameters. */
|
||||
|
||||
case VI_MODIFY:
|
||||
jailparam_init(¶ms[0], "name");
|
||||
jailparam_import(¶ms[0], argv[0]);
|
||||
for (i = 1; i < argc; i++) {
|
||||
for (str = argv[i]; *str != '=' && *str != 0; str++) {
|
||||
/* Do nothing - search for '=' delimeter. */
|
||||
}
|
||||
if (*str == 0)
|
||||
break;
|
||||
*str++ = 0;
|
||||
if (*str == 0)
|
||||
break;
|
||||
jailparam_init(¶ms[i], argv[i]);
|
||||
jailparam_import(¶ms[i], str);
|
||||
}
|
||||
if (i != argc)
|
||||
break;
|
||||
if (jailparam_set(params, i, JAIL_UPDATE) < 0)
|
||||
break;
|
||||
exit(0);
|
||||
|
||||
case VI_DESTROY:
|
||||
if ((jid = jail_getid(argv[0])) < 0)
|
||||
break;
|
||||
if (jail_remove(jid) < 0)
|
||||
break;
|
||||
exit(0);
|
||||
|
||||
case VI_SWITCHTO:
|
||||
jid = jail_getid(name);
|
||||
if (jid < 0)
|
||||
goto abort;
|
||||
if ((jid = jail_getid(argv[0])) < 0)
|
||||
break;
|
||||
if (jail_attach(jid) < 0)
|
||||
goto abort;
|
||||
|
||||
if (argc == 2) {
|
||||
printf("Switched to jail %s\n", argv[1]);
|
||||
if ((shell = getenv("SHELL")) == NULL)
|
||||
execlp("/bin/sh", argv[0], NULL);
|
||||
break;
|
||||
if (argc == 1) {
|
||||
printf("Switched to vimage %s\n", argv[0]);
|
||||
if ((str = getenv("SHELL")) == NULL)
|
||||
execlp("/bin/sh", invocname, NULL);
|
||||
else
|
||||
execlp(shell, argv[0], NULL);
|
||||
execlp(str, invocname, NULL);
|
||||
} else
|
||||
execvp(argv[2], &argv[2]);
|
||||
execvp(argv[1], &argv[1]);
|
||||
break;
|
||||
|
||||
case VI_DESTROY:
|
||||
jid = jail_getid(name);
|
||||
if (jid < 0)
|
||||
goto abort;
|
||||
if (jail_remove(jid) < 0)
|
||||
goto abort;
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [-cdilr] vi_name [args]\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
/* Should be unreachable. */
|
||||
break;
|
||||
}
|
||||
|
||||
abort:
|
||||
if (jail_errmsg[0])
|
||||
fprintf(stderr, "Error: %s\n", jail_errmsg);
|
||||
else
|
||||
@ -172,27 +324,69 @@ abort:
|
||||
}
|
||||
|
||||
static int
|
||||
getjail(char *name, int lastjid, int *vnet)
|
||||
getjail(vstat_t *vs, int lastjid, int verbose)
|
||||
{
|
||||
struct jailparam params[3];
|
||||
int jid;
|
||||
struct jailparam params[32]; /* Must be > max(psize). */
|
||||
int psize = 0;
|
||||
|
||||
if (lastjid < 0) {
|
||||
jid = jail_getid(name);
|
||||
if (jid < 0)
|
||||
return (jid);
|
||||
jailparam_init(¶ms[0], "jid");
|
||||
jailparam_import_raw(¶ms[0], &jid, sizeof jid);
|
||||
} else {
|
||||
jailparam_init(¶ms[0], "lastjid");
|
||||
jailparam_import_raw(¶ms[0], &lastjid, sizeof lastjid);
|
||||
}
|
||||
jailparam_init(¶ms[1], "name");
|
||||
jailparam_import_raw(¶ms[1], name, MAXHOSTNAMELEN);
|
||||
name[0] = 0;
|
||||
jailparam_init(¶ms[2], "vnet");
|
||||
jailparam_import_raw(¶ms[2], vnet, sizeof(*vnet));
|
||||
jid = jailparam_get(params, 3, 0);
|
||||
jailparam_free(params, 3);
|
||||
return (jid);
|
||||
bzero(params, sizeof(params));
|
||||
bzero(vs, sizeof(*vs));
|
||||
|
||||
jailparam_init(¶ms[psize], "lastjid");
|
||||
jailparam_import_raw(¶ms[psize++], &lastjid, sizeof lastjid);
|
||||
|
||||
jailparam_init(¶ms[psize], "vnet");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->vnet, sizeof(vs->vnet));
|
||||
|
||||
jailparam_init(¶ms[psize], "name");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->name, sizeof(vs->name));
|
||||
|
||||
if (verbose == 0)
|
||||
goto done;
|
||||
|
||||
jailparam_init(¶ms[psize], "path");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->path, sizeof(vs->path));
|
||||
|
||||
jailparam_init(¶ms[psize], "host.hostname");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->hostname,
|
||||
sizeof(vs->hostname));
|
||||
|
||||
jailparam_init(¶ms[psize], "host.domainname");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->domainname,
|
||||
sizeof(vs->domainname));
|
||||
|
||||
jailparam_init(¶ms[psize], "children.cur");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->childcnt,
|
||||
sizeof(vs->childcnt));
|
||||
|
||||
if (verbose == 1)
|
||||
goto done;
|
||||
|
||||
jailparam_init(¶ms[psize], "children.max");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->childmax,
|
||||
sizeof(vs->childmax));
|
||||
|
||||
jailparam_init(¶ms[psize], "cpuset.id");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->cpuset,
|
||||
sizeof(vs->cpuset));
|
||||
|
||||
jailparam_init(¶ms[psize], "parent");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->parentjid,
|
||||
sizeof(vs->parentjid));
|
||||
|
||||
jailparam_init(¶ms[psize], "allow.raw_sockets");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->rawsock,
|
||||
sizeof(vs->rawsock));
|
||||
|
||||
jailparam_init(¶ms[psize], "allow.socket_af");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->socket_af,
|
||||
sizeof(vs->socket_af));
|
||||
|
||||
jailparam_init(¶ms[psize], "allow.mount");
|
||||
jailparam_import_raw(¶ms[psize++], &vs->mount, sizeof(vs->mount));
|
||||
|
||||
done:
|
||||
vs->jid = jailparam_get(params, psize, 0);
|
||||
jailparam_free(params, psize);
|
||||
return (vs->jid);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user