[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] tools/libxl: rename remus device to checkpoint device
commit 304400459ef051d12ae84ba8a7b2eccdadc0f7fb Author: Wen Congyang <wency@xxxxxxxxxxxxxx> AuthorDate: Wed Jul 15 15:45:47 2015 +0800 Commit: Wei Liu <wei.liu2@xxxxxxxxxx> CommitDate: Fri Feb 26 15:14:47 2016 +0000 tools/libxl: rename remus device to checkpoint device This patch is auto generated by the following commands: 1. git mv tools/libxl/libxl_remus_device.c tools/libxl/libxl_checkpoint_device.c 2. perl -pi -e 's/libxl_remus_device/libxl_checkpoint_device/g' tools/libxl/Makefile 3. perl -pi -e 's/\blibxl__remus_devices/libxl__checkpoint_devices/g' tools/libxl/*.[ch] 4. perl -pi -e 's/\blibxl__remus_device\b/libxl__checkpoint_device/g' tools/libxl/*.[ch] 5. perl -pi -e 's/\blibxl__remus_device_instance_ops\b/libxl__checkpoint_device_instance_ops/g' tools/libxl/*.[ch] 6. perl -pi -e 's/\blibxl__remus_callback\b/libxl__checkpoint_callback/g' tools/libxl/*.[ch] 7. perl -pi -e 's/\bremus_device_init\b/checkpoint_device_init/g' tools/libxl/*.[ch] 8. perl -pi -e 's/\bremus_devices_setup\b/checkpoint_devices_setup/g' tools/libxl/*.[ch] 9. perl -pi -e 's/\bdefine_remus_checkpoint_api\b/define_checkpoint_api/g' tools/libxl/*.[ch] 10. perl -pi -e 's/\brds\b/cds/g' tools/libxl/*.[ch] 11. perl -pi -e 's/REMUS_DEVICE/CHECKPOINT_DEVICE/g' tools/libxl/*.[ch] tools/libxl/*.idl 12. perl -pi -e 's/REMUS_DEVOPS/CHECKPOINT_DEVOPS/g' tools/libxl/*.[ch] tools/libxl/*.idl 13. perl -pi -e 's/\bremus\b/checkpoint/g' tools/libxl/libxl_checkpoint_device.[ch] 14. perl -pi -e 's/\bremus device/checkpoint device/g' tools/libxl/libxl_internal.h 15. perl -pi -e 's/\bRemus device/checkpoint device/g' tools/libxl/libxl_internal.h 16. perl -pi -e 's/\bremus abstract/checkpoint abstract/g' tools/libxl/libxl_internal.h 17. perl -pi -e 's/\bremus invocation/checkpoint invocation/g' tools/libxl/libxl_internal.h 18. perl -pi -e 's/\blibxl__remus_device_\(/libxl__checkpoint_device_(/g' tools/libxl/libxl_internal.h The patch also fixes the following backword compatibility: The error code ERROR_REMUS_XXX was introduced in Xen 4.5, and changed to ERROR_CHECKPOINT_XXX after previous renaming. Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> Signed-off-by: Yang Hongyang <hongyang.yang@xxxxxxxxxxxx> Reviewed-Lightly-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- tools/libxl/Makefile | 2 +- tools/libxl/libxl.h | 12 ++ tools/libxl/libxl_checkpoint_device.c | 327 ++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 112 ++++++------ tools/libxl/libxl_netbuffer.c | 108 +++++------ tools/libxl/libxl_nonetbuffer.c | 10 +- tools/libxl/libxl_remus.c | 76 ++++---- tools/libxl/libxl_remus_device.c | 327 ---------------------------------- tools/libxl/libxl_remus_disk_drbd.c | 52 +++--- tools/libxl/libxl_types.idl | 4 +- 10 files changed, 521 insertions(+), 509 deletions(-) diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 263ea0e..789a12e 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -64,7 +64,7 @@ else LIBXL_OBJS-y += libxl_no_convert_callout.o endif -LIBXL_OBJS-y += libxl_remus.o libxl_remus_device.o libxl_remus_disk_drbd.o +LIBXL_OBJS-y += libxl_remus.o libxl_checkpoint_device.o libxl_remus_disk_drbd.o LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o libxl_psr.o LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o libxl_arm.o libxl_libfdt_compat.o diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 6225db1..f9e3ef5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -883,6 +883,18 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src); */ #define LIBXL_HAVE_CHECKPOINTED_STREAM 1 +/* + * ERROR_REMUS_XXX error code only exists from Xen 4.5, Xen 4.6 and it + * is changed to ERROR_CHECKPOINT_XXX in Xen 4.7 + */ +#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION >= 0x040500 \ + && LIBXL_API_VERSION < 0x040700 +#define ERROR_REMUS_DEVOPS_DOES_NOT_MATCH \ + ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH +#define ERROR_REMUS_DEVICE_NOT_SUPPORTED \ + ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED +#endif + typedef char **libxl_string_list; void libxl_string_list_dispose(libxl_string_list *sl); int libxl_string_list_length(const libxl_string_list *sl); diff --git a/tools/libxl/libxl_checkpoint_device.c b/tools/libxl/libxl_checkpoint_device.c new file mode 100644 index 0000000..109cd23 --- /dev/null +++ b/tools/libxl/libxl_checkpoint_device.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2014 FUJITSU LIMITED + * Author: Yang Hongyang <yanghy@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" + +extern const libxl__checkpoint_device_instance_ops remus_device_nic; +extern const libxl__checkpoint_device_instance_ops remus_device_drbd_disk; +static const libxl__checkpoint_device_instance_ops *remus_ops[] = { + &remus_device_nic, + &remus_device_drbd_disk, + NULL, +}; + +/*----- helper functions -----*/ + +static int init_device_subkind(libxl__checkpoint_devices_state *cds) +{ + /* init device subkind-specific state in the libxl ctx */ + int rc; + STATE_AO_GC(cds->ao); + + if (libxl__netbuffer_enabled(gc)) { + rc = init_subkind_nic(cds); + if (rc) goto out; + } + + rc = init_subkind_drbd_disk(cds); + if (rc) goto out; + + rc = 0; +out: + return rc; +} + +static void cleanup_device_subkind(libxl__checkpoint_devices_state *cds) +{ + /* cleanup device subkind-specific state in the libxl ctx */ + STATE_AO_GC(cds->ao); + + if (libxl__netbuffer_enabled(gc)) + cleanup_subkind_nic(cds); + + cleanup_subkind_drbd_disk(cds); +} + +/*----- setup() and teardown() -----*/ + +/* callbacks */ + +static void all_devices_setup_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc); +static void device_setup_iterate(libxl__egc *egc, + libxl__ao_device *aodev); +static void devices_teardown_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc); + +/* checkpoint device setup and teardown */ + +static libxl__checkpoint_device* checkpoint_device_init(libxl__egc *egc, + libxl__checkpoint_devices_state *cds, + libxl__device_kind kind, + void *libxl_dev) +{ + libxl__checkpoint_device *dev = NULL; + + STATE_AO_GC(cds->ao); + GCNEW(dev); + dev->backend_dev = libxl_dev; + dev->kind = kind; + dev->cds = cds; + + return dev; +} + +static void checkpoint_devices_setup(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); + +void libxl__checkpoint_devices_setup(libxl__egc *egc, libxl__checkpoint_devices_state *cds) +{ + int i, rc; + + STATE_AO_GC(cds->ao); + + rc = init_device_subkind(cds); + if (rc) + goto out; + + cds->num_devices = 0; + cds->num_nics = 0; + cds->num_disks = 0; + + if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF)) + cds->nics = libxl_device_nic_list(CTX, cds->domid, &cds->num_nics); + + if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD)) + cds->disks = libxl_device_disk_list(CTX, cds->domid, &cds->num_disks); + + if (cds->num_nics == 0 && cds->num_disks == 0) + goto out; + + GCNEW_ARRAY(cds->devs, cds->num_nics + cds->num_disks); + + for (i = 0; i < cds->num_nics; i++) { + cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds, + LIBXL__DEVICE_KIND_VIF, + &cds->nics[i]); + } + + for (i = 0; i < cds->num_disks; i++) { + cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds, + LIBXL__DEVICE_KIND_VBD, + &cds->disks[i]); + } + + checkpoint_devices_setup(egc, cds); + + return; + +out: + cds->callback(egc, cds, rc); +} + +static void checkpoint_devices_setup(libxl__egc *egc, + libxl__checkpoint_devices_state *cds) +{ + int i, rc; + + STATE_AO_GC(cds->ao); + + libxl__multidev_begin(ao, &cds->multidev); + cds->multidev.callback = all_devices_setup_cb; + for (i = 0; i < cds->num_devices; i++) { + libxl__checkpoint_device *dev = cds->devs[i]; + dev->ops_index = -1; + libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev); + + dev->aodev.rc = ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED; + dev->aodev.callback = device_setup_iterate; + device_setup_iterate(egc,&dev->aodev); + } + + rc = 0; + libxl__multidev_prepared(egc, &cds->multidev, rc); +} + + +static void device_setup_iterate(libxl__egc *egc, libxl__ao_device *aodev) +{ + libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); + EGC_GC; + + if (aodev->rc != ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED && + aodev->rc != ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH) + /* might be success or disaster */ + goto out; + + do { + dev->ops = remus_ops[++dev->ops_index]; + if (!dev->ops) { + libxl_device_nic * nic = NULL; + libxl_device_disk * disk = NULL; + uint32_t domid; + int devid; + if (dev->kind == LIBXL__DEVICE_KIND_VIF) { + nic = (libxl_device_nic *)dev->backend_dev; + domid = nic->backend_domid; + devid = nic->devid; + } else if (dev->kind == LIBXL__DEVICE_KIND_VBD) { + disk = (libxl_device_disk *)dev->backend_dev; + domid = disk->backend_domid; + devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL); + } else { + LOG(ERROR,"device kind not handled by checkpoint: %s", + libxl__device_kind_to_string(dev->kind)); + aodev->rc = ERROR_FAIL; + goto out; + } + LOG(ERROR,"device not handled by checkpoint" + " (device=%s:%"PRId32"/%"PRId32")", + libxl__device_kind_to_string(dev->kind), + domid, devid); + aodev->rc = ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED; + goto out; + } + } while (dev->ops->kind != dev->kind); + + /* found the next ops_index to try */ + assert(dev->aodev.callback == device_setup_iterate); + dev->ops->setup(egc,dev); + return; + + out: + libxl__multidev_one_callback(egc,aodev); +} + +static void all_devices_setup_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc) +{ + STATE_AO_GC(multidev->ao); + + /* Convenience aliases */ + libxl__checkpoint_devices_state *const cds = + CONTAINER_OF(multidev, *cds, multidev); + + cds->callback(egc, cds, rc); +} + +void libxl__checkpoint_devices_teardown(libxl__egc *egc, + libxl__checkpoint_devices_state *cds) +{ + int i; + libxl__checkpoint_device *dev; + + STATE_AO_GC(cds->ao); + + libxl__multidev_begin(ao, &cds->multidev); + cds->multidev.callback = devices_teardown_cb; + for (i = 0; i < cds->num_devices; i++) { + dev = cds->devs[i]; + if (!dev->ops || !dev->matched) + continue; + + libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev); + dev->ops->teardown(egc,dev); + } + + libxl__multidev_prepared(egc, &cds->multidev, 0); +} + +static void devices_teardown_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc) +{ + int i; + + STATE_AO_GC(multidev->ao); + + /* Convenience aliases */ + libxl__checkpoint_devices_state *const cds = + CONTAINER_OF(multidev, *cds, multidev); + + /* clean nic */ + for (i = 0; i < cds->num_nics; i++) + libxl_device_nic_dispose(&cds->nics[i]); + free(cds->nics); + cds->nics = NULL; + cds->num_nics = 0; + + /* clean disk */ + for (i = 0; i < cds->num_disks; i++) + libxl_device_disk_dispose(&cds->disks[i]); + free(cds->disks); + cds->disks = NULL; + cds->num_disks = 0; + + cleanup_device_subkind(cds); + + cds->callback(egc, cds, rc); +} + +/*----- checkpointing APIs -----*/ + +/* callbacks */ + +static void devices_checkpoint_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc); + +/* API implementations */ + +#define define_checkpoint_api(api) \ +void libxl__checkpoint_devices_##api(libxl__egc *egc, \ + libxl__checkpoint_devices_state *cds) \ +{ \ + int i; \ + libxl__checkpoint_device *dev; \ + \ + STATE_AO_GC(cds->ao); \ + \ + libxl__multidev_begin(ao, &cds->multidev); \ + cds->multidev.callback = devices_checkpoint_cb; \ + for (i = 0; i < cds->num_devices; i++) { \ + dev = cds->devs[i]; \ + if (!dev->matched || !dev->ops->api) \ + continue; \ + libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev);\ + dev->ops->api(egc,dev); \ + } \ + \ + libxl__multidev_prepared(egc, &cds->multidev, 0); \ +} + +define_checkpoint_api(postsuspend); + +define_checkpoint_api(preresume); + +define_checkpoint_api(commit); + +static void devices_checkpoint_cb(libxl__egc *egc, + libxl__multidev *multidev, + int rc) +{ + STATE_AO_GC(multidev->ao); + + /* Convenience aliases */ + libxl__checkpoint_devices_state *const cds = + CONTAINER_OF(multidev, *cds, multidev); + + cds->callback(egc, cds, rc); +} diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 656bccd..630f048 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2794,9 +2794,9 @@ typedef struct libxl__save_helper_state { * marshalling and xc callback functions */ } libxl__save_helper_state; -/*----- remus device related state structure -----*/ +/*----- checkpoint device related state structure -----*/ /* - * The abstract Remus device layer exposes a common + * The abstract checkpoint device layer exposes a common * set of API to [external] libxl for manipulating devices attached to * a guest protected by Remus. The device layer also exposes a set of * [internal] interfaces that every device type must implement. @@ -2804,34 +2804,34 @@ typedef struct libxl__save_helper_state { * The following API are exposed to libxl: * * One-time configuration operations: - * +libxl__remus_devices_setup + * +libxl__checkpoint_devices_setup * > Enable output buffering for NICs, setup disk replication, etc. - * +libxl__remus_devices_teardown + * +libxl__checkpoint_devices_teardown * > Disable output buffering and disk replication; teardown any * associated external setups like qdiscs for NICs. * * Operations executed every checkpoint (in order of invocation): - * +libxl__remus_devices_postsuspend - * +libxl__remus_devices_preresume - * +libxl__remus_devices_commit + * +libxl__checkpoint_devices_postsuspend + * +libxl__checkpoint_devices_preresume + * +libxl__checkpoint_devices_commit * * Each device type needs to implement the interfaces specified in - * the libxl__remus_device_instance_ops if it wishes to support Remus. + * the libxl__checkpoint_device_instance_ops if it wishes to support Remus. * - * The high-level control flow through the Remus device layer is shown below: + * The high-level control flow through the checkpoint device layer is shown below: * * xl remus * |-> libxl_domain_remus_start - * |-> libxl__remus_devices_setup - * |-> Per-checkpoint libxl__remus_devices_[postsuspend,preresume,commit] + * |-> libxl__checkpoint_devices_setup + * |-> Per-checkpoint libxl__checkpoint_devices_[postsuspend,preresume,commit] * ... * |-> On backup failure, network error or other internal errors: - * libxl__remus_devices_teardown + * libxl__checkpoint_devices_teardown */ -typedef struct libxl__remus_device libxl__remus_device; -typedef struct libxl__remus_devices_state libxl__remus_devices_state; -typedef struct libxl__remus_device_instance_ops libxl__remus_device_instance_ops; +typedef struct libxl__checkpoint_device libxl__checkpoint_device; +typedef struct libxl__checkpoint_devices_state libxl__checkpoint_devices_state; +typedef struct libxl__checkpoint_device_instance_ops libxl__checkpoint_device_instance_ops; /* * Interfaces to be implemented by every device subkind that wishes to @@ -2841,7 +2841,7 @@ typedef struct libxl__remus_device_instance_ops libxl__remus_device_instance_ops * synchronous and call dev->aodev.callback directly (as the last * thing they do). */ -struct libxl__remus_device_instance_ops { +struct libxl__checkpoint_device_instance_ops { /* the device kind this ops belongs to... */ libxl__device_kind kind; @@ -2852,12 +2852,12 @@ struct libxl__remus_device_instance_ops { * Asynchronous. */ - void (*postsuspend)(libxl__egc *egc, libxl__remus_device *dev); - void (*preresume)(libxl__egc *egc, libxl__remus_device *dev); - void (*commit)(libxl__egc *egc, libxl__remus_device *dev); + void (*postsuspend)(libxl__egc *egc, libxl__checkpoint_device *dev); + void (*preresume)(libxl__egc *egc, libxl__checkpoint_device *dev); + void (*commit)(libxl__egc *egc, libxl__checkpoint_device *dev); /* - * setup() and teardown() are refer to the actual remus device. + * setup() and teardown() are refer to the actual checkpoint device. * Asynchronous. * teardown is called even if setup fails. */ @@ -2866,45 +2866,45 @@ struct libxl__remus_device_instance_ops { * device. If matched, the device will then be managed with this set of * subkind operations. * Yields 0 if the device successfully set up. - * REMUS_DEVOPS_DOES_NOT_MATCH if the ops does not match the device. + * CHECKPOINT_DEVOPS_DOES_NOT_MATCH if the ops does not match the device. * any other rc indicates failure. */ - void (*setup)(libxl__egc *egc, libxl__remus_device *dev); - void (*teardown)(libxl__egc *egc, libxl__remus_device *dev); + void (*setup)(libxl__egc *egc, libxl__checkpoint_device *dev); + void (*teardown)(libxl__egc *egc, libxl__checkpoint_device *dev); }; -int init_subkind_nic(libxl__remus_devices_state *rds); -void cleanup_subkind_nic(libxl__remus_devices_state *rds); -int init_subkind_drbd_disk(libxl__remus_devices_state *rds); -void cleanup_subkind_drbd_disk(libxl__remus_devices_state *rds); +int init_subkind_nic(libxl__checkpoint_devices_state *cds); +void cleanup_subkind_nic(libxl__checkpoint_devices_state *cds); +int init_subkind_drbd_disk(libxl__checkpoint_devices_state *cds); +void cleanup_subkind_drbd_disk(libxl__checkpoint_devices_state *cds); -typedef void libxl__remus_callback(libxl__egc *, - libxl__remus_devices_state *, int rc); +typedef void libxl__checkpoint_callback(libxl__egc *, + libxl__checkpoint_devices_state *, int rc); /* - * State associated with a remus invocation, including parameters - * passed to the remus abstract device layer by the remus + * State associated with a checkpoint invocation, including parameters + * passed to the checkpoint abstract device layer by the remus * save/restore machinery. */ -struct libxl__remus_devices_state { - /*---- must be set by caller of libxl__remus_device_(setup|teardown) ----*/ +struct libxl__checkpoint_devices_state { + /*---- must be set by caller of libxl__checkpoint_device_(setup|teardown) ----*/ libxl__ao *ao; uint32_t domid; - libxl__remus_callback *callback; + libxl__checkpoint_callback *callback; int device_kind_flags; /*----- private for abstract layer only -----*/ int num_devices; /* - * this array is allocated before setup the remus devices by the - * remus abstract layer. - * devs may be NULL, means there's no remus devices that has been set up. + * this array is allocated before setup the checkpoint devices by the + * checkpoint abstract layer. + * devs may be NULL, means there's no checkpoint devices that has been set up. * the size of this array is 'num_devices', which is the total number * of libxl nic devices and disk devices(num_nics + num_disks). */ - libxl__remus_device **devs; + libxl__checkpoint_device **devs; libxl_device_nic *nics; int num_nics; @@ -2926,20 +2926,20 @@ struct libxl__remus_devices_state { /* * Information about a single device being handled by remus. - * Allocated by the remus abstract layer. + * Allocated by the checkpoint abstract layer. */ -struct libxl__remus_device { +struct libxl__checkpoint_device { /*----- shared between abstract and concrete layers -----*/ /* * if this is true, that means the subkind ops match the device */ bool matched; - /*----- set by remus device abstruct layer -----*/ - /* libxl__device_* which this remus device related to */ + /*----- set by checkpoint device abstruct layer -----*/ + /* libxl__device_* which this checkpoint device related to */ const void *backend_dev; libxl__device_kind kind; - libxl__remus_devices_state *rds; + libxl__checkpoint_devices_state *cds; libxl__ao_device aodev; /*----- private for abstract layer only -----*/ @@ -2950,7 +2950,7 @@ struct libxl__remus_device { * individual devices. */ int ops_index; - const libxl__remus_device_instance_ops *ops; + const libxl__checkpoint_device_instance_ops *ops; /*----- private for concrete (device-specific) layer -----*/ @@ -2958,17 +2958,17 @@ struct libxl__remus_device { void *concrete_data; }; -/* the following 5 APIs are async ops, call rds->callback when done */ -_hidden void libxl__remus_devices_setup(libxl__egc *egc, - libxl__remus_devices_state *rds); -_hidden void libxl__remus_devices_teardown(libxl__egc *egc, - libxl__remus_devices_state *rds); -_hidden void libxl__remus_devices_postsuspend(libxl__egc *egc, - libxl__remus_devices_state *rds); -_hidden void libxl__remus_devices_preresume(libxl__egc *egc, - libxl__remus_devices_state *rds); -_hidden void libxl__remus_devices_commit(libxl__egc *egc, - libxl__remus_devices_state *rds); +/* the following 5 APIs are async ops, call cds->callback when done */ +_hidden void libxl__checkpoint_devices_setup(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); +_hidden void libxl__checkpoint_devices_teardown(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); +_hidden void libxl__checkpoint_devices_postsuspend(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); +_hidden void libxl__checkpoint_devices_preresume(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); +_hidden void libxl__checkpoint_devices_commit(libxl__egc *egc, + libxl__checkpoint_devices_state *cds); _hidden int libxl__netbuffer_enabled(libxl__gc *gc); /*----- Legacy conversion helper -----*/ @@ -3122,7 +3122,7 @@ struct libxl__domain_save_state { int hvm; int xcflags; libxl__domain_suspend_state dsps; - libxl__remus_devices_state rds; + libxl__checkpoint_devices_state cds; libxl__ev_time checkpoint_timeout; /* used for Remus checkpoint */ int interval; /* checkpoint interval (for Remus) */ libxl__stream_write_state sws; diff --git a/tools/libxl/libxl_netbuffer.c b/tools/libxl/libxl_netbuffer.c index c245a4e..33c2a42 100644 --- a/tools/libxl/libxl_netbuffer.c +++ b/tools/libxl/libxl_netbuffer.c @@ -38,21 +38,21 @@ int libxl__netbuffer_enabled(libxl__gc *gc) return 1; } -int init_subkind_nic(libxl__remus_devices_state *rds) +int init_subkind_nic(libxl__checkpoint_devices_state *cds) { int rc, ret; - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); - rds->nlsock = nl_socket_alloc(); - if (!rds->nlsock) { + cds->nlsock = nl_socket_alloc(); + if (!cds->nlsock) { LOG(ERROR, "cannot allocate nl socket"); rc = ERROR_FAIL; goto out; } - ret = nl_connect(rds->nlsock, NETLINK_ROUTE); + ret = nl_connect(cds->nlsock, NETLINK_ROUTE); if (ret) { LOG(ERROR, "failed to open netlink socket: %s", nl_geterror(ret)); @@ -61,7 +61,7 @@ int init_subkind_nic(libxl__remus_devices_state *rds) } /* get list of all qdiscs installed on network devs. */ - ret = rtnl_qdisc_alloc_cache(rds->nlsock, &rds->qdisc_cache); + ret = rtnl_qdisc_alloc_cache(cds->nlsock, &cds->qdisc_cache); if (ret) { LOG(ERROR, "failed to allocate qdisc cache: %s", nl_geterror(ret)); @@ -70,9 +70,9 @@ int init_subkind_nic(libxl__remus_devices_state *rds) } if (dss->remus->netbufscript) { - rds->netbufscript = libxl__strdup(gc, dss->remus->netbufscript); + cds->netbufscript = libxl__strdup(gc, dss->remus->netbufscript); } else { - rds->netbufscript = GCSPRINTF("%s/remus-netbuf-setup", + cds->netbufscript = GCSPRINTF("%s/remus-netbuf-setup", libxl__xen_script_dir_path()); } @@ -82,22 +82,22 @@ out: return rc; } -void cleanup_subkind_nic(libxl__remus_devices_state *rds) +void cleanup_subkind_nic(libxl__checkpoint_devices_state *cds) { - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); /* free qdisc cache */ - if (rds->qdisc_cache) { - nl_cache_clear(rds->qdisc_cache); - nl_cache_free(rds->qdisc_cache); - rds->qdisc_cache = NULL; + if (cds->qdisc_cache) { + nl_cache_clear(cds->qdisc_cache); + nl_cache_free(cds->qdisc_cache); + cds->qdisc_cache = NULL; } /* close & free nlsock */ - if (rds->nlsock) { - nl_close(rds->nlsock); - nl_socket_free(rds->nlsock); - rds->nlsock = NULL; + if (cds->nlsock) { + nl_close(cds->nlsock); + nl_socket_free(cds->nlsock); + cds->nlsock = NULL; } } @@ -111,17 +111,17 @@ void cleanup_subkind_nic(libxl__remus_devices_state *rds) * it must ONLY be used for remus because if driver domains * were in use it would constitute a security vulnerability. */ -static const char *get_vifname(libxl__remus_device *dev, +static const char *get_vifname(libxl__checkpoint_device *dev, const libxl_device_nic *nic) { const char *vifname = NULL; const char *path; int rc; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); /* Convenience aliases */ - const uint32_t domid = dev->rds->domid; + const uint32_t domid = dev->cds->domid; path = GCSPRINTF("%s/backend/vif/%d/%d/vifname", libxl__xs_get_dompath(gc, 0), domid, nic->devid); @@ -144,19 +144,19 @@ static void free_qdisc(libxl__remus_device_nic *remus_nic) remus_nic->qdisc = NULL; } -static int init_qdisc(libxl__remus_devices_state *rds, +static int init_qdisc(libxl__checkpoint_devices_state *cds, libxl__remus_device_nic *remus_nic) { int rc, ret, ifindex; struct rtnl_link *ifb = NULL; struct rtnl_qdisc *qdisc = NULL; - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); /* Now that we have brought up REMUS_IFB device with plug qdisc for * this vif, so we need to refill the qdisc cache. */ - ret = nl_cache_refill(rds->nlsock, rds->qdisc_cache); + ret = nl_cache_refill(cds->nlsock, cds->qdisc_cache); if (ret) { LOG(ERROR, "cannot refill qdisc cache: %s", nl_geterror(ret)); rc = ERROR_FAIL; @@ -164,7 +164,7 @@ static int init_qdisc(libxl__remus_devices_state *rds, } /* get a handle to the REMUS_IFB interface */ - ret = rtnl_link_get_kernel(rds->nlsock, 0, remus_nic->ifb, &ifb); + ret = rtnl_link_get_kernel(cds->nlsock, 0, remus_nic->ifb, &ifb); if (ret) { LOG(ERROR, "cannot obtain handle for %s: %s", remus_nic->ifb, nl_geterror(ret)); @@ -187,7 +187,7 @@ static int init_qdisc(libxl__remus_devices_state *rds, * There is no need to explicitly free this qdisc as its just a * reference from the qdisc cache we allocated earlier. */ - qdisc = rtnl_qdisc_get_by_parent(rds->qdisc_cache, ifindex, TC_H_ROOT); + qdisc = rtnl_qdisc_get_by_parent(cds->qdisc_cache, ifindex, TC_H_ROOT); if (qdisc) { const char *tc_kind = rtnl_tc_get_kind(TC_CAST(qdisc)); /* Sanity check: Ensure that the root qdisc is a plug qdisc. */ @@ -231,19 +231,19 @@ static void netbuf_teardown_script_cb(libxl__egc *egc, * $REMUS_IFB (for teardown) * setup/teardown as command line arg. */ -static void setup_async_exec(libxl__remus_device *dev, char *op) +static void setup_async_exec(libxl__checkpoint_device *dev, char *op) { int arraysize, nr = 0; char **env = NULL, **args = NULL; libxl__remus_device_nic *remus_nic = dev->concrete_data; - libxl__remus_devices_state *rds = dev->rds; + libxl__checkpoint_devices_state *cds = dev->cds; libxl__async_exec_state *aes = &dev->aodev.aes; - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); /* Convenience aliases */ - char *const script = libxl__strdup(gc, rds->netbufscript); - const uint32_t domid = rds->domid; + char *const script = libxl__strdup(gc, cds->netbufscript); + const uint32_t domid = cds->domid; const int dev_id = remus_nic->devid; const char *const vif = remus_nic->vif; const char *const ifb = remus_nic->ifb; @@ -269,7 +269,7 @@ static void setup_async_exec(libxl__remus_device *dev, char *op) args[nr++] = NULL; assert(nr == arraysize); - aes->ao = dev->rds->ao; + aes->ao = dev->cds->ao; aes->what = GCSPRINTF("%s %s", args[0], args[1]); aes->env = env; aes->args = args; @@ -286,13 +286,13 @@ static void setup_async_exec(libxl__remus_device *dev, char *op) /* setup() and teardown() */ -static void nic_setup(libxl__egc *egc, libxl__remus_device *dev) +static void nic_setup(libxl__egc *egc, libxl__checkpoint_device *dev) { int rc; libxl__remus_device_nic *remus_nic; const libxl_device_nic *nic = dev->backend_dev; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); /* * thers's no subkind of nic devices, so nic ops is always matched @@ -330,15 +330,15 @@ static void netbuf_setup_script_cb(libxl__egc *egc, int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); - libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); + libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_device_nic *remus_nic = dev->concrete_data; - libxl__remus_devices_state *rds = dev->rds; + libxl__checkpoint_devices_state *cds = dev->cds; const char *out_path_base, *hotplug_error = NULL; - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); /* Convenience aliases */ - const uint32_t domid = rds->domid; + const uint32_t domid = cds->domid; const int devid = remus_nic->devid; const char *const vif = remus_nic->vif; const char **const ifb = &remus_nic->ifb; @@ -377,7 +377,7 @@ static void netbuf_setup_script_cb(libxl__egc *egc, if (hotplug_error) { LOG(ERROR, "netbuf script %s setup failed for vif %s: %s", - rds->netbufscript, vif, hotplug_error); + cds->netbufscript, vif, hotplug_error); rc = ERROR_FAIL; goto out; } @@ -388,17 +388,17 @@ static void netbuf_setup_script_cb(libxl__egc *egc, } LOG(DEBUG, "%s will buffer packets from vif %s", *ifb, vif); - rc = init_qdisc(rds, remus_nic); + rc = init_qdisc(cds, remus_nic); out: aodev->rc = rc; aodev->callback(egc, aodev); } -static void nic_teardown(libxl__egc *egc, libxl__remus_device *dev) +static void nic_teardown(libxl__egc *egc, libxl__checkpoint_device *dev) { int rc; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); setup_async_exec(dev, "teardown"); @@ -418,7 +418,7 @@ static void netbuf_teardown_script_cb(libxl__egc *egc, int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); - libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); + libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_device_nic *remus_nic = dev->concrete_data; if (status && !rc) @@ -441,12 +441,12 @@ enum { /* API implementations */ static int remus_netbuf_op(libxl__remus_device_nic *remus_nic, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int buffer_op) { int rc, ret; - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); if (buffer_op == tc_buffer_start) ret = rtnl_qdisc_plug_buffer(remus_nic->qdisc); @@ -458,7 +458,7 @@ static int remus_netbuf_op(libxl__remus_device_nic *remus_nic, goto out; } - ret = rtnl_qdisc_add(rds->nlsock, remus_nic->qdisc, NLM_F_REQUEST); + ret = rtnl_qdisc_add(cds->nlsock, remus_nic->qdisc, NLM_F_REQUEST); if (ret) { rc = ERROR_FAIL; goto out; @@ -475,33 +475,33 @@ out: return rc; } -static void nic_postsuspend(libxl__egc *egc, libxl__remus_device *dev) +static void nic_postsuspend(libxl__egc *egc, libxl__checkpoint_device *dev) { int rc; libxl__remus_device_nic *remus_nic = dev->concrete_data; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); - rc = remus_netbuf_op(remus_nic, dev->rds, tc_buffer_start); + rc = remus_netbuf_op(remus_nic, dev->cds, tc_buffer_start); dev->aodev.rc = rc; dev->aodev.callback(egc, &dev->aodev); } -static void nic_commit(libxl__egc *egc, libxl__remus_device *dev) +static void nic_commit(libxl__egc *egc, libxl__checkpoint_device *dev) { int rc; libxl__remus_device_nic *remus_nic = dev->concrete_data; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); - rc = remus_netbuf_op(remus_nic, dev->rds, tc_buffer_release); + rc = remus_netbuf_op(remus_nic, dev->cds, tc_buffer_release); dev->aodev.rc = rc; dev->aodev.callback(egc, &dev->aodev); } -const libxl__remus_device_instance_ops remus_device_nic = { +const libxl__checkpoint_device_instance_ops remus_device_nic = { .kind = LIBXL__DEVICE_KIND_VIF, .setup = nic_setup, .teardown = nic_teardown, diff --git a/tools/libxl/libxl_nonetbuffer.c b/tools/libxl/libxl_nonetbuffer.c index 3c659c2..4b68152 100644 --- a/tools/libxl/libxl_nonetbuffer.c +++ b/tools/libxl/libxl_nonetbuffer.c @@ -22,25 +22,25 @@ int libxl__netbuffer_enabled(libxl__gc *gc) return 0; } -int init_subkind_nic(libxl__remus_devices_state *rds) +int init_subkind_nic(libxl__checkpoint_devices_state *cds) { return 0; } -void cleanup_subkind_nic(libxl__remus_devices_state *rds) +void cleanup_subkind_nic(libxl__checkpoint_devices_state *cds) { return; } -static void nic_setup(libxl__egc *egc, libxl__remus_device *dev) +static void nic_setup(libxl__egc *egc, libxl__checkpoint_device *dev) { - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); dev->aodev.rc = ERROR_FAIL; dev->aodev.callback(egc, &dev->aodev); } -const libxl__remus_device_instance_ops remus_device_nic = { +const libxl__checkpoint_device_instance_ops remus_device_nic = { .kind = LIBXL__DEVICE_KIND_VIF, .setup = nic_setup, }; diff --git a/tools/libxl/libxl_remus.c b/tools/libxl/libxl_remus.c index 340d076..d41a439 100644 --- a/tools/libxl/libxl_remus.c +++ b/tools/libxl/libxl_remus.c @@ -21,9 +21,9 @@ /*-------------------- Remus setup and teardown ---------------------*/ static void remus_setup_done(libxl__egc *egc, - libxl__remus_devices_state *rds, int rc); + libxl__checkpoint_devices_state *cds, int rc); static void remus_setup_failed(libxl__egc *egc, - libxl__remus_devices_state *rds, int rc); + libxl__checkpoint_devices_state *cds, int rc); static void remus_checkpoint_stream_written( libxl__egc *egc, libxl__stream_write_state *sws, int rc); static void libxl__remus_domain_suspend_callback(void *data); @@ -34,7 +34,7 @@ void libxl__remus_setup(libxl__egc *egc, libxl__domain_save_state *dss) { /* Convenience aliases */ - libxl__remus_devices_state *const rds = &dss->rds; + libxl__checkpoint_devices_state *const cds = &dss->cds; const libxl_domain_remus_info *const info = dss->remus; libxl__srm_save_autogen_callbacks *const callbacks = &dss->sws.shs.callbacks.save.a; @@ -46,15 +46,15 @@ void libxl__remus_setup(libxl__egc *egc, LOG(ERROR, "Remus: No support for network buffering"); goto out; } - rds->device_kind_flags |= (1 << LIBXL__DEVICE_KIND_VIF); + cds->device_kind_flags |= (1 << LIBXL__DEVICE_KIND_VIF); } if (libxl_defbool_val(info->diskbuf)) - rds->device_kind_flags |= (1 << LIBXL__DEVICE_KIND_VBD); + cds->device_kind_flags |= (1 << LIBXL__DEVICE_KIND_VBD); - rds->ao = ao; - rds->domid = dss->domid; - rds->callback = remus_setup_done; + cds->ao = ao; + cds->domid = dss->domid; + cds->callback = remus_setup_done; dss->sws.checkpoint_callback = remus_checkpoint_stream_written; @@ -62,7 +62,7 @@ void libxl__remus_setup(libxl__egc *egc, callbacks->postcopy = libxl__remus_domain_resume_callback; callbacks->checkpoint = libxl__remus_domain_save_checkpoint_callback; - libxl__remus_devices_setup(egc, rds); + libxl__checkpoint_devices_setup(egc, cds); return; out: @@ -70,9 +70,9 @@ out: } static void remus_setup_done(libxl__egc *egc, - libxl__remus_devices_state *rds, int rc) + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); STATE_AO_GC(dss->ao); if (!rc) { @@ -82,14 +82,14 @@ static void remus_setup_done(libxl__egc *egc, LOG(ERROR, "Remus: failed to setup device for guest with domid %u, rc %d", dss->domid, rc); - rds->callback = remus_setup_failed; - libxl__remus_devices_teardown(egc, rds); + cds->callback = remus_setup_failed; + libxl__checkpoint_devices_teardown(egc, cds); } static void remus_setup_failed(libxl__egc *egc, - libxl__remus_devices_state *rds, int rc) + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); STATE_AO_GC(dss->ao); if (rc) @@ -100,7 +100,7 @@ static void remus_setup_failed(libxl__egc *egc, } static void remus_teardown_done(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc); void libxl__remus_teardown(libxl__egc *egc, libxl__domain_save_state *dss, @@ -110,15 +110,15 @@ void libxl__remus_teardown(libxl__egc *egc, LOG(WARN, "Remus: Domain suspend terminated with rc %d," " teardown Remus devices...", rc); - dss->rds.callback = remus_teardown_done; - libxl__remus_devices_teardown(egc, &dss->rds); + dss->cds.callback = remus_teardown_done; + libxl__checkpoint_devices_teardown(egc, &dss->cds); } static void remus_teardown_done(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); STATE_AO_GC(dss->ao); if (rc) @@ -133,10 +133,10 @@ static void remus_teardown_done(libxl__egc *egc, static void remus_domain_suspend_callback_common_done(libxl__egc *egc, libxl__domain_suspend_state *dsps, int ok); static void remus_devices_postsuspend_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc); static void remus_devices_preresume_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc); static void libxl__remus_domain_suspend_callback(void *data) @@ -158,9 +158,9 @@ static void remus_domain_suspend_callback_common_done(libxl__egc *egc, if (rc) goto out; - libxl__remus_devices_state *const rds = &dss->rds; - rds->callback = remus_devices_postsuspend_cb; - libxl__remus_devices_postsuspend(egc, rds); + libxl__checkpoint_devices_state *const cds = &dss->cds; + cds->callback = remus_devices_postsuspend_cb; + libxl__checkpoint_devices_postsuspend(egc, cds); return; out: @@ -169,10 +169,10 @@ out: } static void remus_devices_postsuspend_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); if (rc) goto out; @@ -192,16 +192,16 @@ static void libxl__remus_domain_resume_callback(void *data) libxl__domain_save_state *dss = shs->caller_state; STATE_AO_GC(dss->ao); - libxl__remus_devices_state *const rds = &dss->rds; - rds->callback = remus_devices_preresume_cb; - libxl__remus_devices_preresume(egc, rds); + libxl__checkpoint_devices_state *const cds = &dss->cds; + cds->callback = remus_devices_preresume_cb; + libxl__checkpoint_devices_preresume(egc, cds); } static void remus_devices_preresume_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); STATE_AO_GC(dss->ao); if (rc) @@ -223,7 +223,7 @@ out: /*----- remus asynchronous checkpoint callback -----*/ static void remus_devices_commit_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc); static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs, @@ -245,7 +245,7 @@ static void remus_checkpoint_stream_written( libxl__domain_save_state *dss = CONTAINER_OF(sws, *dss, sws); /* Convenience aliases */ - libxl__remus_devices_state *const rds = &dss->rds; + libxl__checkpoint_devices_state *const cds = &dss->cds; STATE_AO_GC(dss->ao); @@ -254,8 +254,8 @@ static void remus_checkpoint_stream_written( goto out; } - rds->callback = remus_devices_commit_cb; - libxl__remus_devices_commit(egc, rds); + cds->callback = remus_devices_commit_cb; + libxl__checkpoint_devices_commit(egc, cds); return; @@ -264,10 +264,10 @@ out: } static void remus_devices_commit_cb(libxl__egc *egc, - libxl__remus_devices_state *rds, + libxl__checkpoint_devices_state *cds, int rc) { - libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); STATE_AO_GC(dss->ao); diff --git a/tools/libxl/libxl_remus_device.c b/tools/libxl/libxl_remus_device.c deleted file mode 100644 index a6cb7f6..0000000 --- a/tools/libxl/libxl_remus_device.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2014 FUJITSU LIMITED - * Author: Yang Hongyang <yanghy@xxxxxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; version 2.1 only. with the special - * exception on linking described in file LICENSE. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -#include "libxl_osdeps.h" /* must come before any other headers */ - -#include "libxl_internal.h" - -extern const libxl__remus_device_instance_ops remus_device_nic; -extern const libxl__remus_device_instance_ops remus_device_drbd_disk; -static const libxl__remus_device_instance_ops *remus_ops[] = { - &remus_device_nic, - &remus_device_drbd_disk, - NULL, -}; - -/*----- helper functions -----*/ - -static int init_device_subkind(libxl__remus_devices_state *rds) -{ - /* init device subkind-specific state in the libxl ctx */ - int rc; - STATE_AO_GC(rds->ao); - - if (libxl__netbuffer_enabled(gc)) { - rc = init_subkind_nic(rds); - if (rc) goto out; - } - - rc = init_subkind_drbd_disk(rds); - if (rc) goto out; - - rc = 0; -out: - return rc; -} - -static void cleanup_device_subkind(libxl__remus_devices_state *rds) -{ - /* cleanup device subkind-specific state in the libxl ctx */ - STATE_AO_GC(rds->ao); - - if (libxl__netbuffer_enabled(gc)) - cleanup_subkind_nic(rds); - - cleanup_subkind_drbd_disk(rds); -} - -/*----- setup() and teardown() -----*/ - -/* callbacks */ - -static void all_devices_setup_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc); -static void device_setup_iterate(libxl__egc *egc, - libxl__ao_device *aodev); -static void devices_teardown_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc); - -/* remus device setup and teardown */ - -static libxl__remus_device* remus_device_init(libxl__egc *egc, - libxl__remus_devices_state *rds, - libxl__device_kind kind, - void *libxl_dev) -{ - libxl__remus_device *dev = NULL; - - STATE_AO_GC(rds->ao); - GCNEW(dev); - dev->backend_dev = libxl_dev; - dev->kind = kind; - dev->rds = rds; - - return dev; -} - -static void remus_devices_setup(libxl__egc *egc, - libxl__remus_devices_state *rds); - -void libxl__remus_devices_setup(libxl__egc *egc, libxl__remus_devices_state *rds) -{ - int i, rc; - - STATE_AO_GC(rds->ao); - - rc = init_device_subkind(rds); - if (rc) - goto out; - - rds->num_devices = 0; - rds->num_nics = 0; - rds->num_disks = 0; - - if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF)) - rds->nics = libxl_device_nic_list(CTX, rds->domid, &rds->num_nics); - - if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD)) - rds->disks = libxl_device_disk_list(CTX, rds->domid, &rds->num_disks); - - if (rds->num_nics == 0 && rds->num_disks == 0) - goto out; - - GCNEW_ARRAY(rds->devs, rds->num_nics + rds->num_disks); - - for (i = 0; i < rds->num_nics; i++) { - rds->devs[rds->num_devices++] = remus_device_init(egc, rds, - LIBXL__DEVICE_KIND_VIF, - &rds->nics[i]); - } - - for (i = 0; i < rds->num_disks; i++) { - rds->devs[rds->num_devices++] = remus_device_init(egc, rds, - LIBXL__DEVICE_KIND_VBD, - &rds->disks[i]); - } - - remus_devices_setup(egc, rds); - - return; - -out: - rds->callback(egc, rds, rc); -} - -static void remus_devices_setup(libxl__egc *egc, - libxl__remus_devices_state *rds) -{ - int i, rc; - - STATE_AO_GC(rds->ao); - - libxl__multidev_begin(ao, &rds->multidev); - rds->multidev.callback = all_devices_setup_cb; - for (i = 0; i < rds->num_devices; i++) { - libxl__remus_device *dev = rds->devs[i]; - dev->ops_index = -1; - libxl__multidev_prepare_with_aodev(&rds->multidev, &dev->aodev); - - dev->aodev.rc = ERROR_REMUS_DEVICE_NOT_SUPPORTED; - dev->aodev.callback = device_setup_iterate; - device_setup_iterate(egc,&dev->aodev); - } - - rc = 0; - libxl__multidev_prepared(egc, &rds->multidev, rc); -} - - -static void device_setup_iterate(libxl__egc *egc, libxl__ao_device *aodev) -{ - libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); - EGC_GC; - - if (aodev->rc != ERROR_REMUS_DEVICE_NOT_SUPPORTED && - aodev->rc != ERROR_REMUS_DEVOPS_DOES_NOT_MATCH) - /* might be success or disaster */ - goto out; - - do { - dev->ops = remus_ops[++dev->ops_index]; - if (!dev->ops) { - libxl_device_nic * nic = NULL; - libxl_device_disk * disk = NULL; - uint32_t domid; - int devid; - if (dev->kind == LIBXL__DEVICE_KIND_VIF) { - nic = (libxl_device_nic *)dev->backend_dev; - domid = nic->backend_domid; - devid = nic->devid; - } else if (dev->kind == LIBXL__DEVICE_KIND_VBD) { - disk = (libxl_device_disk *)dev->backend_dev; - domid = disk->backend_domid; - devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL); - } else { - LOG(ERROR,"device kind not handled by remus: %s", - libxl__device_kind_to_string(dev->kind)); - aodev->rc = ERROR_FAIL; - goto out; - } - LOG(ERROR,"device not handled by remus" - " (device=%s:%"PRId32"/%"PRId32")", - libxl__device_kind_to_string(dev->kind), - domid, devid); - aodev->rc = ERROR_REMUS_DEVICE_NOT_SUPPORTED; - goto out; - } - } while (dev->ops->kind != dev->kind); - - /* found the next ops_index to try */ - assert(dev->aodev.callback == device_setup_iterate); - dev->ops->setup(egc,dev); - return; - - out: - libxl__multidev_one_callback(egc,aodev); -} - -static void all_devices_setup_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc) -{ - STATE_AO_GC(multidev->ao); - - /* Convenience aliases */ - libxl__remus_devices_state *const rds = - CONTAINER_OF(multidev, *rds, multidev); - - rds->callback(egc, rds, rc); -} - -void libxl__remus_devices_teardown(libxl__egc *egc, - libxl__remus_devices_state *rds) -{ - int i; - libxl__remus_device *dev; - - STATE_AO_GC(rds->ao); - - libxl__multidev_begin(ao, &rds->multidev); - rds->multidev.callback = devices_teardown_cb; - for (i = 0; i < rds->num_devices; i++) { - dev = rds->devs[i]; - if (!dev->ops || !dev->matched) - continue; - - libxl__multidev_prepare_with_aodev(&rds->multidev, &dev->aodev); - dev->ops->teardown(egc,dev); - } - - libxl__multidev_prepared(egc, &rds->multidev, 0); -} - -static void devices_teardown_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc) -{ - int i; - - STATE_AO_GC(multidev->ao); - - /* Convenience aliases */ - libxl__remus_devices_state *const rds = - CONTAINER_OF(multidev, *rds, multidev); - - /* clean nic */ - for (i = 0; i < rds->num_nics; i++) - libxl_device_nic_dispose(&rds->nics[i]); - free(rds->nics); - rds->nics = NULL; - rds->num_nics = 0; - - /* clean disk */ - for (i = 0; i < rds->num_disks; i++) - libxl_device_disk_dispose(&rds->disks[i]); - free(rds->disks); - rds->disks = NULL; - rds->num_disks = 0; - - cleanup_device_subkind(rds); - - rds->callback(egc, rds, rc); -} - -/*----- checkpointing APIs -----*/ - -/* callbacks */ - -static void devices_checkpoint_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc); - -/* API implementations */ - -#define define_remus_checkpoint_api(api) \ -void libxl__remus_devices_##api(libxl__egc *egc, \ - libxl__remus_devices_state *rds) \ -{ \ - int i; \ - libxl__remus_device *dev; \ - \ - STATE_AO_GC(rds->ao); \ - \ - libxl__multidev_begin(ao, &rds->multidev); \ - rds->multidev.callback = devices_checkpoint_cb; \ - for (i = 0; i < rds->num_devices; i++) { \ - dev = rds->devs[i]; \ - if (!dev->matched || !dev->ops->api) \ - continue; \ - libxl__multidev_prepare_with_aodev(&rds->multidev, &dev->aodev);\ - dev->ops->api(egc,dev); \ - } \ - \ - libxl__multidev_prepared(egc, &rds->multidev, 0); \ -} - -define_remus_checkpoint_api(postsuspend); - -define_remus_checkpoint_api(preresume); - -define_remus_checkpoint_api(commit); - -static void devices_checkpoint_cb(libxl__egc *egc, - libxl__multidev *multidev, - int rc) -{ - STATE_AO_GC(multidev->ao); - - /* Convenience aliases */ - libxl__remus_devices_state *const rds = - CONTAINER_OF(multidev, *rds, multidev); - - rds->callback(egc, rds, rc); -} diff --git a/tools/libxl/libxl_remus_disk_drbd.c b/tools/libxl/libxl_remus_disk_drbd.c index 1c3a88a..4dddc58 100644 --- a/tools/libxl/libxl_remus_disk_drbd.c +++ b/tools/libxl/libxl_remus_disk_drbd.c @@ -26,30 +26,30 @@ typedef struct libxl__remus_drbd_disk { int ackwait; } libxl__remus_drbd_disk; -int init_subkind_drbd_disk(libxl__remus_devices_state *rds) +int init_subkind_drbd_disk(libxl__checkpoint_devices_state *cds) { - STATE_AO_GC(rds->ao); + STATE_AO_GC(cds->ao); - rds->drbd_probe_script = GCSPRINTF("%s/block-drbd-probe", + cds->drbd_probe_script = GCSPRINTF("%s/block-drbd-probe", libxl__xen_script_dir_path()); return 0; } -void cleanup_subkind_drbd_disk(libxl__remus_devices_state *rds) +void cleanup_subkind_drbd_disk(libxl__checkpoint_devices_state *cds) { return; } /*----- helper functions, for async calls -----*/ static void drbd_async_call(libxl__egc *egc, - libxl__remus_device *dev, - void func(libxl__remus_device *), + libxl__checkpoint_device *dev, + void func(libxl__checkpoint_device *), libxl__ev_child_callback callback) { int pid, rc; libxl__ao_device *aodev = &dev->aodev; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); /* Fork and call */ pid = libxl__ev_child_fork(gc, &aodev->child, callback); @@ -82,21 +82,21 @@ static void match_async_exec_cb(libxl__egc *egc, /* implementations */ -static void match_async_exec(libxl__egc *egc, libxl__remus_device *dev); +static void match_async_exec(libxl__egc *egc, libxl__checkpoint_device *dev); -static void drbd_setup(libxl__egc *egc, libxl__remus_device *dev) +static void drbd_setup(libxl__egc *egc, libxl__checkpoint_device *dev) { - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); match_async_exec(egc, dev); } -static void match_async_exec(libxl__egc *egc, libxl__remus_device *dev) +static void match_async_exec(libxl__egc *egc, libxl__checkpoint_device *dev) { int arraysize, nr = 0, rc; const libxl_device_disk *disk = dev->backend_dev; libxl__async_exec_state *aes = &dev->aodev.aes; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); /* setup env & args */ arraysize = 1; @@ -107,12 +107,12 @@ static void match_async_exec(libxl__egc *egc, libxl__remus_device *dev) arraysize = 3; nr = 0; GCNEW_ARRAY(aes->args, arraysize); - aes->args[nr++] = dev->rds->drbd_probe_script; + aes->args[nr++] = dev->cds->drbd_probe_script; aes->args[nr++] = disk->pdev_path; aes->args[nr++] = NULL; assert(nr <= arraysize); - aes->ao = dev->rds->ao; + aes->ao = dev->cds->ao; aes->what = GCSPRINTF("%s %s", aes->args[0], aes->args[1]); aes->timeout_ms = LIBXL_HOTPLUG_TIMEOUT * 1000; aes->callback = match_async_exec_cb; @@ -136,7 +136,7 @@ static void match_async_exec_cb(libxl__egc *egc, int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); - libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); + libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_drbd_disk *drbd_disk; const libxl_device_disk *disk = dev->backend_dev; @@ -146,7 +146,7 @@ static void match_async_exec_cb(libxl__egc *egc, goto out; if (status) { - rc = ERROR_REMUS_DEVOPS_DOES_NOT_MATCH; + rc = ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH; /* BUG: seems to assume that any exit status means `no match' */ /* BUG: exit status will have been logged as an error */ goto out; @@ -171,10 +171,10 @@ out: aodev->callback(egc, aodev); } -static void drbd_teardown(libxl__egc *egc, libxl__remus_device *dev) +static void drbd_teardown(libxl__egc *egc, libxl__checkpoint_device *dev) { libxl__remus_drbd_disk *drbd_disk = dev->concrete_data; - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); close(drbd_disk->ctl_fd); dev->aodev.rc = 0; @@ -191,9 +191,9 @@ static void checkpoint_async_call_done(libxl__egc *egc, /* API implementations */ /* this op will not wait and block, so implement as sync op */ -static void drbd_postsuspend(libxl__egc *egc, libxl__remus_device *dev) +static void drbd_postsuspend(libxl__egc *egc, libxl__checkpoint_device *dev) { - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); libxl__remus_drbd_disk *rdd = dev->concrete_data; @@ -207,16 +207,16 @@ static void drbd_postsuspend(libxl__egc *egc, libxl__remus_device *dev) } -static void drbd_preresume_async(libxl__remus_device *dev); +static void drbd_preresume_async(libxl__checkpoint_device *dev); -static void drbd_preresume(libxl__egc *egc, libxl__remus_device *dev) +static void drbd_preresume(libxl__egc *egc, libxl__checkpoint_device *dev) { - STATE_AO_GC(dev->rds->ao); + STATE_AO_GC(dev->cds->ao); drbd_async_call(egc, dev, drbd_preresume_async, checkpoint_async_call_done); } -static void drbd_preresume_async(libxl__remus_device *dev) +static void drbd_preresume_async(libxl__checkpoint_device *dev) { libxl__remus_drbd_disk *rdd = dev->concrete_data; int ackwait = rdd->ackwait; @@ -235,7 +235,7 @@ static void checkpoint_async_call_done(libxl__egc *egc, { int rc; libxl__ao_device *aodev = CONTAINER_OF(child, *aodev, child); - libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); + libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_drbd_disk *rdd = dev->concrete_data; STATE_AO_GC(aodev->ao); @@ -253,7 +253,7 @@ out: aodev->callback(egc, aodev); } -const libxl__remus_device_instance_ops remus_device_drbd_disk = { +const libxl__checkpoint_device_instance_ops remus_device_drbd_disk = { .kind = LIBXL__DEVICE_KIND_VBD, .setup = drbd_setup, .teardown = drbd_teardown, diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 605fb9a..632c009 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -61,8 +61,8 @@ libxl_error = Enumeration("error", [ (-15, "LOCK_FAIL"), (-16, "JSON_CONFIG_EMPTY"), (-17, "DEVICE_EXISTS"), - (-18, "REMUS_DEVOPS_DOES_NOT_MATCH"), - (-19, "REMUS_DEVICE_NOT_SUPPORTED"), + (-18, "CHECKPOINT_DEVOPS_DOES_NOT_MATCH"), + (-19, "CHECKPOINT_DEVICE_NOT_SUPPORTED"), (-20, "VNUMA_CONFIG_INVALID"), (-21, "DOMAIN_NOTFOUND"), (-22, "ABORTED"), -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |