migration: Refactor migration_completion_precopy() to return bool
migration_completion_precopy() reports its error through the Error **errp argument, so its int return value carries no information beyond success/failure. Convert it to return a bool, matching the common convention. Convert its underlying helper qemu_savevm_state_complete_precopy() likewise, and in turn qemu_savevm_state_non_iterable(), which it calls. Adjust all callers accordingly. Refactor and clean migration_completion() code too, which no longer needs to track int return values. Signed-off-by: Avihai Horon <avihaih@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260706085211.13905-16-avihaih@nvidia.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
Avihai Horon committed
Jul 6, 2026 at 11:52 UTC
511b786d13ea9250500ec951257dbc0993ac34e0
3 files changed
+31
-40
migration/migration.c
+14
-21
@@ -2659,8 +2659,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
2659
*/
2660
qemu_savevm_send_postcopy_listen(fb);
2661
2662
- ret = qemu_savevm_state_non_iterable(fb, errp);
2663
- if (ret) {
2662
+ if (!qemu_savevm_state_non_iterable(fb, errp)) {
2663
error_prepend(errp, "Postcopy save non-iterable states failed: ");
2664
goto fail_closefb;
2665
}
@@ -2858,22 +2857,22 @@ static bool migration_switchover_start(MigrationState *s, Error **errp)
2857
return true;
2858
}
2859
2861
-static int migration_completion_precopy(MigrationState *s, Error **errp)
2860
+static bool migration_completion_precopy(MigrationState *s, Error **errp)
2861
{
2863
- int ret;
2862
+ bool ret = false;
2863
2864
bql_lock();
2865
2866
if (!migrate_mode_is_cpr()) {
2868
- ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
2869
- if (ret < 0) {
2870
- error_setg_errno(errp, -ret, "Failed to stop the VM");
2867
+ int r = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
2868
+
2869
+ if (r < 0) {
2870
+ error_setg_errno(errp, -r, "Failed to stop the VM");
2871
goto out_unlock;
2872
}
2873
}
2874
2875
if (!migration_switchover_start(s, errp)) {
2876
- ret = -EFAULT;
2876
goto out_unlock;
2877
}
2878
@@ -2910,18 +2909,17 @@ static void migration_completion_postcopy(MigrationState *s)
2909
*/
2910
static void migration_completion(MigrationState *s)
2911
{
2913
- int ret = 0;
2912
Error *local_err = NULL;
2913
2914
if (s->state == MIGRATION_STATUS_ACTIVE) {
2917
- ret = migration_completion_precopy(s, &local_err);
2915
+ if (!migration_completion_precopy(s, &local_err)) {
2916
+ goto fail;
2917
+ }
2918
} else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
2919
migration_completion_postcopy(s);
2920
} else {
2921
- ret = -1;
2922
- }
2923
-
2924
- if (ret < 0) {
2921
+ error_setg(&local_err, "Unexpected migration completion status %s",
2922
+ MigrationStatus_str(s->state));
2923
goto fail;
2924
}
2925
@@ -2945,12 +2943,7 @@ static void migration_completion(MigrationState *s)
2943
return;
2944
2945
fail:
2948
- if (local_err) {
2949
- migrate_error_propagate(s, local_err);
2950
- } else if (qemu_file_get_error_obj(s->to_dst_file, &local_err)) {
2951
- migrate_error_propagate(s, local_err);
2952
- } else if (ret) {
2953
- error_setg_errno(&local_err, -ret, "Error in migration completion");
2946
+ if (local_err || qemu_file_get_error_obj(s->to_dst_file, &local_err)) {
2947
migrate_error_propagate(s, local_err);
2948
}
2949
@@ -3863,7 +3856,7 @@ static void *bg_migration_thread(void *opaque)
3856
goto fail_with_bql;
3857
}
3858
3866
- if (qemu_savevm_state_non_iterable(fb, &local_err)) {
3859
+ if (!qemu_savevm_state_non_iterable(fb, &local_err)) {
3860
error_prepend(&local_err, "Failed to save non-iterable devices ");
3861
goto fail_with_bql;
3862
}
migration/savevm.c
+15
-17
@@ -1737,13 +1737,12 @@ void qemu_savevm_state_end_precopy(MigrationState *s, QEMUFile *f)
1737
qemu_savevm_state_vm_desc(s, f);
1738
}
1739
1740
-int qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp)
1740
+bool qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp)
1741
{
1742
MigrationState *ms = migrate_get_current();
1743
int64_t start_ts_each, end_ts_each;
1744
JSONWriter *vmdesc = ms->vmdesc;
1745
SaveStateEntry *se;
1746
- int ret;
1746
1747
/* Making sure cpu states are synchronized before saving non-iterable */
1748
cpu_synchronize_all_states();
@@ -1756,9 +1755,8 @@ int qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp)
1755
1756
start_ts_each = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
1757
1759
- ret = vmstate_save(f, se, vmdesc, errp);
1760
- if (ret) {
1761
- return ret;
1758
+ if (vmstate_save(f, se, vmdesc, errp) < 0) {
1759
+ return false;
1760
}
1761
1762
end_ts_each = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
@@ -1768,10 +1766,10 @@ int qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp)
1766
1767
trace_vmstate_downtime_checkpoint("src-non-iterable-saved");
1768
1771
- return 0;
1769
+ return true;
1770
}
1771
1774
-int qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp)
1772
+bool qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp)
1773
{
1774
ERRP_GUARD();
1775
QEMUFile *f = s->to_dst_file;
@@ -1781,12 +1779,11 @@ int qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp)
1779
if (ret) {
1780
qemu_file_get_error_obj(f, errp);
1781
error_prepend(errp, "Failed to save iterable device state: ");
1784
- return ret;
1782
+ return false;
1783
}
1784
1787
- ret = qemu_savevm_state_non_iterable(f, errp);
1788
- if (ret) {
1789
- return ret;
1785
+ if (!qemu_savevm_state_non_iterable(f, errp)) {
1786
+ return false;
1787
}
1788
1789
qemu_savevm_state_end_precopy(s, f);
@@ -1795,10 +1792,10 @@ int qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp)
1792
if (ret) {
1793
qemu_file_get_error_obj(f, errp);
1794
error_prepend(errp, "Failed to flush QEMUFile: ");
1798
- return ret;
1795
+ return false;
1796
}
1797
1801
- return 0;
1798
+ return true;
1799
}
1800
1801
static void qemu_savevm_query_pending(MigrationState *s,
@@ -1928,7 +1925,9 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
1925
goto cleanup;
1926
}
1927
1931
- ret = qemu_savevm_state_complete_precopy(ms, errp);
1928
+ if (!qemu_savevm_state_complete_precopy(ms, errp)) {
1929
+ ret = -1;
1930
+ }
1931
cleanup:
1932
qemu_savevm_state_cleanup();
1933
@@ -1962,9 +1961,8 @@ int qemu_save_device_state(QEMUFile *f, Error **errp)
1961
return ret;
1962
}
1963
1965
- ret = qemu_savevm_state_non_iterable(f, errp);
1966
- if (ret) {
1967
- return ret;
1964
+ if (!qemu_savevm_state_non_iterable(f, errp)) {
1965
+ return -1;
1966
}
1967
1968
qemu_savevm_state_end(f);
migration/savevm.h
+2
-2
@@ -44,7 +44,7 @@ void qemu_savevm_state_header(QEMUFile *f);
44
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy);
45
void qemu_savevm_state_cleanup(void);
46
void qemu_savevm_state_complete_postcopy(QEMUFile *f);
47
-int qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp);
47
+bool qemu_savevm_state_complete_precopy(MigrationState *s, Error **errp);
48
void qemu_savevm_query_pending_iter(MigrationState *s, MigPendingData *pending,
49
bool exact);
50
bool qemu_savevm_query_pending_final(MigrationState *s,
@@ -74,7 +74,7 @@ int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis,
74
Error **errp);
75
int qemu_load_device_state(QEMUFile *f, Error **errp);
76
int qemu_loadvm_approve_switchover(const char *approver);
77
-int qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp);
77
+bool qemu_savevm_state_non_iterable(QEMUFile *f, Error **errp);
78
int qemu_savevm_state_non_iterable_early(QEMUFile *f,
79
JSONWriter *vmdesc,
80
Error **errp);