def->ncontrollers++;
}
+int
+virDomainControllerFind(virDomainDefPtr def,
+ int type, int idx)
+{
+ int i;
+
+ for (i = 0 ; i < def->ncontrollers ; i++) {
+ if ((def->controllers[i]->type == type) &&
+ (def->controllers[i]->idx == idx)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+virDomainControllerDefPtr
+virDomainControllerRemove(virDomainDefPtr def, size_t i)
+{
+ virDomainControllerDefPtr controller = def->controllers[i];
+
+ if (def->ncontrollers > 1) {
+ memmove(def->controllers + i,
+ def->controllers + i + 1,
+ sizeof(*def->controllers) *
+ (def->ncontrollers - (i + 1)));
+ def->ncontrollers--;
+ if (VIR_REALLOC_N(def->controllers, def->ncontrollers) < 0) {
+ /* ignore, harmless */
+ }
+ } else {
+ VIR_FREE(def->controllers);
+ def->ncontrollers = 0;
+ }
+
+ return controller;
+}
int virDomainLeaseIndex(virDomainDefPtr def,
virDomainLeaseDefPtr lease)
virDomainControllerDefPtr controller);
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
virDomainControllerDefPtr controller);
-
+int virDomainControllerFind(virDomainDefPtr def, int type, int idx);
+virDomainControllerDefPtr virDomainControllerRemove(virDomainDefPtr def, size_t i);
int virDomainLeaseIndex(virDomainDefPtr def,
virDomainLeaseDefPtr lease);
virDomainClockOffsetTypeToString;
virDomainConfigFile;
virDomainControllerDefFree;
+virDomainControllerFind;
virDomainControllerInsert;
virDomainControllerInsertPreAlloced;
virDomainControllerModelSCSITypeFromString;
virDomainControllerModelSCSITypeToString;
virDomainControllerModelUSBTypeFromString;
virDomainControllerModelUSBTypeToString;
+virDomainControllerRemove;
virDomainControllerTypeToString;
virDomainCpuPlacementModeTypeFromString;
virDomainCpuPlacementModeTypeToString;
virDomainNetDefPtr net;
virDomainHostdevDefPtr hostdev;
virDomainLeaseDefPtr lease;
+ virDomainControllerDefPtr controller;
switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
dev->data.lease = NULL;
break;
+ case VIR_DOMAIN_DEVICE_CONTROLLER:
+ controller = dev->data.controller;
+ if (virDomainControllerFind(vmdef, controller->type,
+ controller->idx) > 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Target already exists"));
+ return -1;
+ }
+
+ if (virDomainControllerInsert(vmdef, controller) < 0)
+ return -1;
+ dev->data.controller = NULL;
+
+ if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0)
+ return -1;
+ break;
+
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("persistent attach of device is not supported"));
virDomainNetDefPtr net, det_net;
virDomainHostdevDefPtr hostdev, det_hostdev;
virDomainLeaseDefPtr lease, det_lease;
+ virDomainControllerDefPtr cont, det_cont;
+ int idx;
switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
break;
case VIR_DOMAIN_DEVICE_HOSTDEV: {
- int idx;
-
hostdev = dev->data.hostdev;
if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
virDomainLeaseDefFree(det_lease);
break;
+ case VIR_DOMAIN_DEVICE_CONTROLLER:
+ cont = dev->data.controller;
+ if ((idx = virDomainControllerFind(vmdef, cont->type,
+ cont->idx)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("device not present in domain configuration"));
+ return -1;
+ }
+ det_cont = virDomainControllerRemove(vmdef, idx);
+ virDomainControllerDefFree(det_cont);
+
+ break;
+
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("persistent detach of device is not supported"));
virDomainObjPtr vm,
virDomainControllerDefPtr controller)
{
- int i;
int ret = -1;
const char* type = virDomainControllerTypeToString(controller->type);
char *devstr = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
bool releaseaddr = false;
- for (i = 0 ; i < vm->def->ncontrollers ; i++) {
- if ((vm->def->controllers[i]->type == controller->type) &&
- (vm->def->controllers[i]->idx == controller->idx)) {
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("target %s:%d already exists"),
- type, controller->idx);
- return -1;
- }
+ if (virDomainControllerFind(vm->def, controller->type, controller->idx) > 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("target %s:%d already exists"),
+ type, controller->idx);
+ return -1;
}
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
- int i, ret = -1;
+ int idx, ret = -1;
virDomainControllerDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
- for (i = 0 ; i < vm->def->ncontrollers ; i++) {
- if ((vm->def->controllers[i]->type == dev->data.controller->type) &&
- (vm->def->controllers[i]->idx == dev->data.controller->idx)) {
- detach = vm->def->controllers[i];
- break;
- }
- }
-
- if (!detach) {
+ if ((idx = virDomainControllerFind(vm->def,
+ dev->data.controller->type,
+ dev->data.controller->idx)) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("disk controller %s:%d not found"),
virDomainControllerTypeToString(dev->data.controller->type),
goto cleanup;
}
+ detach = vm->def->controllers[idx];
+
if (!virDomainDeviceAddressIsValid(&detach->info,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
- if (vm->def->ncontrollers > 1) {
- memmove(vm->def->controllers + i,
- vm->def->controllers + i + 1,
- sizeof(*vm->def->controllers) *
- (vm->def->ncontrollers - (i + 1)));
- vm->def->ncontrollers--;
- if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers) < 0) {
- /* ignore, harmless */
- }
- } else {
- VIR_FREE(vm->def->controllers);
- vm->def->ncontrollers = 0;
- }
+ virDomainControllerRemove(vm->def, idx);
+ virDomainControllerDefFree(detach);
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
detach->info.addr.pci.slot) < 0)
VIR_WARN("Unable to release PCI address on controller");
- virDomainControllerDefFree(detach);
-
ret = 0;
cleanup: