hostdevs have a link back to the original network device. This is fairly
generic accepting any type of device, however, we don't intend to make
use of this approach in future. It can thus be specialized to network
devices.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/domain_conf.c | 18 ++++++++----------
src/conf/domain_conf.h | 8 +++++++-
src/libxl/libxl_driver.c | 4 ++--
src/network/bridge_driver.c | 3 +--
src/qemu/qemu_command.c | 3 +--
src/qemu/qemu_domain_address.c | 4 ++--
src/qemu/qemu_driver.c | 2 +-
src/qemu/qemu_hotplug.c | 14 ++++++--------
src/qemu/qemu_hotplug.h | 2 +-
src/util/virhostdev.c | 17 ++++++++---------
10 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 96aa750683..cc352dc6d0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2721,7 +2721,7 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
/* If there is a parent device object, it will handle freeing
* def->info.
*/
- if (def->parent.type == VIR_DOMAIN_DEVICE_NONE)
+ if (!def->parent)
virDomainDeviceInfoFree(def->info);
switch (def->mode) {
@@ -2792,7 +2792,7 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
/* If there is a parent device object, it will handle freeing
* the memory.
*/
- if (def->parent.type == VIR_DOMAIN_DEVICE_NONE)
+ if (!def->parent)
VIR_FREE(def);
}
@@ -5350,7 +5350,7 @@ virDomainDefCollectBootOrder(virDomainDefPtr def ATTRIBUTE_UNUSED,
return 0;
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
- dev->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE) {
+ dev->data.hostdev->parent) {
/* This hostdev is a child of a higher level device
* (e.g. interface), and thus already being counted on the
* list for the other device type.
@@ -6191,7 +6191,7 @@ virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr def,
return 0;
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
- dev->data.hostdev->parent.type == VIR_DOMAIN_DEVICE_NET) {
+ dev->data.hostdev->parent) {
/* This hostdev is a copy of some previous interface.
* Aliases are duplicated. */
return 0;
@@ -11112,8 +11112,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
} else if (actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
virDomainHostdevDefPtr hostdev = &actual->data.hostdev.def;
- hostdev->parent.type = VIR_DOMAIN_DEVICE_NET;
-
hostdev->parent.data.net = parent;
+ hostdev->parent = parent;
hostdev->info = &parent->info;
/* The helper function expects type to already be found and
* passed in as a string, since it is in a different place in
@@ -11774,8 +11773,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
hostdev = &def->data.hostdev.def;
- hostdev->parent.type = VIR_DOMAIN_DEVICE_NET;
-
hostdev->parent.data.net = def;
+ hostdev->parent = def;
hostdev->info = &def->info;
/* The helper function expects type to already be found and
* passed in as a string, since it is in a different place in
@@ -28971,11 +28969,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
}
for (n = 0; n < def->nhostdevs; n++) {
- /* If parent.type != NONE, this is just a pointer to the
+ /* If parent != NONE, this is just a pointer to the
* hostdev in a higher-level device (e.g. virDomainNetDef),
* and will have already been formatted there.
*/
- if (def->hostdevs[n]->parent.type == VIR_DOMAIN_DEVICE_NONE &&
+ if (!def->hostdevs[n]->parent &&
virDomainHostdevDefFormat(buf, def->hostdevs[n], flags) < 0) {
goto error;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 07c4e3bd69..0b84e48f1b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -444,7 +444,13 @@ struct _virDomainHostdevCaps {
/* basic device for direct passthrough */
struct _virDomainHostdevDef {
- virDomainDeviceDef parent; /* higher level Def containing this */
+ /* If 'parent' is non-NULL it means this host dev was
+ * not originally present in the XML. It was copied from
+ * a network interface for convenience when handling
+ * hostdevs internally. This hostdev should never be
+ * visible to the user except as part of the interface
+ */
+ virDomainNetDefPtr parent;
int mode; /* enum virDomainHostdevMode */
int startupPolicy; /* enum virDomainStartupPolicy */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 8bf5b50f32..2df3f5d363 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3922,9 +3922,9 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
/* If this is a network hostdev, we need to use the higher-level
* detach function so that mac address / virtualport are reset
*/
- if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET)
+ if (hostdev->parent)
ret = libxlDomainDetachNetDevice(driver, vm,
-
hostdev->parent.data.net);
+ hostdev->parent);
else
ret = libxlDomainDetachHostDevice(driver, vm, hostdev);
break;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 530f326417..314939cb17 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4499,8 +4499,7 @@ networkAllocateActualDevice(virNetworkPtr net,
netdef->name);
goto error;
}
- iface->data.network.actual->data.hostdev.def.parent.type =
VIR_DOMAIN_DEVICE_NET;
-
iface->data.network.actual->data.hostdev.def.parent.data.net = iface;
+ iface->data.network.actual->data.hostdev.def.parent = iface;
iface->data.network.actual->data.hostdev.def.info = &iface->info;
iface->data.network.actual->data.hostdev.def.mode =
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
iface->data.network.actual->data.hostdev.def.managed =
netdef->forward.managed ? 1 : 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 74f34af292..11c40f2019 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5585,8 +5585,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
/* bootNet will be non-0 if boot order was set and no other
* net devices were encountered
*/
- if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
- bootIndex == 0) {
+ if (hostdev->parent && bootIndex == 0) {
bootIndex = *bootHostdevNet;
*bootHostdevNet = 0;
}
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 32fdd59566..4c80251463 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1433,7 +1433,7 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
if (!virDeviceInfoPCIAddressIsPresent(info) ||
((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) &&
- (device->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE))) {
+ device->data.hostdev->parent)) {
/* If a hostdev has a parent, its info will be a part of the
* parent, and will have its address collected during the scan
* of the parent's device type.
@@ -1528,7 +1528,7 @@ qemuDomainCollectPCIAddressExtension(virDomainDefPtr def
ATTRIBUTE_UNUSED,
if (!virDeviceInfoPCIAddressExtensionIsPresent(info) ||
((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) &&
- (device->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE))) {
+ device->data.hostdev->parent)) {
/* If a hostdev has a parent, its info will be a part of the
* parent, and will have its address collected during the scan
* of the parent's device type.
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7820c7f5db..df577aa869 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8069,7 +8069,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
break;
case VIR_DOMAIN_DEVICE_NET:
- ret = qemuDomainDetachNetDevice(driver, vm, dev, async);
+ ret = qemuDomainDetachNetDevice(driver, vm,
dev->data.net, async);
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
ret = qemuDomainDetachHostDevice(driver, vm, dev, async);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7e69c78f6f..f27fb9a826 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4593,11 +4593,9 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
virObjectEventStateQueue(driver->domainEventState, event);
- if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET) {
- net =
hostdev->parent.data.net;
-
+ if (hostdev->parent) {
for (i = 0; i < vm->def->nnets; i++) {
- if (vm->def->nets[i] == net) {
+ if (vm->def->nets[i] == hostdev->parent) {
virDomainNetRemove(vm->def, i);
break;
}
@@ -5783,8 +5781,8 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
/* If this is a network hostdev, we need to use the higher-level detach
* function so that mac address / virtualport are reset
*/
- if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
- return qemuDomainDetachNetDevice(driver, vm, &detach->parent, async);
+ if (detach->parent)
+ return qemuDomainDetachNetDevice(driver, vm, detach->parent, async);
else
return qemuDomainDetachThisHostDevice(driver, vm, detach, async);
}
@@ -5964,14 +5962,14 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
+ virDomainNetDefPtr net,
bool async)
{
int detachidx, ret = -1;
virDomainNetDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
- if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
+ if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0)
goto cleanup;
detach = vm->def->nets[detachidx];
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 7ac03b7810..d3fa588aac 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -109,7 +109,7 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
bool async);
int qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
+ virDomainNetDefPtr net,
bool async);
int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 6be395cdda..7f692a5289 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -333,8 +333,7 @@ virHostdevIsPCINetDevice(virDomainHostdevDefPtr hostdev)
{
return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
- hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
-
hostdev->parent.data.net;
+ hostdev->parent != NULL;
}
@@ -427,7 +426,7 @@ virHostdevSaveNetConfig(virDomainHostdevDefPtr hostdev,
int vf = -1;
if (!virHostdevIsPCINetDevice(hostdev) ||
- virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net))
+ virDomainNetGetActualVirtPortProfile(hostdev->parent))
return 0;
if (virHostdevIsVirtualFunction(hostdev) != 1) {
@@ -474,8 +473,8 @@ virHostdevSetNetConfig(virDomainHostdevDefPtr hostdev,
if (virHostdevNetDevice(hostdev, -1, &linkdev, &vf) < 0)
return -1;
- vlan = virDomainNetGetActualVlan(hostdev->parent.data.net);
- virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net);
+ vlan = virDomainNetGetActualVlan(hostdev->parent);
+ virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent);
if (virtPort) {
if (vlan) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -485,11 +484,11 @@ virHostdevSetNetConfig(virDomainHostdevDefPtr hostdev,
return -1;
}
if (virHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort,
- &hostdev->parent.data.net->mac,
+ &hostdev->parent->mac,
uuid, port_profile_associate) < 0)
return -1;
} else {
- if (virNetDevSetNetConfig(linkdev, vf, &hostdev->parent.data.net->mac,
+ if (virNetDevSetNetConfig(linkdev, vf, &hostdev->parent->mac,
vlan, NULL, true) < 0)
return -1;
}
@@ -535,10 +534,10 @@ virHostdevRestoreNetConfig(virDomainHostdevDefPtr hostdev,
if (virHostdevNetDevice(hostdev, 0, &linkdev, &vf) < 0)
return -1;
- virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net);
+ virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent);
if (virtPort) {
return virHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort,
-
&hostdev->parent.data.net->mac,
+ &hostdev->parent->mac,
NULL,
port_profile_associate);
} else {
--
2.20.1