WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] libxenlight: implement cdrom insert/eject

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] libxenlight: implement cdrom insert/eject
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 08 Dec 2009 06:20:17 -0800
Delivery-date: Tue, 08 Dec 2009 06:20:31 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1260258472 0
# Node ID 91555131e235f814e68179dc5ffd6b698be882be
# Parent  d988dd0f05f24ad3c5b1f6b84b28b8b3e93f6005
libxenlight: implement cdrom insert/eject

This patch implements functions in libxenlight to change the cdrom in
a VM at run time and to handle cdrom eject requests from guests.

This patch adds two new commands to xl: cd-insert and cd-eject; it
also modifies xl to handle cdrom eject requests coming from guests
(actually coming from qemu).

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/libxl/libxl.c          |  202 +++++++++++++++++++++++++++++++++++++++----
 tools/libxl/libxl.h          |   38 +++++++-
 tools/libxl/libxl_device.c   |    2 
 tools/libxl/libxl_internal.h |    2 
 tools/libxl/libxl_utils.c    |   30 ++++++
 tools/libxl/libxl_utils.h    |    1 
 tools/libxl/xl.c             |  172 ++++++++++++++++++++++++++++++++----
 7 files changed, 411 insertions(+), 36 deletions(-)

diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl.c       Tue Dec 08 07:47:52 2009 +0000
@@ -460,25 +460,80 @@ int libxl_domain_shutdown(struct libxl_c
     return 0;
 }
 
