[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 9/9] libxl: Convert to asynchronous: device removal
On Fri, 2012-01-13 at 19:25 +0000, Ian Jackson wrote: > Convert libxl_FOO_device_remove, and the function which does the bulk > of the work, libxl__device_remove, to the new async ops scheme. > > Adjust all callers. > > Also remove libxl__wait_for_device_state which is now obsolete. > > Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > --- > tools/libxl/libxl.c | 60 +++++++++++++-------- > tools/libxl/libxl.h | 16 ++++-- > tools/libxl/libxl_device.c | 118 > +++++++++++++----------------------------- > tools/libxl/libxl_internal.h | 30 ++--------- > tools/libxl/xl_cmdimpl.c | 4 +- > 5 files changed, 93 insertions(+), 135 deletions(-) > > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c > index 9890d79..d63da97 100644 > --- a/tools/libxl/libxl.c > +++ b/tools/libxl/libxl.c > @@ -1310,19 +1310,23 @@ out: > } > > int libxl_device_disk_remove(libxl_ctx *ctx, uint32_t domid, > - libxl_device_disk *disk) > + libxl_device_disk *disk, > + const libxl_asyncop_how *ao_how) > { > - GC_INIT(ctx); > + AO_CREATE(ctx, domid, ao_how); > libxl__device device; > int rc; > > rc = libxl__device_from_disk(gc, domid, disk, &device); > if (rc != 0) goto out; > > - rc = libxl__device_remove(gc, &device, 1); > + rc = libxl__initiate_device_remove(ao, &device); > + if (rc) goto out; > + > + AO_INPROGRESS; > + > out: > - GC_FREE; > - return rc; > + AO_ABORT(rc); > } After all the internal complexity the actual usage is refreshingly simple. Phew! > > int libxl_device_disk_destroy(libxl_ctx *ctx, uint32_t domid, > @@ -1536,11 +1540,11 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t > domid, libxl_device_disk *disk) > > ret = 0; > > - libxl_device_disk_remove(ctx, domid, disks + i); > + libxl_device_disk_remove(ctx, domid, disks + i, 0); > libxl_device_disk_add(ctx, domid, disk); > stubdomid = libxl_get_stubdom_id(ctx, domid); > if (stubdomid) { > - libxl_device_disk_remove(ctx, stubdomid, disks + i); > + libxl_device_disk_remove(ctx, stubdomid, disks + i, 0); > libxl_device_disk_add(ctx, stubdomid, disk); > } > out: The async capability here ought to be propagated to the libxl_cdrom_insert interface too. I guess that would mean handling compound asynchronous operations. ...in the fullness of time, of course. > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h > index 416d6e8..602bd01 100644 > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c > index 5d05e90..e905133 100644 > --- a/tools/libxl/libxl_device.c > +++ b/tools/libxl/libxl_device.c > @@ -357,85 +357,41 @@ int libxl__device_disk_dev_number(const char *virtpath, > int *pdisk, > return -1; > } > [...] > +typedef struct { > + libxl__ao *ao; > + libxl__ev_devstate ds; > +} libxl__ao_device_remove; > + > +static void device_remove_cleanup(libxl__gc *gc, > + libxl__ao_device_remove *aorm) { > + if (!aorm) return; > + libxl__ev_devstate_cancel(gc, &aorm->ds); > +} > [...] > +static void device_remove_callback(libxl__egc *egc, libxl__ev_devstate *ds, > + int rc) { > + libxl__ao_device_remove *aorm = CONTAINER_OF(ds, *aorm, ds); > + libxl__gc *gc = &aorm->ao->gc; > + libxl__ao_complete(egc, aorm->ao, rc); > + device_remove_cleanup(gc, aorm); > } > [...] > +int libxl__initiate_device_remove(libxl__ao *ao, libxl__device *dev) > { > + /* Arranges that dev will be removed from its guest. When > + * this is done, the ao will be completed. An error > + * return from libxl__device_remove means that the ao > + * will _not_ be completed and the caller must do so. Do you mean aborted or cancelled rather than completed here? > + */ > + AO_GC; > libxl_ctx *ctx = libxl__gc_owner(gc); > xs_transaction_t t; > char *be_path = libxl__device_backend_path(gc, dev); > char *state_path = libxl__sprintf(gc, "%s/state", be_path); > char *state = libxl__xs_read(gc, XBT_NULL, state_path); > int rc = 0; > + libxl__ao_device_remove *aorm = 0; > > if (!state) > goto out; > @@ -458,23 +414,21 @@ retry_transaction: > } > } > [...] > libxl__device_destroy_tapdisk(gc, be_path); > [...] > + aorm = libxl__zalloc(gc, sizeof(*aorm)); > + aorm->ao = ao; > + libxl__ev_devstate_init(&aorm->ds); > [...] > + rc = libxl__ev_devstate_wait(gc, &aorm->ds, device_remove_callback, > + state_path, XenbusStateClosed, > + LIBXL_DESTROY_TIMEOUT * 1000); > + if (rc) goto out; > + > + return 0; > + > + out: > + device_remove_cleanup(gc, aorm); > return rc; > } > > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index b7f0f54..9920fb9 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -653,35 +653,15 @@ _hidden char *libxl__device_backend_path(libxl__gc *gc, > libxl__device *device); [...] > +/* Arranges that dev will be removed from its guest. When > + * this is done, the ao will be completed. An error > + * return from libxl__device_remove means that the ao > + * will _not_ be completed and the caller must do so. */ This is the same comment as at the head of the implementation so the same comment re aborting applies. Do we need both comments? > +_hidden int libxl__initiate_device_remove(libxl__ao*, libxl__device *dev); > > /* > * libxl__ev_devstate - waits a given time for a device to > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index c2b7a1e..659a9e6 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -4624,7 +4624,7 @@ int main_networkdetach(int argc, char **argv) > return 1; > } > } > - if (libxl_device_nic_remove(ctx, domid, &nic)) { > + if (libxl_device_nic_remove(ctx, domid, &nic, 0)) { > fprintf(stderr, "libxl_device_nic_del failed.\n"); > return 1; > } There aren't actually any examples of a caller using the ao-ness in xl are there? I know that sync is for the most part ao+wait but I'm a bit concerned that e.g. several of the paths in libxl__ao_complete probably haven't been run and one of the flow-charts added to tools/libxl/libxl_event.c in patch 6/8 has probably never happened either. IMHO this isn't a blocker for this patch but since xl is, in addition to being a toolstack, a testbed for libxl perhaps one or more "gratuitously asynchronous" calls could be made? Perhaps the libxl_cdrom_insert case would be an interesting one? In particular the case in the create_domain() event loop (e.g. so that the response to a cdrom eject does not block shutdown processing). Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |