[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v10 16/31] secondary vm suspend/resume/checkpoint code
On 02/25/2016 11:56 PM, Wei Liu wrote: > On Mon, Feb 22, 2016 at 10:52:20AM +0800, Wen Congyang wrote: >> Secondary vm is running in colo mode. So we will do >> the following things again and again: >> 1. Resume secondary vm >> a. Send CHECKPOINT_SVM_READY to master. >> b. If it is not the first resume, call >> libxl__checkpoint_devices_preresume(). >> c. If it is the first resume(resume right after live migration), >> - call libxl__xc_domain_restore_done() to build the secondary vm. >> - enable secondary vm's logdirty. >> - call libxl__domain_resume() to resume secondary vm. >> - call libxl__checkpoint_devices_setup() to setup checkpoint devices. >> d. Send CHECKPOINT_SVM_RESUMED to master. >> 2. Wait a new checkpoint >> a. Call libxl__checkpoint_devices_commit(). >> b. Read CHECKPOINT_NEW from master. >> 3. Suspend secondary vm >> a. Suspend secondary vm. >> b. Call libxl__checkpoint_devices_postsuspend(). >> c. Send CHECKPOINT_SVM_SUSPENDED to master. >> >> Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> >> Signed-off-by: Yang Hongyang <hongyang.yang@xxxxxxxxxxxx> >> --- >> tools/libxc/xc_sr_common.h | 2 + >> tools/libxc/xc_sr_save.c | 3 +- >> tools/libxl/Makefile | 1 + >> tools/libxl/libxl_colo.h | 24 + >> tools/libxl/libxl_colo_restore.c | 1038 >> ++++++++++++++++++++++++++++++++++++++ >> tools/libxl/libxl_create.c | 37 ++ >> tools/libxl/libxl_internal.h | 19 + >> tools/libxl/libxl_save_callout.c | 7 +- >> tools/libxl/libxl_stream_read.c | 12 + >> tools/libxl/libxl_types.idl | 1 + > > There is a bunch of TODOs in libxl_colo.c but I don't think you're in a > better position to judge whether they should be blocker or not. > >> 10 files changed, 1142 insertions(+), 2 deletions(-) >> create mode 100644 tools/libxl/libxl_colo.h >> create mode 100644 tools/libxl/libxl_colo_restore.c >> >> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h >> index 5d9f497..2bfed64 100644 >> --- a/tools/libxc/xc_sr_common.h >> +++ b/tools/libxc/xc_sr_common.h >> @@ -184,10 +184,12 @@ struct xc_sr_context >> * migration stream >> * 0: Plain VM >> * 1: Remus >> + * 2: COLO >> */ >> enum { >> MIG_STREAM_NONE, /* plain stream */ >> MIG_STREAM_REMUS, >> + MIG_STREAM_COLO, >> } migration_stream; >> >> union /* Common save or restore data. */ >> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c >> index fe210cc..7393355 100644 >> --- a/tools/libxc/xc_sr_save.c >> +++ b/tools/libxc/xc_sr_save.c >> @@ -846,7 +846,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, >> uint32_t dom, >> >> /* If altering migration_stream update this assert too. */ >> assert(checkpointed_stream == MIG_STREAM_NONE || >> - checkpointed_stream == MIG_STREAM_REMUS); >> + checkpointed_stream == MIG_STREAM_REMUS || >> + checkpointed_stream == MIG_STREAM_COLO); >> >> /* >> * TODO: Find some time to better tweak the live migration algorithm. > > [...] > >> + >> +#include "libxl_osdeps.h" /* must come before any other headers */ >> + >> +#include "libxl_internal.h" >> +#include "libxl_colo.h" >> +#include "libxl_sr_stream_format.h" >> + >> +enum { >> + LIBXL_COLO_SETUPED, >> + LIBXL_COLO_SUSPENDED, >> + LIBXL_COLO_RESUMED, >> +}; >> + >> +typedef struct libxl__colo_restore_checkpoint_state >> libxl__colo_restore_checkpoint_state; >> +struct libxl__colo_restore_checkpoint_state { >> + libxl__domain_suspend_state dsps; >> + libxl__logdirty_switch lds; >> + libxl__colo_restore_state *crs; >> + libxl__stream_write_state sws; >> + int status; >> + bool preresume; >> + /* used for teardown */ >> + int teardown_devices; >> + int saved_rc; >> + char *state_file; >> + >> + void (*callback)(libxl__egc *, >> + libxl__colo_restore_checkpoint_state *, >> + int); >> +}; >> + > > Shouldn't the enum and struct belong to libxl_colo.h ? If we inlucde libxl_colo.h in libxl_internal.h, we cannot move this into colo.h, because this structure needs libxl__domain_suspend_state, libxl__logdirty_switch, ... We cannot just declare it, because this structure needs know there size. > >> + >> +static void libxl__colo_restore_domain_resume_callback(void *data); >> +static void libxl__colo_restore_domain_checkpoint_callback(void *data); >> +static void libxl__colo_restore_domain_wait_checkpoint_callback(void *data); >> +static void libxl__colo_restore_domain_suspend_callback(void *data); >> + >> +static const libxl__checkpoint_device_instance_ops *colo_restore_ops[] = { >> + NULL, >> +}; >> + > > It would be helpful to list the callbacks at the beginning of the time > in the order they are supposed to occur. > > See libxl_create.c for example. Search for "Event callbacks, in this > order". > > I've tried to map the algorithm you described in commit message to all > the callbacks, but without some references it is just too time consuming > from my end. > > I think what I'm going to do is to make sure the normal path that > doesn't use COLO is not broken and leave the internal to you and Ian (if > he fancies to dig into details). > > [...] >> + >> +void libxl__colo_restore_setup(libxl__egc *egc, >> + libxl__colo_restore_state *crs) >> +{ >> + libxl__domain_create_state *dcs = CONTAINER_OF(crs, *dcs, crs); >> + libxl__colo_restore_checkpoint_state *crcs; >> + int rc = ERROR_FAIL; >> + >> + /* Convenience aliases */ >> + libxl__srm_restore_autogen_callbacks *const callbacks = >> + &dcs->srs.shs.callbacks.restore.a; >> + const int domid = crs->domid; >> + >> + STATE_AO_GC(crs->ao); >> + >> + GCNEW(crcs); >> + crs->crcs = crcs; >> + crcs->crs = crs; >> + >> + /* setup dsps */ >> + crcs->dsps.ao = ao; >> + crcs->dsps.domid = domid; >> + if (init_dsps(&crcs->dsps)) >> + goto err; >> + >> + callbacks->suspend = libxl__colo_restore_domain_suspend_callback; >> + callbacks->postcopy = libxl__colo_restore_domain_resume_callback; >> + callbacks->checkpoint = libxl__colo_restore_domain_checkpoint_callback; >> + callbacks->wait_checkpoint = >> libxl__colo_restore_domain_wait_checkpoint_callback; >> + >> + /* >> + * Secondary vm is running in colo mode, so we need to call >> + * libxl__xc_domain_restore_done() to create secondary vm. >> + * But we will exit in domain_create_cb(). So replace the >> + * callback here. >> + */ >> + crs->saved_cb = dcs->callback; >> + dcs->callback = libxl__colo_domain_create_cb; >> + crcs->state_file = GCSPRINTF(LIBXL_DEVICE_MODEL_RESTORE_FILE".%d", >> domid); > > Can you use a different name space from the normal one? > > For example, you can put > > #define LIBXL_COLO_DEVICE_MODEL_RESTORE_FILE XXXX > > in libxl_colo.h and use it in all COLO code. > > >> + crcs->status = LIBXL_COLO_SETUPED; >> + >> + libxl__logdirty_init(&crcs->lds); >> + crcs->lds.ao = ao; >> + >> + crcs->sws.fd = crs->send_back_fd; >> + crcs->sws.ao = ao; >> + crcs->sws.back_channel = true; >> + >> + dcs->cds.concrete_data = crs; >> + >> + libxl__stream_write_start(egc, &crcs->sws); >> + >> + rc = 0; >> + >> +out: >> + crs->callback(egc, crs, rc); >> + return; >> + >> +err: >> + goto out; >> +} >> + >> +static void libxl__colo_domain_create_cb(libxl__egc *egc, >> + libxl__domain_create_state *dcs, >> + int rc, uint32_t domid) >> +{ >> + libxl__colo_restore_checkpoint_state *crcs = dcs->crs.crcs; >> + >> + crcs->callback(egc, crcs, rc); >> +} >> + >> + > [...] >> + >> +static void colo_disable_logdirty_done(libxl__egc *egc, >> + libxl__logdirty_switch *lds, >> + int rc) >> +{ >> + libxl__colo_restore_checkpoint_state *crcs = CONTAINER_OF(lds, *crcs, >> lds); >> + >> + EGC_GC; >> + >> + if (rc) >> + LOG(WARN, "cannot disable logdirty"); >> + >> + if (crcs->status == LIBXL_COLO_SUSPENDED) { >> + /* >> + * failover when reading state from master, so no need to >> + * call libxl__domain_restore(). > > You need to update this comment to the right function name. > >> + */ >> + colo_resume_vm(egc, crcs, 0); >> + return; >> + } >> + >> + /* If we cannot disable logdirty, we still can do failover */ >> + crcs->callback(egc, crcs, 0); >> +} >> + > [...] >> >> +/* colo related structure */ >> +typedef struct libxl__colo_restore_state libxl__colo_restore_state; >> +typedef void libxl__colo_callback(libxl__egc *, >> + libxl__colo_restore_state *, int rc); >> +struct libxl__colo_restore_state { >> + /* must set by caller of libxl__colo_(setup|teardown) */ >> + libxl__ao *ao; >> + uint32_t domid; >> + int send_back_fd; >> + int recv_fd; >> + int hvm; >> + libxl__colo_callback *callback; >> + >> + /* private, colo restore checkpoint state */ >> + libxl__domain_create_cb *saved_cb; >> + void *crcs; >> +}; >> > > And this should go to libxl_colo.h, too? And libxl_internal.h includes > libxl_colo.h? If we do so, we should declare libxl__ao, libxl__domain_create_cb in libxl_colo.h Thanks Wen Congyang > > I just don't want to colo structures and functions scatter in > different places. > >> struct libxl__domain_create_state { >> /* filled in by user */ >> @@ -3486,6 +3503,8 @@ struct libxl__domain_create_state { >> /* private to domain_create */ >> int guest_domid; >> libxl__domain_build_state build_state; >> + libxl__colo_restore_state crs; >> + libxl__checkpoint_devices_state cds; >> libxl__bootloader_state bl; >> libxl__stub_dm_spawn_state dmss; >> /* If we're not doing stubdom, we use only dmss.dm, >> diff --git a/tools/libxl/libxl_save_callout.c >> b/tools/libxl/libxl_save_callout.c >> index 0d6949a..b1810b2 100644 >> --- a/tools/libxl/libxl_save_callout.c >> +++ b/tools/libxl/libxl_save_callout.c >> @@ -15,6 +15,7 @@ >> #include "libxl_osdeps.h" >> >> #include "libxl_internal.h" >> +#include "libxl_colo.h" >> >> /* stream_fd is as from the caller (eventually, the application). >> * It may be 0, 1 or 2, in which case we need to dup it elsewhere. >> @@ -68,7 +69,11 @@ void libxl__xc_domain_restore(libxl__egc *egc, >> libxl__domain_create_state *dcs, >> shs->ao = ao; >> shs->domid = domid; >> shs->recv_callback = libxl__srm_callout_received_restore; >> - shs->completion_callback = libxl__xc_domain_restore_done; >> + if (dcs->restore_params.checkpointed_stream == >> + >> LIBXL_CHECKPOINTED_STREAM_COLO) > > This is very strange line wrap. > >> + shs->completion_callback = libxl__colo_restore_teardown; >> + else >> + shs->completion_callback = libxl__xc_domain_restore_done; >> shs->caller_state = dcs; >> shs->need_results = 1; >> >> diff --git a/tools/libxl/libxl_stream_read.c >> b/tools/libxl/libxl_stream_read.c >> index 5d980d9..d6bd2fe 100644 >> --- a/tools/libxl/libxl_stream_read.c >> +++ b/tools/libxl/libxl_stream_read.c >> @@ -846,6 +846,18 @@ void libxl__xc_domain_restore_done(libxl__egc *egc, >> void *dcs_void, >> */ >> if (libxl__stream_read_inuse(stream)) { >> switch (checkpointed_stream) { >> + case LIBXL_CHECKPOINTED_STREAM_COLO: >> + if (stream->completion_callback) { >> + /* >> + * restore, just build the secondary vm, don't close >> + * the stream >> + */ >> + stream->completion_callback(egc, stream, 0); >> + } else { >> + /* failover, just close the stream */ >> + stream_complete(egc, stream, 0); >> + } >> + break; >> case LIBXL_CHECKPOINTED_STREAM_REMUS: >> /* >> * Failover from primary. Domain state is currently at a >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >> index 632c009..33f4a90 100644 >> --- a/tools/libxl/libxl_types.idl >> +++ b/tools/libxl/libxl_types.idl >> @@ -232,6 +232,7 @@ libxl_hdtype = Enumeration("hdtype", [ >> libxl_checkpointed_stream = Enumeration("checkpointed_stream", [ >> (0, "NONE"), >> (1, "REMUS"), >> + (2, "COLO"), >> ]) >> >> # >> -- >> 2.5.0 >> >> >> >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@xxxxxxxxxxxxx >> http://lists.xen.org/xen-devel > > > . > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |