void cprsave(const char *file, CprMode mode, Error **errp) { int ret = 0; ** QEMUFile *f; ** int saved_vm_running = runstate_is_running(); bool restart = (mode == CPR_MODE_RESTART); bool reboot = (mode == CPR_MODE_REBOOT); if (reboot && qemu_ram_volatile(errp)) { return; } if (restart && xen_enabled()) { error_setg(errp, "xen does not support cprsave restart"); return; } if (migrate_colo_enabled()) { error_setg(errp, "error: cprsave does not support x-colo"); return; } if (replay_mode != REPLAY_MODE_NONE) { error_setg(errp, "error: cprsave does not support replay"); return; } f = qf_file_open(file, O_CREAT | O_WRONLY | O_TRUNC, 0600, "cprsave", errp); if (!f) { return; } ** ret = global_state_store(); ** if (ret) { ** error_setg(errp, "Error saving global state"); ** qemu_fclose(f); ** return; ** } if (runstate_check(RUN_STATE_SUSPENDED)) { /* Update timers_state before saving. Suspend did not so do. */ cpu_disable_ticks(); } ** vm_stop(RUN_STATE_SAVE_VM); cpr_is_active = true; ** ret = qemu_save_device_state(f); ** qemu_fclose(f); ** if (ret < 0) { ** error_setg(errp, "Error %d while saving VM state", ret); ** goto err; ** } if (reboot) { shutdown_action = SHUTDOWN_ACTION_POWEROFF; qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } else if (restart) { if (!qemu_chr_cpr_capable(errp)) { goto err; } if (vfio_cprsave(errp)) { goto err; } walkenv(FD_PREFIX, preserve_fd, 0); vhost_dev_reset_all(); qemu_term_exit(); setenv("QEMU_START_FREEZE", "", 1); qemu_system_exec_request(); } goto done; err: ** if (saved_vm_running) { ** vm_start(); ** } done: cpr_is_active = false; return; }