@samitouri / QOSamiQemu / commits / 78ff878a52

migration/savevm: move to new migration APIs

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260304212303.667141-16-vsementsov@yandex-team.ru Signed-off-by: Fabiano Rosas <farosas@suse.de>

Vladimir Sementsov-Ogievskiy committed Mar 5, 2026 at 00:22 UTC 78ff878a52781205f61594366bfa44d2e448cda7
1 file changed +55 -50
migration/savevm.c
+55 -50
@@ -205,27 +205,28 @@ void timer_get(QEMUFile *f, QEMUTimer *ts)
205 * Not in vmstate.c to not add qemu-timer.c as dependency to vmstate.c
206 */
207
208 -static int get_timer(QEMUFile *f, void *pv, size_t size,
209 - const VMStateField *field)
208 +static bool load_timer(QEMUFile *f, void *pv, size_t size,
209 + const VMStateField *field, Error **errp)
210 {
211 QEMUTimer *v = pv;
212 timer_get(f, v);
213 - return 0;
213 + return true;
214 }
215
216 -static int put_timer(QEMUFile *f, void *pv, size_t size,
217 - const VMStateField *field, JSONWriter *vmdesc)
216 +static bool save_timer(QEMUFile *f, void *pv, size_t size,
217 + const VMStateField *field, JSONWriter *vmdesc,
218 + Error **errp)
219 {
220 QEMUTimer *v = pv;
221 timer_put(f, v);
222
222 - return 0;
223 + return true;
224 }
225
226 const VMStateInfo vmstate_info_timer = {
227 .name = "timer",
227 - .get = get_timer,
228 - .put = put_timer,
228 + .load = load_timer,
229 + .save = save_timer,
230 };
231
232
@@ -297,7 +298,7 @@ static uint32_t get_validatable_capabilities_count(void)
298 return result;
299 }
300
300 -static int configuration_pre_save(void *opaque)
301 +static bool configuration_pre_save(void *opaque, Error **errp)
302 {
303 SaveState *state = opaque;
304 const char *current_name = MACHINE_GET_CLASS(current_machine)->name;
@@ -318,7 +319,7 @@ static int configuration_pre_save(void *opaque)
319 }
320 state->uuid = qemu_uuid;
321
321 - return 0;
322 + return true;
323 }
324
325 static void configuration_post_save(void *opaque)
@@ -330,7 +331,7 @@ static void configuration_post_save(void *opaque)
331 state->caps_count = 0;
332 }
333
333 -static int configuration_pre_load(void *opaque)
334 +static bool configuration_pre_load(void *opaque, Error **errp)
335 {
336 SaveState *state = opaque;
337
@@ -339,7 +340,7 @@ static int configuration_pre_load(void *opaque)
340 * minimum possible value for this CPU.
341 */
342 state->target_page_bits = migration_legacy_page_bits();
342 - return 0;
343 + return true;
344 }
345
346 static bool configuration_validate_capabilities(SaveState *state)
@@ -376,28 +377,31 @@ static bool configuration_validate_capabilities(SaveState *state)
377 return ret;
378 }
379
379 -static int configuration_post_load(void *opaque, int version_id)
380 +static bool configuration_post_load(void *opaque, int version_id, Error **errp)
381 {
382 SaveState *state = opaque;
383 const char *current_name = MACHINE_GET_CLASS(current_machine)->name;
383 - int ret = 0;
384 + bool ok = true;
385
386 if (strncmp(state->name, current_name, state->len) != 0) {
386 - error_report("Machine type received is '%.*s' and local is '%s'",
387 - (int) state->len, state->name, current_name);
388 - ret = -EINVAL;
387 + error_setg(errp,
388 + "Machine type received is '%.*s' and local is '%s'",
389 + (int) state->len, state->name, current_name);
390 + ok = false;
391 goto out;
392 }
393
394 if (state->target_page_bits != qemu_target_page_bits()) {
393 - error_report("Received TARGET_PAGE_BITS is %d but local is %d",
394 - state->target_page_bits, qemu_target_page_bits());
395 - ret = -EINVAL;
395 + error_setg(errp,
396 + "Received TARGET_PAGE_BITS is %d but local is %d",
397 + state->target_page_bits, qemu_target_page_bits());
398 + ok = false;
399 goto out;
400 }
401
402 if (!configuration_validate_capabilities(state)) {
400 - ret = -EINVAL;
403 + error_setg(errp, "Failed to validate capabilities");
404 + ok = false;
405 goto out;
406 }
407
@@ -409,11 +413,12 @@ out:
413 state->capabilities = NULL;
414 state->caps_count = 0;
415
412 - return ret;
416 + return ok;
417 }
418
415 -static int get_capability(QEMUFile *f, void *pv, size_t size,
416 - const VMStateField *field)
419 +static bool load_capability(QEMUFile *f, void *pv, size_t size,
420 + const VMStateField *field,
421 + Error **errp)
422 {
423 MigrationCapability *capability = pv;
424 char capability_str[UINT8_MAX + 1];
@@ -426,15 +431,16 @@ static int get_capability(QEMUFile *f, void *pv, size_t size,
431 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
432 if (!strcmp(MigrationCapability_str(i), capability_str)) {
433 *capability = i;
429 - return 0;
434 + return true;
435 }
436 }
432 - error_report("Received unknown capability %s", capability_str);
433 - return -EINVAL;
437 + error_setg(errp, "Received unknown capability %s", capability_str);
438 + return false;
439 }
440
436 -static int put_capability(QEMUFile *f, void *pv, size_t size,
437 - const VMStateField *field, JSONWriter *vmdesc)
441 +static bool save_capability(QEMUFile *f, void *pv, size_t size,
442 + const VMStateField *field, JSONWriter *vmdesc,
443 + Error **errp)
444 {
445 MigrationCapability *capability = pv;
446 const char *capability_str = MigrationCapability_str(*capability);
@@ -443,13 +449,13 @@ static int put_capability(QEMUFile *f, void *pv, size_t size,
449
450 qemu_put_byte(f, len);
451 qemu_put_buffer(f, (uint8_t *)capability_str, len);
446 - return 0;
452 + return true;
453 }
454
455 static const VMStateInfo vmstate_info_capability = {
456 .name = "capability",
451 - .get = get_capability,
452 - .put = put_capability,
457 + .load = load_capability,
458 + .save = save_capability,
459 };
460
461 /* The target-page-bits subsection is present only if the
@@ -539,9 +545,9 @@ static const VMStateDescription vmstate_uuid = {
545 static const VMStateDescription vmstate_configuration = {
546 .name = "configuration",
547 .version_id = 1,
542 - .pre_load = configuration_pre_load,
543 - .post_load = configuration_post_load,
544 - .pre_save = configuration_pre_save,
548 + .pre_load_errp = configuration_pre_load,
549 + .post_load_errp = configuration_post_load,
550 + .pre_save_errp = configuration_pre_save,
551 .post_save = configuration_post_save,
552 .fields = (const VMStateField[]) {
553 VMSTATE_UINT32(len, SaveState),
@@ -969,8 +975,13 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se, Error **errp)
975 }
976 return ret;
977 }
972 - return vmstate_load_state(f, se->vmsd, se->opaque, se->load_version_id,
973 - errp);
978 +
979 + if (!vmstate_load_vmsd(f, se->vmsd, se->opaque, se->load_version_id,
980 + errp)) {
981 + return -EINVAL;
982 + }
983 +
984 + return 0;
985 }
986
987 static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se,
@@ -1028,8 +1039,6 @@ static void save_section_footer(QEMUFile *f, SaveStateEntry *se)
1039 static int vmstate_save(QEMUFile *f, SaveStateEntry *se, JSONWriter *vmdesc,
1040 Error **errp)
1041 {
1031 - int ret;
1032 -
1042 if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
1043 return 0;
1044 }
@@ -1050,10 +1059,8 @@ static int vmstate_save(QEMUFile *f, SaveStateEntry *se, JSONWriter *vmdesc,
1059 if (!se->vmsd) {
1060 vmstate_save_old_style(f, se, vmdesc);
1061 } else {
1053 - ret = vmstate_save_state(f, se->vmsd, se->opaque, vmdesc,
1054 - errp);
1055 - if (ret) {
1056 - return ret;
1062 + if (!vmstate_save_vmsd(f, se->vmsd, se->opaque, vmdesc, errp)) {
1063 + return -EINVAL;
1064 }
1065 }
1066
@@ -1311,8 +1318,8 @@ static void qemu_savevm_send_configuration(MigrationState *s, QEMUFile *f)
1318 json_writer_start_object(vmdesc, "configuration");
1319 }
1320
1314 - vmstate_save_state(f, &vmstate_configuration, &savevm_state,
1315 - vmdesc, &local_err);
1321 + vmstate_save_vmsd(f, &vmstate_configuration, &savevm_state,
1322 + vmdesc, &local_err);
1323 if (local_err) {
1324 error_report_err(local_err);
1325 }
@@ -2721,7 +2728,6 @@ qemu_loadvm_section_part_end(QEMUFile *f, uint8_t type, Error **errp)
2728 static int qemu_loadvm_state_header(QEMUFile *f, Error **errp)
2729 {
2730 unsigned int v;
2724 - int ret;
2731
2732 v = qemu_get_be32(f);
2733 if (v != QEMU_VM_FILE_MAGIC) {
@@ -2752,10 +2758,9 @@ static int qemu_loadvm_state_header(QEMUFile *f, Error **errp)
2758 return -EINVAL;
2759 }
2760
2755 - ret = vmstate_load_state(f, &vmstate_configuration, &savevm_state, 0,
2756 - errp);
2757 - if (ret) {
2758 - return ret;
2761 + if (!vmstate_load_vmsd(f, &vmstate_configuration, &savevm_state, 0,
2762 + errp)) {
2763 + return -EINVAL;
2764 }
2765 }
2766 return 0;