diff --git a/tools/libs/light/libxl_device.c b/tools/libs/light/libxl_device.c index ae2b71b0bf..8bd780493f 100644 --- a/tools/libs/light/libxl_device.c +++ b/tools/libs/light/libxl_device.c @@ -427,7 +427,10 @@ int libxl__device_disk_set_backend(libxl__gc *gc, libxl_device_disk *disk) { LOG(ERROR, "Disk vdev=%s is empty but not cdrom", disk->vdev); return ERROR_INVAL; } - if (disk->pdev_path != NULL && strcmp(disk->pdev_path, "")) { + if (disk->pdev_path != NULL && + (strcmp(disk->pdev_path, "") && + strncmp(disk->pdev_path, LIBXL_STUBDOM_EMPTY_CDROM, + strlen(LIBXL_STUBDOM_EMPTY_CDROM)))) { LOG(ERROR, "Disk vdev=%s is empty but an image has been provided: %s", disk->vdev, disk->pdev_path); diff --git a/tools/libs/light/libxl_disk.c b/tools/libs/light/libxl_disk.c index 59ff996837..95b32f9d29 100644 --- a/tools/libs/light/libxl_disk.c +++ b/tools/libs/light/libxl_disk.c @@ -201,6 +201,32 @@ static int libxl__device_disk_setdefault(libxl__gc *gc, uint32_t domid, disk->backend = LIBXL_DISK_BACKEND_QDISK; } + if (disk->is_cdrom && + disk->format == LIBXL_DISK_FORMAT_EMPTY && + disk->backend == LIBXL_DISK_BACKEND_PHY && + disk->backend_domid == LIBXL_TOOLSTACK_DOMID) { + uint32_t target_domid; + int fd; + + if (libxl_is_stubdom(CTX, domid, &target_domid)) { + LOGED(DEBUG, domid, "Using target_domid %u", target_domid); + } else { + target_domid = domid; + } + free(disk->pdev_path); + disk->pdev_path = + libxl__sprintf(NOGC, LIBXL_STUBDOM_EMPTY_CDROM ".%u", + target_domid); + fd = creat(disk->pdev_path, 0400); + if (fd < 0) { + LOGED(ERROR, domid, "Failed to create empty cdrom \"%s\"", + disk->pdev_path); + return ERROR_FAIL; + } + + close(fd); + } + rc = libxl__device_disk_set_backend(gc, disk); return rc; } @@ -998,7 +1024,7 @@ static void cdrom_insert_ejected(libxl__egc *egc, empty = flexarray_make(gc, 4, 1); flexarray_append_pair(empty, "type", libxl__device_disk_string_of_backend(disk->backend)); - flexarray_append_pair(empty, "params", ""); + flexarray_append_pair(empty, "params", disk->pdev_path ?: ""); for (;;) { rc = libxl__xs_transaction_start(gc, &t); @@ -1174,13 +1200,15 @@ static void cdrom_insert_inserted(libxl__egc *egc, insert = flexarray_make(gc, 4, 1); flexarray_append_pair(insert, "type", libxl__device_disk_string_of_backend(disk->backend)); - if (disk->format != LIBXL_DISK_FORMAT_EMPTY) + if (disk->backend == LIBXL_DISK_BACKEND_QDISK && + disk->format != LIBXL_DISK_FORMAT_EMPTY) { flexarray_append_pair(insert, "params", GCSPRINTF("%s:%s", libxl__device_disk_string_of_format(disk->format), disk->pdev_path)); - else - flexarray_append_pair(insert, "params", ""); + } else { + flexarray_append_pair(insert, "params", disk->pdev_path ?: ""); + } for (;;) { rc = libxl__xs_transaction_start(gc, &t); diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c index 5ee1544d9c..6751fc785f 100644 --- a/tools/libs/light/libxl_domain.c +++ b/tools/libs/light/libxl_domain.c @@ -1525,6 +1525,10 @@ static void devices_destroy_cb(libxl__egc *egc, if (rc < 0) LOGD(ERROR, domid, "libxl__devices_destroy failed"); + /* Remove the file after the hotplug scripts have run. The scripts won't + * run if the file doesn't exist when they are run. */ + libxl__remove_file(gc, GCSPRINTF(LIBXL_STUBDOM_EMPTY_CDROM ".%u", domid)); + vm_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/vm", dom_path)); if (vm_path) if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index d5732d1c37..094d0df9b1 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -120,6 +120,7 @@ #define STUBDOM_CONSOLE_SERIAL 3 #define STUBDOM_SPECIAL_CONSOLES 3 #define LIBXL_LINUX_STUBDOM_MEM 128 +#define LIBXL_STUBDOM_EMPTY_CDROM XEN_RUN_DIR "/empty-cdrom" /* .$domid */ #define TAP_DEVICE_SUFFIX "-emu" #define DOMID_XS_PATH "domid" #define PVSHIM_BASENAME "xen-shim"