This patch strips reusable part of qemudDomainUpdateDeviceFlags()
and consolidate it to qemudDomainModifyDeviceFlags().
No functional changes.
Based on Eric's and Hu's work.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
* src/qemu/qemu_driver.c
(qemudDomainUpdateDeviceLive) : core of UpdateDevice, extracted from
UpdateDeviceFlags()
(qemudDomainUpdateDeviceFlags): reworked as a wrapper function of
ModifyDeviceFlags()
---
src/qemu/qemu_driver.c | 209 +++++++++++++++++++++---------------------------
1 files changed, 90 insertions(+), 119 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f33a7f4..2bdf42e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3991,6 +3991,74 @@ static int qemudDomainDetachDeviceLive(virDomainObjPtr vm,
return ret;
}
+static int
+qemudDomainChangeDiskMediaLive(virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ struct qemud_driver *driver,
+ virBitmapPtr qemuCaps,
+ bool force)
+{
+ virDomainDiskDefPtr disk = dev->data.disk;
+ virCgroupPtr cgroup = NULL;
+ int ret;
+
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
+ if (virCgroupForDomain(driver->cgroup,
+ vm->def->name, &cgroup, 0) !=0 ) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to find cgroup for %s"),
+ vm->def->name);
+ goto end;
+ }
+ if (qemuSetupDiskCgroup(driver, vm, cgroup, disk) < 0)
+ goto end;
+ }
+
+ switch (disk->device) {
+ case VIR_DOMAIN_DISK_DEVICE_CDROM:
+ case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
+ ret = qemuDomainChangeEjectableMedia(driver, vm, disk, qemuCaps, force);
+ if (ret == 0)
+ dev->data.disk = NULL;
+ break;
+ default:
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("disk bus '%s' cannot be updated."),
+ virDomainDiskBusTypeToString(disk->bus));
+ break;
+ }
+end:
+ if (cgroup)
+ virCgroupFree(&cgroup);
+ return ret;
+}
+
+static int qemudDomainUpdateDeviceLive(virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ virDomainPtr dom,
+ virBitmapPtr qemuCaps,
+ bool force)
+{
+ struct qemud_driver *driver = dom->conn->privateData;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_DEVICE_DISK:
+ ret = qemudDomainChangeDiskMediaLive(vm, dev, driver, qemuCaps, force);
+ break;
+ case VIR_DOMAIN_DEVICE_GRAPHICS:
+ ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics);
+ break;
+ default:
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("device type '%s' cannot be updated"),
+ virDomainDeviceTypeToString(dev->type));
+ break;
+ }
+
+ return ret;
+}
+
enum {
QEMUD_DEVICE_ATTACH, QEMUD_DEVICE_DETACH, QEMUD_DEVICE_UPDATE,
};
@@ -4002,10 +4070,25 @@ static int qemudDomainModifyDeviceFlags(virDomainPtr dom, const
char *xml,
virBitmapPtr qemuCaps = NULL;
virDomainObjPtr vm = NULL;
virDomainDeviceDefPtr dev = NULL;
+ bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0;
int ret = -1;
- virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE |
- VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1);
+ switch (action) {
+ case QEMUD_DEVICE_ATTACH:
+ case QEMUD_DEVICE_DETACH:
+ virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE |
+ VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1);
+ break;
+ case QEMUD_DEVICE_UPDATE:
+ virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_CURRENT |
+ VIR_DOMAIN_DEVICE_MODIFY_LIVE |
+ VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
+ VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
+ break;
+ default:
+ break;
+ }
+
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("cannot modify the persistent
configuration of a domain"));
@@ -4048,9 +4131,13 @@ static int qemudDomainModifyDeviceFlags(virDomainPtr dom, const
char *xml,
case QEMUD_DEVICE_DETACH:
ret = qemudDomainDetachDeviceLive(vm, dev, dom, qemuCaps);
break;
+ case QEMUD_DEVICE_UPDATE:
+ ret = qemudDomainUpdateDeviceLive(vm, dev, dom, qemuCaps, force);
+ break;
default:
break;
}
+
/*
* update domain status forcibly because the domain status may be changed
* even if we attach the device failed. For example, a new controller may
@@ -4089,125 +4176,9 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
const char *xml,
unsigned int flags)
{
- struct qemud_driver *driver = dom->conn->privateData;
- virDomainObjPtr vm;
- virDomainDeviceDefPtr dev = NULL;
- virBitmapPtr qemuCaps = NULL;
- virCgroupPtr cgroup = NULL;
- int ret = -1;
- bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0;
-
- virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_CURRENT |
- VIR_DOMAIN_DEVICE_MODIFY_LIVE |
- VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
- VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
-
- if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot modify the persistent
configuration of a domain"));
- return -1;
- }
-
- qemuDriverLock(driver);
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- if (!vm) {
- char uuidstr[VIR_UUID_STRING_BUFLEN];
- virUUIDFormat(dom->uuid, uuidstr);
- qemuReportError(VIR_ERR_NO_DOMAIN,
- _("no domain with matching uuid '%s'"),
uuidstr);
- goto cleanup;
- }
-
- if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
- goto cleanup;
-
- if (!virDomainObjIsActive(vm)) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot attach device on inactive
domain"));
- goto endjob;
- }
-
- dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
- VIR_DOMAIN_XML_INACTIVE);
- if (dev == NULL)
- goto endjob;
-
- if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch,
- NULL,
- &qemuCaps) < 0)
- goto endjob;
-
- switch (dev->type) {
- case VIR_DOMAIN_DEVICE_DISK:
- if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
- if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup,
0) !=0 ) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("Unable to find cgroup for %s"),
- vm->def->name);
- goto endjob;
- }
- if (qemuSetupDiskCgroup(driver, vm, cgroup, dev->data.disk) < 0)
- goto endjob;
- }
-
- switch (dev->data.disk->device) {
- case VIR_DOMAIN_DISK_DEVICE_CDROM:
- case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
- ret = qemuDomainChangeEjectableMedia(driver, vm,
- dev->data.disk,
- qemuCaps,
- force);
- if (ret == 0)
- dev->data.disk = NULL;
- break;
-
-
- default:
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("disk bus '%s' cannot be updated."),
- virDomainDiskBusTypeToString(dev->data.disk->bus));
- break;
- }
-
- if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(driver, vm, cgroup, dev->data.disk) < 0)
- VIR_WARN("Failed to teardown cgroup for disk path %s",
- NULLSTR(dev->data.disk->src));
- }
- break;
-
- case VIR_DOMAIN_DEVICE_GRAPHICS:
- ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics);
- break;
-
- default:
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("device type '%s' cannot be updated"),
- virDomainDeviceTypeToString(dev->type));
- break;
- }
-
- if (!ret && virDomainSaveStatus(driver->caps, driver->stateDir, vm)
< 0)
- ret = -1;
-
-endjob:
- if (qemuDomainObjEndJob(vm) == 0)
- vm = NULL;
-
-cleanup:
- if (cgroup)
- virCgroupFree(&cgroup);
-
- qemuCapsFree(qemuCaps);
- virDomainDeviceDefFree(dev);
- if (vm)
- virDomainObjUnlock(vm);
- qemuDriverUnlock(driver);
- return ret;
+ return qemudDomainModifyDeviceFlags(dom, xml, flags, QEMUD_DEVICE_UPDATE);
}
-
-
static int qemudDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
unsigned int flags)
{
--
1.7.4.1