From: Pavel Hrdina <phrdina@redhat.com> Currently virDomainNetDef and virDomainActualNetDef use virDomainHostdevDef directly as structure and the code doesn't call virDomainHostdevDefNew() that would initialize private data. This is hackish quick fix to solve a crash that happens in two scenarios: 1. attaching any interface with hostdev backend 0x0000fffbfc0e2a90 in qemuDomainAttachHostPCIDevice (driver=0xfffbb4006750, vm=0xfffbf001f790, hostdev=0xfffbf400b150) at ../src/qemu/qemu_hotplug.c:1652 1652 if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0) 2. starting VM with interface with hostdev backend using iommufd 0x00007f6638d5b9ca in qemuProcessOpenVfioDeviceFd (hostdev=hostdev@entry=0x7f6634425ee0) at ../src/qemu/qemu_process.c:7719 7719 hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd); Proper fix for this issue is to refactor network code to use pointer and to use virDomainHostdevDefNew(). Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/conf/domain_conf.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3528b90742..8090becdcf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3517,6 +3517,20 @@ void virDomainVideoDefFree(virDomainVideoDef *def) } +static int +virDomainHostdevDefPrivateDataNew(virDomainHostdevDef *def, + virDomainXMLOption *xmlopt) +{ + if (!xmlopt || !xmlopt->privateData.hostdevNew) + return 0; + + if (!(def->privateData = xmlopt->privateData.hostdevNew())) + return -1; + + return 0; +} + + virDomainHostdevDef * virDomainHostdevDefNew(virDomainXMLOption *xmlopt) { @@ -3526,8 +3540,7 @@ virDomainHostdevDefNew(virDomainXMLOption *xmlopt) def->info = g_new0(virDomainDeviceInfo, 1); - if (xmlopt && xmlopt->privateData.hostdevNew && - !(def->privateData = xmlopt->privateData.hostdevNew())) { + if (virDomainHostdevDefPrivateDataNew(def, xmlopt) < 0) { VIR_FREE(def->info); VIR_FREE(def); return NULL; @@ -9739,6 +9752,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virDomainHostdevDef *hostdev = &actual->data.hostdev.def; int type; + if (virDomainHostdevDefPrivateDataNew(hostdev, xmlopt) < 0) + goto error; + hostdev->parentnet = parent; hostdev->info = &parent->info; /* The helper function expects type to already be found and @@ -10432,6 +10448,9 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, g_autofree char *addrtype = virXPathString("string(./source/address/@type)", ctxt); int type; + if (virDomainHostdevDefPrivateDataNew(&def->data.hostdev.def, xmlopt) < 0) + return NULL; + def->data.hostdev.def.parentnet = def; def->data.hostdev.def.info = &def->info; def->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; -- 2.53.0