domain_conf: initialize network hostdev private data

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>
This commit is contained in:
Pavel Hrdina committed 2026-02-26 11:00:15 +01:00
1 parent 10d5a41231
commit fe782ed334
1 file changed
+21 -2
+21 -2
View 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;