@samitouri / QOSamiQemu / commits / 511b786d13

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);