[libvirt] [PATCH v2 00/20] cpu: Fix and improve the ppc64 driver
by Andrea Bolognani
Patches 01-07 are cleanups, 08-10 are bug fixes and 11-20
improve the driver.
Changes in v2:
* Implement compatibility with guests defined on older
libvirt versions
* Always use fallback='forbid' when emitting CPU definitions
* Update all tests in one go instead of changing them
several times
* Handle test failure and system failure differently in
cpuTestGuestData()
* Simplify ppc64DriverNodeData()
* Simplify XML parsing code
* Remove unnecessary NULL checks
* Add even more test cases
* Other small changes such as shuffling chunks between
commits to make the history more readable
Cheers.
Andrea Bolognani (20):
cpu: Mark driver functions in ppc64 driver
cpu: Simplify NULL handling in ppc64 driver
cpu: Simplify ppc64ModelFromCPU()
cpu: Reorder functions in the ppc64 driver
cpu: Remove ISA information from CPU map XML
tests: Remove unused file
tests: Improve result handling in cpuTestGuestData()
cpu: Never skip CPU model name check in ppc64 driver
cpu: CPU model names have to match on ppc64
cpu: Use ppc64Compute() to implement ppc64DriverCompare()
tests: Temporarily disable ppc64 cpu tests
cpu: Align ppc64 CPU data with x86
cpu: Support multiple PVRs in the ppc64 driver
cpu: Simplify ppc64 part of CPU map XML
cpu: Parse and use PVR masks in the ppc64 driver
cpu: Add POWER8NVL information to CPU map XML
cpu: Implement backwards compatibility in the ppc64 driver
cpu: Forbid model fallback in the ppc64 driver
tests: Re-enable ppc64 cpu tests
tests: Add a bunch of cpu test case for ppc64
src/cpu/cpu.h | 2 +-
src/cpu/cpu_map.xml | 59 +--
src/cpu/cpu_ppc64.c | 451 +++++++++++++--------
src/cpu/cpu_ppc64_data.h | 12 +-
tests/cputest.c | 55 ++-
tests/cputestdata/ppc64-baseline-1-result.xml | 3 -
.../ppc64-baseline-incompatible-models.xml | 14 +
.../ppc64-baseline-incompatible-vendors.xml | 4 +-
tests/cputestdata/ppc64-baseline-legacy.xml | 14 +
.../ppc64-baseline-no-vendor-result.xml | 2 +-
tests/cputestdata/ppc64-baseline-no-vendor.xml | 2 +-
.../ppc64-baseline-same-model-result.xml | 3 +
tests/cputestdata/ppc64-baseline-same-model.xml | 14 +
tests/cputestdata/ppc64-exact.xml | 3 -
tests/cputestdata/ppc64-guest-exact.xml | 3 +
.../ppc64-guest-legacy-incompatible.xml | 3 +
tests/cputestdata/ppc64-guest-legacy-invalid.xml | 3 +
tests/cputestdata/ppc64-guest-legacy.xml | 3 +
tests/cputestdata/ppc64-guest-nofallback.xml | 3 +-
tests/cputestdata/ppc64-guest-strict.xml | 3 +
tests/cputestdata/ppc64-guest.xml | 3 +-
.../ppc64-host+guest,ppc_models-result.xml | 2 +-
... ppc64-host+guest-legacy,ppc_models-result.xml} | 2 +-
tests/cputestdata/ppc64-host-better.xml | 6 +
tests/cputestdata/ppc64-host-incomp-arch.xml | 6 +
tests/cputestdata/ppc64-host-no-vendor.xml | 5 +
tests/cputestdata/ppc64-host-worse.xml | 6 +
tests/cputestdata/ppc64-host.xml | 2 +-
tests/cputestdata/ppc64-strict.xml | 3 -
29 files changed, 444 insertions(+), 247 deletions(-)
delete mode 100644 tests/cputestdata/ppc64-baseline-1-result.xml
create mode 100644 tests/cputestdata/ppc64-baseline-incompatible-models.xml
create mode 100644 tests/cputestdata/ppc64-baseline-legacy.xml
create mode 100644 tests/cputestdata/ppc64-baseline-same-model-result.xml
create mode 100644 tests/cputestdata/ppc64-baseline-same-model.xml
delete mode 100644 tests/cputestdata/ppc64-exact.xml
create mode 100644 tests/cputestdata/ppc64-guest-exact.xml
create mode 100644 tests/cputestdata/ppc64-guest-legacy-incompatible.xml
create mode 100644 tests/cputestdata/ppc64-guest-legacy-invalid.xml
create mode 100644 tests/cputestdata/ppc64-guest-legacy.xml
create mode 100644 tests/cputestdata/ppc64-guest-strict.xml
rename tests/cputestdata/{ppc64-host+guest-nofallback,ppc_models,POWER7_v2.1-result.xml => ppc64-host+guest-legacy,ppc_models-result.xml} (64%)
create mode 100644 tests/cputestdata/ppc64-host-better.xml
create mode 100644 tests/cputestdata/ppc64-host-incomp-arch.xml
create mode 100644 tests/cputestdata/ppc64-host-no-vendor.xml
create mode 100644 tests/cputestdata/ppc64-host-worse.xml
delete mode 100644 tests/cputestdata/ppc64-strict.xml
--
2.4.3
9 years, 3 months
[libvirt] [PATCH] virDomainCoreDumpWithFormat: Mention enum for @dumpformat
by Michal Privoznik
So the API takes @dumpformat argument. This is what makes it special
when compared to virDomainCoreDump. The argument is there so that
users can choose the format of resulting core dump file. And to ease
them the choosing process we even have an enum with supported values
across all the hypervisors. But we don't mention the enum in the
function description anywhere. Fix it!
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
Pushed as trivial.
src/libvirt-domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 837933f..dc89bab 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -1281,7 +1281,7 @@ virDomainCoreDump(virDomainPtr domain, const char *to, unsigned int flags)
* virDomainCoreDumpWithFormat:
* @domain: a domain object
* @to: path for the core file
- * @dumpformat: format of domain memory's dump
+ * @dumpformat: format of domain memory's dump (one of virDomainCoreDumpFormat enum)
* @flags: bitwise-OR of virDomainCoreDumpFlags
*
* This method will dump the core of a domain on a given file for analysis.
--
2.4.6
9 years, 3 months
[libvirt] [PATCHv2] conf: more useful error message when pci function is out of range
by Laine Stump
If a pci address had a function number out of range, the error message
would be:
Insufficient specification for PCI address
which is logged by virDevicePCIAddressParseXML() after
virDevicePCIAddressIsValid returns a failure.
This patch enhances virDevicePCIAddressIsValid() to optionally report
the error itself (since it is the place that decides which part of the
address is "invalid"), and uses that feature when calling from
virDevicePCIAddressParseXML(), so that the error will be more useful,
e.g.:
Invalid PCI address function=0x8, must be <= 7
Previously, virDevicePCIAddressIsValid didn't check for the
theoretical limits of domain or bus, only for slot or function. While
adding log messages, we also correct that ommission. (The RNG for PCI
addresses already enforces this limit, which by the way means that we
can't add any negative tests for this - as far as I know our
domainschematest has no provisions for passing XML that is supposed to
fail).
Note that virDevicePCIAddressIsValid() can only check against the
absolute maximum attribute values for *any* possible PCI controller,
not for the actual maximums of the specific controller that this
device is attaching to; fortunately there is later more specific
validation for guest-side PCI addresses when building the set of
assigned PCI addresses. For host-side PCI addresses (e.g. for
<hostdev> and for network device pools), we rely on the error that
will be logged when it is found that the device doesn't actually
exist.
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1004596
---
Change from V1:
V1 simply removed the validation from virDevicePCIAddressParseXML() in
favor of allowing things later in the parse process to figure out the
out-of-bounds conditions, but jtomko pointed out that there are other
uses of virDevicePCIAddressParseXML() aside from the guest-side PCI
addresses of devices, and that the other uses relied on the one
validation check in virDevicePCIAddressParseXML() to make sure the
address was sensible. So instead of simply removing the check, I had
to make it smarter about what it logged. In the process, I added
checks for max domain and bus.
src/conf/device_conf.c | 52 +++++++++++++++++++++++++++++++++++++++++---------
src/conf/device_conf.h | 5 +++--
src/conf/domain_conf.c | 2 +-
3 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
index e7b7957..4e15d38 100644
--- a/src/conf/device_conf.c
+++ b/src/conf/device_conf.c
@@ -1,7 +1,7 @@
/*
* device_conf.c: device XML handling
*
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -55,12 +55,49 @@ VIR_ENUM_IMPL(virNetDevFeature,
"rdma",
"txudptnl")
-int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)
+int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr,
+ bool report)
{
- /* PCI bus has 32 slots and 8 functions per slot */
- if (addr->slot >= 32 || addr->function >= 8)
+ if (addr->domain > 0xFFFF) {
+ if (report)
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid PCI address domain='0x%x', "
+ "must be <= 0xFFFF"),
+ addr->domain);
+ return 0;
+ }
+ if (addr->bus > 0xFF) {
+ if (report)
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid PCI address bus='0x%x', "
+ "must be <= 0xFF"),
+ addr->bus);
return 0;
- return addr->domain || addr->bus || addr->slot;
+ }
+ if (addr->slot > 0x1F) {
+ if (report)
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid PCI address slot='0x%x', "
+ "must be <= 0x1F"),
+ addr->slot);
+ return 0;
+ }
+ if (addr->function > 7) {
+ if (report)
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid PCI address function=0x%x, "
+ "must be <= 7"),
+ addr->function);
+ return 0;
+ }
+ if (!(addr->domain || addr->bus || addr->slot)) {
+ if (report)
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid PCI address 0000:00:00, at least "
+ "one of domain, bus, or slot must be > 0"));
+ return 0;
+ }
+ return 1;
}
@@ -115,11 +152,8 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
goto cleanup;
}
- if (!virDevicePCIAddressIsValid(addr)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Insufficient specification for PCI address"));
+ if (!virDevicePCIAddressIsValid(addr, true))
goto cleanup;
- }
ret = 0;
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index 40a2b3d..85ce40f 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -1,7 +1,7 @@
/*
* device_conf.h: device XML handling entry points
*
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2012, 2014-2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -81,7 +81,8 @@ typedef enum {
VIR_ENUM_DECL(virNetDevFeature)
-int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr);
+int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr,
+ bool report);
int virDevicePCIAddressParseXML(xmlNodePtr node,
virDevicePCIAddressPtr addr);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8a89b9a..5142201 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3133,7 +3133,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
switch (info->type) {
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
- return virDevicePCIAddressIsValid(&info->addr.pci);
+ return virDevicePCIAddressIsValid(&info->addr.pci, false);
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
return 1;
--
2.1.0
9 years, 3 months
[libvirt] [PATCH] Inherit namespace feature
by ik.nitk
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>
---
docs/drvlxc.html.in | 18 +++
docs/schemas/domaincommon.rng | 42 ++++++
src/Makefile.am | 4 +-
src/lxc/lxc_conf.c | 2 +-
src/lxc/lxc_conf.h | 15 +++
src/lxc/lxc_container.c | 236 +++++++++++++++++++++++++++++++++-
src/lxc/lxc_domain.c | 164 ++++++++++++++++++++++-
src/lxc/lxc_domain.h | 1 +
tests/lxcxml2xmldata/lxc-sharenet.xml | 33 +++++
tests/lxcxml2xmltest.c | 1 +
10 files changed, 507 insertions(+), 9 deletions(-)
create mode 100644 tests/lxcxml2xmldata/lxc-sharenet.xml
diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in
index a094bd9..d14d4c7 100644
--- a/docs/drvlxc.html.in
+++ b/docs/drvlxc.html.in
@@ -590,6 +590,24 @@ 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.
+</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 1120003..803b327 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>
@@ -5012,6 +5015,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/src/Makefile.am b/src/Makefile.am
index be63e26..ef96a5a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1319,7 +1319,7 @@ 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) libvirt-lxc.la $(FUSE_LIBS)
if WITH_BLKID
libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS)
libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS)
@@ -2709,6 +2709,8 @@ libvirt_lxc_LDADD = \
libvirt-net-rpc.la \
libvirt_security_manager.la \
libvirt_conf.la \
+ libvirt.la \
+ libvirt-lxc.la \
libvirt_util.la \
../gnulib/lib/libgnu.la
if WITH_DTRACE_PROBES
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index c393cb5..96a0f47 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_conf.h b/src/lxc/lxc_conf.h
index 8340b1f..72b1d44 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -67,6 +67,21 @@ struct _virLXCDriverConfig {
bool securityRequireConfined;
};
+
+typedef enum {
+ VIR_DOMAIN_NAMESPACE_SHARENET = 0,
+ VIR_DOMAIN_NAMESPACE_SHAREIPC,
+ VIR_DOMAIN_NAMESPACE_SHAREUTS,
+ VIR_DOMAIN_NAMESPACE_LAST,
+} virDomainNamespace;
+
+typedef struct _lxcDomainDef lxcDomainDef;
+typedef lxcDomainDef *lxcDomainDefPtr;
+struct _lxcDomainDef {
+ char *ns_type[VIR_DOMAIN_NAMESPACE_LAST];
+ char *ns_val[VIR_DOMAIN_NAMESPACE_LAST];
+};
+
struct _virLXCDriver {
virMutex lock;
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 11e9514..d8362ab 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>
@@ -2321,6 +2321,181 @@ virArch lxcContainerGetAlt32bitArch(virArch arch)
return VIR_ARCH_NONE;
}
+struct ns_info {
+ const char *proc_name;
+ int clone_flag;
+}ns_info_local[VIR_DOMAIN_NAMESPACE_LAST] = {
+ [VIR_DOMAIN_NAMESPACE_SHARENET] = {"net", CLONE_NEWNET},
+ [VIR_DOMAIN_NAMESPACE_SHAREIPC] = {"ipc", CLONE_NEWIPC},
+ [VIR_DOMAIN_NAMESPACE_SHAREUTS] = {"uts", CLONE_NEWUTS}
+};
+
+static int lxcOpen_ns(lxcDomainDefPtr lxcDef, int ns_fd[VIR_DOMAIN_NAMESPACE_LAST])
+{
+ int i, n, rc = 0;
+ virDomainPtr dom = NULL;
+ virConnectPtr conn = NULL;
+ pid_t pid;
+ int nfdlist;
+ int *fdlist;
+ char *path = NULL;
+ char *eptr;
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++)
+ ns_fd[i] = -1;
+
+ if (STREQ_NULLABLE("netns", lxcDef->ns_type[VIR_DOMAIN_NAMESPACE_SHARENET])) {
+ if (virAsprintf(&path, "/var/run/netns/%s", lxcDef->ns_val[VIR_DOMAIN_NAMESPACE_SHARENET]) < 0)
+ return -1;
+ ns_fd[VIR_DOMAIN_NAMESPACE_SHARENET] = open(path, O_RDONLY);
+ VIR_FREE(path);
+ if (ns_fd[VIR_DOMAIN_NAMESPACE_SHARENET] < 0) {
+ virReportSystemError(errno,
+ _("failed to open netns %s"), lxcDef->ns_val[VIR_DOMAIN_NAMESPACE_SHARENET]);
+ return -1;
+ }
+ }
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++) {
+ /* If not yet intialized by above: netns*/
+ if (lxcDef->ns_type[i] && ns_fd[i] == -1) {
+ pid = strtol(lxcDef->ns_val[i], &eptr, 10);
+ if (*eptr != '\0' || pid < 1) {
+ /* check if the domain is running, then set the namespaces
+ * to that container
+ */
+ const char *ns[] = { "user", "ipc", "uts", "net", "pid", "mnt" };
+ conn = virConnectOpen("lxc:///");
+ if (!conn) {
+ virReportError(virGetLastError()->code,
+ _("unable to get connect to lxc %s"), lxcDef->ns_val[i]);
+ rc = -1;
+ goto cleanup;
+ }
+ dom = virDomainLookupByName(conn, lxcDef->ns_val[i]);
+ if (!dom) {
+ virReportError(virGetLastError()->code,
+ _("Unable to lookup peer containeri %s"),
+ lxcDef->ns_val[i]);
+ rc = -1;
+ goto cleanup;
+ }
+ if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0) {
+ virReportError(virGetLastError()->code,
+ _("Unable to open %s"), lxcDef->ns_val[i]);
+ rc = -1;
+ goto cleanup;
+ }
+ for (n = 0; n < ARRAY_CARDINALITY(ns); n++) {
+ if (STREQ(ns[n], ns_info_local[i].proc_name)) {
+ ns_fd[i] = fdlist[n];
+ } else {
+ if (VIR_CLOSE(fdlist[n]) < 0)
+ VIR_ERROR(_("failed to close fd. ignoring.."));
+ }
+ }
+ if (nfdlist > 0)
+ VIR_FREE(fdlist);
+ } else {
+ if (virAsprintf(&path, "/proc/%d/ns/%s", pid, ns_info_local[i].proc_name) < 0)
+ return -1;
+ ns_fd[i] = open(path, O_RDONLY);
+ VIR_FREE(path);
+ if (ns_fd[i] < 0) {
+ virReportSystemError(errno,
+ _("failed to open ns %s"), lxcDef->ns_val[i]);
+ return -1;
+ }
+ }
+ }
+ }
+ cleanup:
+ if (dom)
+ virDomainFree(dom);
+ if (conn)
+ virConnectClose(conn);
+ return rc;
+}
+
+
+static void lxcClose_ns(int ns_fd[VIR_DOMAIN_NAMESPACE_LAST])
+{
+ int i;
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++) {
+ if (ns_fd[i] > -1) {
+ if (VIR_CLOSE(ns_fd[i]) < 0)
+ virReportSystemError(errno, "%s", _("failed to close file"));
+ ns_fd[i] = -1;
+ }
+ }
+}
+
+
+/**
+ * lxcPreserve_ns:
+ * @ns_fd: array to store current namespace
+ * @clone_flags: namespaces that need to be preserved
+ */
+static int lxcPreserve_ns(int ns_fd[VIR_DOMAIN_NAMESPACE_LAST], int clone_flags)
+{
+ int i, saved_errno;
+ char *path = NULL;
+
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++)
+ ns_fd[i] = -1;
+
+ if (!virFileExists("/proc/self/ns")) {
+ virReportSystemError(errno, "%s",
+ _("Kernel does not support attach; preserve_ns ignored"));
+ return -1;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++) {
+ if ((clone_flags & ns_info_local[i].clone_flag) == 0)
+ continue;
+ if (virAsprintf(&path, "/proc/self/ns/%s",
+ ns_info_local[i].proc_name) < 0)
+ goto error;
+ ns_fd[i] = open(path, O_RDONLY | O_CLOEXEC);
+ if (ns_fd[i] < 0)
+ goto error;
+ VIR_FREE(path);
+ }
+ return 0;
+ error:
+ saved_errno = errno;
+ lxcClose_ns(ns_fd);
+ errno = saved_errno;
+ virReportSystemError(errno, _("lxcPreserve_ns failed for '%s'"), path);
+ VIR_FREE(path);
+ return -1;
+}
+
+/**
+ * lxcAttach_ns:
+ * @ns_fd: array of namespaces to attach
+ */
+static int lxcAttach_ns(const int ns_fd[VIR_DOMAIN_NAMESPACE_LAST])
+{
+ int i;
+
+ for (i = 0; i < VIR_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'")
+ , ns_info_local[i].proc_name);
+ return -1;
+ }
+ }
+ return 0;
+}
+
/**
* lxcContainerStart:
@@ -2346,9 +2521,13 @@ int lxcContainerStart(virDomainDefPtr def,
char **ttyPaths)
{
pid_t pid;
- int cflags;
+ int cflags, i;
int stacksize = getpagesize() * 4;
char *stack, *stacktop;
+ int saved_ns_fd[VIR_DOMAIN_NAMESPACE_LAST];
+ int ns_inherit_fd[VIR_DOMAIN_NAMESPACE_LAST];
+ int preserve_mask = 0;
+ lxcDomainDefPtr lxcDef;
lxc_child_argv_t args = {
.config = def,
.securityDriver = securityDriver,
@@ -2368,7 +2547,12 @@ int lxcContainerStart(virDomainDefPtr def,
stacktop = stack + stacksize;
- cflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD;
+ lxcDef = def->namespaceData;
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++)
+ if (lxcDef && lxcDef->ns_type[i])
+ preserve_mask |= ns_info_local[i].clone_flag;
+
+ cflags = CLONE_NEWPID|CLONE_NEWNS|SIGCHLD;
if (userns_required(def)) {
if (userns_supported()) {
@@ -2381,10 +2565,43 @@ int lxcContainerStart(virDomainDefPtr def,
return -1;
}
}
+ if (!lxcDef || !lxcDef->ns_type[VIR_DOMAIN_NAMESPACE_SHARENET]) {
+ if (lxcNeedNetworkNamespace(def)) {
+ VIR_DEBUG("Enable network namespaces");
+ cflags |= CLONE_NEWNET;
+ }
+ } else {
+ VIR_DEBUG("Inheriting a net namespace");
+ }
+
+ if (!lxcDef || !lxcDef->ns_type[VIR_DOMAIN_NAMESPACE_SHAREIPC]) {
+ cflags |= CLONE_NEWIPC;
+ } else {
+ VIR_DEBUG("Inheriting an IPC namespace");
+ }
+
+ if (!lxcDef || !lxcDef->ns_type[VIR_DOMAIN_NAMESPACE_SHAREUTS]) {
+ cflags |= CLONE_NEWUTS;
+ } else {
+ VIR_DEBUG("Inheriting a UTS namespace");
+ }
+
+ if (lxcDef && lxcPreserve_ns(saved_ns_fd, preserve_mask) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("failed to preserve the namespace"));
+ return -1;
+ }
- if (lxcNeedNetworkNamespace(def)) {
- VIR_DEBUG("Enable network namespaces");
- cflags |= CLONE_NEWNET;
+ if (lxcDef && lxcOpen_ns(lxcDef, ns_inherit_fd)) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("failed to open the namespace"));
+ return -1;
+ }
+
+ if (lxcDef && lxcAttach_ns(ns_inherit_fd) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("failed to attach the namespace"));
+ return -1;
}
VIR_DEBUG("Cloning container init process");
@@ -2397,7 +2614,14 @@ int lxcContainerStart(virDomainDefPtr def,
_("Failed to run clone container"));
return -1;
}
+ if (lxcDef && lxcAttach_ns(saved_ns_fd)) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("failed to restore saved namespaces"));
+ }
+ /* clean up */
+ if (lxcDef)
+ lxcClose_ns(ns_inherit_fd);
return pid;
}
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 70606f3..5e63969 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -26,8 +26,14 @@
#include "viralloc.h"
#include "virlog.h"
#include "virerror.h"
+#include <fcntl.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 +47,163 @@ static void *virLXCDomainObjPrivateAlloc(void)
return priv;
}
+VIR_ENUM_DECL(virDomainNamespace)
+VIR_ENUM_IMPL(virDomainNamespace, VIR_DOMAIN_NAMESPACE_LAST,
+ N_("sharenet"),
+ N_("shareipc"),
+ N_("shareuts"))
+
+static void
+lxcDomainDefNamespaceFree(void *nsdata)
+{
+ int j;
+ lxcDomainDefPtr lxcDef = nsdata;
+ for (j = 0; j < VIR_DOMAIN_NAMESPACE_LAST; j++) {
+ VIR_FREE(lxcDef->ns_type[j]);
+ VIR_FREE(lxcDef->ns_val[j]);
+ }
+ 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;
+ /* Init ns_herit_fd for namespaces */
+ for (i = 0; i < VIR_DOMAIN_NAMESPACE_LAST; i++) {
+ lxcDef->ns_type[i] = NULL;
+ lxcDef->ns_val[i] = NULL;
+ }
+
+ node = ctxt->node;
+ if ((n = virXPathNodeSet("./lxc:namespace/*", ctxt, &nodes)) < 0)
+ goto error;
+ uses_lxc_ns |= n > 0;
+
+ for (i = 0; i < n; i++) {
+ feature =
+ virDomainNamespaceTypeFromString((const char *) nodes[i]->name);
+ if (feature < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported Namespace feature: %s"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ ctxt->node = nodes[i];
+
+ switch ((virDomainNamespace) feature) {
+ case VIR_DOMAIN_NAMESPACE_SHARENET:
+ case VIR_DOMAIN_NAMESPACE_SHAREIPC:
+ case VIR_DOMAIN_NAMESPACE_SHAREUTS:
+ {
+ tmp = virXMLPropString(nodes[i], "type");
+ if (tmp == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No lxc environment type specified"));
+ goto error;
+ }
+ /* save the tmp so that its needed while writing to xml */
+ lxcDef->ns_type[feature] = tmp;
+ tmp = virXMLPropString(nodes[i], "value");
+ if (tmp == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No lxc environment type specified"));
+ goto error;
+ }
+ lxcDef->ns_val[feature] = tmp;
+ }
+ break;
+ case VIR_DOMAIN_NAMESPACE_LAST:
+ break;
+ }
+ }
+ 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 j;
+
+ if (!lxcDef)
+ return 0;
+
+ virBufferAddLit(buf, "<lxc:namespace>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (j = 0; j < VIR_DOMAIN_NAMESPACE_LAST; j++) {
+ switch ((virDomainNamespace) j) {
+ case VIR_DOMAIN_NAMESPACE_SHAREIPC:
+ case VIR_DOMAIN_NAMESPACE_SHAREUTS:
+ case VIR_DOMAIN_NAMESPACE_SHARENET:
+ {
+ if (lxcDef->ns_type[j]) {
+ virBufferAsprintf(buf, "<lxc:%s type='%s' value='%s'/>\n",
+ virDomainNamespaceTypeToString(j),
+ lxcDef->ns_type[j],
+ lxcDef->ns_val[j]);
+ }
+ }
+ break;
+ case VIR_DOMAIN_NAMESPACE_LAST:
+ break;
+ }
+ }
+
+ 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;
@@ -77,7 +240,6 @@ virLXCDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
} else {
priv->initpid = thepid;
}
-
return 0;
}
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 751aece..25df999 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -41,6 +41,7 @@ struct _virLXCDomainObjPrivate {
virCgroupPtr cgroup;
};
+extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
diff --git a/tests/lxcxml2xmldata/lxc-sharenet.xml b/tests/lxcxml2xmldata/lxc-sharenet.xml
new file mode 100644
index 0000000..a2b8d1b
--- /dev/null
+++ b/tests/lxcxml2xmldata/lxc-sharenet.xml
@@ -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>
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);
--
1.9.1
9 years, 3 months
[libvirt] [PATCH 00/18] cpu: Fix and improve the ppc64 driver
by Andrea Bolognani
This series depends on
[PATCH 0/4] cpu: Rename {powerpc,ppc} => ppc64
which has been already ACKed[1] and is pending upload.
Patches 1-11 are fixes and cleanups that don't introduce
any new feature in the driver and just lay the groundwork
for the second part of the series.
Patches 12-18 rework the driver and add some test cases
to cover both existing an new features.
Cheers.
[1] https://www.redhat.com/archives/libvir-list/2015-July/msg01170.html
Andrea Bolognani (18):
cpu: Mark driver functions in ppc64 driver
cpu: Simplify NULL handling in ppc64 driver
cpu: Add NULL check in ppc64ModelCopy()
cpu: Use a different name for the copy in ppc64ModelFromCPU()
cpu: Reorder functions in the ppc64 driver
cpu: Remove ISA information from CPU map XML
tests: Remove unused file
tests: Known failing tests should never succeed
cpu: Don't skip CPU model name check in ppc64 driver
cpu: CPU model names have to match on ppc64
cpu: Use ppc64Compute() to implement ppc64DriverCompare()
cpu: Align ppc64 CPU data with x86
cpu: Support multiple PVRs in the ppc64 driver
cpu: Simplify ppc64 part of CPU map XML
cpu: Add PVR mask to CPU map XML for ppc64 models
cpu: Parse and use PVR masks in the ppc64 driver
cpu: Add POWER8 NVL information to CPU map XML
tests: Add a bunch of ppc64 cases to the cpu test
src/cpu/cpu.h | 2 +-
src/cpu/cpu_map.xml | 59 +--
src/cpu/cpu_ppc64.c | 432 +++++++++++++--------
src/cpu/cpu_ppc64_data.h | 12 +-
tests/cputest.c | 34 +-
tests/cputestdata/ppc64-baseline-1-result.xml | 3 -
.../ppc64-baseline-incompatible-models.xml | 14 +
.../ppc64-baseline-incompatible-vendors.xml | 4 +-
.../ppc64-baseline-no-vendor-result.xml | 2 +-
tests/cputestdata/ppc64-baseline-no-vendor.xml | 2 +-
.../ppc64-baseline-same-model-result.xml | 3 +
tests/cputestdata/ppc64-baseline-same-model.xml | 14 +
tests/cputestdata/ppc64-exact.xml | 2 +-
tests/cputestdata/ppc64-guest-nofallback.xml | 2 +-
tests/cputestdata/ppc64-guest.xml | 2 +-
.../ppc64-host+guest,ppc_models-result.xml | 2 +-
...st-nofallback,ppc_models,POWER7_v2.1-result.xml | 5 -
tests/cputestdata/ppc64-host-better.xml | 6 +
tests/cputestdata/ppc64-host-incomp-arch.xml | 6 +
tests/cputestdata/ppc64-host-no-vendor.xml | 5 +
tests/cputestdata/ppc64-host-worse.xml | 6 +
tests/cputestdata/ppc64-host.xml | 2 +-
tests/cputestdata/ppc64-strict.xml | 4 +-
23 files changed, 385 insertions(+), 238 deletions(-)
delete mode 100644 tests/cputestdata/ppc64-baseline-1-result.xml
create mode 100644 tests/cputestdata/ppc64-baseline-incompatible-models.xml
create mode 100644 tests/cputestdata/ppc64-baseline-same-model-result.xml
create mode 100644 tests/cputestdata/ppc64-baseline-same-model.xml
delete mode 100644 tests/cputestdata/ppc64-host+guest-nofallback,ppc_models,POWER7_v2.1-result.xml
create mode 100644 tests/cputestdata/ppc64-host-better.xml
create mode 100644 tests/cputestdata/ppc64-host-incomp-arch.xml
create mode 100644 tests/cputestdata/ppc64-host-no-vendor.xml
create mode 100644 tests/cputestdata/ppc64-host-worse.xml
--
2.4.3
9 years, 3 months
[libvirt] [PATCH] virNetDevBandwidthParseRate: Reject negative values
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1022292
The following XML really does not make any sense:
<inbound average="-1" burst="-2" peak="-3" floor="-4"/>
There can't be a negative packet rate. Well, so far we haven't
assigned any meaning to it. So reject it unless users harm themselves,
because otherwise we turn the negative numbers into really big values.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/netdev_bandwidth_conf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c
index fdd5b7f..8824332 100644
--- a/src/conf/netdev_bandwidth_conf.c
+++ b/src/conf/netdev_bandwidth_conf.c
@@ -50,7 +50,7 @@ virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate)
floor = virXMLPropString(node, "floor");
if (average) {
- if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) {
+ if (virStrToLong_ullp(average, NULL, 10, &rate->average) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not convert bandwidth average value '%s'"),
average);
@@ -68,21 +68,21 @@ virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate)
goto cleanup;
}
- if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) {
+ if (peak && virStrToLong_ullp(peak, NULL, 10, &rate->peak) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not convert bandwidth peak value '%s'"),
peak);
goto cleanup;
}
- if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0) {
+ if (burst && virStrToLong_ullp(burst, NULL, 10, &rate->burst) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not convert bandwidth burst value '%s'"),
burst);
goto cleanup;
}
- if (floor && virStrToLong_ull(floor, NULL, 10, &rate->floor) < 0) {
+ if (floor && virStrToLong_ullp(floor, NULL, 10, &rate->floor) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not convert bandwidth floor value '%s'"),
floor);
--
2.4.6
9 years, 3 months
[libvirt] [PATCH 1/2] numa_conf: Introduce virDomainNumaGetMaxCPUID
by Michal Privoznik
This function should return the greatest CPU number set in
/domain/cpu/numa/cell/@cpus. The idea is that we should compare
the returned value against /domain/vcpu value. Yes, there exist
users who think the following is a good idea:
<vcpu placement='static'>4</vcpu>
<cpu mode='host-model'>
<model fallback='allow'/>
<numa>
<cell id='0' cpus='0-1' memory='1048576' unit='KiB'/>
<cell id='1' cpus='9-10' memory='2097152' unit='KiB'/>
</numa>
</cpu>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/numa_conf.c | 17 +++++++++++++++++
src/conf/numa_conf.h | 3 +++
src/libvirt_private.syms | 1 +
3 files changed, 21 insertions(+)
diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
index 57da215..5c123b9 100644
--- a/src/conf/numa_conf.c
+++ b/src/conf/numa_conf.c
@@ -847,6 +847,23 @@ virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa)
return ret;
}
+unsigned int
+virDomainNumaGetMaxCPUID(virDomainNumaPtr numa)
+{
+ size_t i;
+ unsigned int ret = 0;
+
+ for (i = 0; i < numa->nmem_nodes; i++) {
+ int bit;
+
+ bit = virBitmapLastSetBit(virDomainNumaGetNodeCpumask(numa, i));
+ if (bit > ret)
+ ret = bit;
+ }
+
+ return ret;
+}
+
virDomainNumaPtr
virDomainNumaNew(void)
diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
index 6739065..90deacb 100644
--- a/src/conf/numa_conf.h
+++ b/src/conf/numa_conf.h
@@ -99,6 +99,9 @@ unsigned long long virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
unsigned long long virDomainNumaGetMemorySize(virDomainNumaPtr numa)
ATTRIBUTE_NONNULL(1);
+unsigned int
+virDomainNumaGetMaxCPUID(virDomainNumaPtr numa);
+
/*
* Formatters
*/
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0517c24..0b67bfe 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -684,6 +684,7 @@ virDomainNumaGetNodeCount;
virDomainNumaGetNodeCpumask;
virDomainNumaGetNodeMemoryAccessMode;
virDomainNumaGetNodeMemorySize;
+virDomainNumaGetMaxCPUID;
virDomainNumaNew;
virDomainNumaSetNodeMemorySize;
virDomainNumatuneFormatNodeset;
--
2.4.6
9 years, 3 months
[libvirt] [PATCH 0/3] qemu: Return true pinning info
by Martin Kletzander
First two patches just prepare the ground for the third one that
explains what needs to be fixed and ho it's done.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1162947
Martin Kletzander (3):
conf: Pass private data to Parse function of XML options
qemu: Keep numad hint after reboot
qemu: Return true pining info when using numad
src/conf/domain_conf.c | 2 +-
src/conf/domain_conf.h | 17 +++++++++--------
src/libxl/libxl_domain.c | 3 ++-
src/lxc/lxc_domain.c | 3 ++-
src/qemu/qemu_domain.c | 33 ++++++++++++++++++++++++++++++++-
src/qemu/qemu_driver.c | 11 +++++++++++
6 files changed, 57 insertions(+), 12 deletions(-)
--
2.4.6
9 years, 3 months
[libvirt] [PATCH] qemu: Fix reporting of physical capacity for block devices
by Peter Krempa
Qemu reports physical size 0 for block devices. As 15fa84acbb55ebfee6a4
changed the behavior of qemuDomainGetBlockInfo to just query the monitor
this created a regression since we didn't report the size correctly any
more.
This patch adds code to refresh the physical size of a block device by
opening it and seeking to the end and uses it both in
qemuDomainGetBlockInfo and also in qemuDomainGetStatsOneBlock that was
broken since it was introduced in this respect.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1250982
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 18 ++++++++++++++++--
src/util/virstoragefile.c | 39 +++++++++++++++++++++++++++++++++++++++
src/util/virstoragefile.h | 2 ++
4 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0517c24..5d320b7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2156,6 +2156,7 @@ virStorageSourceParseRBDColonString;
virStorageSourcePoolDefFree;
virStorageSourcePoolModeTypeFromString;
virStorageSourcePoolModeTypeToString;
+virStorageSourceUpdateBlockPhysicalSize;
virStorageTypeFromString;
virStorageTypeToString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7a984a8..6998e12 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11827,8 +11827,16 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
info->allocation = entry->wr_highest_offset;
}
+ if (entry->physical) {
+ info->physical = entry->physical;
+ } else {
+ if (virStorageSourceUpdateBlockPhysicalSize(disk->src, true) < 0)
+ goto endjob;
+
+ info->physical = disk->src->physical;
+ }
+
info->capacity = entry->capacity;
- info->physical = entry->physical;
ret = 0;
@@ -19274,9 +19282,15 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
if (entry->capacity)
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
"capacity", entry->capacity);
- if (entry->physical)
+ if (entry->physical) {
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
"physical", entry->physical);
+ } else {
+ if (virStorageSourceUpdateBlockPhysicalSize(src, false) == 0) {
+ QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
+ "physical", src->physical);
+ }
+ }
ret = 0;
cleanup:
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 6c3017c..2aa1d90 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2587,6 +2587,45 @@ virStorageSourceNewFromBacking(virStorageSourcePtr parent)
}
+/**
+ * @src: disk source definiton structure
+ * @report: report libvirt errors if set to true
+ *
+ * Updates src->physical for block devices since qemu doesn't report the current
+ * size correctly for them. Returns 0 on success, -1 on error.
+ */
+int
+virStorageSourceUpdateBlockPhysicalSize(virStorageSourcePtr src,
+ bool report)
+{
+ int fd = -1;
+ off_t end;
+ int ret = -1;
+
+ if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_BLOCK)
+ return 0;
+
+ if ((fd = open(src->path, O_RDONLY)) < 0) {
+ if (report)
+ virReportSystemError(errno, _("failed to open block device '%s'"),
+ src->path);
+ return -1;
+ }
+
+ if ((end = lseek(fd, 0, SEEK_END)) == (off_t) -1) {
+ if (report)
+ virReportSystemError(errno,
+ _("failed to seek to end of '%s'"), src->path);
+ } else {
+ src->physical = end;
+ ret = 0;
+ }
+
+ VIR_FORCE_CLOSE(fd);
+ return ret;
+}
+
+
static char *
virStorageFileCanonicalizeFormatPath(char **components,
size_t ncomponents,
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index aa17a00..b98fe25 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -362,6 +362,8 @@ bool virStorageSourceIsLocalStorage(virStorageSourcePtr src);
bool virStorageSourceIsEmpty(virStorageSourcePtr src);
void virStorageSourceFree(virStorageSourcePtr def);
void virStorageSourceBackingStoreClear(virStorageSourcePtr def);
+int virStorageSourceUpdateBlockPhysicalSize(virStorageSourcePtr src,
+ bool report);
virStorageSourcePtr virStorageSourceNewFromBacking(virStorageSourcePtr parent);
virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
bool backingChain)
--
2.4.5
9 years, 3 months
[libvirt] unsupported configuration: unknown video model 'virtio' - virtio-vga
by poma
$ qemu-system-x86_64 ... -device virtio-vga
# lspci -d 1af4:1050 -knn
00:03.0 VGA compatible controller [0300]: Red Hat, Inc Device [1af4:1050] (rev 01)
Subsystem: Red Hat, Inc Device [1af4:1100]
Kernel driver in use: virtio-pci
Kernel modules: virtio_pci
# dmesg | grep virtio
[ 1.727390] [drm] pci: virtio-vga detected
[ 1.729315] [drm] virtio vbuffers: 80 bufs, 192B each, 15kB total.
[ 2.023845] virtio_gpu virtio0: fb0: virtiodrmfb frame buffer device
[ 2.023846] virtio_gpu virtio0: registered panic notifier
[ 2.043135] [drm] Initialized virtio_gpu 0.0.1 0 on minor 0
# journalctl -b -u libvirtd.service -o cat
Starting Virtualization daemon...
Started Virtualization daemon.
libvirt version: 1.2.17, package: 1.fc23 (Fedora Project, 2015-07-14-18:18:48, buildvm-03.phx2.fedoraproject.org)
unsupported configuration: unknown video model 'virtio'
Soonish?
9 years, 3 months