[libvirt] [PATCH v2 0/2] add support for kvm-hint-dedicated performance hint
by Menno Lageman
v2 of:
https://www.redhat.com/archives/libvir-list/2019-August/msg00363.html
diff to v1:
- reword description in documentation
- move check for valid domain config to qemuDomainDefValidate
Wim ten Have (2):
qemu: support for kvm-hint-dedicated performance hint
tests: add tests for kvm-hint-dedicated feature
docs/formatdomain.html.in | 7 +++++++
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 4 ++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 5 +++++
src/qemu/qemu_domain.c | 11 ++++++++++-
tests/qemuxml2argvdata/kvm-features-off.xml | 1 +
tests/qemuxml2argvdata/kvm-features.args | 4 ++--
tests/qemuxml2argvdata/kvm-features.xml | 4 +++-
tests/qemuxml2xmloutdata/kvm-features-off.xml | 1 +
tests/qemuxml2xmloutdata/kvm-features.xml | 4 +++-
11 files changed, 42 insertions(+), 5 deletions(-)
--
2.21.0
5 years, 4 months
[libvirt] [PATCH 0/2] add support for kvm-hint-dedicated performance hint
by Menno Lageman
QEMU version 2.12.1 introduced a performance feature under commit
be7773268d98 ("target-i386: add KVM_HINTS_DEDICATED performance hint")
This patch adds a new KVM feature 'hint-dedicated' to set this performance
hint for KVM guests.
Wim ten Have (2):
qemu: support for kvm-hint-dedicated performance hint
tests: add tests for kvm-hint-dedicated feature
docs/formatdomain.html.in | 7 +++++++
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 4 ++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 13 +++++++++++++
tests/qemuxml2argvdata/kvm-features-off.xml | 1 +
tests/qemuxml2argvdata/kvm-features.args | 4 ++--
tests/qemuxml2argvdata/kvm-features.xml | 4 +++-
tests/qemuxml2xmloutdata/kvm-features-off.xml | 1 +
tests/qemuxml2xmloutdata/kvm-features.xml | 4 +++-
10 files changed, 40 insertions(+), 4 deletions(-)
--
2.21.0
5 years, 4 months
[libvirt] [PATCH] util: allow tap-based guest interfaces to have MAC address prefix 0xFE
by Laine Stump
Back in July 2010, commit 6ea90b84 (meant to resolve
https://bugzilla.redhat.com/571991 ) added code to set the MAC address
of any tap device to the associated guest interface's MAC, but with
the first byte replaced with 0xFE. This was done in order to assure
that
1) the tap MAC and guest interface MAC were different (otherwise L2
forwarding through the tap would not work, and the kernel would
repeatedly issue a warning stating as much).
2) any bridge device that had one of these taps attached would *not*
take on the MAC of the tap (leading to network instability as
guests started and stopped)
A couple years later, https://bugzilla.redhat.com/798467 was filed,
complaining that a user could configure a tap-based guest interface to
have a MAC address that itself had a first byte of 0xFE, silently
(other than the kernel warning messages) resulting in a non-working
configuration. This was fixed by commit 5d571045, which logged an
error and failed the guest start / interface attach if the MAC's first
byte was 0xFE.
Although this restriction only reduces the potential pool of MAC
addresses from 2^46 (last two bits of byte 1 must be set to 10) by
2^32 (still 4 orders of magnitude larger than the entire IPv4 address
space), it also means that management software that autogenerates MAC
addresses must have special code to avoid an 0xFE prefix. Now after 7
years, someone has noticed this restriction and requested that we
remove it.
So instead of failing when 0xFE is found as the first byte, this patch
removes the restriction by just replacing the first byte in the tap
device MAC with 0xFA if the first byte in the guest interface is
0xFE. 0xFA is the next-highest value that still has 10 as the lowest
two bits, and still
2) meets the requirement of "tap MAC must be different from guest
interface MAC", and
3) is high enough that there should never be an issue of the attached
bridge device taking on the MAC of the tap.
The result is that *any* MAC can be chosen by management software
(although it would still not work correctly if a multicast MAC (lowest
bit of first byte set to 1) was chosen), but that's a different
issue).
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
Yes, I find it slightly problematic that the same setting is in two
different places in the code, but 1) that is pre-existing, and 2) if I
moved the MAC address setting down one level into virNetDevTapCreate(),
the code would *still* need to be duplicated, since there are two
different implementations of virNetDevTapCreate(). If anyone is
bothered by this, then I can resubmit with an extra patch to add a new
virNetDevTapCreate() that just calls a platform-specific
virNetDevTapCreateInternal(), then sets the tap mac address. Only by
request though :-).
src/qemu/qemu_interface.c | 11 ++++++++++-
src/util/virnetdevtap.c | 26 ++++++++++++--------------
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c8effa68f4..72ed51cb1f 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -444,8 +444,17 @@ qemuInterfaceEthernetConnect(virDomainDefPtr def,
}
virDomainAuditNetDevice(def, net, tunpath, true);
+
+ /* The tap device's MAC address cannot match the MAC address
+ * used by the guest. This results in "received packet on
+ * vnetX with own address as source address" error logs from
+ * the kernel.
+ */
virMacAddrSet(&tapmac, &net->mac);
- tapmac.addr[0] = 0xFE;
+ if (tapmac.addr[0] == 0xFE)
+ tapmac.addr[0] = 0xFA;
+ else
+ tapmac.addr[0] = 0xFE;
if (virNetDevSetMAC(net->ifname, &tapmac) < 0)
goto cleanup;
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index b65c26bee1..4548b51b5b 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -668,7 +668,6 @@ int virNetDevTapCreateInBridgePort(const char *brname,
unsigned int flags)
{
virMacAddr tapmac;
- char macaddrstr[VIR_MAC_STRING_BUFLEN];
size_t i;
if (virNetDevTapCreate(ifname, tunpath, tapfd, tapfdSize, flags) < 0)
@@ -682,19 +681,18 @@ int virNetDevTapCreateInBridgePort(const char *brname,
*/
virMacAddrSet(&tapmac, macaddr);
if (!(flags & VIR_NETDEV_TAP_CREATE_USE_MAC_FOR_BRIDGE)) {
- if (macaddr->addr[0] == 0xFE) {
- /* For normal use, the tap device's MAC address cannot
- * match the MAC address used by the guest. This results
- * in "received packet on vnetX with own address as source
- * address" error logs from the kernel.
- */
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Unable to use MAC address starting with "
- "reserved value 0xFE - '%s' - "),
- virMacAddrFormat(macaddr, macaddrstr));
- goto error;
- }
- tapmac.addr[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */
+ /* The tap device's MAC address cannot match the MAC address
+ * used by the guest. This results in "received packet on
+ * vnetX with own address as source address" error logs from
+ * the kernel. Making the tap address as high as possible
+ * discourages the bridge from using this tap's MAC as its own
+ * (a Linux host bridge will take on the lowest numbered MAC
+ * of all devices attached to it).
+ */
+ if (tapmac.addr[0] == 0xFE)
+ tapmac.addr[0] = 0xFA;
+ else
+ tapmac.addr[0] = 0xFE;
}
if (virNetDevSetMAC(*ifname, &tapmac) < 0)
--
2.21.0
5 years, 4 months
[libvirt] [PATCH] nwfilter: move standard XML configs out of examples dir
by Daniel P. Berrangé
The nwfilter XML configs are not merely examples, they are data that is
actively shipped and used in production by users.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
examples/Makefile.am | 10 ----------
src/nwfilter/Makefile.inc.am | 8 ++++++++
.../xml/nwfilter => src/nwfilter/xml}/allow-arp.xml | 0
.../nwfilter/xml}/allow-dhcp-server.xml | 0
.../xml/nwfilter => src/nwfilter/xml}/allow-dhcp.xml | 0
.../nwfilter/xml}/allow-incoming-ipv4.xml | 0
.../xml/nwfilter => src/nwfilter/xml}/allow-ipv4.xml | 0
.../nwfilter/xml}/clean-traffic-gateway.xml | 0
.../nwfilter => src/nwfilter/xml}/clean-traffic.xml | 0
.../nwfilter/xml}/no-arp-ip-spoofing.xml | 0
.../nwfilter/xml}/no-arp-mac-spoofing.xml | 0
.../nwfilter => src/nwfilter/xml}/no-arp-spoofing.xml | 0
.../nwfilter => src/nwfilter/xml}/no-ip-multicast.xml | 0
.../nwfilter => src/nwfilter/xml}/no-ip-spoofing.xml | 0
.../nwfilter => src/nwfilter/xml}/no-mac-broadcast.xml | 0
.../nwfilter => src/nwfilter/xml}/no-mac-spoofing.xml | 0
.../nwfilter/xml}/no-other-l2-traffic.xml | 0
.../nwfilter/xml}/no-other-rarp-traffic.xml | 0
.../nwfilter/xml}/qemu-announce-self-rarp.xml | 0
.../nwfilter/xml}/qemu-announce-self.xml | 0
20 files changed, 8 insertions(+), 10 deletions(-)
rename {examples/xml/nwfilter => src/nwfilter/xml}/allow-arp.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/allow-dhcp-server.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/allow-dhcp.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/allow-incoming-ipv4.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/allow-ipv4.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/clean-traffic-gateway.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/clean-traffic.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-arp-ip-spoofing.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-arp-mac-spoofing.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-arp-spoofing.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-ip-multicast.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-ip-spoofing.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-mac-broadcast.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-mac-spoofing.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-other-l2-traffic.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/no-other-rarp-traffic.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/qemu-announce-self-rarp.xml (100%)
rename {examples/xml/nwfilter => src/nwfilter/xml}/qemu-announce-self.xml (100%)
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 0adb4b42e2..ad635bdcc0 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -16,8 +16,6 @@
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
-FILTERS = $(wildcard $(srcdir)/xml/nwfilter/*.xml)
-
ADMIN_EXAMPLES = \
$(wildcard $(srcdir)/c/admin/*.c) \
$(NULL)
@@ -56,7 +54,6 @@ EXTRA_DIST = \
$(STORAGE_XML_EXAMPLES) \
$(SYSTEMTAP_EXAMPLES) \
$(TEST_XML_EXAMPLES) \
- $(FILTERS) \
$(NULL)
AM_CPPFLAGS = \
@@ -111,13 +108,6 @@ c_misc_event_test_SOURCES = c/misc/event-test.c
c_misc_hellolibvirt_SOURCES = c/misc/hellolibvirt.c
c_misc_openauth_SOURCES = c/misc/openauth.c
-if WITH_NWFILTER
-
-nwfilterdir = $(sysconfdir)/libvirt/nwfilter
-nwfilter_DATA = $(FILTERS)
-
-endif WITH_NWFILTER
-
examplesdir = $(docdir)/examples
adminexamplesdir = $(examplesdir)/c/admin
diff --git a/src/nwfilter/Makefile.inc.am b/src/nwfilter/Makefile.inc.am
index 277f75a9bd..7693634e29 100644
--- a/src/nwfilter/Makefile.inc.am
+++ b/src/nwfilter/Makefile.inc.am
@@ -1,5 +1,9 @@
# vim: filetype=automake
+NWFILTER_XML_FILES = $(wildcard $(srcdir)/nwfilter/xml/*.xml)
+
+EXTRA_DIST += $(NWFILTER_XML_FILES)
+
NWFILTER_DRIVER_SOURCES = \
nwfilter/nwfilter_driver.h \
nwfilter/nwfilter_driver.c \
@@ -19,6 +23,10 @@ STATEFUL_DRIVER_SOURCE_FILES += $(NWFILTER_DRIVER_SOURCES)
EXTRA_DIST += $(NWFILTER_DRIVER_SOURCES)
if WITH_NWFILTER
+
+nwfilterxmldir = $(sysconfdir)/libvirt/nwfilter
+nwfilterxml_DATA = $(NWFILTER_XML_FILES)
+
noinst_LTLIBRARIES += libvirt_driver_nwfilter_impl.la
libvirt_driver_nwfilter_la_SOURCES =
libvirt_driver_nwfilter_la_LIBADD = libvirt_driver_nwfilter_impl.la
diff --git a/examples/xml/nwfilter/allow-arp.xml b/src/nwfilter/xml/allow-arp.xml
similarity index 100%
rename from examples/xml/nwfilter/allow-arp.xml
rename to src/nwfilter/xml/allow-arp.xml
diff --git a/examples/xml/nwfilter/allow-dhcp-server.xml b/src/nwfilter/xml/allow-dhcp-server.xml
similarity index 100%
rename from examples/xml/nwfilter/allow-dhcp-server.xml
rename to src/nwfilter/xml/allow-dhcp-server.xml
diff --git a/examples/xml/nwfilter/allow-dhcp.xml b/src/nwfilter/xml/allow-dhcp.xml
similarity index 100%
rename from examples/xml/nwfilter/allow-dhcp.xml
rename to src/nwfilter/xml/allow-dhcp.xml
diff --git a/examples/xml/nwfilter/allow-incoming-ipv4.xml b/src/nwfilter/xml/allow-incoming-ipv4.xml
similarity index 100%
rename from examples/xml/nwfilter/allow-incoming-ipv4.xml
rename to src/nwfilter/xml/allow-incoming-ipv4.xml
diff --git a/examples/xml/nwfilter/allow-ipv4.xml b/src/nwfilter/xml/allow-ipv4.xml
similarity index 100%
rename from examples/xml/nwfilter/allow-ipv4.xml
rename to src/nwfilter/xml/allow-ipv4.xml
diff --git a/examples/xml/nwfilter/clean-traffic-gateway.xml b/src/nwfilter/xml/clean-traffic-gateway.xml
similarity index 100%
rename from examples/xml/nwfilter/clean-traffic-gateway.xml
rename to src/nwfilter/xml/clean-traffic-gateway.xml
diff --git a/examples/xml/nwfilter/clean-traffic.xml b/src/nwfilter/xml/clean-traffic.xml
similarity index 100%
rename from examples/xml/nwfilter/clean-traffic.xml
rename to src/nwfilter/xml/clean-traffic.xml
diff --git a/examples/xml/nwfilter/no-arp-ip-spoofing.xml b/src/nwfilter/xml/no-arp-ip-spoofing.xml
similarity index 100%
rename from examples/xml/nwfilter/no-arp-ip-spoofing.xml
rename to src/nwfilter/xml/no-arp-ip-spoofing.xml
diff --git a/examples/xml/nwfilter/no-arp-mac-spoofing.xml b/src/nwfilter/xml/no-arp-mac-spoofing.xml
similarity index 100%
rename from examples/xml/nwfilter/no-arp-mac-spoofing.xml
rename to src/nwfilter/xml/no-arp-mac-spoofing.xml
diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/src/nwfilter/xml/no-arp-spoofing.xml
similarity index 100%
rename from examples/xml/nwfilter/no-arp-spoofing.xml
rename to src/nwfilter/xml/no-arp-spoofing.xml
diff --git a/examples/xml/nwfilter/no-ip-multicast.xml b/src/nwfilter/xml/no-ip-multicast.xml
similarity index 100%
rename from examples/xml/nwfilter/no-ip-multicast.xml
rename to src/nwfilter/xml/no-ip-multicast.xml
diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/src/nwfilter/xml/no-ip-spoofing.xml
similarity index 100%
rename from examples/xml/nwfilter/no-ip-spoofing.xml
rename to src/nwfilter/xml/no-ip-spoofing.xml
diff --git a/examples/xml/nwfilter/no-mac-broadcast.xml b/src/nwfilter/xml/no-mac-broadcast.xml
similarity index 100%
rename from examples/xml/nwfilter/no-mac-broadcast.xml
rename to src/nwfilter/xml/no-mac-broadcast.xml
diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/src/nwfilter/xml/no-mac-spoofing.xml
similarity index 100%
rename from examples/xml/nwfilter/no-mac-spoofing.xml
rename to src/nwfilter/xml/no-mac-spoofing.xml
diff --git a/examples/xml/nwfilter/no-other-l2-traffic.xml b/src/nwfilter/xml/no-other-l2-traffic.xml
similarity index 100%
rename from examples/xml/nwfilter/no-other-l2-traffic.xml
rename to src/nwfilter/xml/no-other-l2-traffic.xml
diff --git a/examples/xml/nwfilter/no-other-rarp-traffic.xml b/src/nwfilter/xml/no-other-rarp-traffic.xml
similarity index 100%
rename from examples/xml/nwfilter/no-other-rarp-traffic.xml
rename to src/nwfilter/xml/no-other-rarp-traffic.xml
diff --git a/examples/xml/nwfilter/qemu-announce-self-rarp.xml b/src/nwfilter/xml/qemu-announce-self-rarp.xml
similarity index 100%
rename from examples/xml/nwfilter/qemu-announce-self-rarp.xml
rename to src/nwfilter/xml/qemu-announce-self-rarp.xml
diff --git a/examples/xml/nwfilter/qemu-announce-self.xml b/src/nwfilter/xml/qemu-announce-self.xml
similarity index 100%
rename from examples/xml/nwfilter/qemu-announce-self.xml
rename to src/nwfilter/xml/qemu-announce-self.xml
--
2.21.0
5 years, 4 months
[libvirt] [PATCH] m4: Drop libxml2 version number from configure help
by Andrea Bolognani
We don't include this information for any other library, and
having it there means there are two places we need to change
every time the required version is bumped.
configure will provide the user with a nice error message,
which includes the required version, if libxml2 found on the
system is too old.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
Pushed as trivial.
m4/virt-libxml.m4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/m4/virt-libxml.m4 b/m4/virt-libxml.m4
index 9aefbdc3f1..cce54d88fb 100644
--- a/m4/virt-libxml.m4
+++ b/m4/virt-libxml.m4
@@ -18,7 +18,7 @@ dnl <http://www.gnu.org/licenses/>.
dnl
AC_DEFUN([LIBVIRT_ARG_LIBXML], [
- LIBVIRT_ARG_WITH([LIBXML], [libxml-2.0 (>= 2.9.1) location], [check])
+ LIBVIRT_ARG_WITH([LIBXML], [libxml-2.0 location], [check])
])
AC_DEFUN([LIBVIRT_CHECK_LIBXML], [
--
2.21.0
5 years, 4 months
[libvirt] [PATCH v2 0/3] test_driver: implement the remaining ManagedSave APIs
by Ilias Stamatis
Ilias Stamatis (3):
test_driver: use domain-private data to store managed image
test_driver: implement virDomainManagedSaveGetXMLDesc
test_driver: implement virDomainManagedSaveDefineXML
src/test/test_driver.c | 93 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 1 deletion(-)
--
2.22.0
5 years, 4 months
[libvirt] [PATCH v2] snapshot: Store both config and live XML in the snapshot domain
by Maxiwell S. Garcia
The snapshot-create operation of running guests saves the live
XML and uses it to replace the active and inactive domain in
case of revert. So, the config XML is ignored by the snapshot
process. This commit changes it and adds the config XML in the
snapshot XML as the <inactiveDomain> entry.
In case of offline guest, the behavior remains the same and the
config XML is saved in the snapshot XML as <domain> entry. The
behavior of older snapshots of running guests, that don't have
the new <inactiveDomain>, remains the same too. The revert, in
this case, overrides both active and inactive domain with the
<domain> entry. So, the <inactiveDomain> in the snapshot XML is
not required to snapshot work, but it's useful to preserve the
config XML of running guests.
Signed-off-by: Maxiwell S. Garcia <maxiwell(a)linux.ibm.com>
---
src/conf/moment_conf.c | 1 +
src/conf/moment_conf.h | 11 +++++++++
src/conf/snapshot_conf.c | 48 +++++++++++++++++++++++++++++++++++-----
src/qemu/qemu_driver.c | 27 +++++++++++++++++-----
src/util/virxml.c | 45 +++++++++++++++++++++++++++++++++++++
src/util/virxml.h | 8 +++++++
6 files changed, 130 insertions(+), 10 deletions(-)
diff --git a/src/conf/moment_conf.c b/src/conf/moment_conf.c
index fea13f0f97..f54a44b33e 100644
--- a/src/conf/moment_conf.c
+++ b/src/conf/moment_conf.c
@@ -66,6 +66,7 @@ virDomainMomentDefDispose(void *obj)
VIR_FREE(def->description);
VIR_FREE(def->parent_name);
virDomainDefFree(def->dom);
+ virDomainDefFree(def->inactiveDom);
}
/* Provide defaults for creation time and moment name after parsing XML */
diff --git a/src/conf/moment_conf.h b/src/conf/moment_conf.h
index 9fdbef2172..70cc47bd70 100644
--- a/src/conf/moment_conf.h
+++ b/src/conf/moment_conf.h
@@ -36,7 +36,18 @@ struct _virDomainMomentDef {
char *parent_name;
long long creationTime; /* in seconds */
+ /*
+ * Store the active domain definition in case of online
+ * guest and the inactive domain definition in case of
+ * offline guest
+ */
virDomainDefPtr dom;
+
+ /*
+ * Store the inactive domain definition in case of online
+ * guest and leave NULL in case of offline guest
+ */
+ virDomainDefPtr inactiveDom;
};
virClassPtr virClassForDomainMomentDef(void);
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 324901a560..8aeac9ab20 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -243,6 +243,8 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
char *memoryFile = NULL;
bool offline = !!(flags & VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE);
virSaveCookieCallbacksPtr saveCookie = virDomainXMLOptionGetSaveCookie(xmlopt);
+ int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
if (!(def = virDomainSnapshotDefNew()))
return NULL;
@@ -292,8 +294,6 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
* clients will have to decide between best effort
* initialization or outright failure. */
if ((tmp = virXPathString("string(./domain/@type)", ctxt))) {
- int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
- VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
xmlNodePtr domainNode = virXPathNode("./domain", ctxt);
VIR_FREE(tmp);
@@ -309,6 +309,20 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
} else {
VIR_WARN("parsing older snapshot that lacks domain");
}
+
+ /* /inactiveDomain entry saves the config XML present in a running
+ * VM. In case of absent, leave parent.inactiveDom NULL and use
+ * parent.dom for config and live XML. */
+ if (virXPathString("string(./inactiveDomain/@type)", ctxt)) {
+ xmlNodePtr domainNode = virXPathNode("./inactiveDomain", ctxt);
+
+ if (domainNode) {
+ def->parent.inactiveDom = virDomainDefParseNode(ctxt->node->doc, domainNode,
+ caps, xmlopt, NULL, domainflags);
+ if (!def->parent.inactiveDom)
+ goto cleanup;
+ }
+ }
} else if (virDomainXMLOptionRunMomentPostParse(xmlopt, &def->parent) < 0) {
goto cleanup;
}
@@ -845,6 +859,10 @@ virDomainSnapshotDefFormatInternal(virBufferPtr buf,
{
size_t i;
int domainflags = VIR_DOMAIN_DEF_FORMAT_INACTIVE;
+ virBuffer inactivedom_buf = VIR_BUFFER_INITIALIZER;
+ xmlXPathContextPtr inactivedom_ctxt = NULL;
+ char *inactivedom_str = NULL;
+ int ret = -1;
if (flags & VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE)
domainflags |= VIR_DOMAIN_DEF_FORMAT_SECURE;
@@ -903,6 +921,20 @@ virDomainSnapshotDefFormatInternal(virBufferPtr buf,
virBufferAddLit(buf, "</domain>\n");
}
+ if (def->parent.inactiveDom) {
+ if (virDomainDefFormatInternal(def->parent.inactiveDom, caps,
+ domainflags, &inactivedom_buf, xmlopt) < 0)
+ goto error;
+
+ inactivedom_ctxt = virXPathBuildContext(&inactivedom_buf);
+ if (!(inactivedom_str = virXPathRenameNode("/domain", "inactiveDomain",
+ inactivedom_ctxt)))
+ goto error;
+
+ virBufferAddStr(buf, inactivedom_str);
+ virBufferAddLit(buf, "\n");
+ }
+
if (virSaveCookieFormatBuf(buf, def->cookie,
virDomainXMLOptionGetSaveCookie(xmlopt)) < 0)
goto error;
@@ -917,11 +949,17 @@ virDomainSnapshotDefFormatInternal(virBufferPtr buf,
if (virBufferCheckError(buf) < 0)
goto error;
- return 0;
+ ret = 0;
error:
- virBufferFreeAndReset(buf);
- return -1;
+ VIR_FREE(inactivedom_str);
+ xmlXPathFreeContext(inactivedom_ctxt);
+ virBufferFreeAndReset(&inactivedom_buf);
+
+ if (ret < 0)
+ virBufferFreeAndReset(buf);
+
+ return ret;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 482f915b67..9b95e9b766 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15697,6 +15697,13 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto endjob;
+ if (vm->newDef) {
+ def->parent.inactiveDom = virDomainDefCopy(vm->newDef, caps,
+ driver->xmlopt, NULL, true);
+ if (!def->parent.inactiveDom)
+ goto endjob;
+ }
+
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
align_match = false;
@@ -16231,6 +16238,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuDomainObjPrivatePtr priv;
int rc;
virDomainDefPtr config = NULL;
+ virDomainDefPtr inactiveConfig = NULL;
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
bool was_stopped = false;
@@ -16331,17 +16339,22 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
* in the failure cases where we know there was no change? */
}
- /* Prepare to copy the snapshot inactive xml as the config of this
- * domain.
- *
- * XXX Should domain snapshots track live xml rather
- * than inactive xml? */
+ /* Prepare to copy the snapshot inactive domain as the config XML
+ * and the snapshot domain as the live XML. In case of inactive domain
+ * NULL, both config and live XML will be copied from snapshot domain.
+ */
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps,
driver->xmlopt, NULL, true);
if (!config)
goto endjob;
}
+ if (snap->def->inactiveDom) {
+ inactiveConfig = virDomainDefCopy(snap->def->inactiveDom, caps,
+ driver->xmlopt, NULL, true);
+ if (!inactiveConfig)
+ goto endjob;
+ }
cookie = (qemuDomainSaveCookiePtr) snapdef->cookie;
@@ -16592,6 +16605,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto endjob;
}
+ if (inactiveConfig) {
+ virDomainDefFree(vm->newDef);
+ VIR_STEAL_PTR(vm->newDef, inactiveConfig);
+ }
ret = 0;
endjob:
diff --git a/src/util/virxml.c b/src/util/virxml.c
index f55b9a362c..756c0eedbc 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1408,3 +1408,48 @@ virXPathContextNodeRestore(virXPathContextNodeSavePtr save)
save->ctxt->node = save->node;
}
+
+
+/**
+ * virXPathBuildContext: convert an parent buffer to an
+ * XPath context ptr. The caller has to free the ptr.
+ */
+xmlXPathContextPtr
+virXPathBuildContext(virBufferPtr root)
+{
+ xmlDocPtr doc;
+
+ if (!root)
+ return NULL;
+
+ doc = virXMLParseString(virBufferCurrentContent(root), NULL);
+ if (!doc)
+ return NULL;
+
+ return xmlXPathNewContext(doc);
+}
+
+
+/**
+ * virXPathRenameNode: get the XML node using the 'xpath' and
+ * rename it with the 'newname' string.
+ *
+ * Returns the XML string of the node found by 'xpath' or NULL
+ * on error. The caller has to free the string.
+ */
+char *
+virXPathRenameNode(const char *xpath,
+ const char *newname,
+ xmlXPathContextPtr ctxt)
+{
+ xmlNodePtr node;
+
+ if (!xpath || !newname || !ctxt)
+ return NULL;
+
+ if (!(node = virXPathNode(xpath, ctxt)))
+ return NULL;
+
+ xmlNodeSetName(node, (xmlChar *) newname);
+ return virXMLNodeToString(node->doc, node);
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 6208977dd1..48a507c3c1 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -220,6 +220,14 @@ virXMLFormatElement(virBufferPtr buf,
virBufferPtr childBuf)
ATTRIBUTE_RETURN_CHECK;
+xmlXPathContextPtr
+virXPathBuildContext(virBufferPtr root);
+
+char *
+virXPathRenameNode(const char *xpath,
+ const char *newname,
+ xmlXPathContextPtr ctxt);
+
struct _virXPathContextNodeSave {
xmlXPathContextPtr ctxt;
xmlNodePtr node;
--
2.20.1
5 years, 4 months
[libvirt] [dockerfiles PATCH 0/4] refresh: Some minor cleanups
by Andrea Bolognani
Andrea Bolognani (4):
refresh: Get rid of self.project_name
refresh: Improve project handling
refresh: Look for project with startswith()
refresh: Update comments
refresh | 44 +++++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 21 deletions(-)
--
2.21.0
5 years, 4 months
[libvirt] [PATCH v2] qemu: check if numa cell's cpu range match with cpu topology count
by Maxiwell S. Garcia
QEMU shows a warning message if partial NUMA mapping is set. This patch
adds a warning message in libvirt when editing the XML. It must be an
error in future, when QEMU remove this ability.
Signed-off-by: Maxiwell S. Garcia <maxiwell(a)linux.ibm.com>
---
src/qemu/qemu_domain.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 0555caa6ab..62dd428fca 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4621,15 +4621,24 @@ qemuDomainDefValidate(const virDomainDef *def,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS)) {
unsigned int topologycpus;
unsigned int granularity;
+ unsigned int numacpus;
/* Starting from QEMU 2.5, max vCPU count and overall vCPU topology
* must agree. We only actually enforce this with QEMU 2.7+, due
* to the capability check above */
- if (virDomainDefGetVcpusTopology(def, &topologycpus) == 0 &&
- topologycpus != virDomainDefGetVcpusMax(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("CPU topology doesn't match maximum vcpu count"));
- goto cleanup;
+ if (virDomainDefGetVcpusTopology(def, &topologycpus) == 0) {
+ if (topologycpus != virDomainDefGetVcpusMax(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("CPU topology doesn't match maximum vcpu count"));
+ goto cleanup;
+ }
+
+ numacpus = virDomainNumaGetCPUCountTotal(def->numa);
+ if ((numacpus != 0) && (topologycpus != numacpus)) {
+ VIR_WARN("CPU topology doesn't match numa CPU count; "
+ "partial NUMA mapping is obsoleted and will "
+ "be removed in future");
+ }
}
/* vCPU hotplug granularity must be respected */
--
2.20.1
5 years, 4 months