return true;
}
+static void
+virDomainDeviceInfoFree(virDomainDeviceInfoPtr info)
+{
+ if (info) {
+ virDomainDeviceInfoClear(info);
+ VIR_FREE(info);
+ }
+}
+
static void
virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr 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);
}
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;
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;
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) {
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;
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;
}
}
- if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
+ if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info))
goto cleanup;
identical = true;
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;
} caps;
} source;
virDomainHostdevOrigStates origstates;
- virDomainDeviceInfo info; /* Guest address */
+ virDomainDeviceInfoPtr info; /* Guest address */
};
/* Two types of disk backends */
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);
virDomainGraphicsSpiceZlibCompressionTypeToString;
virDomainGraphicsTypeFromString;
virDomainGraphicsTypeToString;
+virDomainHostdevDefAlloc;
+virDomainHostdevDefClear;
virDomainHostdevDefFree;
virDomainHostdevModeTypeToString;
virDomainHostdevSubsysTypeToString;
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;
}
}
- if (virAsprintf(&hostdev->info.alias, "hostdev%d", idx) < 0) {
+ if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0) {
virReportOOMError();
return -1;
}
/* 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;
}
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)) {
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)) {
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",
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;
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;
}
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:");
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;
def->source.subsys.u.usb.vendor = first;
def->source.subsys.u.usb.product = second;
}
-
-cleanup:
return def;
+
+ error:
+ virDomainHostdevDefFree(def);
+ return NULL;
}
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;
}
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,
&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)
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);
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"));
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);
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) {
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;
}
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)
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;
dev->source.subsys.u.pci.function = funcID;
if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0) {
+ virDomainHostdevDefFree(dev);
goto no_memory;
}
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;
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;