[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 32/32] libxl_disk: Have libxl_cdrom_insert use libxl__ev_qmp
So when QEMU is involve, the operation will be asynchrone and will finish later. This path reimplement libxl__qmp_insert_cdrom to make use of the new libxl__ev_qmp API. It also open the cdrom in libxl and send the FD via QMP, so QEMU doesn't need access permition on the cdrom file. libxl__qmp_insert_cdrom() is now async, libxl_cdrom_insert() is updated to make use of it. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- Notes: v4: switch to the updated libxl__ev_qmp API tools/libxl/libxl_disk.c | 42 +++++++++---- tools/libxl/libxl_internal.h | 14 ++++- tools/libxl/libxl_qmp.c | 117 +++++++++++++++++++++++++++++------ 3 files changed, 142 insertions(+), 31 deletions(-) diff --git a/tools/libxl/libxl_disk.c b/tools/libxl/libxl_disk.c index c759179628..eb086ed909 100644 --- a/tools/libxl/libxl_disk.c +++ b/tools/libxl/libxl_disk.c @@ -672,11 +672,14 @@ typedef struct { int dm_ver; int domid; libxl__domain_userdata_lock *lock; + libxl__qmp_insert_cdrom_state qics; } libxl__cdrom_insert_state; static void cdrom_insert_ejected(libxl__egc *egc, - libxl__cdrom_insert_state *cis); + libxl__qmp_insert_cdrom_state *qics, + int rc); static void cdrom_insert_inserted(libxl__egc *egc, - libxl__cdrom_insert_state *cis); + libxl__qmp_insert_cdrom_state *qics, + int rc); static void cdrom_insert_done(libxl__egc *egc, libxl__cdrom_insert_state *cis, int rc); @@ -777,12 +780,16 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, * by inserting empty media. JSON is not updated. */ if (cis->dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) { - rc = libxl__qmp_insert_cdrom(gc, domid, disk_empty); + libxl__qmp_insert_cdrom_state *qics = &cis->qics; + qics->domid = domid; + qics->disk = disk_empty; + qics->callback = cdrom_insert_ejected; + rc = libxl__qmp_insert_cdrom(gc, qics); if (rc) goto out; + } else { + cdrom_insert_ejected(egc, &cis->qics, 0); } - cdrom_insert_ejected(egc, cis); - return AO_INPROGRESS; out: @@ -794,11 +801,12 @@ out: } static void cdrom_insert_ejected(libxl__egc *egc, - libxl__cdrom_insert_state *cis) + libxl__qmp_insert_cdrom_state *qics, + int rc) { + libxl__cdrom_insert_state *cis = CONTAINER_OF(qics, *cis, qics); STATE_AO_GC(cis->ao); uint32_t domid = cis->domid; - int rc; const char *be_path, *libxl_path; char * tmp; xs_transaction_t t = XBT_NULL; @@ -808,6 +816,9 @@ static void cdrom_insert_ejected(libxl__egc *egc, libxl_device_disk *disk = cis->disk; libxl_device_disk *disk_saved = &cis->disk_saved; + if (rc) + goto out; + be_path = cis->be_path; libxl_path = cis->libxl_path; @@ -851,12 +862,15 @@ static void cdrom_insert_ejected(libxl__egc *egc, if (rc) goto out; if (cis->dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) { - rc = libxl__qmp_insert_cdrom(gc, domid, disk); + qics->domid = domid; + qics->disk = disk; + qics->callback = cdrom_insert_inserted; + rc = libxl__qmp_insert_cdrom(gc, qics); if (rc) goto out; + } else { + cdrom_insert_inserted(egc, qics, 0); } - cdrom_insert_inserted(egc, cis); - return; out: @@ -865,11 +879,12 @@ out: } static void cdrom_insert_inserted(libxl__egc *egc, - libxl__cdrom_insert_state *cis) + libxl__qmp_insert_cdrom_state *qics, + int rc) { + libxl__cdrom_insert_state *cis = CONTAINER_OF(qics, *cis, qics); STATE_AO_GC(cis->ao); uint32_t domid = cis->domid; - int rc; const char *be_path, *libxl_path; char * tmp; xs_transaction_t t = XBT_NULL; @@ -880,6 +895,9 @@ static void cdrom_insert_inserted(libxl__egc *egc, be_path = cis->be_path; libxl_path = cis->libxl_path; + if (rc) + goto out; + insert = flexarray_make(gc, 4, 1); flexarray_append_pair(insert, "type", libxl__device_disk_string_of_backend(disk->backend)); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index cafe8b5733..6b6ac65d00 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1948,7 +1948,19 @@ _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); + +typedef struct libxl__qmp_insert_cdrom_state libxl__qmp_insert_cdrom_state; +struct libxl__qmp_insert_cdrom_state { + /* caller should include this in their own struct */ + /* caller must fill these in, and they must all remain valid */ + int domid; + const libxl_device_disk *disk; + void (*callback)(libxl__egc *egc, libxl__qmp_insert_cdrom_state *, int rc); + /* private to libxl__qmp_insert_cdrom() */ + libxl__ev_qmp ev; +}; +int libxl__qmp_insert_cdrom(libxl__gc *gc, + libxl__qmp_insert_cdrom_state *qics); /* Add a virtual CPU */ _hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index); /* Query the bitmap of CPUs */ diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 07203a6fe6..08c8060095 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -1061,24 +1061,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 { - qmp_parameters_add_string(gc, &args, "target", disk->pdev_path); - qmp_parameters_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; @@ -1395,6 +1377,105 @@ static void dm_state_saved(libxl__egc *egc, libxl__ev_qmp *ev, } +static void qmp_insert_cdrom_addfd_cb(libxl__egc *egc, libxl__ev_qmp *ev, + const libxl__json_object *response, + int rc); +static void qmp_insert_cdrom_done_cb(libxl__egc *egc, libxl__ev_qmp *ev, + const libxl__json_object *response, + int rc); +int libxl__qmp_insert_cdrom(libxl__gc *gc, + libxl__qmp_insert_cdrom_state *qics) +{ + int rc; + libxl__json_object *args = NULL; + int domid = qics->domid; + libxl__ev_qmp *ev = &qics->ev; + const libxl_device_disk *disk = qics->disk; + int dev_number = libxl__device_disk_dev_number(disk->vdev, NULL, NULL); + + libxl__ev_qmp_init(ev); + ev->domid = qics->domid; + ev->cfd = NULL; + + if (disk->format == LIBXL_DISK_FORMAT_EMPTY) { + QMP_PARAMETERS_SPRINTF(&args, "device", "ide-%i", dev_number); + ev->callback = qmp_insert_cdrom_done_cb; + rc = libxl__ev_qmp_send(gc, ev, "eject", args); + } else { + libxl__carefd_begin(); + ev->cfd = libxl__carefd_opened(CTX, open(disk->pdev_path, O_RDONLY)); + if (!ev->cfd) { + 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); + ev->callback = qmp_insert_cdrom_addfd_cb; + rc = libxl__ev_qmp_send(gc, ev, "add-fd", args); + if (rc) + goto out; + } +out: + if (rc) + libxl__carefd_close(ev->cfd); + return rc; +} + +static void qmp_insert_cdrom_addfd_cb(libxl__egc *egc, libxl__ev_qmp *ev, + const libxl__json_object *response, + int rc) +{ + EGC_GC; + libxl__qmp_insert_cdrom_state *qics = CONTAINER_OF(ev, *qics, ev); + libxl__json_object *args = NULL; + const libxl__json_object *o; + const libxl_device_disk *disk = qics->disk; + int dev_number = libxl__device_disk_dev_number(disk->vdev, NULL, NULL); + int fdset; + + libxl__carefd_close(ev->cfd); + ev->cfd = NULL; + + 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); + + ev->callback = qmp_insert_cdrom_done_cb; + QMP_PARAMETERS_SPRINTF(&args, "device", "ide-%i", dev_number); + QMP_PARAMETERS_SPRINTF(&args, "target", "/dev/fdset/%d", fdset); + qmp_parameters_add_string(gc, &args, "arg", + libxl__qemu_disk_format_string(disk->format)); + rc = libxl__ev_qmp_send(gc, ev, "change", args); + if (rc) + goto out; + return; +out: + qmp_insert_cdrom_done_cb(egc, ev, NULL, rc); +} + +static void qmp_insert_cdrom_done_cb(libxl__egc *egc, libxl__ev_qmp *ev, + const libxl__json_object *response, + int rc) +{ + EGC_GC; + libxl__qmp_insert_cdrom_state *qics = CONTAINER_OF(ev, *qics, ev); + + libxl__ev_qmp_dispose(gc, ev); + + qics->callback(egc, qics, rc); +} + /* ------------ Implementation of libxl__ev_qmp ---------------- */ -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |