aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/xl.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-08 07:47:52 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-08 07:47:52 +0000
commit7b4effff892d18d8e83563a7e6868bb7c7749fc5 (patch)
tree75fff8f77c32c9d773064852abc8b549921c6e85 /tools/libxl/xl.c
parent4baca0b56014781751a5dcca4eb8abf4c08b16ba (diff)
downloadxen-7b4effff892d18d8e83563a7e6868bb7c7749fc5.tar.gz
xen-7b4effff892d18d8e83563a7e6868bb7c7749fc5.tar.bz2
xen-7b4effff892d18d8e83563a7e6868bb7c7749fc5.zip
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@eu.citrix.com>
Diffstat (limited to 'tools/libxl/xl.c')
-rw-r--r--tools/libxl/xl.c170
1 files changed, 153 insertions, 17 deletions
diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c
index cb19e7129a..434d947f08 100644
--- a/tools/libxl/xl.c
+++ b/tools/libxl/xl.c
@@ -356,12 +356,14 @@ static void parse_config_file(const char *filename,
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, const char *config_file, const char *restor
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");
}
}
@@ -790,6 +820,108 @@ void console(char *p, int cons_num)
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)
{
int opt = 0, cons_num = 0;
@@ -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]);