mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
lxc: Inherit namespace feature
This patch adds feature for lxc containers to inherit namespaces. This is very similar to what lxc-tools or docker provides. Look for "man lxc-start" and you will find that you can pass command args as [ --share-[net|ipc|uts] name|pid ]. Or check out docker networking option in which you can give --net=container:NAME_or_ID as an option for sharing +namespace. >From this patch you can add extra libvirt option to share namespace in following way. <lxc:namespace> <lxc:sharenet type='netns' value='red'/> <lxc:shareipc type='pid' value='12345'/> <lxc:shareuts type='name' value='container1'/> </lxc:namespace> The netns option is specific to sharenet. It can be used to inherit from existing network namespace. Co-authored: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
f674dc6794
commit
c27553b6e2
@ -590,6 +590,27 @@ Note that allowing capabilities that are normally dropped by default can serious
|
|||||||
affect the security of the container and the host.
|
affect the security of the container and the host.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2><a name="share">Inherit namespaces</a></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Libvirt allows you to inherit the namespace from container/process just like lxc tools
|
||||||
|
or docker provides to share the network namespace. The following can be used to share
|
||||||
|
required namespaces. If we want to share only one then the other namespaces can be ignored.
|
||||||
|
The netns option is specific to sharenet. It can be used in cases we want to use existing network namespace
|
||||||
|
rather than creating new network namespace for the container. In this case privnet option will be
|
||||||
|
ignored.
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<domain type='lxc' xmlns:lxc='http://libvirt.org/schemas/domain/lxc/1.0'>
|
||||||
|
...
|
||||||
|
<lxc:namespace>
|
||||||
|
<lxc:sharenet type='netns' value='red'/>
|
||||||
|
<lxc:shareuts type='name' value='container1'/>
|
||||||
|
<lxc:shareipc type='pid' value='12345'/>
|
||||||
|
</lxc:namespace>
|
||||||
|
</domain>
|
||||||
|
</pre>
|
||||||
|
|
||||||
<h2><a name="usage">Container usage / management</a></h2>
|
<h2><a name="usage">Container usage / management</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -67,6 +67,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name='qemucmdline'/>
|
<ref name='qemucmdline'/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name='lxcsharens'/>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<ref name='keywrap'/>
|
<ref name='keywrap'/>
|
||||||
</optional>
|
</optional>
|
||||||
@ -5057,6 +5060,45 @@
|
|||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Optional hypervisor extensions in their own namespace:
|
||||||
|
LXC
|
||||||
|
-->
|
||||||
|
<define name="lxcsharens">
|
||||||
|
<element name="namespace" ns="http://libvirt.org/schemas/domain/lxc/1.0">
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name="sharenet">
|
||||||
|
<attribute name="type">
|
||||||
|
<choice>
|
||||||
|
<value>netns</value>
|
||||||
|
<value>name</value>
|
||||||
|
<value>pid</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<attribute name='value'/>
|
||||||
|
</element>
|
||||||
|
<element name="shareipc">
|
||||||
|
<attribute name="type">
|
||||||
|
<choice>
|
||||||
|
<value>name</value>
|
||||||
|
<value>pid</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<attribute name='value'/>
|
||||||
|
</element>
|
||||||
|
<element name="shareuts">
|
||||||
|
<attribute name="type">
|
||||||
|
<choice>
|
||||||
|
<value>name</value>
|
||||||
|
<value>pid</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<attribute name='value'/>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="metadata">
|
<define name="metadata">
|
||||||
<element name="metadata">
|
<element name="metadata">
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
|
@ -85,6 +85,7 @@ src/lxc/lxc_native.c
|
|||||||
src/lxc/lxc_container.c
|
src/lxc/lxc_container.c
|
||||||
src/lxc/lxc_conf.c
|
src/lxc/lxc_conf.c
|
||||||
src/lxc/lxc_controller.c
|
src/lxc/lxc_controller.c
|
||||||
|
src/lxc/lxc_domain.c
|
||||||
src/lxc/lxc_driver.c
|
src/lxc/lxc_driver.c
|
||||||
src/lxc/lxc_process.c
|
src/lxc/lxc_process.c
|
||||||
src/libxl/libxl_domain.c
|
src/libxl/libxl_domain.c
|
||||||
|
@ -1320,7 +1320,12 @@ libvirt_driver_lxc_impl_la_CFLAGS = \
|
|||||||
-I$(srcdir)/access \
|
-I$(srcdir)/access \
|
||||||
-I$(srcdir)/conf \
|
-I$(srcdir)/conf \
|
||||||
$(AM_CFLAGS)
|
$(AM_CFLAGS)
|
||||||
libvirt_driver_lxc_impl_la_LIBADD = $(CAPNG_LIBS) $(LIBNL_LIBS) $(FUSE_LIBS)
|
libvirt_driver_lxc_impl_la_LIBADD = \
|
||||||
|
$(CAPNG_LIBS) \
|
||||||
|
$(LIBNL_LIBS) \
|
||||||
|
$(LIBXML_LIBS) \
|
||||||
|
$(FUSE_LIBS)
|
||||||
|
|
||||||
if WITH_BLKID
|
if WITH_BLKID
|
||||||
libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS)
|
libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS)
|
||||||
libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS)
|
libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS)
|
||||||
|
@ -213,7 +213,7 @@ lxcDomainXMLConfInit(void)
|
|||||||
{
|
{
|
||||||
return virDomainXMLOptionNew(&virLXCDriverDomainDefParserConfig,
|
return virDomainXMLOptionNew(&virLXCDriverDomainDefParserConfig,
|
||||||
&virLXCDriverPrivateDataCallbacks,
|
&virLXCDriverPrivateDataCallbacks,
|
||||||
NULL);
|
&virLXCDriverDomainXMLNamespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sched.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -38,7 +39,6 @@
|
|||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
/* Yes, we want linux private one, for _syscall2() macro */
|
/* Yes, we want linux private one, for _syscall2() macro */
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ struct __lxc_child_argv {
|
|||||||
size_t nttyPaths;
|
size_t nttyPaths;
|
||||||
char **ttyPaths;
|
char **ttyPaths;
|
||||||
int handshakefd;
|
int handshakefd;
|
||||||
|
int *nsInheritFDs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
|
static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
|
||||||
@ -2143,6 +2144,35 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lxcAttach_ns:
|
||||||
|
* @ns_fd: array of namespaces to attach
|
||||||
|
*/
|
||||||
|
static int lxcAttachNS(int *ns_fd)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
if (ns_fd)
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
|
||||||
|
if (ns_fd[i] < 0)
|
||||||
|
continue;
|
||||||
|
VIR_DEBUG("Setting into namespace\n");
|
||||||
|
/* We get EINVAL if new NS is same as the current
|
||||||
|
* NS, or if the fd namespace doesn't match the
|
||||||
|
* type passed to setns()'s second param. Since we
|
||||||
|
* pass 0, we know the EINVAL is harmless
|
||||||
|
*/
|
||||||
|
if (setns(ns_fd[i], 0) < 0 &&
|
||||||
|
errno != EINVAL) {
|
||||||
|
virReportSystemError(errno, _("failed to set namespace '%s'"),
|
||||||
|
virLXCDomainNamespaceTypeToString(i));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
VIR_FORCE_CLOSE(ns_fd[i]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lxcContainerChild:
|
* lxcContainerChild:
|
||||||
* @data: pointer to container arguments
|
* @data: pointer to container arguments
|
||||||
@ -2172,6 +2202,12 @@ static int lxcContainerChild(void *data)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lxcAttachNS(argv->nsInheritFDs) < 0) {
|
||||||
|
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
|
||||||
|
_("failed to attach the namespace"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for controller to finish setup tasks, including
|
/* Wait for controller to finish setup tasks, including
|
||||||
* things like move of network interfaces, uid/gid mapping
|
* things like move of network interfaces, uid/gid mapping
|
||||||
*/
|
*/
|
||||||
@ -2342,6 +2378,7 @@ int lxcContainerStart(virDomainDefPtr def,
|
|||||||
int *passFDs,
|
int *passFDs,
|
||||||
int control,
|
int control,
|
||||||
int handshakefd,
|
int handshakefd,
|
||||||
|
int *nsInheritFDs,
|
||||||
size_t nttyPaths,
|
size_t nttyPaths,
|
||||||
char **ttyPaths)
|
char **ttyPaths)
|
||||||
{
|
{
|
||||||
@ -2359,7 +2396,8 @@ int lxcContainerStart(virDomainDefPtr def,
|
|||||||
.monitor = control,
|
.monitor = control,
|
||||||
.nttyPaths = nttyPaths,
|
.nttyPaths = nttyPaths,
|
||||||
.ttyPaths = ttyPaths,
|
.ttyPaths = ttyPaths,
|
||||||
.handshakefd = handshakefd
|
.handshakefd = handshakefd,
|
||||||
|
.nsInheritFDs = nsInheritFDs,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* allocate a stack for the container */
|
/* allocate a stack for the container */
|
||||||
@ -2368,7 +2406,7 @@ int lxcContainerStart(virDomainDefPtr def,
|
|||||||
|
|
||||||
stacktop = stack + stacksize;
|
stacktop = stack + stacksize;
|
||||||
|
|
||||||
cflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD;
|
cflags = CLONE_NEWPID|CLONE_NEWNS|SIGCHLD;
|
||||||
|
|
||||||
if (userns_required(def)) {
|
if (userns_required(def)) {
|
||||||
if (userns_supported()) {
|
if (userns_supported()) {
|
||||||
@ -2381,11 +2419,32 @@ int lxcContainerStart(virDomainDefPtr def,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHARENET] == -1) {
|
||||||
if (lxcNeedNetworkNamespace(def)) {
|
if (lxcNeedNetworkNamespace(def)) {
|
||||||
VIR_DEBUG("Enable network namespaces");
|
VIR_DEBUG("Enable network namespaces");
|
||||||
cflags |= CLONE_NEWNET;
|
cflags |= CLONE_NEWNET;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (lxcNeedNetworkNamespace(def)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Config askes for inherit net namespace "
|
||||||
|
"as well as private network interfaces"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
VIR_DEBUG("Inheriting a net namespace");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC] == -1) {
|
||||||
|
cflags |= CLONE_NEWIPC;
|
||||||
|
} else {
|
||||||
|
VIR_DEBUG("Inheriting an IPC namespace");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS] == -1) {
|
||||||
|
cflags |= CLONE_NEWUTS;
|
||||||
|
} else {
|
||||||
|
VIR_DEBUG("Inheriting a UTS namespace");
|
||||||
|
}
|
||||||
|
|
||||||
VIR_DEBUG("Cloning container init process");
|
VIR_DEBUG("Cloning container init process");
|
||||||
pid = clone(lxcContainerChild, stacktop, cflags, &args);
|
pid = clone(lxcContainerChild, stacktop, cflags, &args);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
# define LXC_CONTAINER_H
|
# define LXC_CONTAINER_H
|
||||||
|
|
||||||
# include "lxc_conf.h"
|
# include "lxc_conf.h"
|
||||||
|
# include "lxc_domain.h"
|
||||||
# include "security/security_manager.h"
|
# include "security/security_manager.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -60,6 +61,7 @@ int lxcContainerStart(virDomainDefPtr def,
|
|||||||
int *passFDs,
|
int *passFDs,
|
||||||
int control,
|
int control,
|
||||||
int handshakefd,
|
int handshakefd,
|
||||||
|
int *nsInheritFDs,
|
||||||
size_t nttyPaths,
|
size_t nttyPaths,
|
||||||
char **ttyPaths);
|
char **ttyPaths);
|
||||||
|
|
||||||
|
@ -119,6 +119,8 @@ struct _virLXCController {
|
|||||||
size_t npassFDs;
|
size_t npassFDs;
|
||||||
int *passFDs;
|
int *passFDs;
|
||||||
|
|
||||||
|
int *nsFDs;
|
||||||
|
|
||||||
size_t nconsoles;
|
size_t nconsoles;
|
||||||
virLXCControllerConsolePtr consoles;
|
virLXCControllerConsolePtr consoles;
|
||||||
char *devptmx;
|
char *devptmx;
|
||||||
@ -287,6 +289,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
|
|||||||
|
|
||||||
VIR_FREE(ctrl->nbdpids);
|
VIR_FREE(ctrl->nbdpids);
|
||||||
|
|
||||||
|
VIR_FREE(ctrl->nsFDs);
|
||||||
virCgroupFree(&ctrl->cgroup);
|
virCgroupFree(&ctrl->cgroup);
|
||||||
|
|
||||||
/* This must always be the last thing to be closed */
|
/* This must always be the last thing to be closed */
|
||||||
@ -2391,6 +2394,7 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
|
|||||||
ctrl->passFDs,
|
ctrl->passFDs,
|
||||||
control[1],
|
control[1],
|
||||||
containerhandshake[1],
|
containerhandshake[1],
|
||||||
|
ctrl->nsFDs,
|
||||||
ctrl->nconsoles,
|
ctrl->nconsoles,
|
||||||
containerTTYPaths)) < 0)
|
containerTTYPaths)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -2400,6 +2404,10 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
|
|||||||
for (i = 0; i < ctrl->npassFDs; i++)
|
for (i = 0; i < ctrl->npassFDs; i++)
|
||||||
VIR_FORCE_CLOSE(ctrl->passFDs[i]);
|
VIR_FORCE_CLOSE(ctrl->passFDs[i]);
|
||||||
|
|
||||||
|
if (ctrl->nsFDs)
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
|
||||||
|
VIR_FORCE_CLOSE(ctrl->nsFDs[i]);
|
||||||
|
|
||||||
if (virLXCControllerSetupCgroupLimits(ctrl) < 0)
|
if (virLXCControllerSetupCgroupLimits(ctrl) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -2468,6 +2476,7 @@ int main(int argc, char *argv[])
|
|||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
size_t nveths = 0;
|
size_t nveths = 0;
|
||||||
char **veths = NULL;
|
char **veths = NULL;
|
||||||
|
int ns_fd[VIR_LXC_DOMAIN_NAMESPACE_LAST];
|
||||||
int handshakeFd = -1;
|
int handshakeFd = -1;
|
||||||
bool bg = false;
|
bool bg = false;
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
@ -2478,6 +2487,9 @@ int main(int argc, char *argv[])
|
|||||||
{ "passfd", 1, NULL, 'p' },
|
{ "passfd", 1, NULL, 'p' },
|
||||||
{ "handshakefd", 1, NULL, 's' },
|
{ "handshakefd", 1, NULL, 's' },
|
||||||
{ "security", 1, NULL, 'S' },
|
{ "security", 1, NULL, 'S' },
|
||||||
|
{ "share-net", 1, NULL, 'N' },
|
||||||
|
{ "share-ipc", 1, NULL, 'I' },
|
||||||
|
{ "share-uts", 1, NULL, 'U' },
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ 0, 0, 0, 0 },
|
{ 0, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
@ -2489,6 +2501,9 @@ int main(int argc, char *argv[])
|
|||||||
size_t i;
|
size_t i;
|
||||||
const char *securityDriver = "none";
|
const char *securityDriver = "none";
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
|
||||||
|
ns_fd[i] = -1;
|
||||||
|
|
||||||
if (setlocale(LC_ALL, "") == NULL ||
|
if (setlocale(LC_ALL, "") == NULL ||
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
|
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
|
||||||
textdomain(PACKAGE) == NULL ||
|
textdomain(PACKAGE) == NULL ||
|
||||||
@ -2504,7 +2519,7 @@ int main(int argc, char *argv[])
|
|||||||
while (1) {
|
while (1) {
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = getopt_long(argc, argv, "dn:v:p:m:c:s:h:S:",
|
c = getopt_long(argc, argv, "dn:v:p:m:c:s:h:S:N:I:U:",
|
||||||
options, NULL);
|
options, NULL);
|
||||||
|
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
@ -2552,6 +2567,30 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHARENET]) < 0) {
|
||||||
|
fprintf(stderr, "malformed --share-net argument '%s'",
|
||||||
|
optarg);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'I':
|
||||||
|
if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC]) < 0) {
|
||||||
|
fprintf(stderr, "malformed --share-ipc argument '%s'",
|
||||||
|
optarg);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'U':
|
||||||
|
if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS]) < 0) {
|
||||||
|
fprintf(stderr, "malformed --share-uts argument '%s'",
|
||||||
|
optarg);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
securityDriver = optarg;
|
securityDriver = optarg;
|
||||||
break;
|
break;
|
||||||
@ -2569,6 +2608,9 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, " -v VETH, --veth VETH\n");
|
fprintf(stderr, " -v VETH, --veth VETH\n");
|
||||||
fprintf(stderr, " -s FD, --handshakefd FD\n");
|
fprintf(stderr, " -s FD, --handshakefd FD\n");
|
||||||
fprintf(stderr, " -S NAME, --security NAME\n");
|
fprintf(stderr, " -S NAME, --security NAME\n");
|
||||||
|
fprintf(stderr, " -N FD, --share-net FD\n");
|
||||||
|
fprintf(stderr, " -I FD, --share-ipc FD\n");
|
||||||
|
fprintf(stderr, " -U FD, --share-uts FD\n");
|
||||||
fprintf(stderr, " -h, --help\n");
|
fprintf(stderr, " -h, --help\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -2621,6 +2663,19 @@ int main(int argc, char *argv[])
|
|||||||
ctrl->passFDs = passFDs;
|
ctrl->passFDs = passFDs;
|
||||||
ctrl->npassFDs = npassFDs;
|
ctrl->npassFDs = npassFDs;
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
|
||||||
|
if (ns_fd[i] != -1) {
|
||||||
|
if (!ctrl->nsFDs) {/*allocate only once */
|
||||||
|
size_t j = 0;
|
||||||
|
if (VIR_ALLOC_N(ctrl->nsFDs, VIR_LXC_DOMAIN_NAMESPACE_LAST) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
for (j = 0; j < VIR_LXC_DOMAIN_NAMESPACE_LAST; j++)
|
||||||
|
ctrl->nsFDs[j] = -1;
|
||||||
|
}
|
||||||
|
ctrl->nsFDs[i] = ns_fd[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nttyFDs; i++) {
|
for (i = 0; i < nttyFDs; i++) {
|
||||||
if (virLXCControllerAddConsole(ctrl, ttyFDs[i]) < 0)
|
if (virLXCControllerAddConsole(ctrl, ttyFDs[i]) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -26,8 +26,13 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
|
#include <libxml/xpathInternals.h>
|
||||||
|
#include "virstring.h"
|
||||||
|
#include "virutil.h"
|
||||||
|
#include "virfile.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||||
|
#define LXC_NAMESPACE_HREF "http://libvirt.org/schemas/domain/lxc/1.0"
|
||||||
|
|
||||||
VIR_LOG_INIT("lxc.lxc_domain");
|
VIR_LOG_INIT("lxc.lxc_domain");
|
||||||
|
|
||||||
@ -41,6 +46,150 @@ static void *virLXCDomainObjPrivateAlloc(void)
|
|||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virLXCDomainNamespace,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_LAST,
|
||||||
|
"sharenet",
|
||||||
|
"shareipc",
|
||||||
|
"shareuts")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virLXCDomainNamespaceSource,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_LAST,
|
||||||
|
"none",
|
||||||
|
"name",
|
||||||
|
"pid",
|
||||||
|
"netns")
|
||||||
|
|
||||||
|
static void
|
||||||
|
lxcDomainDefNamespaceFree(void *nsdata)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
lxcDomainDefPtr lxcDef = nsdata;
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
|
||||||
|
VIR_FREE(lxcDef->ns_val[i]);
|
||||||
|
VIR_FREE(nsdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lxcDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED,
|
||||||
|
xmlNodePtr root ATTRIBUTE_UNUSED,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
void **data)
|
||||||
|
{
|
||||||
|
lxcDomainDefPtr lxcDef = NULL;
|
||||||
|
xmlNodePtr *nodes = NULL;
|
||||||
|
bool uses_lxc_ns = false;
|
||||||
|
xmlNodePtr node;
|
||||||
|
int feature;
|
||||||
|
int n;
|
||||||
|
char *tmp = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (xmlXPathRegisterNs(ctxt, BAD_CAST "lxc", BAD_CAST LXC_NAMESPACE_HREF) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Failed to register xml namespace '%s'"),
|
||||||
|
LXC_NAMESPACE_HREF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(lxcDef) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
node = ctxt->node;
|
||||||
|
if ((n = virXPathNodeSet("./lxc:namespace/*", ctxt, &nodes)) < 0)
|
||||||
|
goto error;
|
||||||
|
uses_lxc_ns |= n > 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if ((feature = virLXCDomainNamespaceTypeFromString(
|
||||||
|
(const char *) nodes[i]->name)) < 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("unsupported Namespace feature: %s"),
|
||||||
|
nodes[i]->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->node = nodes[i];
|
||||||
|
|
||||||
|
if (!(tmp = virXMLPropString(nodes[i], "type"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("No lxc environment type specified"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if ((lxcDef->ns_source[feature] =
|
||||||
|
virLXCDomainNamespaceSourceTypeFromString(tmp)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unknown LXC namespace source '%s'"),
|
||||||
|
tmp);
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
|
||||||
|
if (!(lxcDef->ns_val[feature] =
|
||||||
|
virXMLPropString(nodes[i], "value"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("No lxc environment type specified"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
ctxt->node = node;
|
||||||
|
if (uses_lxc_ns)
|
||||||
|
*data = lxcDef;
|
||||||
|
else
|
||||||
|
VIR_FREE(lxcDef);
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
lxcDomainDefNamespaceFree(lxcDef);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
lxcDomainDefNamespaceFormatXML(virBufferPtr buf,
|
||||||
|
void *nsdata)
|
||||||
|
{
|
||||||
|
lxcDomainDefPtr lxcDef = nsdata;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!lxcDef)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "<lxc:namespace>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
|
||||||
|
if (lxcDef->ns_source[i] == VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<lxc:%s type='%s' value='%s'/>\n",
|
||||||
|
virLXCDomainNamespaceTypeToString(i),
|
||||||
|
virLXCDomainNamespaceSourceTypeToString(
|
||||||
|
lxcDef->ns_source[i]),
|
||||||
|
lxcDef->ns_val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</lxc:namespace>\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
lxcDomainDefNamespaceHref(void)
|
||||||
|
{
|
||||||
|
return "xmlns:lxc='" LXC_NAMESPACE_HREF "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virDomainXMLNamespace virLXCDriverDomainXMLNamespace = {
|
||||||
|
.parse = lxcDomainDefNamespaceParse,
|
||||||
|
.free = lxcDomainDefNamespaceFree,
|
||||||
|
.format = lxcDomainDefNamespaceFormatXML,
|
||||||
|
.href = lxcDomainDefNamespaceHref,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void virLXCDomainObjPrivateFree(void *data)
|
static void virLXCDomainObjPrivateFree(void *data)
|
||||||
{
|
{
|
||||||
virLXCDomainObjPrivatePtr priv = data;
|
virLXCDomainObjPrivatePtr priv = data;
|
||||||
|
@ -27,6 +27,31 @@
|
|||||||
# include "lxc_conf.h"
|
# include "lxc_conf.h"
|
||||||
# include "lxc_monitor.h"
|
# include "lxc_monitor.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SHARENET = 0,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_LAST,
|
||||||
|
} virLXCDomainNamespace;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NAME,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_PID,
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NETNS,
|
||||||
|
|
||||||
|
VIR_LXC_DOMAIN_NAMESPACE_SOURCE_LAST,
|
||||||
|
} virLXCDomainNamespaceSource;
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virLXCDomainNamespace)
|
||||||
|
VIR_ENUM_DECL(virLXCDomainNamespaceSource)
|
||||||
|
|
||||||
|
typedef struct _lxcDomainDef lxcDomainDef;
|
||||||
|
typedef lxcDomainDef *lxcDomainDefPtr;
|
||||||
|
struct _lxcDomainDef {
|
||||||
|
int ns_source[VIR_LXC_DOMAIN_NAMESPACE_LAST]; /* virLXCDomainNamespaceSource */
|
||||||
|
char *ns_val[VIR_LXC_DOMAIN_NAMESPACE_LAST];
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
|
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
|
||||||
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
|
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
|
||||||
@ -41,6 +66,7 @@ struct _virLXCDomainObjPrivate {
|
|||||||
virCgroupPtr cgroup;
|
virCgroupPtr cgroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
|
||||||
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
|
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
|
||||||
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
|
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
|
||||||
|
|
||||||
|
@ -359,6 +359,143 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *nsInfoLocal[VIR_LXC_DOMAIN_NAMESPACE_LAST] = {
|
||||||
|
[VIR_LXC_DOMAIN_NAMESPACE_SHARENET] = "net",
|
||||||
|
[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC] = "ipc",
|
||||||
|
[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS] = "uts",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int virLXCProcessSetupNamespaceName(virConnectPtr conn, int ns_type, const char *name)
|
||||||
|
{
|
||||||
|
virLXCDriverPtr driver = conn->privateData;
|
||||||
|
int fd = -1;
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
virLXCDomainObjPrivatePtr priv;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
vm = virDomainObjListFindByName(driver->domains, name);
|
||||||
|
if (!vm) {
|
||||||
|
virReportError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with matching name '%s'"), name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
|
if (!priv->initpid) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
|
_("Init pid is not yet available"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(&path, "/proc/%lld/ns/%s",
|
||||||
|
(long long int)priv->initpid,
|
||||||
|
nsInfoLocal[ns_type]) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("failed to open ns %s"),
|
||||||
|
virLXCDomainNamespaceTypeToString(ns_type));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(path);
|
||||||
|
virObjectUnlock(vm);
|
||||||
|
virObjectUnref(vm);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int virLXCProcessSetupNamespacePID(int ns_type, const char *name)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (virAsprintf(&path, "/proc/%s/ns/%s",
|
||||||
|
name,
|
||||||
|
nsInfoLocal[ns_type]) < 0)
|
||||||
|
return -1;
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
VIR_FREE(path);
|
||||||
|
if (fd < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("failed to open ns %s"),
|
||||||
|
virLXCDomainNamespaceTypeToString(ns_type));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int virLXCProcessSetupNamespaceNet(int ns_type, const char *name)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
int fd;
|
||||||
|
if (ns_type != VIR_LXC_DOMAIN_NAMESPACE_SHARENET) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("'netns' namespace source can only be "
|
||||||
|
"used with sharenet"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(&path, "/var/run/netns/%s", name) < 0)
|
||||||
|
return -1;
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
VIR_FREE(path);
|
||||||
|
if (fd < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("failed to open netns %s"), name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virLXCProcessSetupNamespaces:
|
||||||
|
* @conn: pointer to connection
|
||||||
|
* @def: pointer to virtual machines namespaceData
|
||||||
|
* @nsFDs: out parameter to store the namespace FD
|
||||||
|
*
|
||||||
|
* Opens the specified namespace that needs to be shared and
|
||||||
|
* will moved into the container namespace later after clone has been called.
|
||||||
|
*
|
||||||
|
* Returns 0 on success or -1 in case of error
|
||||||
|
*/
|
||||||
|
static int virLXCProcessSetupNamespaces(virConnectPtr conn,
|
||||||
|
lxcDomainDefPtr lxcDef,
|
||||||
|
int *nsFDs)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
|
||||||
|
nsFDs[i] = -1;
|
||||||
|
/*If there are no namespace to be opened just return success*/
|
||||||
|
if (lxcDef == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
|
||||||
|
switch (lxcDef->ns_source[i]) {
|
||||||
|
case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE:
|
||||||
|
continue;
|
||||||
|
case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NAME:
|
||||||
|
if ((nsFDs[i] = virLXCProcessSetupNamespaceName(conn, i, lxcDef->ns_val[i])) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_PID:
|
||||||
|
if ((nsFDs[i] = virLXCProcessSetupNamespacePID(i, lxcDef->ns_val[i])) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NETNS:
|
||||||
|
if ((nsFDs[i] = virLXCProcessSetupNamespaceNet(i, lxcDef->ns_val[i])) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virLXCProcessSetupInterfaces:
|
* virLXCProcessSetupInterfaces:
|
||||||
@ -764,6 +901,7 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
|||||||
char **veths,
|
char **veths,
|
||||||
int *ttyFDs,
|
int *ttyFDs,
|
||||||
size_t nttyFDs,
|
size_t nttyFDs,
|
||||||
|
int *nsInheritFDs,
|
||||||
int *files,
|
int *files,
|
||||||
size_t nfiles,
|
size_t nfiles,
|
||||||
int handshakefd,
|
int handshakefd,
|
||||||
@ -825,6 +963,19 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
|||||||
virCommandPassFD(cmd, files[i], 0);
|
virCommandPassFD(cmd, files[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
|
||||||
|
if (nsInheritFDs[i] > 0) {
|
||||||
|
char *tmp = NULL;
|
||||||
|
if (virAsprintf(&tmp, "--share-%s",
|
||||||
|
nsInfoLocal[i]) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
virCommandAddArg(cmd, tmp);
|
||||||
|
virCommandAddArgFormat(cmd, "%d", nsInheritFDs[i]);
|
||||||
|
virCommandPassFD(cmd, nsInheritFDs[i], 0);
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virCommandAddArgPair(cmd, "--security",
|
virCommandAddArgPair(cmd, "--security",
|
||||||
virSecurityManagerGetModel(driver->securityManager));
|
virSecurityManagerGetModel(driver->securityManager));
|
||||||
|
|
||||||
@ -1032,6 +1183,7 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
off_t pos = -1;
|
off_t pos = -1;
|
||||||
char ebuf[1024];
|
char ebuf[1024];
|
||||||
char *timestamp;
|
char *timestamp;
|
||||||
|
int nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_LAST];
|
||||||
virCommandPtr cmd = NULL;
|
virCommandPtr cmd = NULL;
|
||||||
virLXCDomainObjPrivatePtr priv = vm->privateData;
|
virLXCDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virCapsPtr caps = NULL;
|
virCapsPtr caps = NULL;
|
||||||
@ -1204,6 +1356,10 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
|
if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_DEBUG("Setting up namespaces if any");
|
||||||
|
if (virLXCProcessSetupNamespaces(conn, vm->def->namespaceData, nsInheritFDs) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
VIR_DEBUG("Preparing to launch");
|
VIR_DEBUG("Preparing to launch");
|
||||||
if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
|
if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
|
||||||
S_IRUSR|S_IWUSR)) < 0) {
|
S_IRUSR|S_IWUSR)) < 0) {
|
||||||
@ -1223,6 +1379,7 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
vm,
|
vm,
|
||||||
nveths, veths,
|
nveths, veths,
|
||||||
ttyFDs, nttyFDs,
|
ttyFDs, nttyFDs,
|
||||||
|
nsInheritFDs,
|
||||||
files, nfiles,
|
files, nfiles,
|
||||||
handshakefds[1],
|
handshakefds[1],
|
||||||
&logfd,
|
&logfd,
|
||||||
|
33
tests/lxcxml2xmldata/lxc-sharenet.xml
Normal file
33
tests/lxcxml2xmldata/lxc-sharenet.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<domain type='lxc' xmlns:lxc='http://libvirt.org/schemas/domain/lxc/1.0'>
|
||||||
|
<name>jessie</name>
|
||||||
|
<uuid>e21987a5-e98e-9c99-0e35-803e4d9ad1fe</uuid>
|
||||||
|
<memory unit='KiB'>1048576</memory>
|
||||||
|
<currentMemory unit='KiB'>1048576</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64'>exe</type>
|
||||||
|
<init>/sbin/init</init>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>restart</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/libexec/libvirt_lxc</emulator>
|
||||||
|
<filesystem type='mount' accessmode='passthrough'>
|
||||||
|
<source dir='/mach/jessie'/>
|
||||||
|
<target dir='/'/>
|
||||||
|
</filesystem>
|
||||||
|
<console type='pty'>
|
||||||
|
<target type='lxc' port='0'/>
|
||||||
|
</console>
|
||||||
|
</devices>
|
||||||
|
<lxc:namespace>
|
||||||
|
<lxc:sharenet type='netns' value='red'/>
|
||||||
|
<lxc:shareipc type='pid' value='12345'/>
|
||||||
|
<lxc:shareuts type='name' value='container1'/>
|
||||||
|
</lxc:namespace>
|
||||||
|
</domain>
|
@ -133,6 +133,7 @@ mymain(void)
|
|||||||
DO_TEST("filesystem-root");
|
DO_TEST("filesystem-root");
|
||||||
DO_TEST("idmap");
|
DO_TEST("idmap");
|
||||||
DO_TEST("capabilities");
|
DO_TEST("capabilities");
|
||||||
|
DO_TEST("sharenet");
|
||||||
|
|
||||||
virObjectUnref(caps);
|
virObjectUnref(caps);
|
||||||
virObjectUnref(xmlopt);
|
virObjectUnref(xmlopt);
|
||||||
|
Loading…
Reference in New Issue
Block a user