[libvirt] [PATCH 0/2] qemu: expand domain memory statistics
by Derbyshev Dmitriy
From: Derbyshev Dmitry <dderbyshev(a)virtuozzo.com>
QEMU reports timestamp and available along with other memory statistics.
This information was not saved into domain statistics.
Derbyshev Dmitry (2):
qemu: expand domain memory statistics with 'usable'
qemu: expand domain memory statistics with 'last-update' timestamp
include/libvirt/libvirt-domain.h | 12 +++++++++++-
src/libvirt-domain.c | 5 +++++
src/qemu/qemu_monitor_json.c | 23 +++++++++++++----------
tools/virsh-domain-monitor.c | 4 ++++
4 files changed, 33 insertions(+), 11 deletions(-)
--
1.9.5.msysgit.0
8 years, 7 months
[libvirt] [PATCH] qemu: expand domain memory statistics with 'last-update' timestamp
by Derbyshev Dmitriy
From: Derbyshev Dmitry <dderbyshev(a)virtuozzo.com>
QEMU reports timestamp along with other memory statistics, but this information is not saved into domain statistics.
It could be useful to determine if the data reported is fresh or not.
Balloon statistics are not reported in hrf, so no modifications are made in qemu_monitor_text.c.
---
include/libvirt/libvirt-domain.h | 6 +++++-
src/libvirt-domain.c | 2 ++
src/qemu/qemu_monitor_json.c | 21 +++++++++++----------
tools/virsh-domain-monitor.c | 2 ++
4 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index e1d9a0d..51f9785 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -603,11 +603,15 @@ typedef enum {
* is in kB */
VIR_DOMAIN_MEMORY_STAT_RSS = 7,
+
+ /* Timestamp of the last update of statistics */
+ VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE = 8,
+
/*
* The number of statistics supported by this version of the interface.
* To add new statistics, add them to the enum and increase this value.
*/
- VIR_DOMAIN_MEMORY_STAT_NR = 8,
+ VIR_DOMAIN_MEMORY_STAT_NR = 9,
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_MEMORY_STAT_LAST = VIR_DOMAIN_MEMORY_STAT_NR
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 3e144b6..b1c7d73 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -5988,6 +5988,8 @@ virDomainGetInterfaceParameters(virDomainPtr domain,
* The total amount of memory available to the domain's OS (in kb).
* VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON:
* Current balloon value (in kb).
+ * VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE
+ * Timestamp of the last statistic
*
* Returns: The number of stats provided or -1 in case of failure.
*/
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e767414..175ef10 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1602,10 +1602,10 @@ qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon,
* rates and/or whether data has been collected since a previous cycle.
* It's currently unused.
*/
-#define GET_BALLOON_STATS(FIELD, TAG, DIVISOR) \
- if (virJSONValueObjectHasKey(statsdata, FIELD) && \
+#define GET_BALLOON_STATS(OBJECT, FIELD, TAG, DIVISOR) \
+ if (virJSONValueObjectHasKey(OBJECT, FIELD) && \
(got < nr_stats)) { \
- if (virJSONValueObjectGetNumberUlong(statsdata, FIELD, &mem) < 0) { \
+ if (virJSONValueObjectGetNumberUlong(OBJECT, FIELD, &mem) < 0) { \
VIR_DEBUG("Failed to get '%s' value", FIELD); \
} else { \
/* Not being collected? No point in providing bad data */ \
@@ -1676,19 +1676,20 @@ int qemuMonitorJSONGetMemoryStats(qemuMonitorPtr mon,
goto cleanup;
}
- GET_BALLOON_STATS("stat-swap-in",
+ GET_BALLOON_STATS(statsdata, "stat-swap-in",
VIR_DOMAIN_MEMORY_STAT_SWAP_IN, 1024);
- GET_BALLOON_STATS("stat-swap-out",
+ GET_BALLOON_STATS(statsdata, "stat-swap-out",
VIR_DOMAIN_MEMORY_STAT_SWAP_OUT, 1024);
- GET_BALLOON_STATS("stat-major-faults",
+ GET_BALLOON_STATS(statsdata, "stat-major-faults",
VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT, 1);
- GET_BALLOON_STATS("stat-minor-faults",
+ GET_BALLOON_STATS(statsdata, "stat-minor-faults",
VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT, 1);
- GET_BALLOON_STATS("stat-free-memory",
+ GET_BALLOON_STATS(statsdata, "stat-free-memory",
VIR_DOMAIN_MEMORY_STAT_UNUSED, 1024);
- GET_BALLOON_STATS("stat-total-memory",
+ GET_BALLOON_STATS(statsdata, "stat-total-memory",
VIR_DOMAIN_MEMORY_STAT_AVAILABLE, 1024);
-
+ GET_BALLOON_STATS(data, "last-update",
+ VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE, 1);
cleanup:
virJSONValueFree(cmd);
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 0a93949..3893b90 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -373,6 +373,8 @@ cmdDomMemStat(vshControl *ctl, const vshCmd *cmd)
vshPrint(ctl, "actual %llu\n", stats[i].val);
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_RSS)
vshPrint(ctl, "rss %llu\n", stats[i].val);
+ if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE)
+ vshPrint(ctl, "last_update %llu\n", stats[i].val);
}
ret = true;
--
1.9.5.msysgit.0
8 years, 7 months
[libvirt] [PATCH 0/3] Do not check for domain liveness in virDomainObjSetDefTransient
by Ján Tomko
virDomainObjSetDefTransient has an unintuitive attribute 'live':
when set to 'true', it ignores the virDomainObjIsActive test.
The most common usage is on domain startup, where most of the callers
want to create a transient definition even though the domain is not
yet active.
The only place where live=false is still required is
virDomainObjGetPersistentDef (and its usage could possibly be cleaned
up too, since it's only called in the drivers that already do SetDefTransient
on domain startup).
Split out the virDomainObjIsActive check into virDomainObjGetPersistentDef
and remove it for the rest of the callers along with the 'live' attribute.
Ján Tomko (3):
Clean up redundant usage of virDomainObjSetDefTransient
Check if the domain is active in virDomainObjGetPersistentDef
Do not check for domain liveness in virDomainObjSetDefTransient
src/conf/domain_conf.c | 15 ++++-----------
src/conf/domain_conf.h | 3 +--
src/libxl/libxl_domain.c | 3 +--
src/lxc/lxc_process.c | 6 +-----
src/qemu/qemu_process.c | 4 ++--
src/test/test_driver.c | 2 +-
src/uml/uml_driver.c | 5 ++---
7 files changed, 12 insertions(+), 26 deletions(-)
--
2.7.3
8 years, 7 months
[libvirt] [PATCH v5 0/2] qemu: Support for QXL heads
by Martin Kletzander
v5:
- Just a rebase, plus v4 had some hunk in that didn't belong there so
this one's cleaner to look at
- https://www.redhat.com/archives/libvir-list/2016-March/msg01436.html
v4:
- Added test case without "heads="
- Don't consolidate 'size_t i, j' declarations
v3:
- rebase on top of current master in order to cleanly apply
- https://www.redhat.com/archives/libvir-list/2016-March/msg01198.html
v2:
- don't change heads when migrating
- https://www.redhat.com/archives/libvir-list/2016-March/msg00811.html
v1:
- https://www.redhat.com/archives/libvir-list/2016-March/msg00410.html
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1283207
Martin Kletzander (2):
qemu: Check for qxl's max_outputs parameter
qemu: Add support to QXL's max_outputs parameter
src/qemu/qemu_capabilities.c | 5 ++
src/qemu/qemu_capabilities.h | 4 ++
src/qemu/qemu_command.c | 8 +++
src/qemu/qemu_migration.c | 64 ++++++++++++++++++++--
.../qemuxml2argv-video-qxl-heads.args | 28 ++++++++++
.../qemuxml2argv-video-qxl-heads.xml | 47 ++++++++++++++++
.../qemuxml2argv-video-qxl-noheads.args | 24 ++++++++
.../qemuxml2argv-video-qxl-noheads.xml | 39 +++++++++++++
tests/qemuxml2argvtest.c | 16 ++++++
.../qemuxml2xmlout-video-qxl-heads.xml | 47 ++++++++++++++++
.../qemuxml2xmlout-video-qxl-noheads.xml | 39 +++++++++++++
tests/qemuxml2xmltest.c | 3 +
12 files changed, 319 insertions(+), 5 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-qxl-heads.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-qxl-heads.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-qxl-noheads.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-qxl-noheads.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-video-qxl-heads.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-video-qxl-noheads.xml
--
2.8.1
8 years, 7 months
[libvirt] [PATCH v3 0/2] Add support for zero-write detection
by Martin Kletzander
v3:
- I know Peter said he'll review it, but there are conflicts every
once in a while, so rebased version will apply cleanly for a while
- And it's actually not that big of a change to wait for some bigger
things to be designed, I believe =)
- https://www.redhat.com/archives/libvir-list/2016-April/msg01926.html
v2:
- use 'zeroes' instead of 'zeros'
- https://www.redhat.com/archives/libvir-list/2016-February/msg01146.html
v1:
- https://www.redhat.com/archives/libvir-list/2015-December/msg00511.html
Martin Kletzander (2):
conf: Add support of zero-detection for disks
qemu: Add support for zero-detection writes
docs/formatdomain.html.in | 10 +++++
docs/schemas/domaincommon.rng | 12 ++++++
src/conf/domain_conf.c | 21 +++++++++-
src/conf/domain_conf.h | 11 ++++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 ++++++
tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.4.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.5.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.6.0-1.caps | 1 +
.../qemuxml2argv-disk-drive-detect-zeroes.args | 27 +++++++++++++
.../qemuxml2argv-disk-drive-detect-zeroes.xml | 45 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 3 ++
.../qemuxml2xmlout-disk-drive-detect-zeroes.xml | 1 +
tests/qemuxml2xmltest.c | 1 +
17 files changed, 149 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml
--
2.8.1
8 years, 7 months
[libvirt] [PATCH 0/6] Final round of build fixes
by Michal Privoznik
Hopefully.
Michal Privoznik (6):
virNetDevBridgeGet: Avoid NULL dereference
virDomainFormatSchedDef: Handle case when func returns NULL
esxStorageVolGetXMLDesc: Lookup SCSI lun properly
qemuMonitorTextGetAllBlockStatsInfo: Fix line validation
ppc64Compute: Avoid false positive
domain_conf: Avoid false positive
src/conf/domain_conf.c | 27 ++++++++++++++++++++++++---
src/cpu/cpu_ppc64.c | 12 +++++++++++-
src/esx/esx_storage_backend_iscsi.c | 4 ++--
src/qemu/qemu_monitor_text.c | 2 +-
src/util/virnetdevbridge.c | 6 +++++-
5 files changed, 43 insertions(+), 8 deletions(-)
--
2.8.3
8 years, 7 months
[libvirt] [libvirt-perl][PATCH 0/2] Catch up with latest libvirt
by Michal Privoznik
Two public constants are to be introduced in libvirt. While
touching that are of code, update documentation to a constant
of the same origin.
Michal Privoznik (2):
Add PERF_PARAM_MBML and PERF_PARAM_MBMT constants
Expand description for PERF_PARAM_CMT constant
Changes | 1 +
Virt.xs | 2 ++
lib/Sys/Virt/Domain.pm | 16 +++++++++++++++-
3 files changed, 18 insertions(+), 1 deletion(-)
--
2.8.3
8 years, 7 months
[libvirt] [PATCH 0/3] docs/website: drop some old bits
by Cole Robinson
Patches to drop the (busted) website search, (busted) static todo
list, and not-very-useful ChangeLog-old
Cole Robinson (3):
docs: website: remove search
docs: website: drop the static todo list page
docs: drop ChangeLog-old
.gitignore | 2 -
ChangeLog-old | 16699 ----------------------------------------------
Makefile.am | 1 -
TODO | 22 +-
docs/404.html.in | 9 +-
docs/Makefile.am | 31 +-
docs/devhelp/html.xsl | 4 -
docs/index.py | 1266 ----
docs/libvirt.css | 24 -
docs/page.xsl | 8 -
docs/search.php.code.in | 225 -
docs/search.php.in | 18 -
docs/sitemap.html.in | 2 +-
docs/todo.cfg-example | 26 -
docs/todo.pl | 125 -
15 files changed, 13 insertions(+), 18449 deletions(-)
delete mode 100644 ChangeLog-old
delete mode 100755 docs/index.py
delete mode 100644 docs/search.php.code.in
delete mode 100644 docs/search.php.in
delete mode 100644 docs/todo.cfg-example
delete mode 100755 docs/todo.pl
--
2.7.4
8 years, 7 months
[libvirt] [PATCH 0/2] Yet another round of build fixes
by Michal Privoznik
After these regular errors, I still cannot build cleanly:
../../src/conf/domain_conf.c: In function 'virDomainChrPreAlloc':
../../src/conf/domain_conf.c:14109:57: error: potential null pointer dereference [-Werror=null-dereference]
return VIR_REALLOC_N(*arrPtr, *cntPtr + 1);
^
../../src/conf/domain_conf.c: In function 'virDomainChrRemove':
../../src/conf/domain_conf.c:14133:21: error: potential null pointer dereference [-Werror=null-dereference]
for (i = 0; i < *cntPtr; i++) {
^~~~~~~
cc1: all warnings being treated as errors
These are obviously false positives. I know some developers here
are not very fond of fixing those, so my question is - is it
worth the effort or will my patches be NACKed straight away?
Michal Privoznik (2):
apibuild: Substitute only pure number tokens
virSocketAddrIsPrivate: Work on 32bits platforms
docs/apibuild.py | 2 +-
src/util/virsocketaddr.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
--
2.8.3
8 years, 7 months
[libvirt] [PATCH] conf: Skip MAC checks when using an auto-generated one during detach-device
by Kothapally Madhu Pavan
When we try to detach a network device without specifying the
mac address, random mac address is generated. As the generated
mac address will not be available in the running vm, detaching
device will fail erroring out "error: operation failed: no
device matching mac address xx:xx:xx:xx:xx:xx found".
This patch allows to match DetachDeviec xml using PCI address
when mac address is not specified.
Signed-off-by: Kothapally Madhu Pavan <kmp(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 116 +++++++++++++++++++++++++++++-----------------
src/conf/domain_conf.h | 6 ++
src/libxl/libxl_driver.c | 4 +-
src/lxc/lxc_driver.c | 6 +-
src/qemu/qemu_driver.c | 40 ++++++++++++++--
src/qemu/qemu_hotplug.c | 16 ++++--
src/qemu/qemu_hotplug.h | 3 +
7 files changed, 132 insertions(+), 59 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 568c699..f07f178 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13613,14 +13613,20 @@ int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net)
return 0;
}
-/* virDomainNetFindIdx: search according to mac address and guest side
- * PCI address (if specified)
+/* virDomainNetFindIdx:
+ * search according to mac address and guest side PCI address (if specified).
+ *
+ * @def: pointer to domain definition
+ * @net: pointer to network definition that has to be looked up for
+ * @MACAddrNotSpecified: when detaching a device it takes "true" when mac address is
+ * not specified in device xml and a random mac is generated which
+ * cannot be found in the domain def.
*
* Return: index of match if unique match found
* -1 otherwise and an error is logged
*/
int
-virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
+virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net, bool MACAddrNotSpecified)
{
size_t i;
int matchidx = -1;
@@ -13628,50 +13634,76 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
bool PCIAddrSpecified = virDomainDeviceAddressIsValid(&net->info,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI);
- for (i = 0; i < def->nnets; i++) {
- if (virMacAddrCmp(&def->nets[i]->mac, &net->mac))
- continue;
-
- if ((matchidx >= 0) && !PCIAddrSpecified) {
- /* there were multiple matches on mac address, and no
- * qualifying guest-side PCI address was given, so we must
- * fail (NB: a USB address isn't adequate, since it may
- * specify only vendor and product ID, and there may be
- * multiples of those.
- */
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("multiple devices matching mac address %s found"),
- virMacAddrFormat(&net->mac, mac));
- return -1;
- }
+ /* MAC address is not specified in device xml. So, we need not check for it.
+ * Here we check for matching PCI address if specified. */
+ if (MACAddrNotSpecified) {
if (PCIAddrSpecified) {
- if (virPCIDeviceAddressEqual(&def->nets[i]->info.addr.pci,
- &net->info.addr.pci)) {
- /* exit early if the pci address was specified and
- * it matches, as this guarantees no duplicates.
+ for (i = 0; i < def->nnets; i++) {
+ if (virPCIDeviceAddressEqual(&def->nets[i]->info.addr.pci,
+ &net->info.addr.pci)) {
+ matchidx = i;
+ break;
+ }
+ }
+ if (matchidx < 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("no device found on "
+ "%.4x:%.2x:%.2x.%.1x"),
+ net->info.addr.pci.domain,
+ net->info.addr.pci.bus,
+ net->info.addr.pci.slot,
+ net->info.addr.pci.function);
+ }
+ } else {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("mac address and pci address not specified in device xml"));
+ }
+ } else {
+ for (i = 0; i < def->nnets; i++) {
+ if (virMacAddrCmp(&def->nets[i]->mac, &net->mac))
+ continue;
+
+ if ((matchidx >= 0) && !PCIAddrSpecified) {
+ /* there were multiple matches on mac address, and no
+ * qualifying guest-side PCI address was given, so we must
+ * fail (NB: a USB address isn't adequate, since it may
+ * specify only vendor and product ID, and there may be
+ * multiples of those.
*/
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("multiple devices matching mac address %s found"),
+ virMacAddrFormat(&net->mac, mac));
+ return -1;
+ }
+ if (PCIAddrSpecified) {
+ if (virPCIDeviceAddressEqual(&def->nets[i]->info.addr.pci,
+ &net->info.addr.pci)) {
+ /* exit early if the pci address was specified and
+ * it matches, as this guarantees no duplicates.
+ */
+ matchidx = i;
+ break;
+ }
+ } else {
+ /* no PCI address given, so there may be multiple matches */
matchidx = i;
- break;
}
- } else {
- /* no PCI address given, so there may be multiple matches */
- matchidx = i;
}
- }
- if (matchidx < 0) {
- if (PCIAddrSpecified) {
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("no device matching mac address %s found on "
- "%.4x:%.2x:%.2x.%.1x"),
- virMacAddrFormat(&net->mac, mac),
- net->info.addr.pci.domain,
- net->info.addr.pci.bus,
- net->info.addr.pci.slot,
- net->info.addr.pci.function);
- } else {
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("no device matching mac address %s found"),
- virMacAddrFormat(&net->mac, mac));
+ if (matchidx < 0) {
+ if (PCIAddrSpecified) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("no device matching mac address %s found on "
+ "%.4x:%.2x:%.2x.%.1x"),
+ virMacAddrFormat(&net->mac, mac),
+ net->info.addr.pci.domain,
+ net->info.addr.pci.bus,
+ net->info.addr.pci.slot,
+ net->info.addr.pci.function);
+ } else {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("no device matching mac address %s found"),
+ virMacAddrFormat(&net->mac, mac));
+ }
}
}
return matchidx;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b1953b3..d3ebcdc 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2581,6 +2581,8 @@ typedef enum {
VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS = 1 << 8,
/* allow updates in post parse callback that would break ABI otherwise */
VIR_DOMAIN_DEF_PARSE_ABI_UPDATE = 1 << 9,
+ /* indicates mac address is generated when not provided in device xml */
+ VIR_DOMAIN_DEF_PARSE_SKIP_GENERATE_MACADDR = 1 << 10,
} virDomainDefParseFlags;
typedef enum {
@@ -2710,7 +2712,9 @@ int virDomainDiskSourceParse(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virStorageSourcePtr src);
-int virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net);
+int virDomainNetFindIdx(virDomainDefPtr def,
+ virDomainNetDefPtr net,
+ bool MACAddrNotSpecified);
virDomainNetDefPtr virDomainNetFind(virDomainDefPtr def, const char *device);
bool virDomainHasNet(virDomainDefPtr def, virDomainNetDefPtr net);
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 95dfc01..1c53c5f 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3422,7 +3422,7 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
libxl_device_nic_init(&nic);
- if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0)
+ if ((detachidx = virDomainNetFindIdx(vm->def, net, false)) < 0)
goto cleanup;
detach = vm->def->nets[detachidx];
@@ -3521,7 +3521,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
case VIR_DOMAIN_DEVICE_NET:
net = dev->data.net;
- if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+ if ((idx = virDomainNetFindIdx(vmdef, net, false)) < 0)
return -1;
/* this is guaranteed to succeed */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 67f14fe..3d1396a 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3929,7 +3929,7 @@ lxcDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
switch (dev->type) {
case VIR_DOMAIN_DEVICE_NET:
net = dev->data.net;
- if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+ if ((idx = virDomainNetFindIdx(vmdef, net, false)) < 0)
goto cleanup;
virDomainNetDefFree(vmdef->nets[idx]);
@@ -3975,7 +3975,7 @@ lxcDomainDetachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NET:
net = dev->data.net;
- if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+ if ((idx = virDomainNetFindIdx(vmdef, net, false)) < 0)
goto cleanup;
/* this is guaranteed to succeed */
@@ -4759,7 +4759,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
virDomainNetDefPtr detach = NULL;
virNetDevVPortProfilePtr vport = NULL;
- if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
+ if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net, false)) < 0)
goto cleanup;
detach = vm->def->nets[detachidx];
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 10d3e3d..e6c811c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4105,6 +4105,31 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
virObjectUnref(cfg);
}
+static bool qemuIsMacAvailable(const char *xmlStr)
+{
+ xmlNodePtr cur;
+ xmlXPathContextPtr ctxt = NULL;
+
+ if (!virXMLParseStringCtxt(xmlStr, _("(device_definition)"), &ctxt))
+ goto endjob;
+
+ cur = ctxt->node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (xmlStrEqual(cur->name, BAD_CAST "mac"))
+ goto cleanup;
+ }
+ cur = cur->next;
+ }
+
+ endjob:
+ xmlXPathFreeContext(ctxt);
+ return false;
+
+ cleanup:
+ xmlXPathFreeContext(ctxt);
+ return true;
+}
static void
syncNicRxFilterMacAddr(char *ifname, virNetDevRxFilterPtr guestFilter,
@@ -7587,7 +7612,8 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
static int
qemuDomainDetachDeviceLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
- virDomainPtr dom)
+ virDomainPtr dom,
+ unsigned int parse_flags)
{
virQEMUDriverPtr driver = dom->conn->privateData;
int ret = -1;
@@ -7603,7 +7629,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
break;
case VIR_DOMAIN_DEVICE_NET:
- ret = qemuDomainDetachNetDevice(driver, vm, dev);
+ ret = qemuDomainDetachNetDevice(driver, vm, dev, parse_flags);
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
ret = qemuDomainDetachHostDevice(driver, vm, dev);
@@ -7932,6 +7958,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
virDomainChrDefPtr chr;
virDomainFSDefPtr fs;
int idx;
+ bool skipMac = parse_flags & VIR_DOMAIN_DEF_PARSE_SKIP_GENERATE_MACADDR ? true : false;
switch ((virDomainDeviceType) dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
@@ -7946,7 +7973,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NET:
net = dev->data.net;
- if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+ if ((idx = virDomainNetFindIdx(vmdef, net, skipMac)) < 0)
return -1;
/* this is guaranteed to succeed */
@@ -8115,7 +8142,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NET:
net = dev->data.net;
- if ((pos = virDomainNetFindIdx(vmdef, net)) < 0)
+ if ((pos = virDomainNetFindIdx(vmdef, net, false)) < 0)
return -1;
virDomainNetDefFree(vmdef->nets[pos]);
@@ -8452,6 +8479,9 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom,
!(flags & VIR_DOMAIN_AFFECT_LIVE))
parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE;
+ if (!qemuIsMacAvailable(xml))
+ parse_flags |= VIR_DOMAIN_DEF_PARSE_SKIP_GENERATE_MACADDR;
+
dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
caps, driver->xmlopt,
parse_flags);
@@ -8495,7 +8525,7 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom,
VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
goto endjob;
- if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, dom)) < 0)
+ if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, dom, parse_flags)) < 0)
goto endjob;
/*
* update domain status forcibly because the domain status may be
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6ce0a84..2bf82b4 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2163,7 +2163,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
int ret = -1;
int changeidx = -1;
- if ((changeidx = virDomainNetFindIdx(vm->def, newdev)) < 0)
+ if ((changeidx = virDomainNetFindIdx(vm->def, newdev, false)) < 0)
goto cleanup;
devslot = &vm->def->nets[changeidx];
@@ -3825,7 +3825,7 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
* function so that mac address / virtualport are reset
*/
if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
- return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
+ return qemuDomainDetachNetDevice(driver, vm, &detach->parent, 0);
else
return qemuDomainDetachThisHostDevice(driver, vm, detach);
}
@@ -3833,14 +3833,20 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- virDomainDeviceDefPtr dev)
+ virDomainDeviceDefPtr dev,
+ unsigned int parse_flags)
{
int detachidx, ret = -1;
virDomainNetDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
- if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
- goto cleanup;
+ if (parse_flags & VIR_DOMAIN_DEF_PARSE_SKIP_GENERATE_MACADDR) {
+ if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net, true)) < 0)
+ goto cleanup;
+ } else {
+ if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net, false)) < 0)
+ goto cleanup;
+ }
detach = vm->def->nets[detachidx];
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 165d345..f144879 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -82,7 +82,8 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
virDomainDeviceDefPtr dev);
int qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- virDomainDeviceDefPtr dev);
+ virDomainDeviceDefPtr dev,
+ unsigned int parse_flags);
int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev);
8 years, 7 months