Skip to content

Commit 3214bec

Browse files
committed
Merge tag 'migration-20250110-pull-request' of https://gitlab.com/farosas/qemu into staging
Migration pull request - compression: Shameer's fix for CONFIG_UADK build Yuan Liu fixes for zero-page, QPL, qatzip - multifd sync cleanups, prereq. for VFIO and postcopy work - fixes for 9.2 regressions: multifd with pre-9.0 -> post-9.1 migrations (#2720) s390x migration (#2704) - fix for assertions during paused migrations; rework of late-block-activate logic (#2395, #686) - fixes for compressed arrays creation and parsing, mostly affecting s390x # -----BEGIN PGP SIGNATURE----- # # iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmeBDgkQHGZhcm9zYXNA # c3VzZS5kZQAKCRDHmNx0G+wxnSlUEACl31wY+77JxWnBva/eDDwnJ9HiCrqsoqaZ # YIJJXNlk4lYJWNdZRt6p27exzWrQwm+kWKPECeCakgCMlfhnKCvejGq7iV/fJY4o # D8hjE3t1htQ8mfblY1+bqzg3Rml59KwXxiqAwvlljbNWdkXruv026dq9vgJMzFhi # ia043fOO1tYULIoawgmwmLEHnztht0v+ZTZ1v5KQbrH655tpxls/8kHc6v5PXEpA # 3PSmCrCQh1dPtkYRjuJ9yHyfU+/T8tYwIjrU6VR1wQW7MBNkjtqNudaqAFiuyuqn # P8gh4rAQrMhA9y+aq6xSoJP8XGkuOHxLQtlNutlmtbcQyZ7JqgLmK9ZLdoPf21sK # //erV63NoyaciYB9Nk3NXflwroc6zyvo8A584kGNPwBznZOJLESP4SPvVm/nlE29 # vbyq8AWHRjFiqqf6P0ttQLAFkusZJzM1Y9UakF51hyVBX70yfqLG20XXZtIq/aZA # GbBB2Fo0MIlbmWaur3vLsSzn7B8d++Gl9TTGcK/eIXJ1ANCuCxGv9fbXJQlP5F4I # 3OAoSmAVJ2eqw4v0+2WMiEa8yUA5drNnDSI3VRkG+0K9jRfHKXki466/QQdGrNw7 # 8GuuzLBNai3gEKbavDU0Be73r982KjXeYXj7RuAkQfm0d4H7tiwtg91Cd1dPKfzh # mhpmOFJDCg== # =joNM # -----END PGP SIGNATURE----- # gpg: Signature made Fri 10 Jan 2025 07:09:45 EST # gpg: using RSA key AA1B48B0A22326A5A4C364CFC798DC741BEC319D # gpg: issuer "[email protected]" # gpg: Good signature from "Fabiano Rosas <[email protected]>" [unknown] # gpg: aka "Fabiano Almeida Rosas <[email protected]>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: AA1B 48B0 A223 26A5 A4C3 64CF C798 DC74 1BEC 319D * tag 'migration-20250110-pull-request' of https://gitlab.com/farosas/qemu: (25 commits) multifd: bugfix for incorrect migration data with qatzip compression multifd: bugfix for incorrect migration data with QPL compression multifd: bugfix for migration using compression methods s390x: Fix CSS migration migration: Fix arrays of pointers in JSON writer migration: Dump correct JSON format for nullptr replacement migration: Rename vmstate_info_nullptr migration: Fix parsing of s390 stream migration: Remove unused argument in vmsd_desc_field_end migration: Add more error handling to analyze-migration.py migration/block: Rewrite disk activation migration/block: Fix possible race with block_inactive migration/block: Apply late-block-active behavior to postcopy migration/block: Make late-block-active the default qmp/cont: Only activate disks if migration completed migration: Add helper to get target runstate migration/multifd: Fix compat with QEMU < 9.0 migration/multifd: Document the reason to sync for save_setup() migration/multifd: Cleanup src flushes on condition check migration/multifd: Remove sync processing on postcopy ... Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 290f950 + a523bc5 commit 3214bec

22 files changed

+601
-272
lines changed

hw/s390x/s390-virtio-ccw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ static void ccw_machine_2_9_instance_options(MachineState *machine)
12441244
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
12451245
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
12461246
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
1247+
css_migration_enabled = false;
12471248
}
12481249

12491250
static void ccw_machine_2_9_class_options(MachineClass *mc)
@@ -1256,7 +1257,6 @@ static void ccw_machine_2_9_class_options(MachineClass *mc)
12561257
ccw_machine_2_10_class_options(mc);
12571258
compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
12581259
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1259-
css_migration_enabled = false;
12601260
}
12611261
DEFINE_CCW_MACHINE(2, 9);
12621262

