libxl_disk: Use ev_qmp in libxl_cdrom_insert

Make libxl_cdrom_insert asynchronous when QEMU is involved.  And
have the cdrom opened by libxl, sending a file descriptor to QEMU.

The "opaque" parameter of the "add-fd" can help to figure out what a
fdset in QEMU is used for. It can be queried by "query-fdsets".

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
Anthony PERARD authored and Ian Jackson committed 2019-09-19 12:24:56 +01:00
1 parent 06bb05308f
commit 69a77e4008
3 files changed
+101 -46

No files matched your search

+101 -27
View File
@@ -650,14 +650,17 @@ typedef struct {
libxl__ev_devlock qmp_lock;
int dm_ver;
libxl__ev_time time;
libxl__ev_qmp qmp;
} libxl__cdrom_insert_state;
static void cdrom_insert_lock_acquired(libxl__egc *, libxl__ev_devlock *,
int rc);
static void cdrom_insert_ejected(libxl__egc *egc,
libxl__cdrom_insert_state *cis);
static void cdrom_insert_inserted(libxl__egc *egc,
libxl__cdrom_insert_state *cis);
static void cdrom_insert_ejected(libxl__egc *egc, libxl__ev_qmp *,
const libxl__json_object *, int rc);
static void cdrom_insert_addfd_cb(libxl__egc *egc, libxl__ev_qmp *,
const libxl__json_object *, int rc);
static void cdrom_insert_inserted(libxl__egc *egc, libxl__ev_qmp *,
const libxl__json_object *, int rc);
static void cdrom_insert_timout(libxl__egc *egc, libxl__ev_time *ev,
const struct timeval *requested_abs,
int rc);
@@ -684,6 +687,10 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk,
cis->qmp_lock.ao = ao;
cis->qmp_lock.domid = domid;
libxl__ev_time_init(&cis->time);
libxl__ev_qmp_init(&cis->qmp);
cis->qmp.ao = ao;
cis->qmp.domid = domid;
cis->qmp.payload_fd = -1;
libxl_domain_type type = libxl__domain_type(gc, domid);
if (type == LIBXL_DOMAIN_TYPE_INVALID) {
@@ -757,26 +764,22 @@ static void cdrom_insert_lock_acquired(libxl__egc *egc,
LIBXL_HOTPLUG_TIMEOUT * 1000);
if (rc) goto out;
/* We need to eject the original image first. This is implemented
* by inserting empty media. JSON is not updated.
/* We need to eject the original image first.
* JSON is not updated.
*/
if (cis->dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
libxl_device_disk disk_empty;
libxl__json_object *args = NULL;
int devid = libxl__device_disk_dev_number(cis->disk->vdev,
NULL, NULL);
libxl_device_disk_init(&disk_empty);
disk_empty.format = LIBXL_DISK_FORMAT_EMPTY;
disk_empty.vdev = libxl__strdup(NOGC, cis->disk->vdev);
disk_empty.pdev_path = libxl__strdup(NOGC, "");
disk_empty.is_cdrom = 1;
libxl__device_disk_setdefault(gc, cis->domid, &disk_empty, false);
rc = libxl__qmp_insert_cdrom(gc, cis->domid, &disk_empty);
libxl_device_disk_dispose(&disk_empty);
QMP_PARAMETERS_SPRINTF(&args, "device", "ide-%i", devid);
cis->qmp.callback = cdrom_insert_ejected;
rc = libxl__ev_qmp_send(gc, &cis->qmp, "eject", args);
if (rc) goto out;
} else {
cdrom_insert_ejected(egc, &cis->qmp, NULL, 0); /* must be last */
}
cdrom_insert_ejected(egc, cis); /* must be last */
return;
out:
@@ -784,10 +787,12 @@ out:
}
static void cdrom_insert_ejected(libxl__egc *egc,
libxl__cdrom_insert_state *cis)
libxl__ev_qmp *qmp,
const libxl__json_object *response,
int rc)
{
EGC_GC;
int rc;
libxl__cdrom_insert_state *cis = CONTAINER_OF(qmp, *cis, qmp);
libxl__domain_userdata_lock *data_lock = NULL;
libxl__device device;
const char *be_path, *libxl_path;
@@ -795,6 +800,7 @@ static void cdrom_insert_ejected(libxl__egc *egc,
xs_transaction_t t = XBT_NULL;
char *tmp;
libxl_domain_config d_config;
bool has_callback = false;
/* convenience aliases */
libxl_domid domid = cis->domid;
@@ -802,6 +808,8 @@ static void cdrom_insert_ejected(libxl__egc *egc,
libxl_domain_config_init(&d_config);
if (rc) goto out;
rc = libxl__device_from_disk(gc, domid, disk, &device);
if (rc) goto out;
be_path = libxl__device_backend_path(gc, &device);
@@ -857,9 +865,29 @@ static void cdrom_insert_ejected(libxl__egc *egc,
rc = libxl__dm_check_start(gc, &d_config, domid);
if (rc) goto out;
if (cis->dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
rc = libxl__qmp_insert_cdrom(gc, domid, disk);
if (cis->dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN &&
disk->format != LIBXL_DISK_FORMAT_EMPTY) {
libxl__json_object *args = NULL;
assert(qmp->payload_fd == -1);
qmp->payload_fd = open(disk->pdev_path, O_RDONLY);
if (qmp->payload_fd < 0) {
LOGED(ERROR, domid, "Failed to open cdrom file %s",
disk->pdev_path);
rc = ERROR_FAIL;
goto out;
}
/* This free form parameter is not use by QEMU or libxl. */
QMP_PARAMETERS_SPRINTF(&args, "opaque", "%s:%s",
libxl_disk_format_to_string(disk->format),
disk->pdev_path);
qmp->callback = cdrom_insert_addfd_cb;
rc = libxl__ev_qmp_send(gc, qmp, "add-fd", args);
if (rc) goto out;
has_callback = true;
} else {
has_callback = false;
}
rc = 0;
@@ -870,16 +898,58 @@ out:
if (data_lock) libxl__unlock_domain_userdata(data_lock);
if (rc) {
cdrom_insert_done(egc, cis, rc); /* must be last */
} else {
cdrom_insert_inserted(egc, cis); /* must be last */
} else if (!has_callback) {
/* Only called if no asynchronous callback are set. */
cdrom_insert_inserted(egc, qmp, NULL, 0); /* must be last */
}
}
static void cdrom_insert_inserted(libxl__egc *egc,
libxl__cdrom_insert_state *cis)
static void cdrom_insert_addfd_cb(libxl__egc *egc,
libxl__ev_qmp *qmp,
const libxl__json_object *response,
int rc)
{
EGC_GC;
int rc;
libxl__cdrom_insert_state *cis = CONTAINER_OF(qmp, *cis, qmp);
libxl__json_object *args = NULL;
const libxl__json_object *o;
int devid;
int fdset;
/* convenience aliases */
libxl_device_disk *disk = cis->disk;
close(qmp->payload_fd);
qmp->payload_fd = -1;
if (rc) goto out;
o = libxl__json_map_get("fdset-id", response, JSON_INTEGER);
if (!o) {
rc = ERROR_FAIL;
goto out;
}
fdset = libxl__json_object_get_integer(o);
devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
QMP_PARAMETERS_SPRINTF(&args, "device", "ide-%i", devid);
QMP_PARAMETERS_SPRINTF(&args, "target", "/dev/fdset/%d", fdset);
libxl__qmp_param_add_string(gc, &args, "arg",
libxl__qemu_disk_format_string(disk->format));
qmp->callback = cdrom_insert_inserted;
rc = libxl__ev_qmp_send(gc, qmp, "change", args);
out:
if (rc)
cdrom_insert_done(egc, cis, rc); /* must be last */
}
static void cdrom_insert_inserted(libxl__egc *egc,
libxl__ev_qmp *qmp,
const libxl__json_object *response,
int rc)
{
EGC_GC;
libxl__cdrom_insert_state *cis = CONTAINER_OF(qmp, *cis, qmp);
libxl__domain_userdata_lock *data_lock = NULL;
libxl_domain_config d_config;
flexarray_t *insert = NULL;
@@ -894,6 +964,8 @@ static void cdrom_insert_inserted(libxl__egc *egc,
libxl_domain_config_init(&d_config);
if (rc) goto out;
rc = libxl__device_from_disk(gc, domid, disk, &device);
if (rc) goto out;
be_path = libxl__device_backend_path(gc, &device);
@@ -977,6 +1049,8 @@ static void cdrom_insert_done(libxl__egc *egc,
EGC_GC;
libxl__ev_time_deregister(gc, &cis->time);
libxl__ev_qmp_dispose(gc, &cis->qmp);
if (cis->qmp.payload_fd >= 0) close(cis->qmp.payload_fd);
libxl__ev_devlock_unlock(gc, &cis->qmp_lock);
libxl_device_disk_dispose(&cis->disk_saved);
libxl__ao_complete(egc, cis->ao, rc);
-1
View File
@@ -1960,7 +1960,6 @@ _hidden int libxl__qmp_resume(libxl__gc *gc, int domid);
_hidden int libxl__qmp_restore(libxl__gc *gc, int domid, const char *filename);
/* Set dirty bitmap logging status */
_hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable);
_hidden int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid, const libxl_device_disk *disk);
/* Add a virtual CPU */
_hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index);
/* Query the bitmap of CPUs */
-18
View File
@@ -1118,24 +1118,6 @@ int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable)
NULL, NULL);
}
int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid,
const libxl_device_disk *disk)
{
libxl__json_object *args = NULL;
int dev_number = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
QMP_PARAMETERS_SPRINTF(&args, "device", "ide-%i", dev_number);
if (disk->format == LIBXL_DISK_FORMAT_EMPTY) {
return qmp_run_command(gc, domid, "eject", args, NULL, NULL);
} else {
libxl__qmp_param_add_string(gc, &args, "target", disk->pdev_path);
libxl__qmp_param_add_string(gc, &args, "arg",
libxl__qemu_disk_format_string(disk->format));
return qmp_run_command(gc, domid, "change", args, NULL, NULL);
}
}
int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int idx)
{
libxl__json_object *args = NULL;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.