[libvirt] [PATCH v2] qemu: Add flag to force a CDROM eject

Cole Robinson crobinso at redhat.com
Mon Nov 8 19:10:18 UTC 2010


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 at 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




More information about the libvir-list mailing list