-int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd)
-{
-    if (!xs_watch(ctx->xsh, "@releaseDomain", "domain_death"))
+int libxl_get_wait_fd(struct libxl_ctx *ctx, int *fd)
+{
+    *fd = xs_fileno(ctx->xsh);
+    return 0;
+}
+
+int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, 
libxl_waiter *waiter)
+{
+    waiter->path = strdup("@releaseDomain");
+    asprintf(&(waiter->token), "%d", DOMAIN_DEATH);
+    if (!xs_watch(ctx->xsh, waiter->path, waiter->token))
         return -1;
-    *fd = xs_fileno(ctx->xsh);
-    return 0;
-}
-
-int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t 
*info)
+    return 0;
+}
+
+int libxl_wait_for_disk_ejects(struct libxl_ctx *ctx, uint32_t guest_domid, 
libxl_device_disk *disks, int num_disks, libxl_waiter *waiter)
+{
+    int i;
+    uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid);
+
+    if (!domid)
+        domid = guest_domid;
+
+    for (i = 0; i < num_disks; i++) {
+        asprintf(&(waiter[i].path), "%s/device/vbd/%d/eject", 
libxl_xs_get_dompath(ctx, domid), device_disk_dev_number(disks[i].virtpath));
+        asprintf(&(waiter[i].token), "%d", DISK_EJECT);
+        xs_watch(ctx->xsh, waiter->path, waiter->token);
+    }
+    return 0;
+}
+
+int libxl_get_event(struct libxl_ctx *ctx, libxl_event *event)
 {
     unsigned int num;
+    char **events = xs_read_watch(ctx->xsh, &num);
+    if (num != 2) {
+        free(events);
+        return -1;
+    }
+    event->path = strdup(events[XS_WATCH_PATH]);
+    event->token = strdup(events[XS_WATCH_TOKEN]);
+    event->type = atoi(event->token);
+    free(events);
+    return 0;
+}
+
+int libxl_stop_waiting(struct libxl_ctx *ctx, libxl_waiter *waiter)
+{
+    if (!xs_unwatch(ctx->xsh, waiter->path, waiter->token))
+        return -1;
+    else
+        return 0;
+}
+
+int libxl_free_event(libxl_event *event)
+{
+    free(event->path);
+    free(event->token);
+    return 0;
+}
+
+int libxl_free_waiter(libxl_waiter *waiter)
+{
+    free(waiter->path);
+    free(waiter->token);
+    return 0;
+}
+
+int libxl_event_get_domain_death_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, xc_dominfo_t *info)
+{
     int nb_domain, i, rc = 0;
-    char **vec = NULL;
     xc_dominfo_t *list = NULL;
 
-    vec = xs_read_watch(ctx->xsh, &num);
-    if (!vec)
-        return 0;
-    if (!strcmp(vec[XS_WATCH_TOKEN], "domain_death")) {
+    if (event && event->type == DOMAIN_DEATH) {
         list = libxl_domain_infolist(ctx, &nb_domain);
         for (i = 0; i < nb_domain; i++) {
             if (domid == list[i].domid) {
@@ -493,11 +548,39 @@ int libxl_is_domain_dead(struct libxl_ct
         rc = 1;
         goto out;
     }
-
 out:
     free(list);
-    free(vec);
     return rc;
+}
+
+int libxl_event_get_disk_eject_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, libxl_device_disk *disk)
+{
+    if (event && event->type == DISK_EJECT) {
+        char *path;
+        char *backend;
+        char *value = libxl_xs_read(ctx, XBT_NULL, event->path);
+
+        if (!value || strcmp(value,  "eject"))
+            return 0;
+
+        path = strdup(event->path);
+        path[strlen(path) - 6] = '\0';
+        backend = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/backend", path));
+
+        disk->backend_domid = 0;
+        disk->domid = domid;
+        disk->physpath = NULL;
+        disk->phystype = 0;
+        /* this value is returned to the user: do not free right away */
+        disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/dev", backend));
+        disk->unpluggable = 1;
+        disk->readwrite = 0;
+        disk->is_cdrom = 1;
+
+        free(path);
+        return 1;
+    }
+    return 0;
 }
 
 static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid)
@@ -1419,6 +1502,95 @@ int libxl_device_vkb_hard_shutdown(struc
 int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
 {
     return ERROR_NI;
+}
+
+libxl_device_disk *libxl_device_disk_list(struct libxl_ctx *ctx, uint32_t 
domid, int *num)
+{
+    char *be_path_tap, *be_path_vbd;
+    libxl_device_disk *disks = NULL;
+    char **l = NULL;
+    unsigned int numl;
+    int num_disks = 0, i;
+    char *type;
+
+    be_path_vbd = libxl_sprintf(ctx, "%s/backend/vbd/%d", 
libxl_xs_get_dompath(ctx, 0), domid);
+    be_path_tap = libxl_sprintf(ctx, "%s/backend/tap/%d", 
libxl_xs_get_dompath(ctx, 0), domid);
+
+    l = libxl_xs_directory(ctx, XBT_NULL, be_path_vbd, &numl);
+    if (l) {
+        num_disks += numl;
+        disks = realloc(disks, sizeof(libxl_device_disk) * num_disks);
+        for (i = 0; i < numl; i++) {
+            disks[i].backend_domid = 0;
+            disks[i].domid = domid;
+            disks[i].physpath = libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/params", be_path_vbd, l[i]));
+            libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/type", be_path_vbd, l[i])), &(disks[i].phystype));
+            disks[i].virtpath = libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/dev", be_path_vbd, l[i]));
+            disks[i].unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/removable", be_path_vbd, l[i])));
+            if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/mode", be_path_vbd, l[i])), "w"))
+                disks[i].readwrite = 1;
+            else
+                disks[i].readwrite = 0;
+            type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/frontend", be_path_vbd, l[i]))));
+            disks[i].is_cdrom = !strcmp(type, "cdrom");
+        }
+        free(l);
+    }
+    l = libxl_xs_directory(ctx, XBT_NULL, be_path_tap, &numl);
+    if (l) {
+        num_disks += numl;
+        disks = realloc(disks, sizeof(libxl_device_disk) * num_disks);
+        for (i = 0; i < numl; i++) {
+            disks[i].backend_domid = 0;
+            disks[i].domid = domid;
+            disks[i].physpath = libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/params", be_path_tap, l[i]));
+            libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/type", be_path_tap, l[i])), &(disks[i].phystype));
+            disks[i].virtpath = libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/dev", be_path_tap, l[i]));
+            disks[i].unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/removable", be_path_tap, l[i])));
+            if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/mode", be_path_tap, l[i])), "w"))
+                disks[i].readwrite = 1;
+            else
+                disks[i].readwrite = 0;
+            type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/frontend", be_path_vbd, l[i]))));
+            disks[i].is_cdrom = !strcmp(type, "cdrom");
+        }
+        free(l);
+    }
+    *num = num_disks;
+    return disks;
+}
+
+int libxl_cdrom_insert(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disk)
+{
+    int num, i;
+    uint32_t stubdomid;
+    libxl_device_disk *disks;
+
+    if (!disk->physpath) {
+        disk->physpath = "";
+        disk->phystype = PHYSTYPE_PHY;
+    }
+    disks = libxl_device_disk_list(ctx, domid, &num);
+    for (i = 0; i < num; i++) {
+        if (disks[i].is_cdrom && !strcmp(disk->virtpath, disks[i].virtpath))
+            /* found */
+            break;
+    }
+    if (i == num) {
+        XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found");
+        return -1;
+    }
+    libxl_device_disk_del(ctx, disks + i, 1);
+    libxl_device_disk_add(ctx, domid, disk);
+    stubdomid = libxl_get_stubdom_id(ctx, domid);
+    if (stubdomid) {
+        disk_info_domid_fixup(disks + i, stubdomid);
+        libxl_device_disk_del(ctx, disks + i, 1);
+        disk_info_domid_fixup(disk, stubdomid);
+        libxl_device_disk_add(ctx, stubdomid, disk);
+        disk_info_domid_fixup(disk, domid);
+    }
+    return 0;
 }
 
 
/******************************************************************************/
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl.h       Tue Dec 08 07:47:52 2009 +0000
@@ -267,8 +267,40 @@ int libxl_domain_shutdown(struct libxl_c
 int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req);
 int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
 
-int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int 
*fd);
-int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t 
*info);
+/* events handling */
+
+typedef enum {
+    DOMAIN_DEATH,
+    DISK_EJECT,
+} libxl_event_type;
+
+typedef struct {
+    /* event type */
+    libxl_event_type type;
+    /* data for internal use of the library */
+    char *path;
+    char *token;
+} libxl_event;
+
+typedef struct {
+    char *path;
+    char *token;
+} libxl_waiter;
+
+
+int libxl_get_wait_fd(struct libxl_ctx *ctx, int *fd);
+/* waiter is allocated by the caller */
+int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, 
libxl_waiter *waiter);
+/* waiter is a preallocated array of num_disks libxl_waiter elements */
+int libxl_wait_for_disk_ejects(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disks, int num_disks, libxl_waiter *waiter);
+int libxl_get_event(struct libxl_ctx *ctx, libxl_event *event);
+int libxl_stop_waiting(struct libxl_ctx *ctx, libxl_waiter *waiter);
+int libxl_free_event(libxl_event *event);
+int libxl_free_waiter(libxl_waiter *waiter);
+
+int libxl_event_get_domain_death_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, xc_dominfo_t *info);
+int libxl_event_get_disk_eject_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, libxl_device_disk *disk);
+
 
 int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid);
 int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid);