include/migration/misc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,8 @@ bool migration_incoming_postcopy_advised(void);
104104
/* True if background snapshot is active */
105105
bool migration_in_bg_snapshot(void);
106106

107+
/* Wrapper for block active/inactive operations */
108+
bool migration_block_activate(Error **errp);
109+
bool migration_block_inactivate(void);
110+
107111
#endif

migration/block-active.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Block activation tracking for migration purpose
3+
*
4+
* SPDX-License-Identifier: GPL-2.0-or-later
5+
*
6+
* Copyright (C) 2024 Red Hat, Inc.
7+
*/
8+
#include "qemu/osdep.h"
9+
#include "block/block.h"
10+
#include "qapi/error.h"
11+
#include "migration/migration.h"
12+
#include "qemu/error-report.h"
13+
#include "trace.h"
14+
15+
/*
16+
* Migration-only cache to remember the block layer activation status.
17+
* Protected by BQL.
18+
*
19+
* We need this because..
20+
*
21+
* - Migration can fail after block devices are invalidated (during
22+
* switchover phase). When that happens, we need to be able to recover
23+
* the block drive status by re-activating them.
24+
*
25+
* - Currently bdrv_inactivate_all() is not safe to be invoked on top of
26+
* invalidated drives (even if bdrv_activate_all() is actually safe to be
27+
* called any time!). It means remembering this could help migration to
28+
* make sure it won't invalidate twice in a row, crashing QEMU. It can
29+
* happen when we migrate a PAUSED VM from host1 to host2, then migrate
30+
* again to host3 without starting it. TODO: a cleaner solution is to
31+
* allow safe invoke of bdrv_inactivate_all() at anytime, like
32+
* bdrv_activate_all().
33+
*
34+
* For freshly started QEMU, the flag is initialized to TRUE reflecting the
35+
* scenario where QEMU owns block device ownerships.
36+
*
37+
* For incoming QEMU taking a migration stream, the flag is initialized to
38+
* FALSE reflecting that the incoming side doesn't own the block devices,
39+
* not until switchover happens.
40+
*/
41+
static bool migration_block_active;
42+
43+
/* Setup the disk activation status */
44+
void migration_block_active_setup(bool active)
45+
{
46+
migration_block_active = active;
47+
}
48+
49+
bool migration_block_activate(Error **errp)
50+
{
51+
ERRP_GUARD();
52+
53+
assert(bql_locked());
54+
55+
if (migration_block_active) {
56+
trace_migration_block_activation("active-skipped");
57+
return true;
58+
}
59+
60+
trace_migration_block_activation("active");
61+
62+
bdrv_activate_all(errp);
63+
if (*errp) {
64+
error_report_err(error_copy(*errp));
65+
return false;
66+
}
67+
68+
migration_block_active = true;
69+
return true;
70+
}
71+
72+
bool migration_block_inactivate(void)
73+
{
74+
int ret;
75+
76+
assert(bql_locked());
77+
78+
if (!migration_block_active) {
79+
trace_migration_block_activation("inactive-skipped");
80+
return true;
81+
}
82+
83+
trace_migration_block_activation("inactive");
84+
85+
ret = bdrv_inactivate_all();
86+
if (ret) {
87+
error_report("%s: bdrv_inactivate_all() failed: %d",
88+
__func__, ret);
89+
return false;
90+
}
91+
92+
migration_block_active = false;
93+
return true;
94+
}

migration/colo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ static void *colo_process_incoming_thread(void *opaque)
836836

