129 lines
5.4 KiB
Diff
129 lines
5.4 KiB
Diff
|
|
From 448fde35ded33356308f630959a1f96c89739b97 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Xu Yandong <xuyandong2@huawei.com>
|
||
|
|
Date: Wed, 25 Dec 2019 11:14:53 +0800
|
||
|
|
Subject: [PATCH] qemu: homogenize MAC address in live & config when
|
||
|
|
hotplugging a netdev
|
||
|
|
|
||
|
|
Prior to commit 55ce6564634 (first in libvirt 4.6.0), the XML sent to
|
||
|
|
virDomainAttachDeviceFlags() was parsed only once, and the results of
|
||
|
|
that parse were inserted into both the live object of the running
|
||
|
|
domain and into the persistent config. Thus, if MAC address was
|
||
|
|
omitted from in XML for a network device (<interface>), both the live
|
||
|
|
and config object would have the same MAC address.
|
||
|
|
|
||
|
|
Commit 55ce6564634 changed the code to parse the incoming XML twice -
|
||
|
|
once for live and once for config. This does eliminate the problem of
|
||
|
|
PCI (/scsi/sata) address conflicts caused by allocating an address
|
||
|
|
based on existing devices in live object, but then inserting the
|
||
|
|
result into the config (which may already have a device using that
|
||
|
|
address), BUT it also means that when the MAC address of a network
|
||
|
|
device hasn't been specified in the XML, each copy will get a
|
||
|
|
different auto-generated MAC address.
|
||
|
|
|
||
|
|
This results in the MAC address of the device changing the next time
|
||
|
|
the domain is shutdown and restarted, which creates havoc with the
|
||
|
|
guest OS's network config.
|
||
|
|
|
||
|
|
There have been several discussions about this in the last > 1 year,
|
||
|
|
attempting to find the ideal solution to this problem that makes MAC
|
||
|
|
addresses consistent and accounts for all sorts of corner cases with
|
||
|
|
PCI/scsi/sata addresses. All of these discussions fizzled out because
|
||
|
|
every proposal was either too difficult to implement or failed to fix
|
||
|
|
some esoteric case someone thought up.
|
||
|
|
|
||
|
|
So, in the interest of solving the MAC address problem while not
|
||
|
|
making the "other address" situation any worse than before, this patch
|
||
|
|
simply adds a qemuDomainAttachDeviceLiveAndConfigHomogenize() function
|
||
|
|
that (for now) copies the MAC address from the config object to the
|
||
|
|
live object (if the original xml had <mac address='blah'/> then this
|
||
|
|
will be an effective NOP (as the macs already match)).
|
||
|
|
|
||
|
|
Any downstream libvirt containing upstream commit
|
||
|
|
55ce6564634 should have this patch as well.
|
||
|
|
|
||
|
|
https://bugzilla.redhat.com/1783411
|
||
|
|
|
||
|
|
Signed-off-by: Laine Stump <laine@redhat.com>
|
||
|
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||
|
|
(cherry-picked from commit 6c17606b7cce7bf77baef956bde8a0b056666011)
|
||
|
|
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
|
||
|
|
---
|
||
|
|
src/qemu/qemu_driver.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||
|
|
1 file changed, 40 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||
|
|
index 7ff7d92..8749c53 100644
|
||
|
|
--- a/src/qemu/qemu_driver.c
|
||
|
|
+++ b/src/qemu/qemu_driver.c
|
||
|
|
@@ -8592,6 +8592,35 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+
|
||
|
|
+static void
|
||
|
|
+qemuDomainAttachDeviceLiveAndConfigHomogenize(const virDomainDeviceDef *devConf,
|
||
|
|
+ virDomainDeviceDefPtr devLive)
|
||
|
|
+{
|
||
|
|
+ /*
|
||
|
|
+ * Fixup anything that needs to be identical in the live and
|
||
|
|
+ * config versions of DeviceDef, but might not be. Do this by
|
||
|
|
+ * changing the contents of devLive. This is done after all
|
||
|
|
+ * post-parse tweaks and validation, so be very careful about what
|
||
|
|
+ * changes are made. (For example, it would be a very bad idea to
|
||
|
|
+ * change assigned PCI, scsi, or sata addresses, as it could lead
|
||
|
|
+ * to a conflict and there would be nothing to catch it except
|
||
|
|
+ * qemu itself!)
|
||
|
|
+ */
|
||
|
|
+
|
||
|
|
+ /* MAC address should be identical in both DeviceDefs, but if it
|
||
|
|
+ * wasn't specified in the XML, and was instead autogenerated, it
|
||
|
|
+ * will be different for the two since they are each the result of
|
||
|
|
+ * a separate parser call. If it *was* specified, it will already
|
||
|
|
+ * be the same, so copying does no harm.
|
||
|
|
+ */
|
||
|
|
+
|
||
|
|
+ if (devConf->type == VIR_DOMAIN_DEVICE_NET)
|
||
|
|
+ virMacAddrSet(&devLive->data.net->mac, &devConf->data.net->mac);
|
||
|
|
+
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+
|
||
|
|
static int
|
||
|
|
qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
|
||
|
|
virQEMUDriverPtr driver,
|
||
|
|
@@ -8601,6 +8630,7 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
|
||
|
|
virDomainDefPtr vmdef = NULL;
|
||
|
|
virQEMUDriverConfigPtr cfg = NULL;
|
||
|
|
virDomainDeviceDefPtr devConf = NULL;
|
||
|
|
+ virDomainDeviceDef devConfSave = { 0 };
|
||
|
|
virDomainDeviceDefPtr devLive = NULL;
|
||
|
|
int ret = -1;
|
||
|
|
virCapsPtr caps = NULL;
|
||
|
|
@@ -8627,6 +8657,13 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
|
||
|
|
driver->xmlopt, parse_flags)))
|
||
|
|
goto cleanup;
|
||
|
|
|
||
|
|
+ /*
|
||
|
|
+ * devConf will be NULLed out by
|
||
|
|
+ * qemuDomainAttachDeviceConfig(), so save it for later use by
|
||
|
|
+ * qemuDomainAttachDeviceLiveAndConfigHomogenize()
|
||
|
|
+ */
|
||
|
|
+ devConfSave = *devConf;
|
||
|
|
+
|
||
|
|
if (virDomainDeviceValidateAliasForHotplug(vm, devConf,
|
||
|
|
VIR_DOMAIN_AFFECT_CONFIG) < 0)
|
||
|
|
goto cleanup;
|
||
|
|
@@ -8647,6 +8684,9 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
|
||
|
|
driver->xmlopt, parse_flags)))
|
||
|
|
goto cleanup;
|
||
|
|
|
||
|
|
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG)
|
||
|
|
+ qemuDomainAttachDeviceLiveAndConfigHomogenize(&devConfSave, devLive);
|
||
|
|
+
|
||
|
|
if (virDomainDeviceValidateAliasForHotplug(vm, devLive,
|
||
|
|
VIR_DOMAIN_AFFECT_LIVE) < 0)
|
||
|
|
goto cleanup;
|
||
|
|
--
|
||
|
|
2.21.0
|
||
|
|
|