static void domain_suspend_switch_qemu_logdirty_done (libxl__egc *egc, libxl__logdirty_switch *lds, int rc) { libxl__domain_save_state *dss = CONTAINER_OF(lds, *dss, logdirty); if (rc) { dss->rc = rc; libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, -1); } else libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, 0); }
static void colo_common_read_stream_done(libxl__egc *egc, libxl__stream_read_state *stream, int rc) { libxl__colo_save_state *css = CONTAINER_OF(stream, *css, srs); libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); int ok; EGC_GC; if (rc < 0) { /* TODO: it may be a internal error, but we don't know */ LOGD(ERROR, dss->domid, "reading data fails"); ok = 0; goto out; } if (!css->callback) { /* Everythins is OK */ ok = 1; goto out; } /* rc contains the id */ css->callback(egc, css, rc); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, ok); }
static void colo_read_svm_ready_done(libxl__egc *egc, libxl__colo_save_state *css, int id) { libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (id != CHECKPOINT_SVM_READY) { LOGD(ERROR, dss->domid, "invalid section: %d, expected: %d", id, CHECKPOINT_SVM_READY); goto out; } colo_proxy_preresume(&css->cps); css->svm_running = true; dss->cds.callback = colo_preresume_cb; libxl__checkpoint_devices_preresume(egc, &dss->cds); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, 0); }
static void colo_common_write_stream_done(libxl__egc *egc, libxl__stream_write_state *stream, int rc) { libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); int ok; /* Convenience aliases */ libxl__colo_save_state *const css = &dss->css; EGC_GC; if (rc < 0) { /* TODO: it may be a internal error, but we don't know */ LOGD(ERROR, dss->domid, "sending data fails"); ok = 0; goto out; } if (!css->callback) { /* Everythins is OK */ ok = 1; goto out; } css->callback(egc, css, 0); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, ok); }
static void colo_read_svm_suspended_done(libxl__egc *egc, libxl__colo_save_state *css, int id) { int ok = 0; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (id != CHECKPOINT_SVM_SUSPENDED) { LOGD(ERROR, dss->domid, "invalid section: %d, expected: %d", id, CHECKPOINT_SVM_SUSPENDED); goto out; } if (!css->paused && libxl__qmp_query_xen_replication_status(gc, dss->domid)) { LOGD(ERROR, dss->domid, "replication error occurs when primary vm is running"); goto out; } ok = 1; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, ok); }
static void colo_postsuspend_cb(libxl__egc *egc, libxl__checkpoint_devices_state *cds, int rc) { libxl__colo_save_state *css = cds->concrete_data; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (rc) { LOGD(ERROR, dss->domid, "postsuspend fails"); goto out; } if (!css->svm_running) { rc = 0; goto out; } /* * read CHECKPOINT_SVM_SUSPENDED */ css->callback = colo_read_svm_suspended_done; css->srs.checkpoint_callback = colo_common_read_stream_done; libxl__stream_read_checkpoint_state(egc, &css->srs); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, !rc); }
static void colo_preresume_cb(libxl__egc *egc, libxl__checkpoint_devices_state *cds, int rc) { libxl__colo_save_state *css = cds->concrete_data; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (rc) { LOGD(ERROR, dss->domid, "preresume fails"); goto out; } if (css->qdisk_used && !css->qdisk_setuped) { if (libxl__qmp_start_replication(gc, dss->domid, true)) { LOGD(ERROR, dss->domid, "starting replication fails"); goto out; } css->qdisk_setuped = true; } if (!css->paused) { if (libxl__qmp_colo_do_checkpoint(gc, dss->domid)) { LOGD(ERROR, dss->domid, "doing checkpoint fails"); goto out; } } /* Resumes the domain and the device model */ if (libxl__domain_resume(gc, dss->domid, /* Fast Suspend */1)) { LOGD(ERROR, dss->domid, "cannot resume primary vm"); goto out; } /* * The guest should be paused before doing colo because there is * no disk migration. */ if (css->paused) { rc = libxl_domain_unpause(CTX, dss->domid); if (rc) { LOGD(ERROR, dss->domid, "cannot unpause primary vm"); goto out; } css->paused = false; } /* read CHECKPOINT_SVM_RESUMED */ css->callback = colo_read_svm_resumed_done; css->srs.checkpoint_callback = colo_common_read_stream_done; libxl__stream_read_checkpoint_state(egc, &css->srs); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, 0); }
static void colo_device_commit_cb(libxl__egc *egc, libxl__checkpoint_devices_state *cds, int rc) { libxl__colo_save_state *css = cds->concrete_data; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (rc) { LOGD(ERROR, dss->domid, "commit fails"); goto out; } colo_proxy_wait_for_checkpoint(egc, css); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, 0); }
static void colo_start_new_checkpoint(libxl__egc *egc, libxl__checkpoint_devices_state *cds, int rc) { libxl__colo_save_state *css = cds->concrete_data; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); libxl_sr_checkpoint_state srcs = { .id = CHECKPOINT_NEW }; if (rc) goto out; /* write CHECKPOINT_NEW */ css->callback = NULL; dss->sws.checkpoint_callback = colo_common_write_stream_done; libxl__stream_write_checkpoint_state(egc, &dss->sws, &srcs); return; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, 0); }
static void colo_read_svm_resumed_done(libxl__egc *egc, libxl__colo_save_state *css, int id) { int ok = 0; libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); EGC_GC; if (id != CHECKPOINT_SVM_RESUMED) { LOGD(ERROR, dss->domid, "invalid section: %d, expected: %d", id, CHECKPOINT_SVM_RESUMED); goto out; } colo_proxy_postresume(&css->cps); ok = 1; out: libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, ok); }
static void colo_suspend_primary_vm_done(libxl__egc *egc, libxl__domain_suspend_state *dsps, int rc) { libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); EGC_GC; if (rc) { LOGD(ERROR, dss->domid, "cannot suspend primary vm"); goto out; } /* Convenience aliases */ libxl__checkpoint_devices_state *const cds = &dss->cds; cds->callback = colo_postsuspend_cb; libxl__checkpoint_devices_postsuspend(egc, cds); return; out: dss->rc = rc; libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, !rc); }