837837
/* Make sure all file formats throw away their mutable metadata */
838838
bql_lock();
839-
bdrv_activate_all(&local_err);
839+
migration_block_activate(&local_err);
840840
bql_unlock();
841841
if (local_err) {
842842
error_report_err(local_err);

migration/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ migration_files = files(
1111

1212
system_ss.add(files(
1313
'block-dirty-bitmap.c',
14+
'block-active.c',
1415
'channel.c',
1516
'channel-block.c',
1617
'cpu-throttle.c',

migration/migration.c

Lines changed: 52 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,21 @@ static bool migration_needs_multiple_sockets(void)
135135
return migrate_multifd() || migrate_postcopy_preempt();
136136
}
137137

138+
static RunState migration_get_target_runstate(void)
139+
{
140+
/*
141+
* When the global state is not migrated, it means we don't know the
142+
* runstate of the src QEMU. We don't have much choice but assuming
143+
* the VM is running. NOTE: this is pretty rare case, so far only Xen
144+
* uses it.
145+
*/
146+
if (!global_state_received()) {
147+
return RUN_STATE_RUNNING;
148+
}
149+
150+
return global_state_get_runstate();
151+
}
152+
138153
static bool transport_supports_multi_channels(MigrationAddress *addr)
139154
{
140155
if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
@@ -723,30 +738,10 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
723738

724739
static void process_incoming_migration_bh(void *opaque)
725740
{
726-
Error *local_err = NULL;
727741
MigrationIncomingState *mis = opaque;
728742

729743
trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter");
730744

731-
/* If capability late_block_activate is set:
732-
* Only fire up the block code now if we're going to restart the
733-
* VM, else 'cont' will do it.
734-
* This causes file locking to happen; so we don't want it to happen
735-
* unless we really are starting the VM.
736-
*/
737-
if (!migrate_late_block_activate() ||
738-
(autostart && (!global_state_received() ||
739-
runstate_is_live(global_state_get_runstate())))) {
740-
/* Make sure all file formats throw away their mutable metadata.
741-
* If we get an error here, just don't restart the VM yet. */
742-
bdrv_activate_all(&local_err);
743-
if (local_err) {
744-
error_report_err(local_err);
745-
local_err = NULL;
746-
autostart = false;
747-
}
748-
}
749-
750745
/*
751746
* This must happen after all error conditions are dealt with and
752747
* we're sure the VM is going to be running on this host.
@@ -759,10 +754,23 @@ static void process_incoming_migration_bh(void *opaque)
759754

760755
dirty_bitmap_mig_before_vm_start();
761756

762-
if (!global_state_received() ||
763-
runstate_is_live(global_state_get_runstate())) {
757+
if (runstate_is_live(migration_get_target_runstate())) {
764758
if (autostart) {
765-
vm_start();
759+
/*
760+
* Block activation is always delayed until VM starts, either
761+
* here (which means we need to start the dest VM right now..),
762+
* or until qmp_cont() later.
763+
*
764+
* We used to have cap 'late-block-activate' but now we do this
765+
* unconditionally, as it has no harm but only benefit. E.g.,
766+
* it's not part of migration ABI on the time of disk activation.
767+
*
768+
* Make sure all file formats throw away their mutable
769+
* metadata. If error, don't restart the VM yet.
770+
*/
771+
if (migration_block_activate(NULL)) {
772+
vm_start();
773+
}
766774
} else {
767775
runstate_set(RUN_STATE_PAUSED);
768776
}
@@ -1547,16 +1555,6 @@ static void migrate_fd_cancel(MigrationState *s)
15471555
}
15481556
}
15491557
}
1550-
if (s->state == MIGRATION_STATUS_CANCELLING && s->block_inactive) {
1551-
Error *local_err = NULL;
1552-
1553-
bdrv_activate_all(&local_err);
1554-
if (local_err) {
1555-
error_report_err(local_err);
1556-
} else {
1557-
s->block_inactive = false;
1558-
}
1559-
}
15601558
}
15611559

15621560
void migration_add_notifier_mode(NotifierWithReturn *notify,
@@ -1840,6 +1838,12 @@ void qmp_migrate_incoming(const char *uri, bool has_channels,
18401838
return;
18411839
}
18421840

1841+
/*
1842+
* Newly setup incoming QEMU. Mark the block active state to reflect
1843+
* that the src currently owns the disks.
1844+
*/
1845+
migration_block_active_setup(false);
1846+
18431847
once = false;
18441848
}
18451849

@@ -2492,7 +2496,6 @@ static int postcopy_start(MigrationState *ms, Error **errp)
24922496
QIOChannelBuffer *bioc;
24932497
QEMUFile *fb;
24942498
uint64_t bandwidth = migrate_max_postcopy_bandwidth();
2495-
bool restart_block = false;
24962499
int cur_state = MIGRATION_STATUS_ACTIVE;
24972500

24982501
if (migrate_postcopy_preempt()) {
@@ -2528,13 +2531,10 @@ static int postcopy_start(MigrationState *ms, Error **errp)
25282531
goto fail;
25292532
}
25302533