@@ -299,6 +331,8 @@ int libxl_detach_device_model(struct lib
 
 int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disk);
 int libxl_device_disk_del(struct libxl_ctx *ctx, libxl_device_disk *disk, int 
wait);
+libxl_device_disk *libxl_device_disk_list(struct libxl_ctx *ctx, uint32_t 
domid, int *num);
+int libxl_cdrom_insert(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disk);
 
 int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_nic *nic);
 int libxl_device_nic_del(struct libxl_ctx *ctx, libxl_device_nic *nic, int 
wait);
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl_device.c        Tue Dec 08 07:47:52 2009 +0000
@@ -26,7 +26,7 @@
 #include "libxl.h"
 #include "libxl_internal.h"
 
-char *string_of_kinds[] = {
+const char *string_of_kinds[] = {
     [DEVICE_VIF] = "vif",
     [DEVICE_VBD] = "vbd",
     [DEVICE_TAP] = "tap",
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl_internal.h      Tue Dec 08 07:47:52 2009 +0000
@@ -44,6 +44,8 @@ typedef enum {
     DEVICE_VKBD,
     DEVICE_CONSOLE,
 } libxl_device_kinds;
+
+extern const char *string_of_kinds[];
 
 typedef struct {
     uint32_t backend_devid;
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl_utils.c Tue Dec 08 07:47:52 2009 +0000
@@ -214,3 +214,33 @@ int libxl_create_logfile(struct libxl_ct
     return 0;
 }
 
+int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, 
libxl_disk_phystype *phystype)
+{
+    char *p;
+    int rc = 0;
+
+    if (!strcmp(s, "phy")) {
+        *phystype = PHYSTYPE_PHY;
+    } else if (!strcmp(s, "file")) {
+        *phystype = PHYSTYPE_FILE;
+    } else if (!strcmp(s, "tap")) {
+        p = strchr(s, ':');
+        if (!p) {
+            rc = -1;
+            goto out;
+        }
+        p++;
+        if (!strcmp(p, "aio")) {
+            *phystype = PHYSTYPE_AIO;
+        } else if (!strcmp(p, "vhd")) {
+            *phystype = PHYSTYPE_VHD;
+        } else if (!strcmp(p, "qcow")) {
+            *phystype = PHYSTYPE_QCOW;
+        } else if (!strcmp(p, "qcow2")) {
+            *phystype = PHYSTYPE_QCOW2;
+        }
+    }
+out:
+    return rc;
+}
+
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/libxl_utils.h Tue Dec 08 07:47:52 2009 +0000
@@ -32,6 +32,7 @@ int libxl_get_stubdom_id(struct libxl_ct
 int libxl_get_stubdom_id(struct libxl_ctx *ctx, int guest_domid);
 int libxl_is_stubdom(struct libxl_ctx *ctx, int domid);
 int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name);
+int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, 
libxl_disk_phystype *phystype);
 
 #endif
 
diff -r d988dd0f05f2 -r 91555131e235 tools/libxl/xl.c
--- a/tools/libxl/xl.c  Tue Dec 08 07:45:15 2009 +0000
+++ b/tools/libxl/xl.c  Tue Dec 08 07:47:52 2009 +0000
@@ -356,12 +356,14 @@ static void parse_config_file(const char
             if (p2 == NULL) {
                 (*disks)[*num_disks].virtpath = strdup(p);
                 (*disks)[*num_disks].is_cdrom = 0;
+                (*disks)[*num_disks].unpluggable = 1;
             } else {
                 *p2 = '\0';
                 (*disks)[*num_disks].virtpath = strdup(p);
-                if (!strcmp(p2 + 1, "cdrom"))
+                if (!strcmp(p2 + 1, "cdrom")) {
                     (*disks)[*num_disks].is_cdrom = 1;
-                else
+                    (*disks)[*num_disks].unpluggable = 1;
+                } else
                     (*disks)[*num_disks].is_cdrom = 0;
             }
             p = strtok(NULL, ",");
@@ -594,6 +596,7 @@ static void create_domain(int debug, con
     int i, fd;
     int need_daemon = 1;
     libxl_device_model_starting *dm_starting = 0;
+    libxl_waiter *w1 = NULL, *w2 = NULL;
     memset(&dm_info, 0x00, sizeof(dm_info));
 
     printf("Parsing config file %s\n", config_file);
@@ -671,12 +674,17 @@ start:
         need_daemon = 0;
     }
     XL_LOG(&ctx, XL_LOG_DEBUG, "Waiting for domain %s (domid %d) to die", 
info1.name, domid);
-    
-    libxl_wait_for_domain_death(&ctx, domid, &fd);
+    w1 = (libxl_waiter*) malloc(sizeof(libxl_waiter) * num_disks);
+    w2 = (libxl_waiter*) malloc(sizeof(libxl_waiter));
+    libxl_wait_for_disk_ejects(&ctx, domid, disks, num_disks, w1);
+    libxl_wait_for_domain_death(&ctx, domid, w2);
+    libxl_get_wait_fd(&ctx, &fd);
     while (1) {
         int ret;
         fd_set rfds;
         xc_dominfo_t info;
+        libxl_event event;
+        libxl_device_disk disk;
         memset(&info, 0x00, sizeof(xc_dominfo_t));
 
         FD_ZERO(&rfds);
@@ -685,21 +693,35 @@ start:
         ret = select(fd + 1, &rfds, NULL, NULL, NULL);
         if (!ret)
             continue;
-        if (libxl_is_domain_dead(&ctx, domid, &info)) {
-            XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d is dead", domid);
-            if (info.crashed || info.dying || (info.shutdown && 
(info.shutdown_reason != SHUTDOWN_suspend))) {
-                XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d needs to be clean: 
destroying the domain", domid);
-                libxl_domain_destroy(&ctx, domid, 0);
-                if (info.shutdown && (info.shutdown_reason == 
SHUTDOWN_reboot)) {
-                    libxl_ctx_free(&ctx);
-                    XL_LOG(&ctx, XL_LOG_DEBUG, "Done. Rebooting now");
-                    goto start;
+        libxl_get_event(&ctx, &event);
+        switch (event.type) {
+            case DOMAIN_DEATH:
+                if (libxl_event_get_domain_death_info(&ctx, domid, &event, 
&info)) {
+                    XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d is dead", domid);
+                    if (info.crashed || info.dying || (info.shutdown && 
(info.shutdown_reason != SHUTDOWN_suspend))) {
+                        XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d needs to be 
clean: destroying the domain", domid);
+                        libxl_domain_destroy(&ctx, domid, 0);
+                        if (info.shutdown && (info.shutdown_reason == 
SHUTDOWN_reboot)) {
+                            libxl_free_waiter(w1);
+                            libxl_free_waiter(w2);
+                            free(w1);
+                            free(w2);
+                            libxl_ctx_free(&ctx);
+                            XL_LOG(&ctx, XL_LOG_DEBUG, "Done. Rebooting now");
+                            goto start;
+                        }
+                        XL_LOG(&ctx, XL_LOG_DEBUG, "Done. Exiting now");
+                    }
+                    XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d does not need to be 
clean, exiting now", domid);
+                    exit(0);
                 }
-                XL_LOG(&ctx, XL_LOG_DEBUG, "Done. Exiting now");
-            }
-            XL_LOG(&ctx, XL_LOG_DEBUG, "Domain %d does not need to be clean, 
exiting now", domid);
-            exit(0);
-        }
+                break;
+            case DISK_EJECT:
+                if (libxl_event_get_disk_eject_info(&ctx, domid, &event, 
&disk))
+                    libxl_cdrom_insert(&ctx, domid, &disk);
+                break;
+        }
+        libxl_free_event(&event);
     }
 
     close(logfile);
@@ -730,6 +752,8 @@ static void help(char *command)
         printf(" console                       attach to domain's 
console\n\n");
         printf(" save                          save a domain state to restore 
later\n\n");
         printf(" restore                       restore a domain from a saved 
state\n\n");
+        printf(" cd-insert                     insert a cdrom into a guest's 
cd drive\n\n");
+        printf(" cd-eject                      eject a cdrom from a guest's cd 
drive\n\n");
     } else if(!strcmp(command, "create")) {
         printf("Usage: xl create <ConfigFile> [options] [vars]\n\n");
         printf("Create a domain based on <ConfigFile>.\n\n");
@@ -772,6 +796,12 @@ static void help(char *command)
     } else if (!strcmp(command, "console")) {
         printf("Usage: xl console <Domain>\n\n");
         printf("Attach to domain's console.\n\n");
+    } else if (!strcmp(command, "cd-insert")) {
+        printf("Usage: xl cd-insert <Domain> <VirtualDevice> <type:path>\n\n");
+        printf("Insert a cdrom into a guest's cd drive.\n\n");
+    } else if (!strcmp(command, "cd-eject")) {
+        printf("Usage: xl cd-eject <Domain> <VirtualDevice>\n\n");
+        printf("Eject a cdrom from a guest's cd drive.\n\n");
     }
 }
 
@@ -788,6 +818,108 @@ void console(char *p, int cons_num)
         exit(2);
     }
     libxl_console_attach(&ctx, domid, cons_num);
+}
+
+void cd_insert(char *dom, char *virtdev, char *phys)
+{
+    struct libxl_ctx ctx;
+    uint32_t domid;
+    libxl_device_disk disk;
+    char *p;
+
+    libxl_ctx_init(&ctx);
+    libxl_ctx_set_log(&ctx, log_callback, NULL);
+
+    if (libxl_param_to_domid(&ctx, dom, &domid) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", dom);
+        exit(2);
+    }
+
+    disk.backend_domid = 0;
+    disk.domid = domid;
+    if (phys) {
+        p = strchr(phys, ':');
+        if (!p) {
+            fprintf(stderr, "No type specified, ");
+            disk.physpath = phys;
+            if (!strncmp(phys, "/dev", 4)) {
+                fprintf(stderr, "assuming phy:\n");
+                disk.phystype = PHYSTYPE_PHY;
+            } else {
+                fprintf(stderr, "assuming file:\n");
+                disk.phystype = PHYSTYPE_FILE;
+            }
+        } else {
+            p = '\0';
+            disk.physpath = strdup(p);
+            p++;
+            libxl_string_to_phystype(&ctx, p, &disk.phystype);
+        }
+    } else {
+            disk.physpath = NULL;
+            disk.phystype = 0;
+    }
+    disk.virtpath = virtdev;
+    disk.unpluggable = 1;
+    disk.readwrite = 0;
+    disk.is_cdrom = 1;
+
+    libxl_cdrom_insert(&ctx, domid, &disk);
+}
+
+int main_cd_eject(int argc, char **argv)
+{
+    int opt = 0;
+    char *p = NULL, *virtdev;
+
+    while ((opt = getopt(argc, argv, "hn:")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("cd-eject");
+            exit(0);
+        default:
+            fprintf(stderr, "option not supported\n");
+            break;
+        }
+    }
+    if (optind >= argc - 1) {
+        help("cd-eject");
+        exit(2);
+    }
+
+    p = argv[optind];
+    virtdev = argv[optind + 1];
+
+    cd_insert(p, virtdev, NULL);
+    exit(0);
+}
+
+int main_cd_insert(int argc, char **argv)
+{
+    int opt = 0;
+    char *p = NULL, *file = NULL, *virtdev;
+
+    while ((opt = getopt(argc, argv, "hn:")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("cd-insert");
+            exit(0);
+        default:
+            fprintf(stderr, "option not supported\n");
+            break;
+        }
+    }
+    if (optind >= argc - 2) {
+        help("cd-insert");
+        exit(2);
+    }
+
+    p = argv[optind];
+    virtdev = argv[optind + 1];
+    file = argv[optind + 2];
+
+    cd_insert(p, virtdev, file);
+    exit(0);
 }
 
 int main_console(int argc, char **argv)
@@ -1298,6 +1430,10 @@ int main(int argc, char **argv)
         main_save(argc - 1, argv + 1);
     } else if (!strcmp(argv[1], "restore")) {
         main_restore(argc - 1, argv + 1);
+    } else if (!strcmp(argv[1], "cd-insert")) {
+        main_cd_insert(argc - 1, argv + 1);
+    } else if (!strcmp(argv[1], "cd-eject")) {
+        main_cd_eject(argc - 1, argv + 1);
     } else if (!strcmp(argv[1], "help")) {
         if (argc > 2)
             help(argv[2]);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] libxenlight: implement cdrom insert/eject, Xen patchbot-unstable <=