Add the only-cpr-capable option, which causes qemu to exit with an error if any devices that are not capable of cpr are added. This guarantees that cpr-save will not fail due to a blocker.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/migration/cpr.h | 2 +- migration/cpr.c | 13 +++++++++++-- qemu-options.hx | 8 ++++++++ softmmu/vl.c | 6 +++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/migration/cpr.h b/include/migration/cpr.h index ab5f53e..c7eb914 100644 --- a/include/migration/cpr.h +++ b/include/migration/cpr.h @@ -11,7 +11,7 @@ #include "qapi/qapi-types-cpr.h" #include "qemu/notify.h" -void cpr_init(int modes); +void cpr_init(int modes, bool only_cpr_capable); void cpr_set_mode(CprMode mode); CprMode cpr_get_mode(void); bool cpr_enabled(CprMode mode); diff --git a/migration/cpr.c b/migration/cpr.c index 9d6bca4..7f507f1 100644 --- a/migration/cpr.c +++ b/migration/cpr.c @@ -18,9 +18,11 @@ #include "sysemu/sysemu.h" static int cpr_enabled_modes; +static bool only_cpr_capable; -void cpr_init(int modes) +void cpr_init(int modes, bool only_cpr) { + only_cpr_capable = only_cpr; cpr_enabled_modes = modes; cpr_state_load(&error_fatal); } @@ -36,7 +38,7 @@ static GSList *cpr_blockers[CPR_MODE__MAX]; * Add blocker for each mode in varargs list, or for all modes if CPR_MODE_ALL * is specified. Caller terminates the list with 0 or CPR_MODE_ALL. This * function takes ownership of *reasonp, and frees it on error, or in - * cpr_del_blocker. errp is set in a later patch. + * cpr_del_blocker. */ int cpr_add_blocker(Error **reasonp, Error **errp, CprMode mode, ...) { @@ -55,6 +57,13 @@ int cpr_add_blocker(Error **reasonp, Error **errp, CprMode mode, ...) modes = BIT(CPR_MODE__MAX) - 1; } + if (only_cpr_capable && (cpr_enabled_modes & modes)) { + error_propagate_prepend(errp, *reasonp, + "-only-cpr-capable specified, but: "); + *reasonp = NULL; + return -EACCES; + } + for (mode = 0; mode < CPR_MODE__MAX; mode++) { if (modes & BIT(mode)) { cpr_blockers[mode] = g_slist_prepend(cpr_blockers[mode], *reasonp); diff --git a/qemu-options.hx b/qemu-options.hx index 2f4bb2b..25e392f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4511,6 +4511,14 @@ SRST commands. ERST +DEF("only-cpr-capable", 0, QEMU_OPTION_only_cpr_capable, \ + "-only-cpr-capable allow only cpr capable devices\n", QEMU_ARCH_ALL) +SRST +``-only-cpr-capable`` + Only allow cpr capable devices, which guarantees that cpr-save will not + fail due to a cpr blocker. +ERST + DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \ "-nodefaults don't create default devices\n", QEMU_ARCH_ALL) SRST diff --git a/softmmu/vl.c b/softmmu/vl.c index 3e19c74..1bee692 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2604,6 +2604,7 @@ void qemu_init(int argc, char **argv, char **envp) bool userconfig = true; FILE *vmstate_dump_file = NULL; int cpr_modes = 0; + bool only_cpr_capable = false; qemu_add_opts(&qemu_drive_opts); qemu_add_drive_opts(&qemu_legacy_drive_opts); @@ -3321,6 +3322,9 @@ void qemu_init(int argc, char **argv, char **envp) cpr_modes |= BIT(qapi_enum_parse(&CprMode_lookup, optarg, -1, &error_fatal)); break; + case QEMU_OPTION_only_cpr_capable: + only_cpr_capable = true; + break; case QEMU_OPTION_nodefaults: has_defaults = 0; break; @@ -3472,7 +3476,7 @@ void qemu_init(int argc, char **argv, char **envp) qemu_validate_options(machine_opts_dict); qemu_process_sugar_options(); - cpr_init(cpr_modes); + cpr_init(cpr_modes, only_cpr_capable); /* * These options affect everything else and should be processed -- 1.8.3.1