QEMU allows forcing a CDROM eject even if the guest has locked the device.
Expose this via a new UpdateDevice flag, VIR_DOMAIN_DEVICE_MODIFY_FORCE.
This has been requested for RHEV:
https://bugzilla.redhat.com/show_bug.cgi?id=626305
v2: Change flag name, bool cleanups
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
include/libvirt/libvirt.h.in | 2 ++
src/qemu/qemu_driver.c | 15 ++++++++++-----
src/qemu/qemu_monitor.c | 9 +++++----
src/qemu/qemu_monitor.h | 6 ++----
src/qemu/qemu_monitor_json.c | 5 +++--
src/qemu/qemu_monitor_json.h | 3 ++-
src/qemu/qemu_monitor_text.c | 5 +++--
src/qemu/qemu_monitor_text.h | 3 ++-
8 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 81db3a2..5c78270 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1033,6 +1033,8 @@ typedef enum {
VIR_DOMAIN_DEVICE_MODIFY_CURRENT = 0, /* Modify device allocation based on current
domain state */
VIR_DOMAIN_DEVICE_MODIFY_LIVE = (1 << 0), /* Modify live device allocation */
VIR_DOMAIN_DEVICE_MODIFY_CONFIG = (1 << 1), /* Modify persisted device
allocation */
+ VIR_DOMAIN_DEVICE_MODIFY_FORCE = (1 << 2), /* Forcibly modify device
+ (ex. force eject a cdrom) */
} virDomainDeviceModifyFlags;
int virDomainAttachDevice(virDomainPtr domain, const char *xml);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e7b37e1..2728448 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7686,7 +7686,8 @@ cleanup:
static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
- unsigned long long qemuCmdFlags)
+ unsigned long long qemuCmdFlags,
+ bool force)
{
virDomainDiskDefPtr origdisk = NULL;
int i;
@@ -7747,7 +7748,7 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver
*driver,
driveAlias,
disk->src, format);
} else {
- ret = qemuMonitorEjectMedia(priv->mon, driveAlias);
+ ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
@@ -8719,7 +8720,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
ret = qemudDomainChangeEjectableMedia(driver, vm,
dev->data.disk,
- qemuCmdFlags);
+ qemuCmdFlags,
+ false);
if (ret == 0)
dev->data.disk = NULL;
break;
@@ -8906,10 +8908,12 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
unsigned long long qemuCmdFlags;
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, -1);
+ VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
+ VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
@@ -8964,7 +8968,8 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
ret = qemudDomainChangeEjectableMedia(driver, vm,
dev->data.disk,
- qemuCmdFlags);
+ qemuCmdFlags,
+ force);
if (ret == 0)
dev->data.disk = NULL;
break;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 2366fdb..3600fd8 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1146,10 +1146,11 @@ int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, int online)
int qemuMonitorEjectMedia(qemuMonitorPtr mon,
- const char *devname)
+ const char *devname,
+ bool force)
{
int ret;
- DEBUG("mon=%p devname=%s", mon, devname);
+ DEBUG("mon=%p devname=%s force=%d", mon, devname, force);
if (!mon) {
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -1158,9 +1159,9 @@ int qemuMonitorEjectMedia(qemuMonitorPtr mon,
}
if (mon->json)
- ret = qemuMonitorJSONEjectMedia(mon, devname);
+ ret = qemuMonitorJSONEjectMedia(mon, devname, force);
else
- ret = qemuMonitorTextEjectMedia(mon, devname);
+ ret = qemuMonitorTextEjectMedia(mon, devname, force);
return ret;
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7d09145..41b3135 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -203,12 +203,10 @@ int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, int online);
/* XXX should we pass the virDomainDiskDefPtr instead
* and hide devname details inside monitor. Reconsider
* this when doing the QMP implementation
- *
- * XXXX 'eject' has gained a 'force' flag we might like
- * to make use of...
*/
int qemuMonitorEjectMedia(qemuMonitorPtr mon,
- const char *devname);
+ const char *devname,
+ bool force);
int qemuMonitorChangeMedia(qemuMonitorPtr mon,
const char *devname,
const char *newmedia,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d2c6f0a..da51a4f 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1348,12 +1348,13 @@ cleanup:
int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
- const char *devname)
+ const char *devname,
+ bool force)
{
int ret;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("eject",
"s:device", devname,
- "b:force", 0,
+ "b:force", force ? 1 : 0,
NULL);
virJSONValuePtr reply = NULL;
if (!cmd)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 94806c1..c78ee24 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -68,7 +68,8 @@ int qemuMonitorJSONSetBalloon(qemuMonitorPtr mon,
int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, int cpu, int online);
int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
- const char *devname);
+ const char *devname,
+ bool force);
int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
const char *devname,
const char *newmedia,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 7f15008..2552111 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -848,13 +848,14 @@ int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, int online)
int qemuMonitorTextEjectMedia(qemuMonitorPtr mon,
- const char *devname)
+ const char *devname,
+ bool force)
{
char *cmd = NULL;
char *reply = NULL;
int ret = -1;
- if (virAsprintf(&cmd, "eject %s", devname) < 0) {
+ if (virAsprintf(&cmd, "eject %s%s", force ? "-f " :
"", devname) < 0) {
virReportOOMError();
goto cleanup;
}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index c017509..983f402 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -66,7 +66,8 @@ int qemuMonitorTextSetBalloon(qemuMonitorPtr mon,
int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, int online);
int qemuMonitorTextEjectMedia(qemuMonitorPtr mon,
- const char *devname);
+ const char *devname,
+ bool force);
int qemuMonitorTextChangeMedia(qemuMonitorPtr mon,
const char *devname,
const char *newmedia,
--
1.7.2.1