2531-
ret = bdrv_inactivate_all();
2532-
if (ret < 0) {
2533-
error_setg_errno(errp, -ret, "%s: Failed in bdrv_inactivate_all()",
2534-
__func__);
2534+
if (!migration_block_inactivate()) {
2535+
error_setg(errp, "%s: Failed in bdrv_inactivate_all()", __func__);
25352536
goto fail;
25362537
}
2537-
restart_block = true;
25382538

25392539
/*
25402540
* Cause any non-postcopiable, but iterative devices to
@@ -2604,8 +2604,6 @@ static int postcopy_start(MigrationState *ms, Error **errp)
26042604
goto fail_closefb;
26052605
}
26062606

2607-
restart_block = false;
2608-
26092607
/* Now send that blob */
26102608
if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {
26112609
error_setg(errp, "%s: Failed to send packaged data", __func__);
@@ -2650,17 +2648,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
26502648
fail:
26512649
migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
26522650
MIGRATION_STATUS_FAILED);
2653-
if (restart_block) {
2654-
/* A failure happened early enough that we know the destination hasn't
2655-
* accessed block devices, so we're safe to recover.
2656-
*/
2657-
Error *local_err = NULL;
2658-
2659-
bdrv_activate_all(&local_err);
2660-
if (local_err) {
2661-
error_report_err(local_err);
2662-
}
2663-
}
2651+
migration_block_activate(NULL);
26642652
migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
26652653
bql_unlock();
26662654
return -1;
@@ -2729,14 +2717,11 @@ static int migration_completion_precopy(MigrationState *s,
27292717
goto out_unlock;
27302718
}
27312719

2732-
/*
2733-
* Inactivate disks except in COLO, and track that we have done so in order
2734-
* to remember to reactivate them if migration fails or is cancelled.
2735-
*/
2736-
s->block_inactive = !migrate_colo();
27372720
migration_rate_set(RATE_LIMIT_DISABLED);
2721+
2722+
/* Inactivate disks except in COLO */
27382723
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
2739-
s->block_inactive);
2724+
!migrate_colo());
27402725
out_unlock:
27412726
bql_unlock();
27422727
return ret;
@@ -2761,31 +2746,6 @@ static void migration_completion_postcopy(MigrationState *s)
27612746
trace_migration_completion_postcopy_end_after_complete();
27622747
}
27632748

2764-
static void migration_completion_failed(MigrationState *s,
2765-
int current_active_state)
2766-
{
2767-
if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
2768-
s->state == MIGRATION_STATUS_DEVICE)) {
2769-
/*
2770-
* If not doing postcopy, vm_start() will be called: let's
2771-
* regain control on images.
2772-
*/
2773-
Error *local_err = NULL;
2774-
2775-
bql_lock();
2776-
bdrv_activate_all(&local_err);
2777-
if (local_err) {
2778-
error_report_err(local_err);
2779-
} else {
2780-
s->block_inactive = false;
2781-
}
2782-
bql_unlock();
2783-
}
2784-
2785-
migrate_set_state(&s->state, current_active_state,
2786-
MIGRATION_STATUS_FAILED);
2787-
}
2788-
27892749
/**
27902750
* migration_completion: Used by migration_thread when there's not much left.
27912751
* The caller 'breaks' the loop when this returns.
@@ -2839,7 +2799,8 @@ static void migration_completion(MigrationState *s)
28392799
error_free(local_err);
28402800
}
28412801

2842-
migration_completion_failed(s, current_active_state);
2802+
migrate_set_state(&s->state, current_active_state,
2803+
MIGRATION_STATUS_FAILED);
28432804
}
28442805

28452806
/**
@@ -3269,6 +3230,11 @@ static void migration_iteration_finish(MigrationState *s)
32693230
case MIGRATION_STATUS_FAILED:
32703231
case MIGRATION_STATUS_CANCELLED:
32713232
case MIGRATION_STATUS_CANCELLING:
3233+
/*
3234+
* Re-activate the block drives if they're inactivated. Note, COLO
3235+
* shouldn't use block_active at all, so it should be no-op there.
3236+
*/
3237+
migration_block_activate(NULL);
32723238
if (runstate_is_live(s->vm_old_state)) {
32733239
if (!runstate_check(RUN_STATE_SHUTDOWN)) {
32743240
vm_start();
@@ -3842,6 +3808,8 @@ static void migration_instance_init(Object *obj)
38423808
ms->state = MIGRATION_STATUS_NONE;
38433809
ms->mbps = -1;
38443810
ms->pages_per_second = -1;
3811+
/* Freshly started QEMU owns all the block devices */
3812+
migration_block_active_setup(true);
38453813
qemu_sem_init(&ms->pause_sem, 0);
38463814
qemu_mutex_init(&ms->error_mutex);
38473815

migration/migration.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,6 @@ struct MigrationState {
370370
/* Flag set once the migration thread is running (and needs joining) */
371371
bool migration_thread_running;
372372

373-
/* Flag set once the migration thread called bdrv_inactivate_all */
374-
bool block_inactive;
375-
376373
/* Migration is waiting for guest to unplug device */
377374
QemuSemaphore wait_unplug_sem;
378375

@@ -556,4 +553,7 @@ void migration_bitmap_sync_precopy(bool last_stage);
556553
/* migration/block-dirty-bitmap.c */
557554
void dirty_bitmap_mig_init(void);
558555

556+
/* migration/block-active.c */
557+
void migration_block_active_setup(bool active);
558+
559559
#endif

0 commit comments

Comments
 (0)