]> xenbits.xensource.com Git - qemu-xen-4.4-testing.git/commitdiff
implement cdrom eject from the guest
authorIan Jackson <ian.jackson@eu.citrix.com>
Mon, 4 Jan 2010 16:21:55 +0000 (16:21 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Mon, 4 Jan 2010 16:21:55 +0000 (16:21 +0000)
Hi all,
this patch allows a guest to eject the cdrom: when qemu detects that a
cdrom eject request ahs been issued by the guest, it writes eject to the
corresponding xenstore frontend, so that the toolstack can take care of
removing the current cdrom frontend\backend couple and create an empty one
instead.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
hw/ide.c
qemu-xen.h
xenstore.c

index e8d676e8617ee73bf58f59c159eb6e8a146e7f7c..b38de553695bfd228398f66f06a5c2952e8f3a53 100644 (file)
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -35,6 +35,7 @@
 #include "mac_dbdma.h"
 #include "sh.h"
 #include "dma.h"
+#include "qemu-xen.h"
 
 /* debug IDE devices */
 //#define DEBUG_IDE
@@ -2100,6 +2101,7 @@ static void ide_atapi_cmd(IDEState *s)
 
             if (eject && !start) {
                 /* eject the disk */
+                xenstore_do_eject(s->bs);
                 bdrv_eject(s->bs, 1);
             } else if (eject && start) {
                 /* close the tray */
index 29b8161b84af6d8cfd9d892b0b6d08b7c01f7f63..ab4b631983a142f0c9b02a7690cb7526ac0aed8a 100644 (file)
@@ -123,6 +123,8 @@ char *xenstore_read_battery_data(int battery_status);
 int xenstore_refresh_battery_status(void);
 int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
                                          uint32_t build_nr);
+void xenstore_do_eject(BlockDriverState *bs);
+int xenstore_find_device(BlockDriverState *bs);
 
 /* xenfbfront.c */
 int xenfb_pv_display_init(DisplayState *ds);
index 50647197f32ec252516045fdfa72e65b535e5dae..05a1c22ef6d1f403bc067a0009b38834f0ad45c0 100644 (file)
 struct xs_handle *xsh = NULL;
 static char *media_filename[MAX_DRIVES+1];
 static QEMUTimer *insert_timer = NULL;
+static char *xenbus_param_paths[MAX_DRIVES+1];
+
+int xenstore_find_device(BlockDriverState *bs)
+{
+    int i;
+
+    for (i = 0; i < MAX_DRIVES + 1; i++) {
+        if (drives_table[i].bdrv == bs)
+            return i;
+    }
+    return -1;
+}
+
+void xenstore_do_eject(BlockDriverState *bs)
+{
+    int i;
+
+    i = xenstore_find_device(bs);
+    if (i == -1) {
+        fprintf(stderr, "couldn't find disk to eject.\n");
+        return;
+    }
+    if (xenbus_param_paths[i])
+        xs_write(xsh, XBT_NULL, xenbus_param_paths[i], "eject", strlen("eject"));
+}
 
 #define UWAIT_MAX (30*1000000) /* thirty seconds */
 #define UWAIT     (100000)     /* 1/10th second  */
@@ -526,8 +551,15 @@ void xenstore_parse_domain_config(int hvm_domid)
         /* check if it is a cdrom */
         if (danger_type && !strcmp(danger_type, "cdrom")) {
             bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
-            if (pasprintf(&buf, "%s/params", bpath) != -1)
+            if (pasprintf(&buf, "%s/params", bpath) != -1) {
+                char *buf2, *frontend;
                 xs_watch(xsh, buf, dev);
+                asprintf(&buf2, "%s/frontend", bpath);
+                frontend = xs_read(xsh, XBT_NULL, buf2, &len);
+                asprintf(&xenbus_param_paths[nb_drives], "%s/eject", frontend);
+                free(frontend);
+                free(buf2);
+            }
         }
 
         /* open device now if media present */