static void colo_resume_vm(libxl__egc *egc, libxl__colo_restore_checkpoint_state *crcs, int restore_device_model) { libxl__domain_create_state *dcs = CONTAINER_OF(crcs->crs, *dcs, crs); int rc; /* Convenience aliases */ libxl__colo_restore_state *const crs = crcs->crs; EGC_GC; if (!crs->saved_cb) { /* TODO: sync mmu for hvm? */ if (restore_device_model) { rc = libxl__qmp_restore(gc, crs->domid, crcs->state_file); if (rc) { LOGD(ERROR, crs->domid, "cannot restore device model for secondary vm"); crcs->callback(egc, crcs, rc); return; } } rc = libxl__domain_resume(gc, crs->domid, 0); if (rc) LOGD(ERROR, crs->domid, "cannot resume secondary vm"); crcs->callback(egc, crcs, rc); return; } libxl__xc_domain_restore_done(egc, dcs, 0, 0, 0); return; }
void libxl__colo_restore_teardown(libxl__egc *egc, void *dcs_void, int ret, int retval, int errnoval) { libxl__domain_create_state *dcs = dcs_void; libxl__colo_restore_checkpoint_state *crcs = dcs->crs.crcs; int rc = 1; /* convenience aliases */ libxl__colo_restore_state *const crs = &dcs->crs; EGC_GC; if (ret == 0 && retval == 0) rc = 0; LOGD(INFO, crs->domid, "%s", rc ? "colo fails" : "failover"); libxl__stream_write_abort(egc, &crcs->sws, 1); if (crs->saved_cb) { /* crcs->status is LIBXL_COLO_SETUPED */ dcs->srs.completion_callback = NULL; } libxl__xc_domain_restore_done(egc, dcs, ret, retval, errnoval); if (crs->qdisk_setuped) { libxl__qmp_stop_replication(gc, crs->domid, false); crs->qdisk_setuped = false; } crcs->saved_rc = rc; if (!crcs->teardown_devices) { colo_restore_teardown_devices_done(egc, &dcs->cds, 0); return; } dcs->cds.callback = colo_restore_teardown_devices_done; libxl__checkpoint_devices_teardown(egc, &dcs->cds); }
static void domcreate_bootloader_done(libxl__egc *egc, libxl__bootloader_state *bl, int rc) { libxl__domain_create_state *dcs = CONTAINER_OF(bl, *dcs, bl); STATE_AO_GC(bl->ao); /* convenience aliases */ const uint32_t domid = dcs->guest_domid; libxl_domain_config *const d_config = dcs->guest_config; libxl_domain_build_info *const info = &d_config->b_info; const int restore_fd = dcs->restore_fd; libxl__domain_build_state *const state = &dcs->build_state; libxl__srm_restore_autogen_callbacks *const callbacks = &dcs->shs.callbacks.restore.a; if (rc) { domcreate_rebuild_done(egc, dcs, rc); return; } /* consume bootloader outputs. state->pv_{kernel,ramdisk} have * been initialised by the bootloader already. */ state->pv_cmdline = bl->cmdline; /* We might be going to call libxl__spawn_local_dm, or _spawn_stub_dm. * Fill in any field required by either, including both relevant * callbacks (_spawn_stub_dm will overwrite our trespass if needed). */ dcs->dmss.dm.spawn.ao = ao; dcs->dmss.dm.guest_config = dcs->guest_config; dcs->dmss.dm.build_state = &dcs->build_state; dcs->dmss.dm.callback = domcreate_devmodel_started; dcs->dmss.callback = domcreate_devmodel_started; if ( restore_fd < 0 ) { rc = libxl__domain_build(gc, &d_config->b_info, domid, state); domcreate_rebuild_done(egc, dcs, rc); return; } /* Restore */ rc = libxl__build_pre(gc, domid, info, state); if (rc) goto out; /* read signature */ int hvm, pae, superpages; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = libxl_defbool_val(info->u.hvm.pae); callbacks->toolstack_restore = libxl__toolstack_restore; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; superpages = 0; pae = 1; break; default: rc = ERROR_INVAL; goto out; } libxl__xc_domain_restore(egc, dcs, hvm, pae, superpages, 1); return; out: libxl__xc_domain_restore_done(egc, dcs, rc, 0, 0); }