aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-11-03 09:57:32 +0800
committerStefan Hajnoczi <stefanha@redhat.com>2023-11-03 09:57:32 +0800
commit75b7b25d44a64411ea0ae792d5ebad8ddf22527e (patch)
tree26530d73d594c13f116dd88135245586696aafb5 /tests
parent4a6a6cb60de80e9e90d9915abfec8d3d9fcc157c (diff)
parent8e3766eefbb4036cbc280c1f1a0d28537929f7fb (diff)
downloadqemu-75b7b25d44a64411ea0ae792d5ebad8ddf22527e.zip
qemu-75b7b25d44a64411ea0ae792d5ebad8ddf22527e.tar.gz
qemu-75b7b25d44a64411ea0ae792d5ebad8ddf22527e.tar.bz2
Merge tag 'migration-20231102-pull-request' of https://gitlab.com/juan.quintela/qemu into staging
Migration Pull request (20231102) Hi In this pull request: - migration reboot mode (steve) * I disabled the test because our CI don't like programs using so much shared memory. Searching for a fix. - test for postcopy recover (fabiano) - MigrateAddress QAPI (het) - better return path error handling (peter) - traces for downtime (peter) - vmstate_register() check for duplicates (juan) thomas find better solutions for s390x and ipmi. now also works on s390x Please, apply. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmVDipMACgkQ9IfvGFhy # 1yNYnQ/9E5Cywsoqljqa/9FiKBSII2qMrmkfu6JLKqePnsh5pFZiukbudYRuJCCe # ZTDEmD0NmKRJbDx2xRU1qx/e6gKJy+gz37KP89Buuh/WwZHPboPYtxQpGvCSiH26 # J3i+1+TgaqmkLzcO35wa8tp6gneQclWeAwKgMvdb4cm2pJEhgWRKI62ccyLzxeve # UCzFQn60t55ETyVZGnRD4YwdTQvGKH+DPlyTuJOLR3DePuvZd8EdH+ypvB4RLAy7 # 3+CuQOxmF5LRXPbpJuAeOsudbmhhHzrO/yL7ZmsiKQTthsJv+SzC1bO94jhQrawZ # Q7GCii5KpGq0KnRTRKZRGk6XKwxcYRduXMX3R5tXuVmDmCZsjhXzziU8yEdftph8 # 5TJdk1o0Gb043EFu81mrsQYS+9yJqe6sy6m3PTJaec54cAty5ln+c17WOvpAOaSV # +1phe05ftuVPmQ3KWhbIR/tCmavNLwEZxpVIfyaKJx04bFbtQ9gRpRyURORX4KXc # s4WXvNirQEohxYBnP4TPvA09xBTW3V08pk/wRDwt0YDXnLiqCltOuxD8r05K8K4B # MkCLcWj0g7he2tBkF60oz1KSIE0oTB81um9AzLIv5F2YSYLaJM5BIcoC437MR2f4 # MOR7drR1fP5GsRu/SeU5BWvhVq3IvdOxR7G2MLNRJJvl7ZtGXDc= # =uaqL # -----END PGP SIGNATURE----- # gpg: Signature made Thu 02 Nov 2023 19:40:03 HKT # gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full] # gpg: aka "Juan Quintela <quintela@trasno.org>" [full] # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * tag 'migration-20231102-pull-request' of https://gitlab.com/juan.quintela/qemu: (40 commits) migration: modify test_multifd_tcp_none() to use new QAPI syntax. migration: Implement MigrateChannelList to hmp migration flow. migration: Implement MigrateChannelList to qmp migration flow. migration: modify migration_channels_and_uri_compatible() for new QAPI syntax migration: New migrate and migrate-incoming argument 'channels' migration: Convert the file backend to the new QAPI syntax migration: convert exec backend to accept MigrateAddress. migration: convert rdma backend to accept MigrateAddress migration: convert socket backend to accept MigrateAddress migration: convert migration 'uri' into 'MigrateAddress' migration: New QAPI type 'MigrateAddress' migration: Change ram_dirty_bitmap_reload() retval to bool tests/migration-test: Add a test for postcopy hangs during RECOVER migration: Allow network to fail even during recovery migration: Refactor error handling in source return path tests/qtest: migration: add reboot mode test cpr: reboot mode cpr: relax vhost migration blockers cpr: relax blockdev migration blockers migration: per-mode blockers ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/qtest/migration-test.c150
1 files changed, 143 insertions, 7 deletions
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index bc70a14..e803b46 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -728,6 +728,7 @@ typedef struct {
/* Postcopy specific fields */
void *postcopy_data;
bool postcopy_preempt;
+ bool postcopy_recovery_test_fail;
} MigrateCommon;
static int test_migrate_start(QTestState **from, QTestState **to,
@@ -1309,7 +1310,12 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
migrate_prepare_for_dirty_mem(from);
qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
- " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}");
+ " 'arguments': { "
+ " 'channels': [ { 'channel-type': 'main',"
+ " 'addr': { 'transport': 'socket',"
+ " 'type': 'inet',"
+ " 'host': '127.0.0.1',"
+ " 'port': '0' } } ] } }");
/* Wait for the first serial output from the source */
wait_for_serial("src_serial");
@@ -1404,6 +1410,80 @@ static void test_postcopy_preempt_tls_psk(void)
}
#endif
+static void wait_for_postcopy_status(QTestState *one, const char *status)
+{
+ wait_for_migration_status(one, status,
+ (const char * []) { "failed", "active",
+ "completed", NULL });
+}
+
+#ifndef _WIN32
+static void postcopy_recover_fail(QTestState *from, QTestState *to)
+{
+ int ret, pair1[2], pair2[2];
+ char c;
+
+ /* Create two unrelated socketpairs */
+ ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair1);
+ g_assert_cmpint(ret, ==, 0);
+
+ ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair2);
+ g_assert_cmpint(ret, ==, 0);
+
+ /*
+ * Give the guests unpaired ends of the sockets, so they'll all blocked
+ * at reading. This mimics a wrong channel established.
+ */
+ qtest_qmp_fds_assert_success(from, &pair1[0], 1,
+ "{ 'execute': 'getfd',"
+ " 'arguments': { 'fdname': 'fd-mig' }}");
+ qtest_qmp_fds_assert_success(to, &pair2[0], 1,
+ "{ 'execute': 'getfd',"
+ " 'arguments': { 'fdname': 'fd-mig' }}");
+
+ /*
+ * Write the 1st byte as QEMU_VM_COMMAND (0x8) for the dest socket, to
+ * emulate the 1st byte of a real recovery, but stops from there to
+ * keep dest QEMU in RECOVER. This is needed so that we can kick off
+ * the recover process on dest QEMU (by triggering the G_IO_IN event).
+ *
+ * NOTE: this trick is not needed on src QEMUs, because src doesn't
+ * rely on an pre-existing G_IO_IN event, so it will always trigger the
+ * upcoming recovery anyway even if it can read nothing.
+ */
+#define QEMU_VM_COMMAND 0x08
+ c = QEMU_VM_COMMAND;
+ ret = send(pair2[1], &c, 1, 0);
+ g_assert_cmpint(ret, ==, 1);
+
+ migrate_recover(to, "fd:fd-mig");
+ migrate_qmp(from, "fd:fd-mig", "{'resume': true}");
+
+ /*
+ * Make sure both QEMU instances will go into RECOVER stage, then test
+ * kicking them out using migrate-pause.
+ */
+ wait_for_postcopy_status(from, "postcopy-recover");
+ wait_for_postcopy_status(to, "postcopy-recover");
+
+ /*
+ * This would be issued by the admin upon noticing the hang, we should
+ * make sure we're able to kick this out.
+ */
+ migrate_pause(from);
+ wait_for_postcopy_status(from, "postcopy-paused");
+
+ /* Do the same test on dest */
+ migrate_pause(to);
+ wait_for_postcopy_status(to, "postcopy-paused");
+
+ close(pair1[0]);
+ close(pair1[1]);
+ close(pair2[0]);
+ close(pair2[1]);
+}
+#endif /* _WIN32 */
+
static void test_postcopy_recovery_common(MigrateCommon *args)
{
QTestState *from, *to;
@@ -1439,9 +1519,19 @@ static void test_postcopy_recovery_common(MigrateCommon *args)
* migrate-recover command can only succeed if destination machine
* is in the paused state
*/
- wait_for_migration_status(to, "postcopy-paused",
- (const char * []) { "failed", "active",
- "completed", NULL });
+ wait_for_postcopy_status(to, "postcopy-paused");
+ wait_for_postcopy_status(from, "postcopy-paused");
+
+#ifndef _WIN32
+ if (args->postcopy_recovery_test_fail) {
+ /*
+ * Test when a wrong socket specified for recover, and then the
+ * ability to kick it out, and continue with a correct socket.
+ */
+ postcopy_recover_fail(from, to);
+ /* continue with a good recovery */
+ }
+#endif /* _WIN32 */
/*
* Create a new socket to emulate a new channel that is different
@@ -1455,9 +1545,6 @@ static void test_postcopy_recovery_common(MigrateCommon *args)
* Try to rebuild the migration channel using the resume flag and
* the newly created channel
*/
- wait_for_migration_status(from, "postcopy-paused",
- (const char * []) { "failed", "active",
- "completed", NULL });
migrate_qmp(from, uri, "{'resume': true}");
/* Restore the postcopy bandwidth to unlimited */
@@ -1482,6 +1569,17 @@ static void test_postcopy_recovery_compress(void)
test_postcopy_recovery_common(&args);
}
+#ifndef _WIN32
+static void test_postcopy_recovery_double_fail(void)
+{
+ MigrateCommon args = {
+ .postcopy_recovery_test_fail = true,
+ };
+
+ test_postcopy_recovery_common(&args);
+}
+#endif /* _WIN32 */
+
#ifdef CONFIG_GNUTLS
static void test_postcopy_recovery_tls_psk(void)
{
@@ -2026,6 +2124,31 @@ static void test_precopy_file_offset_bad(void)
test_file_common(&args, false);
}
+static void *test_mode_reboot_start(QTestState *from, QTestState *to)
+{
+ migrate_set_parameter_str(from, "mode", "cpr-reboot");
+ migrate_set_parameter_str(to, "mode", "cpr-reboot");
+
+ migrate_set_capability(from, "x-ignore-shared", true);
+ migrate_set_capability(to, "x-ignore-shared", true);
+
+ return NULL;
+}
+
+static void test_mode_reboot(void)
+{
+ g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
+ FILE_TEST_FILENAME);
+ MigrateCommon args = {
+ .start.use_shmem = true,
+ .connect_uri = uri,
+ .listen_uri = "defer",
+ .start_hook = test_mode_reboot_start
+ };
+
+ test_file_common(&args, true);
+}
+
static void test_precopy_tcp_plain(void)
{
MigrateCommon args = {
@@ -3068,6 +3191,11 @@ int main(int argc, char **argv)
qtest_add_func("/migration/postcopy/recovery/compress/plain",
test_postcopy_recovery_compress);
}
+#ifndef _WIN32
+ qtest_add_func("/migration/postcopy/recovery/double-failures",
+ test_postcopy_recovery_double_fail);
+#endif /* _WIN32 */
+
}
qtest_add_func("/migration/bad_dest", test_baddest);
@@ -3096,6 +3224,14 @@ int main(int argc, char **argv)
qtest_add_func("/migration/precopy/file/offset/bad",
test_precopy_file_offset_bad);
+ /*
+ * Our CI system has problems with shared memory.
+ * Don't run this test until we find a workaround.
+ */
+ if (getenv("QEMU_TEST_FLAKY_TESTS")) {
+ qtest_add_func("/migration/mode/reboot", test_mode_reboot);
+ }
+
#ifdef CONFIG_GNUTLS
qtest_add_func("/migration/precopy/unix/tls/psk",
test_precopy_unix_tls_psk);