]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
domain_conf: initialize network hostdev private data
authorPavel Hrdina <phrdina@redhat.com>
Thu, 26 Feb 2026 09:18:23 +0000 (10:18 +0100)
committerPavel Hrdina <phrdina@redhat.com>
Thu, 26 Feb 2026 10:00:15 +0000 (11:00 +0100)
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>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/conf/domain_conf.c

index 3528b9074208c9a817246ff1c3b5b7b0bb2aac8f..8090becdcf6a84ab84783db0711695c3e64465b7 100644 (file)
@@ -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;