mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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@cn.fujitsu.com> Signed-off-by: Yang Hongyang <hongyang.yang@easystack.cn> Reviewed-Lightly-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
3646d07147
commit
304400459e
9 files changed
+293
-281
No files matched your search
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
#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[] = {
|
||||
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,
|
||||
@@ -27,18 +27,18 @@ static const libxl__remus_device_instance_ops *remus_ops[] = {
|
||||
|
||||
/*----- helper functions -----*/
|
||||
|
||||
static int init_device_subkind(libxl__remus_devices_state *rds)
|
||||
static int init_device_subkind(libxl__checkpoint_devices_state *cds)
|
||||
{
|
||||
/* init device subkind-specific state in the libxl ctx */
|
||||
int rc;
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->ao);
|
||||
|
||||
if (libxl__netbuffer_enabled(gc)) {
|
||||
rc = init_subkind_nic(rds);
|
||||
rc = init_subkind_nic(cds);
|
||||
if (rc) goto out;
|
||||
}
|
||||
|
||||
rc = init_subkind_drbd_disk(rds);
|
||||
rc = init_subkind_drbd_disk(cds);
|
||||
if (rc) goto out;
|
||||
|
||||
rc = 0;
|
||||
@@ -46,15 +46,15 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cleanup_device_subkind(libxl__remus_devices_state *rds)
|
||||
static void cleanup_device_subkind(libxl__checkpoint_devices_state *cds)
|
||||
{
|
||||
/* cleanup device subkind-specific state in the libxl ctx */
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->ao);
|
||||
|
||||
if (libxl__netbuffer_enabled(gc))
|
||||
cleanup_subkind_nic(rds);
|
||||
cleanup_subkind_nic(cds);
|
||||
|
||||
cleanup_subkind_drbd_disk(rds);
|
||||
cleanup_subkind_drbd_disk(cds);
|
||||
}
|
||||
|
||||
/*----- setup() and teardown() -----*/
|
||||
@@ -70,103 +70,103 @@ static void devices_teardown_cb(libxl__egc *egc,
|
||||
libxl__multidev *multidev,
|
||||
int rc);
|
||||
|
||||
/* remus device setup and teardown */
|
||||
/* checkpoint device setup and teardown */
|
||||
|
||||
static libxl__remus_device* remus_device_init(libxl__egc *egc,
|
||||
libxl__remus_devices_state *rds,
|
||||
static libxl__checkpoint_device* checkpoint_device_init(libxl__egc *egc,
|
||||
libxl__checkpoint_devices_state *cds,
|
||||
libxl__device_kind kind,
|
||||
void *libxl_dev)
|
||||
{
|
||||
libxl__remus_device *dev = NULL;
|
||||
libxl__checkpoint_device *dev = NULL;
|
||||
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->ao);
|
||||
GCNEW(dev);
|
||||
dev->backend_dev = libxl_dev;
|
||||
dev->kind = kind;
|
||||
dev->rds = rds;
|
||||
dev->cds = cds;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void remus_devices_setup(libxl__egc *egc,
|
||||
libxl__remus_devices_state *rds);
|
||||
static void checkpoint_devices_setup(libxl__egc *egc,
|
||||
libxl__checkpoint_devices_state *cds);
|
||||
|
||||
void libxl__remus_devices_setup(libxl__egc *egc, libxl__remus_devices_state *rds)
|
||||
void libxl__checkpoint_devices_setup(libxl__egc *egc, libxl__checkpoint_devices_state *cds)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->ao);
|
||||
|
||||
rc = init_device_subkind(rds);
|
||||
rc = init_device_subkind(cds);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rds->num_devices = 0;
|
||||
rds->num_nics = 0;
|
||||
rds->num_disks = 0;
|
||||
cds->num_devices = 0;
|
||||
cds->num_nics = 0;
|
||||
cds->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 (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF))
|
||||
cds->nics = libxl_device_nic_list(CTX, cds->domid, &cds->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 (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD))
|
||||
cds->disks = libxl_device_disk_list(CTX, cds->domid, &cds->num_disks);
|
||||
|
||||
if (rds->num_nics == 0 && rds->num_disks == 0)
|
||||
if (cds->num_nics == 0 && cds->num_disks == 0)
|
||||
goto out;
|
||||
|
||||
GCNEW_ARRAY(rds->devs, rds->num_nics + rds->num_disks);
|
||||
GCNEW_ARRAY(cds->devs, cds->num_nics + cds->num_disks);
|
||||
|
||||
for (i = 0; i < rds->num_nics; i++) {
|
||||
rds->devs[rds->num_devices++] = remus_device_init(egc, rds,
|
||||
for (i = 0; i < cds->num_nics; i++) {
|
||||
cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds,
|
||||
LIBXL__DEVICE_KIND_VIF,
|
||||
&rds->nics[i]);
|
||||
&cds->nics[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < rds->num_disks; i++) {
|
||||
rds->devs[rds->num_devices++] = remus_device_init(egc, rds,
|
||||
for (i = 0; i < cds->num_disks; i++) {
|
||||
cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds,
|
||||
LIBXL__DEVICE_KIND_VBD,
|
||||
&rds->disks[i]);
|
||||
&cds->disks[i]);
|
||||
}
|
||||
|
||||
remus_devices_setup(egc, rds);
|
||||
checkpoint_devices_setup(egc, cds);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
rds->callback(egc, rds, rc);
|
||||
cds->callback(egc, cds, rc);
|
||||
}
|
||||
|
||||
static void remus_devices_setup(libxl__egc *egc,
|
||||
libxl__remus_devices_state *rds)
|
||||
static void checkpoint_devices_setup(libxl__egc *egc,
|
||||
libxl__checkpoint_devices_state *cds)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->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];
|
||||
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(&rds->multidev, &dev->aodev);
|
||||
libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev);
|
||||
|
||||
dev->aodev.rc = ERROR_REMUS_DEVICE_NOT_SUPPORTED;
|
||||
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, &rds->multidev, rc);
|
||||
libxl__multidev_prepared(egc, &cds->multidev, rc);
|
||||
}
|
||||
|
||||
|
||||
static void device_setup_iterate(libxl__egc *egc, libxl__ao_device *aodev)
|
||||
{
|
||||
libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev);
|
||||
libxl__checkpoint_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)
|
||||
if (aodev->rc != ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED &&
|
||||
aodev->rc != ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
|
||||
/* might be success or disaster */
|
||||
goto out;
|
||||
|
||||
@@ -186,16 +186,16 @@ static void device_setup_iterate(libxl__egc *egc, libxl__ao_device *aodev)
|
||||
domid = disk->backend_domid;
|
||||
devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
|
||||
} else {
|
||||
LOG(ERROR,"device kind not handled by remus: %s",
|
||||
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 remus"
|
||||
LOG(ERROR,"device not handled by checkpoint"
|
||||
" (device=%s:%"PRId32"/%"PRId32")",
|
||||
libxl__device_kind_to_string(dev->kind),
|
||||
domid, devid);
|
||||
aodev->rc = ERROR_REMUS_DEVICE_NOT_SUPPORTED;
|
||||
aodev->rc = ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
} while (dev->ops->kind != dev->kind);
|
||||
@@ -216,32 +216,32 @@ static void all_devices_setup_cb(libxl__egc *egc,
|
||||
STATE_AO_GC(multidev->ao);
|
||||
|
||||
/* Convenience aliases */
|
||||
libxl__remus_devices_state *const rds =
|
||||
CONTAINER_OF(multidev, *rds, multidev);
|
||||
libxl__checkpoint_devices_state *const cds =
|
||||
CONTAINER_OF(multidev, *cds, multidev);
|
||||
|
||||
rds->callback(egc, rds, rc);
|
||||
cds->callback(egc, cds, rc);
|
||||
}
|
||||
|
||||
void libxl__remus_devices_teardown(libxl__egc *egc,
|
||||
libxl__remus_devices_state *rds)
|
||||
void libxl__checkpoint_devices_teardown(libxl__egc *egc,
|
||||
libxl__checkpoint_devices_state *cds)
|
||||
{
|
||||
int i;
|
||||
libxl__remus_device *dev;
|
||||
libxl__checkpoint_device *dev;
|
||||
|
||||
STATE_AO_GC(rds->ao);
|
||||
STATE_AO_GC(cds->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];
|
||||
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(&rds->multidev, &dev->aodev);
|
||||
libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev);
|
||||
dev->ops->teardown(egc,dev);
|
||||
}
|
||||
|
||||
libxl__multidev_prepared(egc, &rds->multidev, 0);
|
||||
libxl__multidev_prepared(egc, &cds->multidev, 0);
|
||||
}
|
||||
|
||||
static void devices_teardown_cb(libxl__egc *egc,
|
||||
@@ -253,26 +253,26 @@ static void devices_teardown_cb(libxl__egc *egc,
|
||||
STATE_AO_GC(multidev->ao);
|
||||
|
||||
/* Convenience aliases */
|
||||
libxl__remus_devices_state *const rds =
|
||||
CONTAINER_OF(multidev, *rds, multidev);
|
||||
libxl__checkpoint_devices_state *const cds =
|
||||
CONTAINER_OF(multidev, *cds, 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;
|
||||
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 < rds->num_disks; i++)
|
||||
libxl_device_disk_dispose(&rds->disks[i]);
|
||||
free(rds->disks);
|
||||
rds->disks = NULL;
|
||||
rds->num_disks = 0;
|
||||
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(rds);
|
||||
cleanup_device_subkind(cds);
|
||||
|
||||
rds->callback(egc, rds, rc);
|
||||
cds->callback(egc, cds, rc);
|
||||
}
|
||||
|
||||
/*----- checkpointing APIs -----*/
|
||||
@@ -285,33 +285,33 @@ static void devices_checkpoint_cb(libxl__egc *egc,
|
||||
|
||||
/* API implementations */
|
||||
|
||||
#define define_remus_checkpoint_api(api) \
|
||||
void libxl__remus_devices_##api(libxl__egc *egc, \
|
||||
libxl__remus_devices_state *rds) \
|
||||
#define define_checkpoint_api(api) \
|
||||
void libxl__checkpoint_devices_##api(libxl__egc *egc, \
|
||||
libxl__checkpoint_devices_state *cds) \
|
||||
{ \
|
||||
int i; \
|
||||
libxl__remus_device *dev; \
|
||||
libxl__checkpoint_device *dev; \
|
||||
\
|
||||
STATE_AO_GC(rds->ao); \
|
||||
STATE_AO_GC(cds->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]; \
|
||||
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(&rds->multidev, &dev->aodev);\
|
||||
libxl__multidev_prepare_with_aodev(&cds->multidev, &dev->aodev);\
|
||||
dev->ops->api(egc,dev); \
|
||||
} \
|
||||
\
|
||||
libxl__multidev_prepared(egc, &rds->multidev, 0); \
|
||||
libxl__multidev_prepared(egc, &cds->multidev, 0); \
|
||||
}
|
||||
|
||||
define_remus_checkpoint_api(postsuspend);
|
||||
define_checkpoint_api(postsuspend);
|
||||
|
||||
define_remus_checkpoint_api(preresume);
|
||||
define_checkpoint_api(preresume);
|
||||
|
||||
define_remus_checkpoint_api(commit);
|
||||
define_checkpoint_api(commit);
|
||||
|
||||
static void devices_checkpoint_cb(libxl__egc *egc,
|
||||
libxl__multidev *multidev,
|
||||
@@ -320,8 +320,8 @@ static void devices_checkpoint_cb(libxl__egc *egc,
|
||||
STATE_AO_GC(multidev->ao);
|
||||
|
||||
/* Convenience aliases */
|
||||
libxl__remus_devices_state *const rds =
|
||||
CONTAINER_OF(multidev, *rds, multidev);
|
||||
libxl__checkpoint_devices_state *const cds =
|
||||
CONTAINER_OF(multidev, *cds, multidev);
|
||||
|
||||
rds->callback(egc, rds, rc);
|
||||
cds->callback(egc, cds, rc);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
+38
-38
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"),
|
||||
|
||||