[libvirt] [PATCH 0/2] Fix bridge creation/deletion on 2.6.x kernels
by Laine Stump
These two patches fix this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=1252780
which was also separate reported in libvirt-users a couple days ago.
Most people running CentOS6 or RHEL6 also run the downstream version
of libvirt-0.10.2 that has many patches backported from later upstream
releases, but not the patch described in the commit logs of these
proposed patches. And the problem being fixed here only occurs on a
2.6.x kernel, while most people running upstream libvirt are running
something much more modern. That's why not many people have seen the
bug that these patches fix. Still, we claim to fully support upstream
on RHEL6/CentOS6, so we'd better do it right!
Two notes:
1) I tried timing 20 iterations of net-start...net-delete with these
patches vs. a libvirt build that simply calls the ioctls in the
beginnng (i.e. it doesn't try netlink then fall back to ioctl if that
fails), and the time to completion was within 0.25%, so the extra
overhead of trying one then the other isn't significant even on the
older machines that will always fall back to ioctl.
2) There are 2 different versions of Patch 2/2. I did the first one as
an exercise to see how ugly it would be to *not* duplicate the entire
virNetlinkDelLink() function inside the new
virNetDevBridgeDelete(). It was pretty ugly, so I made a cleaner
version that duplicates the code instead. I would be okay pushing
either version, but I think I slightly prefer the one that duplicates
code and remains uncomplicated.
Laine Stump (2):
util: fallback to ioctl(SIOCBRADDBR) if netlink RTM_NEWLINK fails
util: fallback to ioctl(SIOCBRDELBR) if netlink RTM_DELLINK fails
src/util/virnetdevbridge.c | 112 ++++++++++++++++++++++++++++++++------------
src/util/virnetdevmacvlan.c | 2 +-
src/util/virnetlink.c | 17 +++++--
src/util/virnetlink.h | 2 +-
4 files changed, 98 insertions(+), 35 deletions(-)
--
2.1.0
9 years, 2 months
[libvirt] PING: [RFC PATCH 0/3] Implement mockup capabilities cache in QEMU tests
by Pavel Fedin
Hello! I remember you were worrying about a temporary hack in qemu's postparse, because test suite
could not generate proper capability cache. I promised to solve this, and here is (almost) a
solution, i've outlined one small problem to solve together in the cover message. Since then, no
response...
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
> -----Original Message-----
> From: libvir-list-bounces(a)redhat.com [mailto:libvir-list-bounces@redhat.com] On Behalf Of Pavel
> Fedin
> Sent: Tuesday, August 18, 2015 12:40 PM
> To: libvir-list(a)redhat.com
> Cc: Martin Kletzander
> Subject: [libvirt] [RFC PATCH 0/3] Implement mockup capabilities cache in QEMU tests
>
> Since commit e8d55172544c1fafe31a9e09346bdebca4f0d6f9 qemu driver checks
> emulator capabilities during domain XML post-parse. However, test suite
> does not initialize it, therefore a condition to skip all checks if there
> is no cache supplied was added. This is actually a hack, whose sole
> purpose is to make existing test suite working. Additionally, it prevents
> from writing new tests for this particular functionality.
>
> This series attempts to solve this problem by implementing proper cache
> mockup in test suite. The main idea is to create a cache in standard way
> and put there a pre-defined capabilities set (which tests already have).
>
> The main problem here is to know emulator binary name, which is contained
> in the source XML. However, we have to create our cache before reading the
> XML. The simplest way to resolve this is to assume particular binary name
> from test name. Currently tests which assume cross-architecture binary are
> all prefixed with the architecture name (with one exception of "keywrap"
> tests which all assume /usr/bin/qemu-system-s390x and do not have "s390-"
> prefix in their name).
>
> This scheme works fine, unless we use "native" emulator binary. Here we
> have a mess. Most newer tests use /usr/bin/qemu, however there is a large
> number of tests which use /usr/libexec/qemu-kvm or /usr/bin/kvm (i guess
> these are leftovers from the epoch when qemu-kvm was a separate fork of
> qemu). This is currently not handled in any way, and these tests may
> report errors due to missing binaries (because virQEMUCapsCacheLookup()
> attempts to populate the cache automatically by querying the binary if
> not already known).
>
> There are several possible ways to resolve this:
> a) Add all possible names as aliases for /usr/bin/qemu
> b) Forbid to use oldstyle names at all in these tests
> c) Declare some prefix like "kvm-" for those tests who want to use
> /usr/libexec/qemu-kvm. Again, this would ban /usr/bin/kvm and
> /usr/bin/qemu-kvm (if not using aliases like in (b)
> d) Hardcode (optional) emulator name per test. IMHO a bad idea because
> number of tests is huge.
> e) Do some preparsing of the XML and extract binary name from it. Again,
> i disliked it for not being simple enough.
>
> I also thought about an alternate implementation which would patch
> postParseCallback and insert own function there which builds a cache. At
> this point binary name is already known from the XML. However, such a
> design looks like an ugly hack by itself, so i stopped going in this
> direction.
>
> Comments and opinions are welcome.
>
> Pavel Fedin (3):
> Implement virQEMUCapsCache mockup
> Use mockup cache
> Removed unneeded check
>
> src/qemu/qemu_capabilities.c | 10 +---------
> src/qemu/qemu_capspriv.h | 36 +++++++++++++++++++++++++++++++++++
> src/qemu/qemu_domain.c | 5 +----
> tests/qemuagenttest.c | 9 ++++++++-
> tests/qemuargv2xmltest.c | 5 +++++
> tests/qemuhotplugtest.c | 23 ++++++++++++++--------
> tests/qemuxml2argvtest.c | 5 +++++
> tests/qemuxml2xmltest.c | 6 ++++++
> tests/qemuxmlnstest.c | 5 +++++
> tests/testutilsqemu.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> tests/testutilsqemu.h | 3 +++
> 11 files changed, 130 insertions(+), 22 deletions(-)
> create mode 100644 src/qemu/qemu_capspriv.h
> mode change 100644 => 100755 tests/qemuagenttest.c
> mode change 100644 => 100755 tests/qemuhotplugtest.c
> mode change 100644 => 100755 tests/qemuxml2xmltest.c
> mode change 100644 => 100755 tests/testutilsqemu.c
>
> --
> 2.1.4
>
> --
> libvir-list mailing list
> libvir-list(a)redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
9 years, 2 months
[libvirt] [PATCH] lxc: Resolve Coverity RESOURCE_LEAK
by John Ferlan
Commit id 'c27553b6e' added a return -1 in a failure path without
also VIR_FREE(stack)
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/lxc/lxc_container.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index feb8fad..125e1c8 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -2463,6 +2463,7 @@ int lxcContainerStart(virDomainDefPtr def,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Config askes for inherit net namespace "
"as well as private network interfaces"));
+ VIR_FREE(stack);
return -1;
}
VIR_DEBUG("Inheriting a net namespace");
--
2.1.0
9 years, 2 months
[libvirt] [PATCH v3] lxc: Inherit namespace feature
by Daniel P. Berrange
From: Imran Khan <ik.nitk(a)gmail.com>
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.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
docs/drvlxc.html.in | 21 ++++++
docs/schemas/domaincommon.rng | 42 ++++++++++++
po/POTFILES.in | 1 +
src/Makefile.am | 6 +-
src/lxc/lxc_conf.c | 2 +-
src/lxc/lxc_container.c | 71 ++++++++++++++++++--
src/lxc/lxc_container.h | 2 +
src/lxc/lxc_controller.c | 45 ++++++++++++-
src/lxc/lxc_domain.c | 149 ++++++++++++++++++++++++++++++++++++++++++
src/lxc/lxc_domain.h | 26 ++++++++
src/lxc/lxc_process.c | 149 ++++++++++++++++++++++++++++++++++++++++++
tests/lxcxml2xmltest.c | 1 +
12 files changed, 506 insertions(+), 9 deletions(-)
diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in
index a094bd9..d6c57c4 100644
--- a/docs/drvlxc.html.in
+++ b/docs/drvlxc.html.in
@@ -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.
</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>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 043c975..fa026cd 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -68,6 +68,9 @@
<ref name='qemucmdline'/>
</optional>
<optional>
+ <ref name='lxcsharens'/>
+ </optional>
+ <optional>
<ref name='keywrap'/>
</optional>
</interleave>
@@ -5057,6 +5060,45 @@
</element>
</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">
<element name="metadata">
<zeroOrMore>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c58a7c1..dcabcc8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -85,6 +85,7 @@ src/lxc/lxc_native.c
src/lxc/lxc_container.c
src/lxc/lxc_conf.c
src/lxc/lxc_controller.c
+src/lxc/lxc_domain.c
src/lxc/lxc_driver.c
src/lxc/lxc_process.c
src/libxl/libxl_domain.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c4d49a5..fde11ff 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1320,7 +1320,11 @@ libvirt_driver_lxc_impl_la_CFLAGS = \
-I$(srcdir)/access \
-I$(srcdir)/conf \
$(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
libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS)
libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS)
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index b689b92..8ada531 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -213,7 +213,7 @@ lxcDomainXMLConfInit(void)
{
return virDomainXMLOptionNew(&virLXCDriverDomainDefParserConfig,
&virLXCDriverPrivateDataCallbacks,
- NULL);
+ &virLXCDriverDomainXMLNamespace);
}
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 11e9514..d52f57e 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -27,6 +27,7 @@
#include <config.h>
#include <fcntl.h>
+#include <sched.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
@@ -38,7 +39,6 @@
#include <mntent.h>
#include <sys/reboot.h>
#include <linux/reboot.h>
-
/* Yes, we want linux private one, for _syscall2() macro */
#include <linux/unistd.h>
@@ -111,6 +111,7 @@ struct __lxc_child_argv {
size_t nttyPaths;
char **ttyPaths;
int handshakefd;
+ int *nsInheritFDs;
};
static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
@@ -2144,6 +2145,35 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED,
/**
+ * lxcAttach_ns:
+ * @ns_fd: array of namespaces to attach
+ */
+static int lxcAttachNS(int *ns_fd)
+{
+ size_t i;
+
+ 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:
* @data: pointer to container arguments
*
@@ -2172,6 +2202,12 @@ static int lxcContainerChild(void *data)
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
* things like move of network interfaces, uid/gid mapping
*/
@@ -2342,6 +2378,7 @@ int lxcContainerStart(virDomainDefPtr def,
int *passFDs,
int control,
int handshakefd,
+ int *nsInheritFDs,
size_t nttyPaths,
char **ttyPaths)
{
@@ -2359,7 +2396,8 @@ int lxcContainerStart(virDomainDefPtr def,
.monitor = control,
.nttyPaths = nttyPaths,
.ttyPaths = ttyPaths,
- .handshakefd = handshakefd
+ .handshakefd = handshakefd,
+ .nsInheritFDs = nsInheritFDs,
};
/* allocate a stack for the container */
@@ -2368,7 +2406,7 @@ int lxcContainerStart(virDomainDefPtr def,
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_supported()) {
@@ -2381,10 +2419,31 @@ int lxcContainerStart(virDomainDefPtr def,
return -1;
}
}
+ if (nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHARENET] == -1) {
+ if (lxcNeedNetworkNamespace(def)) {
+ VIR_DEBUG("Enable network namespaces");
+ 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 (lxcNeedNetworkNamespace(def)) {
- VIR_DEBUG("Enable network namespaces");
- cflags |= CLONE_NEWNET;
+ if (nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC] == -1) {
+ cflags |= CLONE_NEWIPC;
+ } else {
+ VIR_DEBUG("Inheriting an IPC namespace");
+ }
+
+ if (nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS] == -1) {
+ cflags |= CLONE_NEWUTS;
+ } else {
+ VIR_DEBUG("Inheriting a UTS namespace");
}
VIR_DEBUG("Cloning container init process");
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index 67292ab..33eaab4 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -25,6 +25,7 @@
# define LXC_CONTAINER_H
# include "lxc_conf.h"
+# include "lxc_domain.h"
# include "security/security_manager.h"
enum {
@@ -60,6 +61,7 @@ int lxcContainerStart(virDomainDefPtr def,
int *passFDs,
int control,
int handshakefd,
+ int *nsInheritFDs,
size_t nttyPaths,
char **ttyPaths);
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 48a3597..19190dd 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -119,6 +119,8 @@ struct _virLXCController {
size_t npassFDs;
int *passFDs;
+ int *nsFDs;
+
size_t nconsoles;
virLXCControllerConsolePtr consoles;
char *devptmx;
@@ -2391,6 +2393,7 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
ctrl->passFDs,
control[1],
containerhandshake[1],
+ ctrl->nsFDs,
ctrl->nconsoles,
containerTTYPaths)) < 0)
goto cleanup;
@@ -2400,6 +2403,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
for (i = 0; i < ctrl->npassFDs; i++)
VIR_FORCE_CLOSE(ctrl->passFDs[i]);
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ VIR_FORCE_CLOSE(ctrl->nsFDs[i]);
+
if (virLXCControllerSetupCgroupLimits(ctrl) < 0)
goto cleanup;
@@ -2468,6 +2474,7 @@ int main(int argc, char *argv[])
const char *name = NULL;
size_t nveths = 0;
char **veths = NULL;
+ int ns_fd[VIR_LXC_DOMAIN_NAMESPACE_LAST];
int handshakeFd = -1;
bool bg = false;
const struct option options[] = {
@@ -2478,6 +2485,9 @@ int main(int argc, char *argv[])
{ "passfd", 1, NULL, 'p' },
{ "handshakefd", 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' },
{ 0, 0, 0, 0 },
};
@@ -2489,6 +2499,9 @@ int main(int argc, char *argv[])
size_t i;
const char *securityDriver = "none";
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ ns_fd[i] = -1;
+
if (setlocale(LC_ALL, "") == NULL ||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
textdomain(PACKAGE) == NULL ||
@@ -2504,7 +2517,7 @@ int main(int argc, char *argv[])
while (1) {
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);
if (c == -1)
@@ -2552,6 +2565,30 @@ int main(int argc, char *argv[])
}
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':
securityDriver = optarg;
break;
@@ -2569,6 +2606,9 @@ int main(int argc, char *argv[])
fprintf(stderr, " -v VETH, --veth VETH\n");
fprintf(stderr, " -s FD, --handshakefd FD\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, "\n");
goto cleanup;
@@ -2621,6 +2661,9 @@ int main(int argc, char *argv[])
ctrl->passFDs = passFDs;
ctrl->npassFDs = npassFDs;
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ ctrl->nsFDs[i] = ns_fd[i];
+
for (i = 0; i < nttyFDs; i++) {
if (virLXCControllerAddConsole(ctrl, ttyFDs[i]) < 0)
goto cleanup;
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 2f377d8..e3da9f0 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -26,8 +26,13 @@
#include "viralloc.h"
#include "virlog.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 LXC_NAMESPACE_HREF "http://libvirt.org/schemas/domain/lxc/1.0"
VIR_LOG_INIT("lxc.lxc_domain");
@@ -41,6 +46,150 @@ static void *virLXCDomainObjPrivateAlloc(void)
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)
{
virLXCDomainObjPrivatePtr priv = data;
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 751aece..2119c78 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -27,6 +27,31 @@
# include "lxc_conf.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 virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
@@ -41,6 +66,7 @@ struct _virLXCDomainObjPrivate {
virCgroupPtr cgroup;
};
+extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index e99b039..9699377 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -359,6 +359,135 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
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;
+ char *path;
+
+ vm = virDomainObjListFindByName(driver->domains, name);
+ if (!vm) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching name '%s'"), name);
+ return -1;
+ }
+
+ if (virAsprintf(&path, "/proc/%lld/ns/%s",
+ (long long int)vm->pid,
+ 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:
@@ -764,6 +893,7 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
char **veths,
int *ttyFDs,
size_t nttyFDs,
+ int *nsInheritFDs,
int *files,
size_t nfiles,
int handshakefd,
@@ -825,6 +955,19 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
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",
virSecurityManagerGetModel(driver->securityManager));
@@ -1032,6 +1175,7 @@ int virLXCProcessStart(virConnectPtr conn,
off_t pos = -1;
char ebuf[1024];
char *timestamp;
+ int nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_LAST];
virCommandPtr cmd = NULL;
virLXCDomainObjPrivatePtr priv = vm->privateData;
virCapsPtr caps = NULL;
@@ -1204,6 +1348,10 @@ int virLXCProcessStart(virConnectPtr conn,
if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
goto cleanup;
+ VIR_DEBUG("Setting up namespaces if any");
+ if (virLXCProcessSetupNamespaces(conn, vm->def->namespaceData, nsInheritFDs) < 0)
+ goto cleanup;
+
VIR_DEBUG("Preparing to launch");
if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
S_IRUSR|S_IWUSR)) < 0) {
@@ -1223,6 +1371,7 @@ int virLXCProcessStart(virConnectPtr conn,
vm,
nveths, veths,
ttyFDs, nttyFDs,
+ nsInheritFDs,
files, nfiles,
handshakefds[1],
&logfd,
diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c
index 3e00347..8d824b9 100644
--- a/tests/lxcxml2xmltest.c
+++ b/tests/lxcxml2xmltest.c
@@ -133,6 +133,7 @@ mymain(void)
DO_TEST("filesystem-root");
DO_TEST("idmap");
DO_TEST("capabilities");
+ DO_TEST("sharenet");
virObjectUnref(caps);
virObjectUnref(xmlopt);
--
2.4.3
9 years, 2 months
[libvirt] [PATCH] virt-aa-helper: Improve valid_path
by Michal Privoznik
So, after some movement in virt-aa-helper, I've noticed the
virt-aa-helper-test failing. I've ran gdb (it took me a while to
realize how to do that) and this showed up immediately:
Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb) bt
#0 strlen () at ../sysdeps/x86_64/strlen.S:106
#1 0x0000555555561a13 in array_starts_with (str=0x5555557ce910 "/tmp/tmp.6nI2Fkv0KL/1.img", arr=0x7fffffffd160, size=-1540438016) at security/virt-aa-helper.c:525
#2 0x0000555555561d49 in valid_path (path=0x5555557ce910 "/tmp/tmp.6nI2Fkv0KL/1.img", readonly=false) at security/virt-aa-helper.c:617
#3 0x0000555555562506 in vah_add_path (buf=0x7fffffffd3e0, path=0x5555557cb910 "/tmp/tmp.6nI2Fkv0KL/1.img", perms=0x555555581585 "rw", recursive=false) at security/virt-aa-helper.c:823
#4 0x0000555555562693 in vah_add_file (buf=0x7fffffffd3e0, path=0x5555557cb910 "/tmp/tmp.6nI2Fkv0KL/1.img", perms=0x555555581585 "rw") at security/virt-aa-helper.c:854
#5 0x0000555555562918 in add_file_path (disk=0x5555557d4440, path=0x5555557cb910 "/tmp/tmp.6nI2Fkv0KL/1.img", depth=0, opaque=0x7fffffffd3e0) at security/virt-aa-helper.c:931
#6 0x00007ffff78f18b1 in virDomainDiskDefForeachPath (disk=0x5555557d4440, ignoreOpenFailure=true, iter=0x5555555628a6 <add_file_path>, opaque=0x7fffffffd3e0) at conf/domain_conf.c:23286
#7 0x0000555555562b5f in get_files (ctl=0x7fffffffd670) at security/virt-aa-helper.c:982
#8 0x0000555555564100 in vahParseArgv (ctl=0x7fffffffd670, argc=5, argv=0x7fffffffd7e8) at security/virt-aa-helper.c:1277
#9 0x00005555555643d6 in main (argc=5, argv=0x7fffffffd7e8) at security/virt-aa-helper.c:1332
So I've taken look at valid_path() because it is obviously
calling array_starts_with() with malformed @size. And here's the
result: there are two variables to hold the size of three arrays
and their value is recalculated before each call of
array_starts_with(). What if we just use three variables,
initialize them and do not touch them afterwards?
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/security/virt-aa-helper.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index a78c4c8..b4a8f27 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -546,9 +546,6 @@ array_starts_with(const char *str, const char * const *arr, const long size)
static int
valid_path(const char *path, const bool readonly)
{
- int npaths;
- int nropaths;
-
const char * const restricted[] = {
"/bin/",
"/etc/",
@@ -581,6 +578,10 @@ valid_path(const char *path, const bool readonly)
"/etc/libvirt-sandbox/services/" /* for virt-sandbox service config */
};
+ const int nropaths = ARRAY_CARDINALITY(restricted);
+ const int nrwpaths = ARRAY_CARDINALITY(restricted_rw);
+ const int nopaths = ARRAY_CARDINALITY(override);
+
if (path == NULL) {
vah_error(NULL, 0, _("bad pathname"));
return -1;
@@ -600,21 +601,18 @@ valid_path(const char *path, const bool readonly)
vah_warning(_("path does not exist, skipping file type checks"));
/* overrides are always allowed */
- npaths = sizeof(override)/sizeof(*(override));
- if (array_starts_with(path, override, npaths) == 0)
+ if (array_starts_with(path, override, nopaths) == 0)
return 0;
/* allow read only paths upfront */
if (readonly) {
- nropaths = sizeof(restricted_rw)/sizeof(*(restricted_rw));
- if (array_starts_with(path, restricted_rw, nropaths) == 0)
+ if (array_starts_with(path, restricted_rw, nrwpaths) == 0)
return 0;
}
/* disallow RW acess to all paths in restricted and restriced_rw */
- npaths = sizeof(restricted)/sizeof(*(restricted));
- if ((array_starts_with(path, restricted, npaths) == 0
- || array_starts_with(path, restricted_rw, nropaths) == 0))
+ if ((array_starts_with(path, restricted, nropaths) == 0 ||
+ array_starts_with(path, restricted_rw, nrwpaths) == 0))
return 1;
return 0;
--
2.4.6
9 years, 2 months
[libvirt] [PATCHv2 0/5] manage the shmem device source
by Luyao Huang
v1 link:
https://www.redhat.com/archives/libvir-list/2015-July/msg00926.html
v2 different:
-Introduce new xml element shareable to indicate whether the
device is intended to be shared across multiple guests.
-Make virSecuritySELinuxRestoreSecurityAllLabel and
virSecuritySELinuxSetSecurityAllLabel call set/restore label
-Move struct _virShmObject and _virShmObjectList in virshm.c
and introduce some functions to get the parameter.
-Change the return value to -1 when the function are not supported
on some platform.
-add the code in src/security/security_nop.c
-some small pieces fix
Since there is a shmobj leak when let qemu create shmobj by
themselves, also the label of shmobj/shmem-server socket
is not right. Guest cannot direct use the shmem-server
if users enabled selinux. So it will be better to manage it
in libvirt.
The way i chosed is region the shmem deivce in a list, and
save it status to a local file to avoid losing it after restart
libvirtd, and count the guest which use it, and let the callers
know if there is no guest is using it (then we can relabel/cleanup
some resource).
About shmem-server we decided introduce some new selinux label to
fix that, however ivshmem server still not finished right now (i mean
patches were still being reviewed in qemu-devel), we could implement
the set up ivshmem-server part later.
BTW, during some research i noticed the vhost-user network should have
the same problem like the ivshmem-server, since it use the same way to connect
to guest (a host app connect to guest via socket), and after some test
i found the guest cannot connect to the sockect which created by app if i enable
the Selinux. So i think maybe we could fix these two issue together, if
there is already have a way to make vhost-usr works well with SElinux,
i think we could use that way in this place.
Luyao Huang (5):
conf: introduce seclabels in shmem device element
conf: introduce shareable in shmem device element
util: introduce new helpers to manage shmem device
security: add security part for shmem device
qemu: call the helpers in virshm.c to manage shmem device
configure.ac | 10 +
docs/formatdomain.html.in | 12 +
docs/schemas/domaincommon.rng | 8 +
po/POTFILES.in | 3 +-
src/Makefile.am | 7 +-
src/conf/domain_conf.c | 103 ++-
src/conf/domain_conf.h | 6 +
src/libvirt_private.syms | 26 +
src/qemu/qemu_conf.h | 3 +
src/qemu/qemu_driver.c | 4 +
src/qemu/qemu_process.c | 157 +++++
src/security/security_dac.c | 100 +++
src/security/security_driver.h | 9 +
src/security/security_manager.c | 35 +
src/security/security_manager.h | 6 +
src/security/security_nop.c | 19 +
src/security/security_selinux.c | 97 +++
src/security/security_stack.c | 39 ++
src/util/virshm.c | 739 +++++++++++++++++++++
src/util/virshm.h | 92 +++
.../qemuxml2argv-shmem-seclabel.xml | 55 ++
.../qemuxml2argv-shmem-shareable.xml | 43 ++
tests/qemuxml2xmltest.c | 5 +
23 files changed, 1545 insertions(+), 33 deletions(-)
create mode 100644 src/util/virshm.c
create mode 100644 src/util/virshm.h
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem-seclabel.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem-shareable.xml
--
1.8.3.1
9 years, 2 months
[libvirt] [python PATCH] examples: small fix for nodestats.py example
by Luyao Huang
Add nodestats.py in MANIFEST.in and add a
small description for nodestats.py in README
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
MANIFEST.in | 1 +
examples/README | 3 +++
2 files changed, 4 insertions(+)
diff --git a/MANIFEST.in b/MANIFEST.in
index b5ba783..0d66f9c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -13,6 +13,7 @@ include examples/esxlist.py
include examples/event-test.py
include examples/guest-vcpus/guest-vcpu-daemon.py
include examples/guest-vcpus/guest-vcpu.py
+include examples/nodestats.py
include examples/topology.py
include generator.py
include libvirt-lxc-override-api.xml
diff --git a/examples/README b/examples/README
index 0cb4513..13211b6 100644
--- a/examples/README
+++ b/examples/README
@@ -14,6 +14,9 @@ dhcpleases.py - list dhcp leases for a given virtual network
domipaddrs.py - list IP addresses for guest domains
guest-vcpus - two helpers to make the guest agent event useful with agent based
vCPU state modification
+nodestats.py - print total memory and free memory for each host NUMA node and
+ the memory strictly bound to certain host nodes for each running
+ domain.
The XML files in this directory are examples of the XML format that libvirt
expects, and will have to be adapted for your setup. They are only needed
--
1.8.3.1
9 years, 3 months
[libvirt] [PATCHv2 0/2] qemu: fix the audit log is not correct for memory device
by Luyao Huang
First review:
http://www.redhat.com/archives/libvir-list/2015-July/msg00982.html
Change in v2:
- split it to two patches
- fix some small mistake in hot-unplug part
I change the code in qemuDomainAttachMemory like what we do in other attach deivce
functions. And I have removed the jump in qemuDomainRemoveMemoryDevice, since i just
see only one place need jump to audit, so i refactor the code (thanks John's advise).
Luyao Huang (2):
qemu: fix the audit log is not correct after hot-plug memory success
qemu: fix the audit log is not correct after hot-unplug memory device
src/qemu/qemu_hotplug.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
--
1.8.3.1
9 years, 3 months
[libvirt] [PATCH] virsh: Remove <backingStore> when changing cdrom media source
by Peter Krempa
Since the code is changing the source image path by modifying the
existing XML snippet the <backingStore> element does not get dropped.
The element is ignored though but it might start being used in the
future.
Before this patch, you'd get:
$ virsh change-media --eject --print-xml 10 hdc
<disk type="file" device="cdrom">
<driver name="qemu" type="qcow2"/>
<backingStore type="file" index="1">
<format type="qcow2"/>
<source file="/var/lib/libvirt/images/vm.1436949097"/>
<backingStore/>
</backingStore>
<target dev="hdc" bus="ide"/>
...
</disk>
After:
$ virsh change-media --eject --print-xml 10 hdc
<disk type="file" device="cdrom">
<driver name="qemu" type="qcow2"/>
<target dev="hdc" bus="ide"/>
...
</disk>
---
tools/virsh-domain.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index a61656f..d4d6987 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11415,6 +11415,7 @@ vshUpdateDiskXML(xmlNodePtr disk_node,
vshUpdateDiskXMLType type)
{
xmlNodePtr source = NULL;
+ xmlNodePtr child;
char *device_type = NULL;
char *ret = NULL;
@@ -11430,10 +11431,16 @@ vshUpdateDiskXML(xmlNodePtr disk_node,
}
/* find the current source subelement */
- for (source = disk_node->children; source; source = source->next) {
- if (source->type == XML_ELEMENT_NODE &&
- xmlStrEqual(source->name, BAD_CAST "source"))
- break;
+ for (child = disk_node->children; child; child = child->next) {
+ if (child->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(child->name, BAD_CAST "source"))
+ source = child;
+
+ if (child->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(child->name, BAD_CAST "backingStore")) {
+ xmlUnlinkNode(child);
+ xmlFreeNode(child);
+ }
}
if (type == VSH_UPDATE_DISK_XML_EJECT) {
--
2.4.5
9 years, 3 months
[libvirt] [PATCH] virt-aa-helper: add NVRAM store file for read/write
by Peter Kieser
Some UEFI firmwares may want to use a non-volatile memory to store some
variables.
If AppArmor is enabled, and NVRAM store file is set currently
virt-aa-helper does
not add the NVRAM store file to the template. Add this file for
read/write when
this functionality is defined in domain XML.
Signed-off-by: Peter Kieser <peter(a)kieser.ca>
---
src/security/virt-aa-helper.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 4ce1e7a..2f93172 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1047,6 +1047,10 @@ get_files(vahControl * ctl)
if (vah_add_file(&buf, ctl->def->os.loader->path, "r") != 0)
goto cleanup;
+ if (ctl->def->os.loader && ctl->def->os.loader->nvram)
+ if (vah_add_file(&buf, ctl->def->os.loader->nvram, "rw") != 0)
+ goto cleanup;
+
for (i = 0; i < ctl->def->ngraphics; i++) {
if (ctl->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
ctl->def->graphics[i]->data.vnc.socket &&
9 years, 3 months