In order to allow for a virDomainHostdevDef that uses the virDomainDeviceInfo of a "higher level" device (such as a virDomainNetDef), this patch changes the virDomainDeviceInfo in the HostdevDef into a virDomainDeviceInfoPtr. Rather than adding checks all over the code to check for a null info, we just guarantee that it is always valid. The new function virDomainHostdevDefAlloc() allocates a virDomainDeviceInfo and plugs it in, and virDomainHostdevDefFree() makes sure it is freed. There were 4 places allocating virDomainHostdevDefs, all of them parsers of one sort or another, and those have all had their VIR_ALLOC(hostdev) changed to virDomainHostdevDefAlloc(). Other than that, and the new functions, all the rest of the changes are just mechanical removals of "&" or changing "." to "->". --- V2: also add a virDomainDeviceInfoClear() function. src/conf/domain_conf.c | 63 +++++++++++++++++++++++++++------- src/conf/domain_conf.h | 4 ++- src/libvirt_private.syms | 2 + src/qemu/qemu_command.c | 83 ++++++++++++++++++++------------------------- src/qemu/qemu_hotplug.c | 28 ++++++++-------- src/xenxs/xen_sxpr.c | 5 ++- src/xenxs/xen_xm.c | 8 +++-- 7 files changed, 114 insertions(+), 79 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 03f8564..eb66223 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -786,6 +786,15 @@ bool virDomainObjTaint(virDomainObjPtr obj, return true; } +static void +virDomainDeviceInfoFree(virDomainDeviceInfoPtr info) +{ + if (info) { + virDomainDeviceInfoClear(info); + VIR_FREE(info); + } +} + static void virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr def) @@ -1294,12 +1303,42 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def) VIR_FREE(def); } +virDomainHostdevDefPtr virDomainHostdevDefAlloc(void) +{ + virDomainHostdevDefPtr def = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + if (VIR_ALLOC(def->info) < 0) { + virReportOOMError(); + VIR_FREE(def); + return NULL; + } + return def; +} + +void virDomainHostdevDefClear(virDomainHostdevDefPtr def) +{ + if (!def) + return; + + /* Free all resources in the hostdevdef. Currently the only + * such resource is the virDomainDeviceInfo. + */ + + virDomainDeviceInfoFree(def->info); +} + void virDomainHostdevDefFree(virDomainHostdevDefPtr def) { if (!def) return; - virDomainDeviceInfoClear(&def->info); + /* free all subordinate objects */ + virDomainHostdevDefClear(def); + VIR_FREE(def); } @@ -1877,7 +1916,7 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, device.type = VIR_DOMAIN_DEVICE_HOSTDEV; for (i = 0; i < def->nhostdevs ; i++) { device.data.hostdev = def->hostdevs[i]; - if (cb(def, &device, &def->hostdevs[i]->info, opaque) < 0) + if (cb(def, &device, def->hostdevs[i]->info, opaque) < 0) return -1; } device.type = VIR_DOMAIN_DEVICE_VIDEO; @@ -2743,14 +2782,14 @@ virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node, char *devaddr = virXMLPropString(cur, "devaddr"); if (devaddr && virDomainParseLegacyDeviceAddress(devaddr, - &def->info.addr.pci) < 0) { + &def->info->addr.pci) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to parse devaddr parameter '%s'"), devaddr); VIR_FREE(devaddr); goto out; } - def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + def->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else if ((flags & VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) && xmlStrEqual(cur->name, BAD_CAST "origstates")) { virDomainHostdevOrigStatesPtr states = &def->origstates; @@ -6379,10 +6418,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, virDomainHostdevDefPtr def; char *mode, *type = NULL, *managed = NULL; - if (VIR_ALLOC(def) < 0) { - virReportOOMError(); + if (!(def = virDomainHostdevDefAlloc())) return NULL; - } mode = virXMLPropString(node, "mode"); if (mode) { @@ -6445,8 +6482,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, cur = cur->next; } - if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (virDomainDeviceInfoParseXML(node, bootMap, def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) goto error; @@ -6455,8 +6492,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("PCI host devices must use 'pci' address type")); goto error; @@ -9015,7 +9052,7 @@ static bool virDomainHostdevDefCheckABIStability(virDomainHostdevDefPtr src, } } - if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info)) + if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info)) goto cleanup; identical = true; @@ -11551,7 +11588,7 @@ virDomainHostdevDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </source>\n"); - if (virDomainDeviceInfoFormat(buf, &def->info, + if (virDomainDeviceInfoFormat(buf, def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e9f2391..7815ee7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -380,7 +380,7 @@ struct _virDomainHostdevDef { } caps; } source; virDomainHostdevOrigStates origstates; - virDomainDeviceInfo info; /* Guest address */ + virDomainDeviceInfoPtr info; /* Guest address */ }; /* Two types of disk backends */ @@ -1773,6 +1773,8 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def); void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def); void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); void virDomainVideoDefFree(virDomainVideoDefPtr def); +virDomainHostdevDefPtr virDomainHostdevDefAlloc(void); +void virDomainHostdevDefClear(virDomainHostdevDefPtr def); void virDomainHostdevDefFree(virDomainHostdevDefPtr def); void virDomainHubDefFree(virDomainHubDefPtr def); void virDomainRedirdevDefFree(virDomainRedirdevDefPtr def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b9baf9a..b2c0c71 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -351,6 +351,8 @@ virDomainGraphicsSpiceZlibCompressionTypeFromString; virDomainGraphicsSpiceZlibCompressionTypeToString; virDomainGraphicsTypeFromString; virDomainGraphicsTypeToString; +virDomainHostdevDefAlloc; +virDomainHostdevDefClear; virDomainHostdevDefFree; virDomainHostdevModeTypeToString; virDomainHostdevSubsysTypeToString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index de3054a..db02323 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -570,7 +570,7 @@ qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev idx = 0; for (i = 0 ; i < def->nhostdevs ; i++) { int thisidx; - if ((thisidx = qemuDomainDeviceAliasIndex(&def->hostdevs[i]->info, "hostdev")) < 0) { + if ((thisidx = qemuDomainDeviceAliasIndex(def->hostdevs[i]->info, "hostdev")) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to determine device index for hostdev device")); return -1; @@ -580,7 +580,7 @@ qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev } } - if (virAsprintf(&hostdev->info.alias, "hostdev%d", idx) < 0) { + if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0) { virReportOOMError(); return -1; } @@ -1421,13 +1421,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) /* Host PCI devices */ for (i = 0; i < def->nhostdevs ; i++) { - if (def->hostdevs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + if (def->hostdevs[i]->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) continue; if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; - if (qemuDomainPCIAddressSetNextAddr(addrs, &def->hostdevs[i]->info) < 0) + if (qemuDomainPCIAddressSetNextAddr(addrs, def->hostdevs[i]->info) < 0) goto error; } @@ -2979,14 +2979,14 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, dev->source.subsys.u.pci.bus, dev->source.subsys.u.pci.slot, dev->source.subsys.u.pci.function); - virBufferAsprintf(&buf, ",id=%s", dev->info.alias); + virBufferAsprintf(&buf, ",id=%s", dev->info->alias); if (configfd && *configfd) virBufferAsprintf(&buf, ",configfd=%s", configfd); - if (dev->info.bootIndex) - virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (dev->info->bootIndex) + virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex); + if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0) goto error; - if (qemuBuildRomStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0) goto error; if (virBufferError(&buf)) { @@ -3072,9 +3072,9 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, virBufferAsprintf(&buf, "usb-host,hostbus=%d,hostaddr=%d,id=%s", dev->source.subsys.u.usb.bus, dev->source.subsys.u.usb.device, - dev->info.alias); + dev->info->alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0) goto error; if (virBufferError(&buf)) { @@ -5701,7 +5701,7 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainHostdevDefPtr hostdev = def->hostdevs[i]; char *devstr; - if (hostdev->info.bootIndex) { + if (hostdev->info->bootIndex) { if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -6653,43 +6653,37 @@ cleanup: static virDomainHostdevDefPtr qemuParseCommandLinePCI(const char *val) { - virDomainHostdevDefPtr def = NULL; int bus = 0, slot = 0, func = 0; const char *start; char *end; + virDomainHostdevDefPtr def = virDomainHostdevDefAlloc(); + + if (!def) + goto error; if (!STRPREFIX(val, "host=")) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("unknown PCI device syntax '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = val + strlen("host="); if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract PCI device bus '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = end + 1; if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract PCI device slot '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = end + 1; if (virStrToLong_i(start, NULL, 16, &func) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract PCI device function '%s'"), val); - VIR_FREE(def); - goto cleanup; - } - - if (VIR_ALLOC(def) < 0) { - virReportOOMError(); - goto cleanup; + goto error; } def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; @@ -6698,9 +6692,11 @@ qemuParseCommandLinePCI(const char *val) def->source.subsys.u.pci.bus = bus; def->source.subsys.u.pci.slot = slot; def->source.subsys.u.pci.function = func; - -cleanup: return def; + + error: + virDomainHostdevDefFree(def); + return NULL; } @@ -6710,16 +6706,18 @@ cleanup: static virDomainHostdevDefPtr qemuParseCommandLineUSB(const char *val) { - virDomainHostdevDefPtr def = NULL; + virDomainHostdevDefPtr def = virDomainHostdevDefAlloc(); int first = 0, second = 0; const char *start; char *end; + if (!def) + goto error; + if (!STRPREFIX(val, "host:")) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("unknown USB device syntax '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = val + strlen("host:"); @@ -6727,37 +6725,28 @@ qemuParseCommandLineUSB(const char *val) if (virStrToLong_i(start, &end, 16, &first) < 0 || *end != ':') { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract USB device vendor '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = end + 1; if (virStrToLong_i(start, NULL, 16, &second) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract USB device product '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } } else { if (virStrToLong_i(start, &end, 10, &first) < 0 || *end != '.') { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract USB device bus '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } start = end + 1; if (virStrToLong_i(start, NULL, 10, &second) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot extract USB device address '%s'"), val); - VIR_FREE(def); - goto cleanup; + goto error; } } - if (VIR_ALLOC(def) < 0) { - virReportOOMError(); - goto cleanup; - } - def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; def->managed = 0; def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; @@ -6768,9 +6757,11 @@ qemuParseCommandLineUSB(const char *val) def->source.subsys.u.usb.vendor = first; def->source.subsys.u.usb.product = second; } - -cleanup: return def; + + error: + virDomainHostdevDefFree(def); + return NULL; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index a7f0899..e727cfe 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -918,14 +918,14 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) goto error; - if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info) < 0) + if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0) goto error; releaseaddr = true; if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { configfd = qemuOpenPCIConfig(hostdev); if (configfd >= 0) { if (virAsprintf(&configfd_name, "fd-%s", - hostdev->info.alias) < 0) { + hostdev->info->alias) < 0) { virReportOOMError(); goto error; } @@ -947,7 +947,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, configfd, configfd_name); qemuDomainObjExitMonitorWithDriver(driver, vm); } else { - virDomainDevicePCIAddress guestAddr = hostdev->info.addr.pci; + virDomainDevicePCIAddress guestAddr = hostdev->info->addr.pci; qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorAddPCIHostDevice(priv->mon, @@ -955,8 +955,8 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, &guestAddr); qemuDomainObjExitMonitorWithDriver(driver, vm); - hostdev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - memcpy(&hostdev->info.addr.pci, &guestAddr, sizeof(guestAddr)); + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + memcpy(&hostdev->info->addr.pci, &guestAddr, sizeof(guestAddr)); } virDomainAuditHostdev(vm, hostdev, "attach", ret == 0); if (ret < 0) @@ -972,10 +972,10 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, error: if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && - (hostdev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && + (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, - hostdev->info.addr.pci.slot) < 0) + hostdev->info->addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on host device"); qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1); @@ -2018,14 +2018,14 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, return -1; } - if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { + if (qemuIsMultiFunctionDevice(vm->def, detach->info)) { qemuReportError(VIR_ERR_OPERATION_FAILED, _("cannot hot unplug multifunction PCI device: %s"), dev->data.disk->dst); return -1; } - if (!virDomainDeviceAddressIsValid(&detach->info, + if (!virDomainDeviceAddressIsValid(detach->info, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a PCI address")); @@ -2034,9 +2034,9 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - ret = qemuMonitorDelDevice(priv->mon, detach->info.alias); + ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); } else { - ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info.addr.pci); + ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci); } qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditHostdev(vm, detach, "detach", ret == 0); @@ -2062,7 +2062,7 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, - detach->info.addr.pci.slot) < 0) + detach->info->addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on host device"); if (vm->def->nhostdevs > 1) { @@ -2131,7 +2131,7 @@ qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, return -1; } - if (!detach->info.alias) { + if (!detach->info->alias) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a device alias")); return -1; @@ -2144,7 +2144,7 @@ qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info.alias); + ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditHostdev(vm, detach, "detach", ret == 0); if (ret < 0) diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index f8390ea..8994cbc 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -1076,8 +1076,8 @@ xenParseSxprPCI(virDomainDefPtr def, goto error; } - if (VIR_ALLOC(dev) < 0) - goto no_memory; + if (!(dev = virDomainHostdevDefAlloc())) + goto error; dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; dev->managed = 0; @@ -1088,6 +1088,7 @@ xenParseSxprPCI(virDomainDefPtr def, dev->source.subsys.u.pci.function = funcID; if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0) { + virDomainHostdevDefFree(dev); goto no_memory; } diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c index e580a3e..5862168 100644 --- a/src/xenxs/xen_xm.c +++ b/src/xenxs/xen_xm.c @@ -815,8 +815,8 @@ xenParseXM(virConfPtr conf, int xendConfigVersion, if (virStrToLong_i(func, NULL, 16, &funcID) < 0) goto skippci; - if (VIR_ALLOC(hostdev) < 0) - goto no_memory; + if (!(hostdev = virDomainHostdevDefAlloc())) + goto cleanup; hostdev->managed = 0; hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; @@ -825,8 +825,10 @@ xenParseXM(virConfPtr conf, int xendConfigVersion, hostdev->source.subsys.u.pci.slot = slotID; hostdev->source.subsys.u.pci.function = funcID; - if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0) + if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0) { + virDomainHostdevDefFree(hostdev); goto no_memory; + } def->hostdevs[def->nhostdevs++] = hostdev; hostdev = NULL; -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list