[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH V7 14/29] cpr: restart mode
From: |
Steve Sistare |
Subject: |
[PATCH V7 14/29] cpr: restart mode |
Date: |
Wed, 22 Dec 2021 11:05:19 -0800 |
Provide the cpr-save restart mode, which preserves the guest VM across a
restart of the qemu process. After cpr-save, the caller passes qemu
command-line arguments to cpr-exec, which directly exec's the new qemu
binary. The arguments must include -S so new qemu starts in a paused state.
The caller resumes the guest by calling cpr-load.
To use the restart mode, all guest RAM objects must be shared. The
share=on property is required for memory created with an explicit -object
option. The memfd-alloc machine property is required for memory that is
implicitly created. The memfd values are saved in special cpr state which
is retrieved after exec, and are kept open across exec, after which they
are retrieved and re-mmap'd. Hence guest RAM is preserved in place,
albeit with new virtual addresses in the qemu process.
The restart mode supports vfio devices and explicit memory-backend-memfd
objects in subsequent patches.
cpr-exec syntax:
{ 'command': 'cpr-exec', 'data': { 'argv': [ 'str' ] } }
Add the restart mode:
{ 'enum': 'CprMode', 'data': [ 'reboot', 'restart' ] }
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
migration/cpr.c | 29 ++++++++++++++++++++++++++++-
qapi/cpr.json | 22 +++++++++++++++++++++-
softmmu/physmem.c | 5 ++++-
softmmu/vl.c | 3 +++
4 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/migration/cpr.c b/migration/cpr.c
index ca76124..37eca66 100644
--- a/migration/cpr.c
+++ b/migration/cpr.c
@@ -81,6 +81,34 @@ err:
cpr_set_mode(CPR_MODE_NONE);
}
+static int preserve_fd(const char *name, int id, int fd, void *opaque)
+{
+ qemu_clear_cloexec(fd);
+ return 0;
+}
+
+void qmp_cpr_exec(strList *args, Error **errp)
+{
+ if (xen_enabled()) {
+ error_setg(errp, "xen does not support cpr-exec");
+ return;
+ }
+ if (!runstate_check(RUN_STATE_SAVE_VM)) {
+ error_setg(errp, "runstate is not save-vm");
+ return;
+ }
+ if (cpr_get_mode() != CPR_MODE_RESTART) {
+ error_setg(errp, "cpr-exec requires cpr-save with restart mode");
+ return;
+ }
+
+ cpr_walk_fd(preserve_fd, 0);
+ if (cpr_state_save(errp)) {
+ return;
+ }
+ qemu_system_exec_request(args);
+}
+
void qmp_cpr_load(const char *filename, Error **errp)
{
QEMUFile *f;
@@ -104,7 +132,6 @@ void qmp_cpr_load(const char *filename, Error **errp)
return;
}
- cpr_set_mode(CPR_MODE_REBOOT);
ret = qemu_load_device_state(f);
qemu_fclose(f);
if (ret < 0) {
diff --git a/qapi/cpr.json b/qapi/cpr.json
index 2edd08e..56be0e5 100644
--- a/qapi/cpr.json
+++ b/qapi/cpr.json
@@ -15,11 +15,12 @@
# @CprMode:
#
# @reboot: checkpoint can be cpr-load'ed after a host kexec reboot.
+# @restart: checkpoint can be cpr-load'ed after restarting qemu.
#
# Since: 6.2
##
{ 'enum': 'CprMode',
- 'data': [ 'reboot' ] }
+ 'data': [ 'reboot', 'restart' ] }
##
# @cpr-save:
@@ -33,6 +34,11 @@
# For reboot mode, all guest RAM objects must be non-volatile across reboot,
# and created with the share=on parameter.
#
+# For restart mode, all guest RAM objects must be shared. The share=on
+# property is required for memory created with an explicit -object option,
+# and the memfd-alloc machine property is required for memory that is
+# implicitly created.
+#
# @filename: name of checkpoint file
# @mode: @CprMode mode
#
@@ -43,6 +49,20 @@
'mode': 'CprMode' } }
##
+# @cpr-exec:
+#
+# exec() a command and replace the qemu process. The PID remains the same.
+# @argv[0] should be the path of a new qemu binary, or a prefix command that
+# in turn exec's the new qemu binary. Must be called after cpr-save restart.
+#
+# @argv: arguments to be passed to exec().
+#
+# Since: 6.2
+##
+{ 'command': 'cpr-exec',
+ 'data': { 'argv': [ 'str' ] } }
+
+##
# @cpr-load:
#
# Start virtual machine from checkpoint file that was created earlier using
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 95e2b49..e227195 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -65,6 +65,7 @@
#include "qemu/pmem.h"
+#include "migration/cpr.h"
#include "migration/vmstate.h"
#include "qemu/range.h"
@@ -1991,7 +1992,7 @@ static void ram_block_add(RAMBlock *new_block, Error
**errp)
name = memory_region_name(mr);
if (ms->memfd_alloc) {
Object *parent = &mr->parent_obj;
- int mfd = -1; /* placeholder until next patch */
+ int mfd = cpr_find_fd(name, 0);
mr->align = QEMU_VMALLOC_ALIGN;
if (mfd < 0) {
mfd = qemu_memfd_create(name, maxlen + mr->align,
@@ -1999,6 +2000,7 @@ static void ram_block_add(RAMBlock *new_block, Error
**errp)
if (mfd < 0) {
return;
}
+ cpr_save_fd(name, 0, mfd);
}
qemu_set_cloexec(mfd);
/* The memory backend already set its desired flags. */
@@ -2255,6 +2257,7 @@ void qemu_ram_free(RAMBlock *block)
}
qemu_mutex_lock_ramlist();
+ cpr_delete_fd(memory_region_name(block->mr), 0);
QLIST_REMOVE_RCU(block, next);
ram_list.mru_block = NULL;
/* Write list before version */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index ab3648a..4319e1a 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -76,6 +76,7 @@
#include "hw/i386/pc.h"
#include "migration/misc.h"
#include "migration/snapshot.h"
+#include "migration/cpr.h"
#include "sysemu/tpm.h"
#include "sysemu/dma.h"
#include "hw/audio/soundhw.h"
@@ -3675,6 +3676,8 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_validate_options(machine_opts_dict);
qemu_process_sugar_options();
+ cpr_state_load(&error_fatal);
+
/*
* These options affect everything else and should be processed
* before daemonizing.
--
1.8.3.1
- [PATCH V7 07/29] cpr: reboot HMP interfaces, (continued)
- [PATCH V7 07/29] cpr: reboot HMP interfaces, Steve Sistare, 2021/12/22
- [PATCH V7 05/29] vl: start on wakeup request, Steve Sistare, 2021/12/22
- [PATCH V7 01/29] memory: qemu_check_ram_volatile, Steve Sistare, 2021/12/22
- [PATCH V7 04/29] migration: simplify savevm, Steve Sistare, 2021/12/22
- [PATCH V7 13/29] cpr: preserve extra state, Steve Sistare, 2021/12/22
- [PATCH V7 15/29] cpr: restart HMP interfaces, Steve Sistare, 2021/12/22
- [PATCH V7 17/29] pci: export functions for cpr, Steve Sistare, 2021/12/22
- [PATCH V7 20/29] vfio-pci: cpr part 2 (msi), Steve Sistare, 2021/12/22
- [PATCH V7 19/29] vfio-pci: cpr part 1 (fd and dma), Steve Sistare, 2021/12/22
- [PATCH V7 16/29] hostmem-memfd: cpr for memory-backend-memfd, Steve Sistare, 2021/12/22
- [PATCH V7 14/29] cpr: restart mode,
Steve Sistare <=
- [PATCH V7 18/29] vfio-pci: refactor for cpr, Steve Sistare, 2021/12/22
- [PATCH V7 25/29] chardev: cpr framework, Steve Sistare, 2021/12/22
- [PATCH V7 26/29] chardev: cpr for simple devices, Steve Sistare, 2021/12/22
- [PATCH V7 29/29] cpr: only-cpr-capable option, Steve Sistare, 2021/12/22
- [PATCH V7 21/29] vfio-pci: cpr part 3 (intx), Steve Sistare, 2021/12/22
- [PATCH V7 22/29] vfio-pci: recover from unmap-all-vaddr failure, Steve Sistare, 2021/12/22
- [PATCH V7 24/29] loader: suppress rom_reset during cpr, Steve Sistare, 2021/12/22
- [PATCH V7 23/29] vhost: reset vhost devices for cpr, Steve Sistare, 2021/12/22
- [PATCH V7 27/29] chardev: cpr for pty, Steve Sistare, 2021/12/22
- [PATCH V7 10/29] machine: memfd-alloc option, Steve Sistare, 2021/12/22