#include "migration-helpers.h"
#include "tests/migration/migration-test.h"
+#if defined(__linux__)
+#include "linux/kvm.h"
+#endif
+
/* TODO actually test the results and get rid of this */
#define qtest_qmp_discard_response(...) qobject_unref(qtest_qmp(__VA_ARGS__))
bool use_shmem;
/* only launch the target process */
bool only_target;
+ /* Use dirty ring if true; dirty logging otherwise */
+ bool use_dirty_ring;
char *opts_source;
char *opts_target;
} MigrateStart;
shmem_opts = g_strdup("");
}
- cmd_source = g_strdup_printf("-accel kvm -accel tcg%s%s "
+ cmd_source = g_strdup_printf("-accel kvm%s -accel tcg%s%s "
"-name source,debug-threads=on "
"-m %s "
"-serial file:%s/src_serial "
"%s %s %s %s",
+ args->use_dirty_ring ?
+ ",dirty-ring-size=4096" : "",
machine_opts ? " -machine " : "",
machine_opts ? machine_opts : "",
memory_size, tmpfs,
*from = qtest_init(cmd_source);
}
- cmd_target = g_strdup_printf("-accel kvm -accel tcg%s%s "
+ cmd_target = g_strdup_printf("-accel kvm%s -accel tcg%s%s "
"-name target,debug-threads=on "
"-m %s "
"-serial file:%s/dest_serial "
"-incoming %s "
"%s %s %s %s",
+ args->use_dirty_ring ?
+ ",dirty-ring-size=4096" : "",
machine_opts ? " -machine " : "",
machine_opts ? machine_opts : "",
memory_size, tmpfs, uri,
test_migrate_end(from, to, false);
}
-static void test_precopy_unix(void)
+static void test_precopy_unix_common(bool dirty_ring)
{
g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
MigrateStart *args = migrate_start_new();
QTestState *from, *to;
+ args->use_dirty_ring = dirty_ring;
+
if (test_migrate_start(&from, &to, uri, args)) {
return;
}
test_migrate_end(from, to, true);
}
+static void test_precopy_unix(void)
+{
+ /* Using default dirty logging */
+ test_precopy_unix_common(false);
+}
+
+static void test_precopy_unix_dirty_ring(void)
+{
+ /* Using dirty ring tracking */
+ test_precopy_unix_common(true);
+}
+
#if 0
/* Currently upset on aarch64 TCG */
static void test_ignore_shared(void)
test_migrate_end(from, to2, true);
}
+static bool kvm_dirty_ring_supported(void)
+{
+#if defined(__linux__)
+ int ret, kvm_fd = open("/dev/kvm", O_RDONLY);
+
+ if (kvm_fd < 0) {
+ return false;
+ }
+
+ ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_DIRTY_LOG_RING);
+ close(kvm_fd);
+
+ /* We test with 4096 slots */
+ if (ret < 4096) {
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
int main(int argc, char **argv)
{
char template[] = "/tmp/migration-test-XXXXXX";
qtest_add_func("/migration/multifd/tcp/zstd", test_multifd_tcp_zstd);
#endif
+ if (kvm_dirty_ring_supported()) {
+ qtest_add_func("/migration/dirty_ring",
+ test_precopy_unix_dirty_ring);
+ }
+
ret = g_test_run();
g_assert_cmpint(ret, ==, 0);