diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c index 6487672277..2e9ec4dbf2 100644 --- a/tools/libxl/libxl_dom_save.c +++ b/tools/libxl/libxl_dom_save.c @@ -361,6 +361,7 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss) dsps->ao = ao; dsps->domid = domid; + dsps->live = !!live; rc = libxl__domain_suspend_init(egc, dsps, type); if (rc) goto out; diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c index ca41107412..1e904bae8a 100644 --- a/tools/libxl/libxl_dom_suspend.c +++ b/tools/libxl/libxl_dom_suspend.c @@ -86,7 +86,7 @@ int libxl__domain_suspend_device_model(libxl__gc *gc, if (libxl__qmp_stop(gc, domid)) return ERROR_FAIL; /* Save DM state into filename */ - ret = libxl__qmp_save(gc, domid, filename); + ret = libxl__qmp_save(gc, domid, filename, dsps->live); if (ret) unlink(filename); break; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 506687fbe9..8dd63319fc 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1822,7 +1822,8 @@ _hidden int libxl__qmp_stop(libxl__gc *gc, int domid); /* Resume QEMU. */ _hidden int libxl__qmp_resume(libxl__gc *gc, int domid); /* Save current QEMU state into fd. */ -_hidden int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename); +_hidden int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename, + bool live); /* Load current QEMU state from file. */ _hidden int libxl__qmp_restore(libxl__gc *gc, int domid, const char *filename); /* Set dirty bitmap logging status */ @@ -3264,6 +3265,7 @@ struct libxl__domain_suspend_state { /* set by caller of libxl__domain_suspend_init */ libxl__ao *ao; uint32_t domid; + bool live; /* private */ libxl_domain_type type; diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index b1c6598cf7..d03cb51668 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -350,7 +350,6 @@ static int qmp_handle_response(libxl__gc *gc, libxl__qmp_handler *qmp, return 0; } -#if 0 static bool qmp_qemu_check_version(libxl__qmp_handler *qmp, int major, int minor, int micro) { @@ -359,7 +358,6 @@ static bool qmp_qemu_check_version(libxl__qmp_handler *qmp, int major, (qmp->version.minor > minor || (qmp->version.minor == minor && qmp->version.micro >= micro))); } -#endif /* * Handler functions @@ -942,13 +940,27 @@ int libxl__qmp_system_wakeup(libxl__gc *gc, int domid) return qmp_run_command(gc, domid, "system_wakeup", NULL, NULL, NULL); } -int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename) +int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename, bool live) { libxl__json_object *args = NULL; + libxl__qmp_handler *qmp = NULL; + int rc; + + qmp = libxl__qmp_initialize(gc, domid); + if (!qmp) + return ERROR_FAIL; qmp_parameters_add_string(gc, &args, "filename", (char *)filename); - return qmp_run_command(gc, domid, "xen-save-devices-state", args, - NULL, NULL); + + /* live parameter was added to QEMU 2.11. It signal QEMU that the save + * operation is for a live migration rather that for taking a snapshot. */ + if (qmp_qemu_check_version(qmp, 2, 11, 0)) + qmp_parameters_add_bool(gc, &args, "live", live); + + rc = qmp_synchronous_send(qmp, "xen-save-devices-state", args, + NULL, NULL, qmp->timeout); + libxl__qmp_close(qmp); + return rc; } int libxl__qmp_restore(libxl__gc *gc, int domid, const char *state_file)