From 96d52fcf43f61a95d3aec44aaf8738a1495e447a Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Mon, 8 Nov 2010 12:52:48 -0500 Subject: [PATCH] qemu: Add flag to force a CDROM eject 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 --- 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 81db3a269c..5c78270903 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 bb96c1f9b9..bed208fac5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7704,7 +7704,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; @@ -7765,7 +7766,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); @@ -8732,7 +8733,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; @@ -8919,10 +8921,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, @@ -8977,7 +8981,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 f65512dd12..27223f8145 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1147,10 +1147,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", @@ -1159,9 +1160,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 7d0914566e..41b3135d3e 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 d2c6f0a057..da51a4f5a8 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 94806c1063..c78ee24573 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 7f15008977..25521110e2 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 c017509298..983f402eda 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,