* [PATCH V1 00/11] cpr-exec test
@ 2025-09-19 14:12 Steve Sistare
2025-09-19 14:12 ` [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary Steve Sistare
` (11 more replies)
0 siblings, 12 replies; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Add a migration test for cpr-exec mode.
Depends on the patch series "Live update: cpr-exec".
Steve Sistare (11):
tests/qtest: export qtest_qemu_binary
tests/qtest: qtest_qemu_args
tests/qtest: qtest_create_test_state
tests/qtest: qtest_qemu_spawn_func
tests/qtest: qtest_init_after_exec
migration-test: only_source option
migration-test: shm path accessor
migration-test: misc exports
migration-test: migrate_args
migration-test: strv parameter
migration-test: test cpr-exec
tests/qtest/libqtest.h | 25 +++++++
tests/qtest/migration/bootfile.h | 1 +
tests/qtest/migration/framework.h | 8 +++
tests/qtest/migration/migration-qmp.h | 2 +
tests/qtest/libqtest.c | 108 ++++++++++++++++++++----------
tests/qtest/migration/bootfile.c | 5 ++
tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++
tests/qtest/migration/framework.c | 102 ++++++++++++++++++-----------
tests/qtest/migration/migration-qmp.c | 16 +++++
9 files changed, 317 insertions(+), 70 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 14:47 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 02/11] tests/qtest: qtest_qemu_args Steve Sistare
` (10 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/libqtest.h | 9 +++++++++
tests/qtest/libqtest.c | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index b3f2e7f..6d3199f 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -48,6 +48,15 @@ QTestState *qtest_initf(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
/**
+ * qtest_qemu_binary:
+ * @var: environment variable name
+ *
+ * Look up @var and return its value as the qemu binary path.
+ * If @var is NULL, look up the default var name.
+ */
+const char *qtest_qemu_binary(const char *var);
+
+/**
* qtest_init:
* @extra_args: other arguments to pass to QEMU. CAUTION: these
* arguments are subject to word splitting and shell evaluation.
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index f3d4e08..6f76be1 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -357,7 +357,7 @@ void qtest_remove_abrt_handler(void *data)
}
}
-static const char *qtest_qemu_binary(const char *var)
+const char *qtest_qemu_binary(const char *var)
{
const char *qemu_bin;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 02/11] tests/qtest: qtest_qemu_args
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
2025-09-19 14:12 ` [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 14:51 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 03/11] tests/qtest: qtest_create_test_state Steve Sistare
` (9 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Define an accessor that returns all the arguments used to exec QEMU.
Collect the arguments that were passed to qtest_spawn_qemu, plus the trace
arguments that were composed inside qtest_spawn_qemu, and move them to a
new function qtest_qemu_args.
This will be needed to test the cpr-exec migration mode.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/libqtest.h | 8 ++++++++
tests/qtest/libqtest.c | 54 +++++++++++++++++++++++++++++---------------------
2 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index 6d3199f..a164f58 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -57,6 +57,14 @@ QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
const char *qtest_qemu_binary(const char *var);
/**
+ * qtest_qemu_args:
+ * @extra_args: Other arguments to pass to QEMU.
+ *
+ * Return the command line used to start QEMU, sans binary.
+ */
+gchar *qtest_qemu_args(const char *extra_args);
+
+/**
* qtest_init:
* @extra_args: other arguments to pass to QEMU. CAUTION: these
* arguments are subject to word splitting and shell evaluation.
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 6f76be1..551bc8c 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -409,20 +409,12 @@ static pid_t qtest_create_process(char *cmd)
}
#endif /* _WIN32 */
-static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
- const char *fmt, ...)
+static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
{
- va_list ap;
QTestState *s = g_new0(QTestState, 1);
- const char *trace = g_getenv("QTEST_TRACE");
- g_autofree char *tracearg = trace ?
- g_strdup_printf("-trace %s ", trace) : g_strdup("");
g_autoptr(GString) command = g_string_new("");
- va_start(ap, fmt);
- g_string_append_printf(command, CMD_EXEC "%s %s", qemu_bin, tracearg);
- g_string_append_vprintf(command, fmt, ap);
- va_end(ap);
+ g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
qtest_add_abrt_handler(kill_qemu_hook_func, s);
@@ -466,6 +458,33 @@ static char *qtest_socket_path(const char *suffix)
return g_strdup_printf("%s/qtest-%d.%s", g_get_tmp_dir(), getpid(), suffix);
}
+gchar *qtest_qemu_args(const char *extra_args)
+{
+ g_autofree gchar *socket_path = qtest_socket_path("sock");
+ g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ const char *trace = g_getenv("QTEST_TRACE");
+ g_autofree char *tracearg = trace ? g_strdup_printf("-trace %s ", trace) :
+ g_strdup("");
+ gchar *args = g_strdup_printf(
+ "%s"
+ "-qtest unix:%s "
+ "-qtest-log %s "
+ "-chardev socket,path=%s,id=char0 "
+ "-mon chardev=char0,mode=control "
+ "-display none "
+ "-audio none "
+ "%s"
+ " -accel qtest",
+
+ tracearg,
+ socket_path,
+ getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
+ qmp_socket_path,
+ extra_args ?: "");
+
+ return args;
+}
+
static QTestState *qtest_init_internal(const char *qemu_bin,
const char *extra_args,
bool do_connect)
@@ -474,6 +493,7 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
int sock, qmpsock, i;
g_autofree gchar *socket_path = qtest_socket_path("sock");
g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ g_autofree gchar *args = qtest_qemu_args(extra_args);
/*
* It's possible that if an earlier test run crashed it might
@@ -488,19 +508,7 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- s = qtest_spawn_qemu(qemu_bin,
- "-qtest unix:%s "
- "-qtest-log %s "
- "-chardev socket,path=%s,id=char0 "
- "-mon chardev=char0,mode=control "
- "-display none "
- "-audio none "
- "%s"
- " -accel qtest",
- socket_path,
- getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
- qmp_socket_path,
- extra_args ?: "");
+ s = qtest_spawn_qemu(qemu_bin, args);
qtest_client_set_rx_handler(s, qtest_client_socket_recv_line);
qtest_client_set_tx_handler(s, qtest_client_socket_send);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 03/11] tests/qtest: qtest_create_test_state
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
2025-09-19 14:12 ` [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary Steve Sistare
2025-09-19 14:12 ` [PATCH V1 02/11] tests/qtest: qtest_qemu_args Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 14:52 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func Steve Sistare
` (8 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Refactor qtest_spawn_qemu and create a subroutine to create a QTestState
object, to be used in a subsequent patch.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/libqtest.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 551bc8c..3fa9317 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -409,22 +409,29 @@ static pid_t qtest_create_process(char *cmd)
}
#endif /* _WIN32 */
-static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
+static QTestState *qtest_create_test_state(int pid)
{
QTestState *s = g_new0(QTestState, 1);
+
+ s->qemu_pid = pid;
+ qtest_add_abrt_handler(kill_qemu_hook_func, s);
+ return s;
+}
+
+static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
+{
+ int pid;
g_autoptr(GString) command = g_string_new("");
g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
- qtest_add_abrt_handler(kill_qemu_hook_func, s);
-
if (!silence_spawn_log) {
g_test_message("starting QEMU: %s", command->str);
}
#ifndef _WIN32
- s->qemu_pid = fork();
- if (s->qemu_pid == 0) {
+ pid = fork();
+ if (pid == 0) {
#ifdef __linux__
/*
* Although we register a ABRT handler to kill off QEMU
@@ -447,10 +454,10 @@ static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
exit(1);
}
#else
- s->qemu_pid = qtest_create_process(command->str);
+ pid = qtest_create_process(command->str);
#endif /* _WIN32 */
- return s;
+ return qtest_create_test_state(pid);
}
static char *qtest_socket_path(const char *suffix)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (2 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 03/11] tests/qtest: qtest_create_test_state Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 14:57 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 05/11] tests/qtest: qtest_init_after_exec Steve Sistare
` (7 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Allow the qtest_qemu_spawn caller to pass the function to be called
to perform the spawn. The opaque argument is needed by a new spawn
function in a subsequent patch.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/libqtest.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 3fa9317..d97144e 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -418,7 +418,8 @@ static QTestState *qtest_create_test_state(int pid)
return s;
}
-static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
+static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args,
+ void *opaque)
{
int pid;
g_autoptr(GString) command = g_string_new("");
@@ -492,9 +493,15 @@ gchar *qtest_qemu_args(const char *extra_args)
return args;
}
+typedef QTestState *(*qtest_qemu_spawn_func)(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque);
+
static QTestState *qtest_init_internal(const char *qemu_bin,
const char *extra_args,
- bool do_connect)
+ bool do_connect,
+ qtest_qemu_spawn_func spawn,
+ void *opaque)
{
QTestState *s;
int sock, qmpsock, i;
@@ -515,7 +522,7 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- s = qtest_spawn_qemu(qemu_bin, args);
+ s = spawn(qemu_bin, args, opaque);
qtest_client_set_rx_handler(s, qtest_client_socket_recv_line);
qtest_client_set_tx_handler(s, qtest_client_socket_send);
@@ -570,7 +577,8 @@ void qtest_connect(QTestState *s)
QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
{
- return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true);
+ return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true,
+ qtest_spawn_qemu, NULL);
}
void qtest_qmp_handshake(QTestState *s, QList *capabilities)
@@ -593,7 +601,7 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
QList *capabilities, bool do_connect)
{
QTestState *s = qtest_init_internal(qtest_qemu_binary(var), extra_args,
- do_connect);
+ do_connect, qtest_spawn_qemu, NULL);
if (do_connect) {
qtest_qmp_handshake(s, capabilities);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 05/11] tests/qtest: qtest_init_after_exec
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (3 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 14:59 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 06/11] migration-test: only_source option Steve Sistare
` (6 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Define a function to create a QTestState object representing the state
of QEMU after old QEMU exec's new QEMU. This is needed for testing
the cpr-exec migration mode.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/libqtest.h | 8 ++++++++
tests/qtest/libqtest.c | 19 +++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index a164f58..ce6b9b0 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -57,6 +57,14 @@ QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
const char *qtest_qemu_binary(const char *var);
/**
+ * qtest_init_after_exec:
+ * @from: the previous QEMU state
+ *
+ * Return a test state representing new QEMU after @from exec's it.
+ */
+QTestState *qtest_init_after_exec(QTestState *from);
+
+/**
* qtest_qemu_args:
* @extra_args: Other arguments to pass to QEMU.
*
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index d97144e..3522d75 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -615,6 +615,25 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
return s;
}
+static QTestState *qtest_attach_qemu(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque)
+{
+ int pid = *(int *)opaque;
+ return qtest_create_test_state(pid);
+}
+
+QTestState *qtest_init_after_exec(QTestState *from)
+{
+ void *opaque = (void *)&from->qemu_pid;
+ QTestState *s;
+
+ s = qtest_init_internal(NULL, NULL, true, qtest_attach_qemu, opaque);
+ from->qemu_pid = -1;
+ qtest_qmp_handshake(s, NULL);
+ return s;
+}
+
QTestState *qtest_init(const char *extra_args)
{
return qtest_init_ext(NULL, extra_args, NULL, true);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 06/11] migration-test: only_source option
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (4 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 05/11] tests/qtest: qtest_init_after_exec Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 20:27 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 07/11] migration-test: shm path accessor Steve Sistare
` (5 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Add the only_source option, analogous to only_target.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/framework.h | 2 ++
tests/qtest/migration/framework.c | 24 +++++++++++++++---------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
index 01e425e..f1bb9d4 100644
--- a/tests/qtest/migration/framework.h
+++ b/tests/qtest/migration/framework.h
@@ -103,6 +103,8 @@ typedef struct {
*/
bool hide_stderr;
bool use_shmem;
+ /* only launch the source process */
+ bool only_source;
/* only launch the target process */
bool only_target;
/* Use dirty ring if true; dirty logging otherwise */
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 407c902..9564293 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -234,7 +234,7 @@ static void migrate_start_set_capabilities(QTestState *from, QTestState *to,
* to mimic as closer as that.
*/
migrate_set_capability(from, "events", true);
- if (!args->defer_target_connect) {
+ if (!args->defer_target_connect && to) {
migrate_set_capability(to, "events", true);
}
@@ -246,8 +246,10 @@ static void migrate_start_set_capabilities(QTestState *from, QTestState *to,
if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) {
migrate_set_parameter_int(from, "multifd-channels",
MULTIFD_TEST_CHANNELS);
- migrate_set_parameter_int(to, "multifd-channels",
- MULTIFD_TEST_CHANNELS);
+ if (to) {
+ migrate_set_parameter_int(to, "multifd-channels",
+ MULTIFD_TEST_CHANNELS);
+ }
}
return;
@@ -410,11 +412,13 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
shmem_opts ? shmem_opts : "",
args->opts_target ? args->opts_target : "",
ignore_stderr);
- *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
- !args->defer_target_connect);
- qtest_qmp_set_event_callback(*to,
- migrate_watch_for_events,
- &dst_state);
+ if (!args->only_source) {
+ *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
+ !args->defer_target_connect);
+ qtest_qmp_set_event_callback(*to,
+ migrate_watch_for_events,
+ &dst_state);
+ }
/*
* Remove shmem file immediately to avoid memory leak in test failed case.
@@ -424,7 +428,9 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
unlink(shmem_path);
}
- migrate_start_set_capabilities(*from, *to, args);
+ migrate_start_set_capabilities(*from,
+ args->only_source ? NULL : *to,
+ args);
return 0;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 07/11] migration-test: shm path accessor
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (5 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 06/11] migration-test: only_source option Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 20:28 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 08/11] migration-test: misc exports Steve Sistare
` (4 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Define an accessor for the shm path. It will be referenced from
multiple sites in a subsequent patch.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/framework.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 9564293..9d04f36 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -255,6 +255,11 @@ static void migrate_start_set_capabilities(QTestState *from, QTestState *to,
return;
}
+static char *test_shmem_path(void)
+{
+ return g_strdup_printf("/dev/shm/qemu-%d", getpid());
+}
+
int migrate_start(QTestState **from, QTestState **to, const char *uri,
MigrateStart *args)
{
@@ -342,7 +347,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
}
if (args->use_shmem) {
- shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
+ shmem_path = test_shmem_path();
shmem_opts = g_strdup_printf(
"-object memory-backend-file,id=mem0,size=%s"
",mem-path=%s,share=on -numa node,memdev=mem0",
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 08/11] migration-test: misc exports
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (6 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 07/11] migration-test: shm path accessor Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-19 14:12 ` [PATCH V1 09/11] migration-test: migrate_args Steve Sistare
` (3 subsequent siblings)
11 siblings, 0 replies; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Export misc definitions needed by the cpr-exec test.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/bootfile.h | 1 +
tests/qtest/migration/framework.h | 4 ++++
tests/qtest/migration/bootfile.c | 5 +++++
tests/qtest/migration/framework.c | 7 +++++--
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/tests/qtest/migration/bootfile.h b/tests/qtest/migration/bootfile.h
index 6d6a673..96e784b 100644
--- a/tests/qtest/migration/bootfile.h
+++ b/tests/qtest/migration/bootfile.h
@@ -35,5 +35,6 @@
void bootfile_delete(void);
char *bootfile_create(const char *arch, const char *dir, bool suspend_me);
+char *bootfile_get(void);
#endif /* BOOTFILE_H */
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
index f1bb9d4..7ff3187 100644
--- a/tests/qtest/migration/framework.h
+++ b/tests/qtest/migration/framework.h
@@ -18,6 +18,9 @@
#define FILE_TEST_OFFSET 0x1000
#define FILE_TEST_MARKER 'X'
+#define QEMU_ENV_SRC "QTEST_QEMU_BINARY_SRC"
+#define QEMU_ENV_DST "QTEST_QEMU_BINARY_DST"
+
typedef struct MigrationTestEnv {
bool has_kvm;
bool has_tcg;
@@ -237,6 +240,7 @@ void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
typedef struct QTestMigrationState QTestMigrationState;
QTestMigrationState *get_src(void);
+QTestMigrationState *get_dst(void);
#ifdef CONFIG_GNUTLS
void migration_test_add_tls(MigrationTestEnv *env);
diff --git a/tests/qtest/migration/bootfile.c b/tests/qtest/migration/bootfile.c
index fac059d..479c432 100644
--- a/tests/qtest/migration/bootfile.c
+++ b/tests/qtest/migration/bootfile.c
@@ -68,3 +68,8 @@ char *bootfile_create(const char *arch, const char *dir, bool suspend_me)
return bootpath;
}
+
+char *bootfile_get(void)
+{
+ return bootpath;
+}
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 9d04f36..8f9e359 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -28,8 +28,6 @@
#define QEMU_VM_FILE_MAGIC 0x5145564d
-#define QEMU_ENV_SRC "QTEST_QEMU_BINARY_SRC"
-#define QEMU_ENV_DST "QTEST_QEMU_BINARY_DST"
#define MULTIFD_TEST_CHANNELS 4
unsigned start_address;
@@ -1005,6 +1003,11 @@ QTestMigrationState *get_src(void)
return &src_state;
}
+QTestMigrationState *get_dst(void)
+{
+ return &dst_state;
+}
+
MigrationTestEnv *migration_get_env(void)
{
static MigrationTestEnv *env;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 09/11] migration-test: migrate_args
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (7 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 08/11] migration-test: misc exports Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-29 20:32 ` Fabiano Rosas
2025-09-30 19:51 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 10/11] migration-test: strv parameter Steve Sistare
` (2 subsequent siblings)
11 siblings, 2 replies; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Define the subroutine migrate_args to return the arguments that are
used to exec the source or target qemu process.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/framework.h | 2 ++
tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
2 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
index 7ff3187..51a8a7e 100644
--- a/tests/qtest/migration/framework.h
+++ b/tests/qtest/migration/framework.h
@@ -226,6 +226,8 @@ typedef struct {
void wait_for_serial(const char *side);
void migrate_prepare_for_dirty_mem(QTestState *from);
void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
+
+void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
int migrate_start(QTestState **from, QTestState **to, const char *uri,
MigrateStart *args);
void migrate_end(QTestState *from, QTestState *to, bool test_dest);
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 8f9e359..2dfb1ee 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -258,13 +258,12 @@ static char *test_shmem_path(void)
return g_strdup_printf("/dev/shm/qemu-%d", getpid());
}
-int migrate_start(QTestState **from, QTestState **to, const char *uri,
- MigrateStart *args)
+void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
{
/* options for source and target */
g_autofree gchar *arch_opts = NULL;
- g_autofree gchar *cmd_source = NULL;
- g_autofree gchar *cmd_target = NULL;
+ gchar *cmd_source = NULL;
+ gchar *cmd_target = NULL;
const gchar *ignore_stderr;
g_autofree char *shmem_opts = NULL;
g_autofree char *shmem_path = NULL;
@@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
const char *memory_size;
const char *machine_alias, *machine_opts = "";
g_autofree char *machine = NULL;
- const char *bootpath;
- g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
+ const char *bootpath = bootfile_get();
g_autofree char *memory_backend = NULL;
const char *events;
- if (args->use_shmem) {
- if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
- g_test_skip("/dev/shm is not supported");
- return -1;
- }
- }
-
- dst_state = (QTestMigrationState) { };
- src_state = (QTestMigrationState) { };
- bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
- src_state.suspend_me = args->suspend_me;
-
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
memory_size = "150M";
@@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
if (!qtest_has_machine(machine_alias)) {
g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
g_test_skip(msg);
- return -1;
+ return;
}
machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
@@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
shmem_opts ? shmem_opts : "",
args->opts_source ? args->opts_source : "",
ignore_stderr);
- if (!args->only_target) {
- *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
- qtest_qmp_set_event_callback(*from,
- migrate_watch_for_events,
- &src_state);
- }
/*
* If the monitor connection is deferred, enable events on the command line
@@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
shmem_opts ? shmem_opts : "",
args->opts_target ? args->opts_target : "",
ignore_stderr);
+
+ *from = cmd_source;
+ *to = cmd_target;
+}
+
+int migrate_start(QTestState **from, QTestState **to, const char *uri,
+ MigrateStart *args)
+{
+ g_autofree gchar *cmd_source = NULL;
+ g_autofree gchar *cmd_target = NULL;
+ g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
+
+ if (args->use_shmem) {
+ if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
+ g_test_skip("/dev/shm is not supported");
+ return -1;
+ }
+ }
+
+ dst_state = (QTestMigrationState) { };
+ src_state = (QTestMigrationState) { };
+ bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
+ src_state.suspend_me = args->suspend_me;
+
+ migrate_args(&cmd_source, &cmd_target, uri, args);
+
+ if (!args->only_target) {
+ *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
+ qtest_qmp_set_event_callback(*from,
+ migrate_watch_for_events,
+ &src_state);
+ }
+
if (!args->only_source) {
*to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
!args->defer_target_connect);
@@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
* It's valid because QEMU has already opened this file
*/
if (args->use_shmem) {
+ g_autofree char *shmem_path = test_shmem_path();
unlink(shmem_path);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 10/11] migration-test: strv parameter
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (8 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 09/11] migration-test: migrate_args Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-19 14:12 ` [PATCH V1 11/11] migration-test: test cpr-exec Steve Sistare
2025-09-30 14:35 ` [PATCH V1 00/11] cpr-exec test Fabiano Rosas
11 siblings, 0 replies; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Define migrate_set_parameter_strv.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/migration-qmp.h | 2 ++
tests/qtest/migration/migration-qmp.c | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/tests/qtest/migration/migration-qmp.h b/tests/qtest/migration/migration-qmp.h
index faa8181..44482d2 100644
--- a/tests/qtest/migration/migration-qmp.h
+++ b/tests/qtest/migration/migration-qmp.h
@@ -34,6 +34,8 @@ void read_blocktime(QTestState *who);
void wait_for_migration_pass(QTestState *who, QTestMigrationState *src_state);
void migrate_set_parameter_str(QTestState *who, const char *parameter,
const char *value);
+void migrate_set_parameter_strv(QTestState *who, const char *parameter,
+ char **strv);
void migrate_set_parameter_bool(QTestState *who, const char *parameter,
int value);
void migrate_ensure_non_converge(QTestState *who);
diff --git a/tests/qtest/migration/migration-qmp.c b/tests/qtest/migration/migration-qmp.c
index 66dd369..c803fce 100644
--- a/tests/qtest/migration/migration-qmp.c
+++ b/tests/qtest/migration/migration-qmp.c
@@ -442,6 +442,22 @@ void migrate_set_parameter_str(QTestState *who, const char *parameter,
migrate_check_parameter_str(who, parameter, value);
}
+void migrate_set_parameter_strv(QTestState *who, const char *parameter,
+ char **strv)
+{
+ g_autofree char *args = g_strjoinv("\",\"", strv);
+ g_autoptr(GString) value = g_string_new("");
+ g_autofree char *command = NULL;
+
+ g_string_printf(value, "\"%s\"", args);
+
+ command = g_strdup_printf("{ 'execute': 'migrate-set-parameters',"
+ "'arguments': { %%s: [ %s ]}}",
+ value->str);
+
+ qtest_qmp_assert_success(who, command, parameter);
+}
+
static long long migrate_get_parameter_bool(QTestState *who,
const char *parameter)
{
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH V1 11/11] migration-test: test cpr-exec
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (9 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 10/11] migration-test: strv parameter Steve Sistare
@ 2025-09-19 14:12 ` Steve Sistare
2025-09-30 17:08 ` Peter Xu
2025-09-30 14:35 ` [PATCH V1 00/11] cpr-exec test Fabiano Rosas
11 siblings, 1 reply; 30+ messages in thread
From: Steve Sistare @ 2025-09-19 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Peter Xu,
Steve Sistare
Add a test for the cpr-exec migration mode.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
index 5e764a6..f33af76 100644
--- a/tests/qtest/migration/cpr-tests.c
+++ b/tests/qtest/migration/cpr-tests.c
@@ -110,6 +110,125 @@ static void test_mode_transfer_defer(void)
test_mode_transfer_common(true);
}
+static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
+{
+ g_autofree char *qtest_from_args = NULL;
+ g_autofree char *from_args = NULL;
+ g_autofree char *to_args = NULL;
+ g_autofree char *exec_args = NULL;
+ g_auto(GStrv) argv = NULL;
+ char *from_str, *src, *dst;
+
+ args->start.hide_stderr = false; /* omit redirection word from args */
+ migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
+ qtest_from_args = qtest_qemu_args(from_args);
+
+ /* De-dup spaces so argv does not contain empty strings */
+ from_str = src = dst = g_strstrip(qtest_from_args);
+ do {
+ if (*src != ' ' || src[-1] != ' ') {
+ *dst++ = *src;
+ }
+ } while (*src++);
+
+ exec_args = g_strconcat(qtest_qemu_binary(QEMU_ENV_SRC),
+ " -incoming defer ", from_str, NULL);
+ argv = g_strsplit(exec_args, " ", -1);
+ migrate_set_parameter_strv(who, "cpr-exec-command", argv);
+}
+
+static void wait_for_migration_event(QTestState *who, const char *waitfor)
+{
+ QDict *rsp, *data;
+ char *status;
+ bool done = false;
+
+ while (!done) {
+ rsp = qtest_qmp_eventwait_ref(who, "MIGRATION");
+ g_assert(qdict_haskey(rsp, "data"));
+ data = qdict_get_qdict(rsp, "data");
+ g_assert(qdict_haskey(data, "status"));
+ status = g_strdup(qdict_get_str(data, "status"));
+ g_assert(strcmp(status, "failed"));
+ done = !strcmp(status, waitfor);
+ qobject_unref(rsp);
+ }
+}
+
+static void test_cpr_exec(MigrateCommon *args)
+{
+ QTestState *from, *to;
+ void *data_hook = NULL;
+ g_autofree char *connect_uri = g_strdup(args->connect_uri);
+ g_autofree char *filename = g_strdup_printf("%s/%s", tmpfs,
+ FILE_TEST_FILENAME);
+
+
+ if (migrate_start(&from, NULL, args->listen_uri, &args->start)) {
+ return;
+ }
+
+ /* Source and dest never run concurrently */
+ g_assert_false(args->live);
+
+ if (args->start_hook) {
+ data_hook = args->start_hook(from, NULL);
+ }
+
+ wait_for_serial("src_serial");
+ set_cpr_exec_args(from, args);
+ migrate_set_capability(from, "events", true);
+ migrate_qmp(from, NULL, connect_uri, NULL, "{}");
+ wait_for_migration_event(from, "completed");
+
+ to = qtest_init_after_exec(from);
+
+ qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
+ " 'arguments': { "
+ " 'channels': [ { 'channel-type': 'main',"
+ " 'addr': { 'transport': 'file',"
+ " 'filename': %s,"
+ " 'offset': 0 } } ] } }",
+ filename);
+ wait_for_migration_complete(to);
+
+ wait_for_resume(to, get_dst());
+ /* Device on target is still named src_serial because args do not change */
+ wait_for_serial("src_serial");
+
+ if (args->end_hook) {
+ args->end_hook(from, to, data_hook);
+ }
+
+ migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
+}
+
+static void *test_mode_exec_start(QTestState *from, QTestState *to)
+{
+ assert(!to);
+ migrate_set_parameter_str(from, "mode", "cpr-exec");
+ return NULL;
+}
+
+static void test_mode_exec(void)
+{
+ g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
+ FILE_TEST_FILENAME);
+ g_autofree char *listen_uri = g_strdup_printf("defer");
+
+ MigrateCommon args = {
+ .start.only_source = true,
+ .start.opts_source = "-machine aux-ram-share=on -nodefaults",
+ .start.memory_backend = "-object memory-backend-memfd,id=pc.ram,size=%s"
+ " -machine memory-backend=pc.ram",
+ .connect_uri = uri,
+ .listen_uri = listen_uri,
+ .start_hook = test_mode_exec_start,
+ };
+
+ test_cpr_exec(&args);
+}
+
void migration_test_add_cpr(MigrationTestEnv *env)
{
tmpfs = env->tmpfs;
@@ -132,5 +251,6 @@ void migration_test_add_cpr(MigrationTestEnv *env)
migration_test_add("/migration/mode/transfer", test_mode_transfer);
migration_test_add("/migration/mode/transfer/defer",
test_mode_transfer_defer);
+ migration_test_add("/migration/mode/exec", test_mode_exec);
}
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary
2025-09-19 14:12 ` [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary Steve Sistare
@ 2025-09-29 14:47 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 14:47 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
> tests/qtest/libqtest.h | 9 +++++++++
> tests/qtest/libqtest.c | 2 +-
> 2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
> index b3f2e7f..6d3199f 100644
> --- a/tests/qtest/libqtest.h
> +++ b/tests/qtest/libqtest.h
> @@ -48,6 +48,15 @@ QTestState *qtest_initf(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
> QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
>
> /**
> + * qtest_qemu_binary:
> + * @var: environment variable name
> + *
> + * Look up @var and return its value as the qemu binary path.
> + * If @var is NULL, look up the default var name.
> + */
> +const char *qtest_qemu_binary(const char *var);
> +
> +/**
> * qtest_init:
> * @extra_args: other arguments to pass to QEMU. CAUTION: these
> * arguments are subject to word splitting and shell evaluation.
> diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
> index f3d4e08..6f76be1 100644
> --- a/tests/qtest/libqtest.c
> +++ b/tests/qtest/libqtest.c
> @@ -357,7 +357,7 @@ void qtest_remove_abrt_handler(void *data)
> }
> }
>
> -static const char *qtest_qemu_binary(const char *var)
> +const char *qtest_qemu_binary(const char *var)
> {
> const char *qemu_bin;
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 02/11] tests/qtest: qtest_qemu_args
2025-09-19 14:12 ` [PATCH V1 02/11] tests/qtest: qtest_qemu_args Steve Sistare
@ 2025-09-29 14:51 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 14:51 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Define an accessor that returns all the arguments used to exec QEMU.
> Collect the arguments that were passed to qtest_spawn_qemu, plus the trace
> arguments that were composed inside qtest_spawn_qemu, and move them to a
> new function qtest_qemu_args.
>
> This will be needed to test the cpr-exec migration mode.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 03/11] tests/qtest: qtest_create_test_state
2025-09-19 14:12 ` [PATCH V1 03/11] tests/qtest: qtest_create_test_state Steve Sistare
@ 2025-09-29 14:52 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 14:52 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Refactor qtest_spawn_qemu and create a subroutine to create a QTestState
> object, to be used in a subsequent patch.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
> tests/qtest/libqtest.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
> index 551bc8c..3fa9317 100644
> --- a/tests/qtest/libqtest.c
> +++ b/tests/qtest/libqtest.c
> @@ -409,22 +409,29 @@ static pid_t qtest_create_process(char *cmd)
> }
> #endif /* _WIN32 */
>
> -static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
> +static QTestState *qtest_create_test_state(int pid)
> {
> QTestState *s = g_new0(QTestState, 1);
> +
> + s->qemu_pid = pid;
> + qtest_add_abrt_handler(kill_qemu_hook_func, s);
> + return s;
> +}
> +
> +static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
> +{
> + int pid;
> g_autoptr(GString) command = g_string_new("");
>
> g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
>
> - qtest_add_abrt_handler(kill_qemu_hook_func, s);
> -
> if (!silence_spawn_log) {
> g_test_message("starting QEMU: %s", command->str);
> }
>
> #ifndef _WIN32
> - s->qemu_pid = fork();
> - if (s->qemu_pid == 0) {
> + pid = fork();
> + if (pid == 0) {
> #ifdef __linux__
> /*
> * Although we register a ABRT handler to kill off QEMU
> @@ -447,10 +454,10 @@ static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args)
> exit(1);
> }
> #else
> - s->qemu_pid = qtest_create_process(command->str);
> + pid = qtest_create_process(command->str);
> #endif /* _WIN32 */
>
> - return s;
> + return qtest_create_test_state(pid);
> }
>
> static char *qtest_socket_path(const char *suffix)
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func
2025-09-19 14:12 ` [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func Steve Sistare
@ 2025-09-29 14:57 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 14:57 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Allow the qtest_qemu_spawn caller to pass the function to be called
> to perform the spawn. The opaque argument is needed by a new spawn
> function in a subsequent patch.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 05/11] tests/qtest: qtest_init_after_exec
2025-09-19 14:12 ` [PATCH V1 05/11] tests/qtest: qtest_init_after_exec Steve Sistare
@ 2025-09-29 14:59 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 14:59 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Define a function to create a QTestState object representing the state
> of QEMU after old QEMU exec's new QEMU. This is needed for testing
> the cpr-exec migration mode.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
> ---
> tests/qtest/libqtest.h | 8 ++++++++
> tests/qtest/libqtest.c | 19 +++++++++++++++++++
> 2 files changed, 27 insertions(+)
>
> diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
> index a164f58..ce6b9b0 100644
> --- a/tests/qtest/libqtest.h
> +++ b/tests/qtest/libqtest.h
> @@ -57,6 +57,14 @@ QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
> const char *qtest_qemu_binary(const char *var);
>
> /**
> + * qtest_init_after_exec:
> + * @from: the previous QEMU state
qts is the term used in libqtest. I'll amend it myself.
> + *
> + * Return a test state representing new QEMU after @from exec's it.
> + */
> +QTestState *qtest_init_after_exec(QTestState *from);
> +
> +/**
> * qtest_qemu_args:
> * @extra_args: Other arguments to pass to QEMU.
> *
> diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
> index d97144e..3522d75 100644
> --- a/tests/qtest/libqtest.c
> +++ b/tests/qtest/libqtest.c
> @@ -615,6 +615,25 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
> return s;
> }
>
> +static QTestState *qtest_attach_qemu(const char *qemu_bin,
> + const char *extra_args,
> + void *opaque)
> +{
> + int pid = *(int *)opaque;
> + return qtest_create_test_state(pid);
> +}
> +
> +QTestState *qtest_init_after_exec(QTestState *from)
> +{
> + void *opaque = (void *)&from->qemu_pid;
> + QTestState *s;
> +
> + s = qtest_init_internal(NULL, NULL, true, qtest_attach_qemu, opaque);
> + from->qemu_pid = -1;
> + qtest_qmp_handshake(s, NULL);
> + return s;
> +}
> +
> QTestState *qtest_init(const char *extra_args)
> {
> return qtest_init_ext(NULL, extra_args, NULL, true);
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 06/11] migration-test: only_source option
2025-09-19 14:12 ` [PATCH V1 06/11] migration-test: only_source option Steve Sistare
@ 2025-09-29 20:27 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 20:27 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Add the only_source option, analogous to only_target.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 07/11] migration-test: shm path accessor
2025-09-19 14:12 ` [PATCH V1 07/11] migration-test: shm path accessor Steve Sistare
@ 2025-09-29 20:28 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 20:28 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Define an accessor for the shm path. It will be referenced from
> multiple sites in a subsequent patch.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-19 14:12 ` [PATCH V1 09/11] migration-test: migrate_args Steve Sistare
@ 2025-09-29 20:32 ` Fabiano Rosas
2025-09-30 14:35 ` Steven Sistare
2025-09-30 19:51 ` Fabiano Rosas
1 sibling, 1 reply; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-29 20:32 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Define the subroutine migrate_args to return the arguments that are
> used to exec the source or target qemu process.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
> tests/qtest/migration/framework.h | 2 ++
> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
> 2 files changed, 41 insertions(+), 25 deletions(-)
>
> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
> index 7ff3187..51a8a7e 100644
> --- a/tests/qtest/migration/framework.h
> +++ b/tests/qtest/migration/framework.h
> @@ -226,6 +226,8 @@ typedef struct {
> void wait_for_serial(const char *side);
> void migrate_prepare_for_dirty_mem(QTestState *from);
> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
> +
> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
> int migrate_start(QTestState **from, QTestState **to, const char *uri,
> MigrateStart *args);
> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
> index 8f9e359..2dfb1ee 100644
> --- a/tests/qtest/migration/framework.c
> +++ b/tests/qtest/migration/framework.c
> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
> }
>
> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
> - MigrateStart *args)
> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
> {
> /* options for source and target */
> g_autofree gchar *arch_opts = NULL;
> - g_autofree gchar *cmd_source = NULL;
> - g_autofree gchar *cmd_target = NULL;
> + gchar *cmd_source = NULL;
> + gchar *cmd_target = NULL;
> const gchar *ignore_stderr;
> g_autofree char *shmem_opts = NULL;
> g_autofree char *shmem_path = NULL;
> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> const char *memory_size;
> const char *machine_alias, *machine_opts = "";
> g_autofree char *machine = NULL;
> - const char *bootpath;
> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
> + const char *bootpath = bootfile_get();
> g_autofree char *memory_backend = NULL;
> const char *events;
>
> - if (args->use_shmem) {
> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> - g_test_skip("/dev/shm is not supported");
> - return -1;
> - }
> - }
> -
> - dst_state = (QTestMigrationState) { };
> - src_state = (QTestMigrationState) { };
> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
> - src_state.suspend_me = args->suspend_me;
> -
> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
> memory_size = "150M";
>
> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> if (!qtest_has_machine(machine_alias)) {
> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
> g_test_skip(msg);
> - return -1;
> + return;
> }
>
> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> shmem_opts ? shmem_opts : "",
> args->opts_source ? args->opts_source : "",
> ignore_stderr);
> - if (!args->only_target) {
> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
> - qtest_qmp_set_event_callback(*from,
> - migrate_watch_for_events,
> - &src_state);
> - }
>
> /*
> * If the monitor connection is deferred, enable events on the command line
> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> shmem_opts ? shmem_opts : "",
> args->opts_target ? args->opts_target : "",
> ignore_stderr);
> +
> + *from = cmd_source;
> + *to = cmd_target;
> +}
> +
> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
> + MigrateStart *args)
> +{
> + g_autofree gchar *cmd_source = NULL;
> + g_autofree gchar *cmd_target = NULL;
> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
> +
> + if (args->use_shmem) {
> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> + g_test_skip("/dev/shm is not supported");
> + return -1;
> + }
> + }
> +
> + dst_state = (QTestMigrationState) { };
> + src_state = (QTestMigrationState) { };
> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
> + src_state.suspend_me = args->suspend_me;
I've been thinking of moving QTestState inside QTestMigrationState, so
these variables are not loosely kept without a accompanying
QTestState. When implementing ping-pong tests the current code got a bit
out of hand. Also the "src_serial" problem later on would be resolved by
a new qtms->serial.
What's stopping me at the moment is the amount of churn. If you spot a
better solution let be know.
> +
> + migrate_args(&cmd_source, &cmd_target, uri, args);
> +
> + if (!args->only_target) {
> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
> + qtest_qmp_set_event_callback(*from,
> + migrate_watch_for_events,
> + &src_state);
> + }
> +
> if (!args->only_source) {
> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
> !args->defer_target_connect);
> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> * It's valid because QEMU has already opened this file
> */
> if (args->use_shmem) {
> + g_autofree char *shmem_path = test_shmem_path();
> unlink(shmem_path);
> }
Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-29 20:32 ` Fabiano Rosas
@ 2025-09-30 14:35 ` Steven Sistare
0 siblings, 0 replies; 30+ messages in thread
From: Steven Sistare @ 2025-09-30 14:35 UTC (permalink / raw)
To: Fabiano Rosas, qemu-devel; +Cc: Laurent Vivier, Paolo Bonzini, Peter Xu
On 9/29/2025 4:32 PM, Fabiano Rosas wrote:
> Steve Sistare <steven.sistare@oracle.com> writes:
>
>> Define the subroutine migrate_args to return the arguments that are
>> used to exec the source or target qemu process.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> ---
>> tests/qtest/migration/framework.h | 2 ++
>> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
>> 2 files changed, 41 insertions(+), 25 deletions(-)
>>
>> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
>> index 7ff3187..51a8a7e 100644
>> --- a/tests/qtest/migration/framework.h
>> +++ b/tests/qtest/migration/framework.h
>> @@ -226,6 +226,8 @@ typedef struct {
>> void wait_for_serial(const char *side);
>> void migrate_prepare_for_dirty_mem(QTestState *from);
>> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
>> +
>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
>> int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> MigrateStart *args);
>> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
>> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
>> index 8f9e359..2dfb1ee 100644
>> --- a/tests/qtest/migration/framework.c
>> +++ b/tests/qtest/migration/framework.c
>> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
>> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
>> }
>>
>> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> - MigrateStart *args)
>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
>> {
>> /* options for source and target */
>> g_autofree gchar *arch_opts = NULL;
>> - g_autofree gchar *cmd_source = NULL;
>> - g_autofree gchar *cmd_target = NULL;
>> + gchar *cmd_source = NULL;
>> + gchar *cmd_target = NULL;
>> const gchar *ignore_stderr;
>> g_autofree char *shmem_opts = NULL;
>> g_autofree char *shmem_path = NULL;
>> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> const char *memory_size;
>> const char *machine_alias, *machine_opts = "";
>> g_autofree char *machine = NULL;
>> - const char *bootpath;
>> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>> + const char *bootpath = bootfile_get();
>> g_autofree char *memory_backend = NULL;
>> const char *events;
>>
>> - if (args->use_shmem) {
>> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>> - g_test_skip("/dev/shm is not supported");
>> - return -1;
>> - }
>> - }
>> -
>> - dst_state = (QTestMigrationState) { };
>> - src_state = (QTestMigrationState) { };
>> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
>> - src_state.suspend_me = args->suspend_me;
>> -
>> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
>> memory_size = "150M";
>>
>> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> if (!qtest_has_machine(machine_alias)) {
>> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
>> g_test_skip(msg);
>> - return -1;
>> + return;
>> }
>>
>> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
>> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> shmem_opts ? shmem_opts : "",
>> args->opts_source ? args->opts_source : "",
>> ignore_stderr);
>> - if (!args->only_target) {
>> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>> - qtest_qmp_set_event_callback(*from,
>> - migrate_watch_for_events,
>> - &src_state);
>> - }
>>
>> /*
>> * If the monitor connection is deferred, enable events on the command line
>> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> shmem_opts ? shmem_opts : "",
>> args->opts_target ? args->opts_target : "",
>> ignore_stderr);
>> +
>> + *from = cmd_source;
>> + *to = cmd_target;
>> +}
>> +
>> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> + MigrateStart *args)
>> +{
>> + g_autofree gchar *cmd_source = NULL;
>> + g_autofree gchar *cmd_target = NULL;
>> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>> +
>> + if (args->use_shmem) {
>> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>> + g_test_skip("/dev/shm is not supported");
>> + return -1;
>> + }
>> + }
>> +
>> + dst_state = (QTestMigrationState) { };
>> + src_state = (QTestMigrationState) { };
>> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
>> + src_state.suspend_me = args->suspend_me;
>
> I've been thinking of moving QTestState inside QTestMigrationState, so
> these variables are not loosely kept without a accompanying
> QTestState. When implementing ping-pong tests the current code got a bit
> out of hand. Also the "src_serial" problem later on would be resolved by
> a new qtms->serial.
>
> What's stopping me at the moment is the amount of churn. If you spot a
> better solution let be know.
I had the same thought, or having QTestMigrationState and QTestState point to
each other. Perhaps the latter would cause less churn.
Thanks very much for reviewing my patches!
- Steve
>
>> +
>> + migrate_args(&cmd_source, &cmd_target, uri, args);
>> +
>> + if (!args->only_target) {
>> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>> + qtest_qmp_set_event_callback(*from,
>> + migrate_watch_for_events,
>> + &src_state);
>> + }
>> +
>> if (!args->only_source) {
>> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
>> !args->defer_target_connect);
>> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> * It's valid because QEMU has already opened this file
>> */
>> if (args->use_shmem) {
>> + g_autofree char *shmem_path = test_shmem_path();
>> unlink(shmem_path);
>> }
>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 00/11] cpr-exec test
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
` (10 preceding siblings ...)
2025-09-19 14:12 ` [PATCH V1 11/11] migration-test: test cpr-exec Steve Sistare
@ 2025-09-30 14:35 ` Fabiano Rosas
11 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-30 14:35 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Add a migration test for cpr-exec mode.
> Depends on the patch series "Live update: cpr-exec".
>
> Steve Sistare (11):
> tests/qtest: export qtest_qemu_binary
> tests/qtest: qtest_qemu_args
> tests/qtest: qtest_create_test_state
> tests/qtest: qtest_qemu_spawn_func
> tests/qtest: qtest_init_after_exec
> migration-test: only_source option
> migration-test: shm path accessor
> migration-test: misc exports
> migration-test: migrate_args
> migration-test: strv parameter
> migration-test: test cpr-exec
>
> tests/qtest/libqtest.h | 25 +++++++
> tests/qtest/migration/bootfile.h | 1 +
> tests/qtest/migration/framework.h | 8 +++
> tests/qtest/migration/migration-qmp.h | 2 +
> tests/qtest/libqtest.c | 108 ++++++++++++++++++++----------
> tests/qtest/migration/bootfile.c | 5 ++
> tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++
> tests/qtest/migration/framework.c | 102 ++++++++++++++++++-----------
> tests/qtest/migration/migration-qmp.c | 16 +++++
> 9 files changed, 317 insertions(+), 70 deletions(-)
Queued up to patch 10 to qtest-next.
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 11/11] migration-test: test cpr-exec
2025-09-19 14:12 ` [PATCH V1 11/11] migration-test: test cpr-exec Steve Sistare
@ 2025-09-30 17:08 ` Peter Xu
2025-09-30 18:23 ` Steven Sistare
0 siblings, 1 reply; 30+ messages in thread
From: Peter Xu @ 2025-09-30 17:08 UTC (permalink / raw)
To: Steve Sistare; +Cc: qemu-devel, Fabiano Rosas, Laurent Vivier, Paolo Bonzini
On Fri, Sep 19, 2025 at 07:12:33AM -0700, Steve Sistare wrote:
> Add a test for the cpr-exec migration mode.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Looks good, only some nitpicks or pure questions below.
> ---
> tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 120 insertions(+)
>
> diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
> index 5e764a6..f33af76 100644
> --- a/tests/qtest/migration/cpr-tests.c
> +++ b/tests/qtest/migration/cpr-tests.c
> @@ -110,6 +110,125 @@ static void test_mode_transfer_defer(void)
> test_mode_transfer_common(true);
> }
>
> +static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
> +{
> + g_autofree char *qtest_from_args = NULL;
> + g_autofree char *from_args = NULL;
> + g_autofree char *to_args = NULL;
> + g_autofree char *exec_args = NULL;
> + g_auto(GStrv) argv = NULL;
> + char *from_str, *src, *dst;
> +
> + args->start.hide_stderr = false; /* omit redirection word from args */
It's default off, right? Could I request for some more explanations?
Could we also set it in test_mode_exec() directly if needed?
> + migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
> + qtest_from_args = qtest_qemu_args(from_args);
> +
> + /* De-dup spaces so argv does not contain empty strings */
> + from_str = src = dst = g_strstrip(qtest_from_args);
> + do {
> + if (*src != ' ' || src[-1] != ' ') {
> + *dst++ = *src;
> + }
> + } while (*src++);
Pure ask.. when will empty string be present?
> +
> + exec_args = g_strconcat(qtest_qemu_binary(QEMU_ENV_SRC),
Should this be QEMU_ENV_DST?
OTOH, we can use migration_get_env()->qemu_dst to reduce referencing global
vars.
> + " -incoming defer ", from_str, NULL);
> + argv = g_strsplit(exec_args, " ", -1);
> + migrate_set_parameter_strv(who, "cpr-exec-command", argv);
> +}
> +
> +static void wait_for_migration_event(QTestState *who, const char *waitfor)
> +{
> + QDict *rsp, *data;
> + char *status;
> + bool done = false;
> +
> + while (!done) {
> + rsp = qtest_qmp_eventwait_ref(who, "MIGRATION");
> + g_assert(qdict_haskey(rsp, "data"));
> + data = qdict_get_qdict(rsp, "data");
> + g_assert(qdict_haskey(data, "status"));
> + status = g_strdup(qdict_get_str(data, "status"));
> + g_assert(strcmp(status, "failed"));
> + done = !strcmp(status, waitfor);
> + qobject_unref(rsp);
> + }
> +}
> +
> +static void test_cpr_exec(MigrateCommon *args)
> +{
> + QTestState *from, *to;
> + void *data_hook = NULL;
> + g_autofree char *connect_uri = g_strdup(args->connect_uri);
> + g_autofree char *filename = g_strdup_printf("%s/%s", tmpfs,
> + FILE_TEST_FILENAME);
> +
> +
Newline can be dropped.
> + if (migrate_start(&from, NULL, args->listen_uri, &args->start)) {
> + return;
> + }
> +
> + /* Source and dest never run concurrently */
> + g_assert_false(args->live);
> +
> + if (args->start_hook) {
> + data_hook = args->start_hook(from, NULL);
> + }
> +
> + wait_for_serial("src_serial");
> + set_cpr_exec_args(from, args);
> + migrate_set_capability(from, "events", true);
> + migrate_qmp(from, NULL, connect_uri, NULL, "{}");
> + wait_for_migration_event(from, "completed");
> +
> + to = qtest_init_after_exec(from);
> +
> + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
> + " 'arguments': { "
> + " 'channels': [ { 'channel-type': 'main',"
> + " 'addr': { 'transport': 'file',"
> + " 'filename': %s,"
> + " 'offset': 0 } } ] } }",
> + filename);
> + wait_for_migration_complete(to);
> +
> + wait_for_resume(to, get_dst());
> + /* Device on target is still named src_serial because args do not change */
> + wait_for_serial("src_serial");
> +
> + if (args->end_hook) {
> + args->end_hook(from, to, data_hook);
> + }
> +
> + migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
> +}
> +
> +static void *test_mode_exec_start(QTestState *from, QTestState *to)
> +{
> + assert(!to);
> + migrate_set_parameter_str(from, "mode", "cpr-exec");
> + return NULL;
> +}
> +
> +static void test_mode_exec(void)
> +{
> + g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
> + FILE_TEST_FILENAME);
> + g_autofree char *listen_uri = g_strdup_printf("defer");
> +
> + MigrateCommon args = {
> + .start.only_source = true,
> + .start.opts_source = "-machine aux-ram-share=on -nodefaults",
> + .start.memory_backend = "-object memory-backend-memfd,id=pc.ram,size=%s"
> + " -machine memory-backend=pc.ram",
> + .connect_uri = uri,
> + .listen_uri = listen_uri,
> + .start_hook = test_mode_exec_start,
> + };
> +
> + test_cpr_exec(&args);
> +}
> +
> void migration_test_add_cpr(MigrationTestEnv *env)
> {
> tmpfs = env->tmpfs;
> @@ -132,5 +251,6 @@ void migration_test_add_cpr(MigrationTestEnv *env)
> migration_test_add("/migration/mode/transfer", test_mode_transfer);
> migration_test_add("/migration/mode/transfer/defer",
> test_mode_transfer_defer);
> + migration_test_add("/migration/mode/exec", test_mode_exec);
> }
> }
> --
> 1.8.3.1
>
--
Peter Xu
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 11/11] migration-test: test cpr-exec
2025-09-30 17:08 ` Peter Xu
@ 2025-09-30 18:23 ` Steven Sistare
2025-09-30 19:02 ` Peter Xu
0 siblings, 1 reply; 30+ messages in thread
From: Steven Sistare @ 2025-09-30 18:23 UTC (permalink / raw)
To: Peter Xu; +Cc: qemu-devel, Fabiano Rosas, Laurent Vivier, Paolo Bonzini
On 9/30/2025 1:08 PM, Peter Xu wrote:
> On Fri, Sep 19, 2025 at 07:12:33AM -0700, Steve Sistare wrote:
>> Add a test for the cpr-exec migration mode.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>
> Looks good, only some nitpicks or pure questions below.
>
>> ---
>> tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 120 insertions(+)
>>
>> diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
>> index 5e764a6..f33af76 100644
>> --- a/tests/qtest/migration/cpr-tests.c
>> +++ b/tests/qtest/migration/cpr-tests.c
>> @@ -110,6 +110,125 @@ static void test_mode_transfer_defer(void)
>> test_mode_transfer_common(true);
>> }
>>
>> +static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
>> +{
>> + g_autofree char *qtest_from_args = NULL;
>> + g_autofree char *from_args = NULL;
>> + g_autofree char *to_args = NULL;
>> + g_autofree char *exec_args = NULL;
>> + g_auto(GStrv) argv = NULL;
>> + char *from_str, *src, *dst;
>> +
>> + args->start.hide_stderr = false; /* omit redirection word from args */
>
> It's default off, right? Could I request for some more explanations?
Yes, the default is false, so I will omit this line. I will change it to
an assertion. (IIRC when I first wrote this code 1-2 years ago, the cpr-exec
test was a derivative of a precopy common test that set hide_stderr=true).
hide_stderr must be false when deriving cpr-exec arguments because of
this code in framework.c:
if (!getenv("QTEST_LOG") && args->hide_stderr) {
ignore_stderr = "2>/dev/null";
ignore_stderr is appended to the command line. For cpr-exec the command line
may not include redirection, because we pass it to execv(), not to the shell.
> Could we also set it in test_mode_exec() directly if needed?
Yes, one can set hide_stderr when launching the source VM.
>> + migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
>> + qtest_from_args = qtest_qemu_args(from_args);
>> +
>> + /* De-dup spaces so argv does not contain empty strings */
>> + from_str = src = dst = g_strstrip(qtest_from_args);
>> + do {
>> + if (*src != ' ' || src[-1] != ' ') {
>> + *dst++ = *src;
>> + }
>> + } while (*src++);
>
> Pure ask.. when will empty string be present?
migrate_args() format strings "%s %s %s" produce " " when the arguments
are empty strings. Then g_strsplit(" ") would produce an array of 3
empty strings.
>> +
>> + exec_args = g_strconcat(qtest_qemu_binary(QEMU_ENV_SRC),
>
> Should this be QEMU_ENV_DST?
Good catch, thanks, will fix.
> OTOH, we can use migration_get_env()->qemu_dst to reduce referencing global
> vars.
OK, that works.
>> + " -incoming defer ", from_str, NULL);
>> + argv = g_strsplit(exec_args, " ", -1);
>> + migrate_set_parameter_strv(who, "cpr-exec-command", argv);
>> +}
>> +
>> +static void wait_for_migration_event(QTestState *who, const char *waitfor)
>> +{
>> + QDict *rsp, *data;
>> + char *status;
>> + bool done = false;
>> +
>> + while (!done) {
>> + rsp = qtest_qmp_eventwait_ref(who, "MIGRATION");
>> + g_assert(qdict_haskey(rsp, "data"));
>> + data = qdict_get_qdict(rsp, "data");
>> + g_assert(qdict_haskey(data, "status"));
>> + status = g_strdup(qdict_get_str(data, "status"));
>> + g_assert(strcmp(status, "failed"));
>> + done = !strcmp(status, waitfor);
>> + qobject_unref(rsp);
>> + }
>> +}
>> +
>> +static void test_cpr_exec(MigrateCommon *args)
>> +{
>> + QTestState *from, *to;
>> + void *data_hook = NULL;
>> + g_autofree char *connect_uri = g_strdup(args->connect_uri);
>> + g_autofree char *filename = g_strdup_printf("%s/%s", tmpfs,
>> + FILE_TEST_FILENAME);
>> +
>> +
>
> Newline can be dropped.
OK.
- Steve
>> + if (migrate_start(&from, NULL, args->listen_uri, &args->start)) {
>> + return;
>> + }
>> +
>> + /* Source and dest never run concurrently */
>> + g_assert_false(args->live);
>> +
>> + if (args->start_hook) {
>> + data_hook = args->start_hook(from, NULL);
>> + }
>> +
>> + wait_for_serial("src_serial");
>> + set_cpr_exec_args(from, args);
>> + migrate_set_capability(from, "events", true);
>> + migrate_qmp(from, NULL, connect_uri, NULL, "{}");
>> + wait_for_migration_event(from, "completed");
>> +
>> + to = qtest_init_after_exec(from);
>> +
>> + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
>> + " 'arguments': { "
>> + " 'channels': [ { 'channel-type': 'main',"
>> + " 'addr': { 'transport': 'file',"
>> + " 'filename': %s,"
>> + " 'offset': 0 } } ] } }",
>> + filename);
>> + wait_for_migration_complete(to);
>> +
>> + wait_for_resume(to, get_dst());
>> + /* Device on target is still named src_serial because args do not change */
>> + wait_for_serial("src_serial");
>> +
>> + if (args->end_hook) {
>> + args->end_hook(from, to, data_hook);
>> + }
>> +
>> + migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
>> +}
>> +
>> +static void *test_mode_exec_start(QTestState *from, QTestState *to)
>> +{
>> + assert(!to);
>> + migrate_set_parameter_str(from, "mode", "cpr-exec");
>> + return NULL;
>> +}
>> +
>> +static void test_mode_exec(void)
>> +{
>> + g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
>> + FILE_TEST_FILENAME);
>> + g_autofree char *listen_uri = g_strdup_printf("defer");
>> +
>> + MigrateCommon args = {
>> + .start.only_source = true,
>> + .start.opts_source = "-machine aux-ram-share=on -nodefaults",
>> + .start.memory_backend = "-object memory-backend-memfd,id=pc.ram,size=%s"
>> + " -machine memory-backend=pc.ram",
>> + .connect_uri = uri,
>> + .listen_uri = listen_uri,
>> + .start_hook = test_mode_exec_start,
>> + };
>> +
>> + test_cpr_exec(&args);
>> +}
>> +
>> void migration_test_add_cpr(MigrationTestEnv *env)
>> {
>> tmpfs = env->tmpfs;
>> @@ -132,5 +251,6 @@ void migration_test_add_cpr(MigrationTestEnv *env)
>> migration_test_add("/migration/mode/transfer", test_mode_transfer);
>> migration_test_add("/migration/mode/transfer/defer",
>> test_mode_transfer_defer);
>> + migration_test_add("/migration/mode/exec", test_mode_exec);
>> }
>> }
>> --
>> 1.8.3.1
>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 11/11] migration-test: test cpr-exec
2025-09-30 18:23 ` Steven Sistare
@ 2025-09-30 19:02 ` Peter Xu
2025-09-30 19:07 ` Steven Sistare
0 siblings, 1 reply; 30+ messages in thread
From: Peter Xu @ 2025-09-30 19:02 UTC (permalink / raw)
To: Steven Sistare; +Cc: qemu-devel, Fabiano Rosas, Laurent Vivier, Paolo Bonzini
On Tue, Sep 30, 2025 at 02:23:49PM -0400, Steven Sistare wrote:
> On 9/30/2025 1:08 PM, Peter Xu wrote:
> > On Fri, Sep 19, 2025 at 07:12:33AM -0700, Steve Sistare wrote:
> > > Add a test for the cpr-exec migration mode.
> > >
> > > Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> >
> > Looks good, only some nitpicks or pure questions below.
> >
> > > ---
> > > tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 120 insertions(+)
> > >
> > > diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
> > > index 5e764a6..f33af76 100644
> > > --- a/tests/qtest/migration/cpr-tests.c
> > > +++ b/tests/qtest/migration/cpr-tests.c
> > > @@ -110,6 +110,125 @@ static void test_mode_transfer_defer(void)
> > > test_mode_transfer_common(true);
> > > }
> > > +static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
> > > +{
> > > + g_autofree char *qtest_from_args = NULL;
> > > + g_autofree char *from_args = NULL;
> > > + g_autofree char *to_args = NULL;
> > > + g_autofree char *exec_args = NULL;
> > > + g_auto(GStrv) argv = NULL;
> > > + char *from_str, *src, *dst;
> > > +
> > > + args->start.hide_stderr = false; /* omit redirection word from args */
> >
> > It's default off, right? Could I request for some more explanations?
>
> Yes, the default is false, so I will omit this line. I will change it to
> an assertion. (IIRC when I first wrote this code 1-2 years ago, the cpr-exec
> test was a derivative of a precopy common test that set hide_stderr=true).
>
> hide_stderr must be false when deriving cpr-exec arguments because of
> this code in framework.c:
>
> if (!getenv("QTEST_LOG") && args->hide_stderr) {
> ignore_stderr = "2>/dev/null";
>
> ignore_stderr is appended to the command line. For cpr-exec the command line
> may not include redirection, because we pass it to execv(), not to the shell.
Please kindly add this rich comment above the assertion..
>
> > Could we also set it in test_mode_exec() directly if needed?
>
> Yes, one can set hide_stderr when launching the source VM.
>
> > > + migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
> > > + qtest_from_args = qtest_qemu_args(from_args);
> > > +
> > > + /* De-dup spaces so argv does not contain empty strings */
> > > + from_str = src = dst = g_strstrip(qtest_from_args);
> > > + do {
> > > + if (*src != ' ' || src[-1] != ' ') {
> > > + *dst++ = *src;
> > > + }
> > > + } while (*src++);
> >
> > Pure ask.. when will empty string be present?
>
> migrate_args() format strings "%s %s %s" produce " " when the arguments
> are empty strings. Then g_strsplit(" ") would produce an array of 3
> empty strings.
... and here too.
Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 11/11] migration-test: test cpr-exec
2025-09-30 19:02 ` Peter Xu
@ 2025-09-30 19:07 ` Steven Sistare
0 siblings, 0 replies; 30+ messages in thread
From: Steven Sistare @ 2025-09-30 19:07 UTC (permalink / raw)
To: Peter Xu; +Cc: qemu-devel, Fabiano Rosas, Laurent Vivier, Paolo Bonzini
On 9/30/2025 3:02 PM, Peter Xu wrote:
> On Tue, Sep 30, 2025 at 02:23:49PM -0400, Steven Sistare wrote:
>> On 9/30/2025 1:08 PM, Peter Xu wrote:
>>> On Fri, Sep 19, 2025 at 07:12:33AM -0700, Steve Sistare wrote:
>>>> Add a test for the cpr-exec migration mode.
>>>>
>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>
>>> Looks good, only some nitpicks or pure questions below.
>>>
>>>> ---
>>>> tests/qtest/migration/cpr-tests.c | 120 ++++++++++++++++++++++++++++++++++++++
>>>> 1 file changed, 120 insertions(+)
>>>>
>>>> diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
>>>> index 5e764a6..f33af76 100644
>>>> --- a/tests/qtest/migration/cpr-tests.c
>>>> +++ b/tests/qtest/migration/cpr-tests.c
>>>> @@ -110,6 +110,125 @@ static void test_mode_transfer_defer(void)
>>>> test_mode_transfer_common(true);
>>>> }
>>>> +static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
>>>> +{
>>>> + g_autofree char *qtest_from_args = NULL;
>>>> + g_autofree char *from_args = NULL;
>>>> + g_autofree char *to_args = NULL;
>>>> + g_autofree char *exec_args = NULL;
>>>> + g_auto(GStrv) argv = NULL;
>>>> + char *from_str, *src, *dst;
>>>> +
>>>> + args->start.hide_stderr = false; /* omit redirection word from args */
>>>
>>> It's default off, right? Could I request for some more explanations?
>>
>> Yes, the default is false, so I will omit this line. I will change it to
>> an assertion. (IIRC when I first wrote this code 1-2 years ago, the cpr-exec
>> test was a derivative of a precopy common test that set hide_stderr=true).
>>
>> hide_stderr must be false when deriving cpr-exec arguments because of
>> this code in framework.c:
>>
>> if (!getenv("QTEST_LOG") && args->hide_stderr) {
>> ignore_stderr = "2>/dev/null";
>>
>> ignore_stderr is appended to the command line. For cpr-exec the command line
>> may not include redirection, because we pass it to execv(), not to the shell.
>
> Please kindly add this rich comment above the assertion..
will do.
>
>>
>>> Could we also set it in test_mode_exec() directly if needed?
>>
>> Yes, one can set hide_stderr when launching the source VM.
>>
>>>> + migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
>>>> + qtest_from_args = qtest_qemu_args(from_args);
>>>> +
>>>> + /* De-dup spaces so argv does not contain empty strings */
>>>> + from_str = src = dst = g_strstrip(qtest_from_args);
>>>> + do {
>>>> + if (*src != ' ' || src[-1] != ' ') {
>>>> + *dst++ = *src;
>>>> + }
>>>> + } while (*src++);
>>>
>>> Pure ask.. when will empty string be present?
>>
>> migrate_args() format strings "%s %s %s" produce " " when the arguments
>> are empty strings. Then g_strsplit(" ") would produce an array of 3
>> empty strings.
>
> ... and here too.
will do.
- Steve
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-19 14:12 ` [PATCH V1 09/11] migration-test: migrate_args Steve Sistare
2025-09-29 20:32 ` Fabiano Rosas
@ 2025-09-30 19:51 ` Fabiano Rosas
2025-09-30 19:59 ` Steven Sistare
1 sibling, 1 reply; 30+ messages in thread
From: Fabiano Rosas @ 2025-09-30 19:51 UTC (permalink / raw)
To: Steve Sistare, qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Peter Xu, Steve Sistare
Steve Sistare <steven.sistare@oracle.com> writes:
> Define the subroutine migrate_args to return the arguments that are
> used to exec the source or target qemu process.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
> tests/qtest/migration/framework.h | 2 ++
> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
> 2 files changed, 41 insertions(+), 25 deletions(-)
>
> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
> index 7ff3187..51a8a7e 100644
> --- a/tests/qtest/migration/framework.h
> +++ b/tests/qtest/migration/framework.h
> @@ -226,6 +226,8 @@ typedef struct {
> void wait_for_serial(const char *side);
> void migrate_prepare_for_dirty_mem(QTestState *from);
> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
> +
> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
> int migrate_start(QTestState **from, QTestState **to, const char *uri,
> MigrateStart *args);
> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
> index 8f9e359..2dfb1ee 100644
> --- a/tests/qtest/migration/framework.c
> +++ b/tests/qtest/migration/framework.c
> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
> }
>
> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
> - MigrateStart *args)
> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
> {
> /* options for source and target */
> g_autofree gchar *arch_opts = NULL;
> - g_autofree gchar *cmd_source = NULL;
> - g_autofree gchar *cmd_target = NULL;
> + gchar *cmd_source = NULL;
> + gchar *cmd_target = NULL;
> const gchar *ignore_stderr;
> g_autofree char *shmem_opts = NULL;
> g_autofree char *shmem_path = NULL;
> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> const char *memory_size;
> const char *machine_alias, *machine_opts = "";
> g_autofree char *machine = NULL;
> - const char *bootpath;
> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
> + const char *bootpath = bootfile_get();
> g_autofree char *memory_backend = NULL;
> const char *events;
>
> - if (args->use_shmem) {
> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> - g_test_skip("/dev/shm is not supported");
> - return -1;
> - }
> - }
> -
> - dst_state = (QTestMigrationState) { };
> - src_state = (QTestMigrationState) { };
> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
> - src_state.suspend_me = args->suspend_me;
> -
> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
> memory_size = "150M";
>
> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> if (!qtest_has_machine(machine_alias)) {
> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
> g_test_skip(msg);
> - return -1;
> + return;
A common pitfall is that g_test_skip() doesn't actually ends the
test. The -1 needs to be propagated up, otherwise the test will proceed
with the unsupported machine.
> }
>
> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> shmem_opts ? shmem_opts : "",
> args->opts_source ? args->opts_source : "",
> ignore_stderr);
> - if (!args->only_target) {
> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
> - qtest_qmp_set_event_callback(*from,
> - migrate_watch_for_events,
> - &src_state);
> - }
>
> /*
> * If the monitor connection is deferred, enable events on the command line
> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> shmem_opts ? shmem_opts : "",
> args->opts_target ? args->opts_target : "",
> ignore_stderr);
> +
> + *from = cmd_source;
> + *to = cmd_target;
> +}
> +
> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
> + MigrateStart *args)
> +{
> + g_autofree gchar *cmd_source = NULL;
> + g_autofree gchar *cmd_target = NULL;
> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
> +
> + if (args->use_shmem) {
> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> + g_test_skip("/dev/shm is not supported");
> + return -1;
> + }
> + }
> +
> + dst_state = (QTestMigrationState) { };
> + src_state = (QTestMigrationState) { };
> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
> + src_state.suspend_me = args->suspend_me;
> +
> + migrate_args(&cmd_source, &cmd_target, uri, args);
> +
> + if (!args->only_target) {
> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
> + qtest_qmp_set_event_callback(*from,
> + migrate_watch_for_events,
> + &src_state);
> + }
> +
> if (!args->only_source) {
> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
> !args->defer_target_connect);
> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
> * It's valid because QEMU has already opened this file
> */
> if (args->use_shmem) {
> + g_autofree char *shmem_path = test_shmem_path();
> unlink(shmem_path);
> }
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-30 19:51 ` Fabiano Rosas
@ 2025-09-30 19:59 ` Steven Sistare
2025-09-30 21:14 ` Steven Sistare
0 siblings, 1 reply; 30+ messages in thread
From: Steven Sistare @ 2025-09-30 19:59 UTC (permalink / raw)
To: Fabiano Rosas, qemu-devel; +Cc: Laurent Vivier, Paolo Bonzini, Peter Xu
On 9/30/2025 3:51 PM, Fabiano Rosas wrote:
> Steve Sistare <steven.sistare@oracle.com> writes:
>
>> Define the subroutine migrate_args to return the arguments that are
>> used to exec the source or target qemu process.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> ---
>> tests/qtest/migration/framework.h | 2 ++
>> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
>> 2 files changed, 41 insertions(+), 25 deletions(-)
>>
>> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
>> index 7ff3187..51a8a7e 100644
>> --- a/tests/qtest/migration/framework.h
>> +++ b/tests/qtest/migration/framework.h
>> @@ -226,6 +226,8 @@ typedef struct {
>> void wait_for_serial(const char *side);
>> void migrate_prepare_for_dirty_mem(QTestState *from);
>> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
>> +
>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
>> int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> MigrateStart *args);
>> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
>> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
>> index 8f9e359..2dfb1ee 100644
>> --- a/tests/qtest/migration/framework.c
>> +++ b/tests/qtest/migration/framework.c
>> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
>> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
>> }
>>
>> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> - MigrateStart *args)
>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
>> {
>> /* options for source and target */
>> g_autofree gchar *arch_opts = NULL;
>> - g_autofree gchar *cmd_source = NULL;
>> - g_autofree gchar *cmd_target = NULL;
>> + gchar *cmd_source = NULL;
>> + gchar *cmd_target = NULL;
>> const gchar *ignore_stderr;
>> g_autofree char *shmem_opts = NULL;
>> g_autofree char *shmem_path = NULL;
>> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> const char *memory_size;
>> const char *machine_alias, *machine_opts = "";
>> g_autofree char *machine = NULL;
>> - const char *bootpath;
>> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>> + const char *bootpath = bootfile_get();
>> g_autofree char *memory_backend = NULL;
>> const char *events;
>>
>> - if (args->use_shmem) {
>> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>> - g_test_skip("/dev/shm is not supported");
>> - return -1;
>> - }
>> - }
>> -
>> - dst_state = (QTestMigrationState) { };
>> - src_state = (QTestMigrationState) { };
>> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
>> - src_state.suspend_me = args->suspend_me;
>> -
>> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
>> memory_size = "150M";
>>
>> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> if (!qtest_has_machine(machine_alias)) {
>> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
>> g_test_skip(msg);
>> - return -1;
>> + return;
>
> A common pitfall is that g_test_skip() doesn't actually ends the
> test. The -1 needs to be propagated up, otherwise the test will proceed
> with the unsupported machine.
Thanks.
migrate_args() will return an error code.
I'll send a V2 of this patch, and fix the call to migrate_args in patch
"cpr-exec test".
- Steve
>
>> }
>>
>> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
>> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> shmem_opts ? shmem_opts : "",
>> args->opts_source ? args->opts_source : "",
>> ignore_stderr);
>> - if (!args->only_target) {
>> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>> - qtest_qmp_set_event_callback(*from,
>> - migrate_watch_for_events,
>> - &src_state);
>> - }
>>
>> /*
>> * If the monitor connection is deferred, enable events on the command line
>> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> shmem_opts ? shmem_opts : "",
>> args->opts_target ? args->opts_target : "",
>> ignore_stderr);
>> +
>> + *from = cmd_source;
>> + *to = cmd_target;
>> +}
>> +
>> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> + MigrateStart *args)
>> +{
>> + g_autofree gchar *cmd_source = NULL;
>> + g_autofree gchar *cmd_target = NULL;
>> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>> +
>> + if (args->use_shmem) {
>> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>> + g_test_skip("/dev/shm is not supported");
>> + return -1;
>> + }
>> + }
>> +
>> + dst_state = (QTestMigrationState) { };
>> + src_state = (QTestMigrationState) { };
>> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
>> + src_state.suspend_me = args->suspend_me;
>> +
>> + migrate_args(&cmd_source, &cmd_target, uri, args);
>> +
>> + if (!args->only_target) {
>> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>> + qtest_qmp_set_event_callback(*from,
>> + migrate_watch_for_events,
>> + &src_state);
>> + }
>> +
>> if (!args->only_source) {
>> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
>> !args->defer_target_connect);
>> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>> * It's valid because QEMU has already opened this file
>> */
>> if (args->use_shmem) {
>> + g_autofree char *shmem_path = test_shmem_path();
>> unlink(shmem_path);
>> }
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-30 19:59 ` Steven Sistare
@ 2025-09-30 21:14 ` Steven Sistare
2025-10-01 12:16 ` Fabiano Rosas
0 siblings, 1 reply; 30+ messages in thread
From: Steven Sistare @ 2025-09-30 21:14 UTC (permalink / raw)
To: Fabiano Rosas, qemu-devel; +Cc: Laurent Vivier, Paolo Bonzini, Peter Xu
On 9/30/2025 3:59 PM, Steven Sistare wrote:
> On 9/30/2025 3:51 PM, Fabiano Rosas wrote:
>> Steve Sistare <steven.sistare@oracle.com> writes:
>>
>>> Define the subroutine migrate_args to return the arguments that are
>>> used to exec the source or target qemu process.
>>>
>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>> ---
>>> tests/qtest/migration/framework.h | 2 ++
>>> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
>>> 2 files changed, 41 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
>>> index 7ff3187..51a8a7e 100644
>>> --- a/tests/qtest/migration/framework.h
>>> +++ b/tests/qtest/migration/framework.h
>>> @@ -226,6 +226,8 @@ typedef struct {
>>> void wait_for_serial(const char *side);
>>> void migrate_prepare_for_dirty_mem(QTestState *from);
>>> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
>>> +
>>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
>>> int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> MigrateStart *args);
>>> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
>>> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
>>> index 8f9e359..2dfb1ee 100644
>>> --- a/tests/qtest/migration/framework.c
>>> +++ b/tests/qtest/migration/framework.c
>>> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
>>> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
>>> }
>>> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> - MigrateStart *args)
>>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
>>> {
>>> /* options for source and target */
>>> g_autofree gchar *arch_opts = NULL;
>>> - g_autofree gchar *cmd_source = NULL;
>>> - g_autofree gchar *cmd_target = NULL;
>>> + gchar *cmd_source = NULL;
>>> + gchar *cmd_target = NULL;
>>> const gchar *ignore_stderr;
>>> g_autofree char *shmem_opts = NULL;
>>> g_autofree char *shmem_path = NULL;
>>> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> const char *memory_size;
>>> const char *machine_alias, *machine_opts = "";
>>> g_autofree char *machine = NULL;
>>> - const char *bootpath;
>>> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>>> + const char *bootpath = bootfile_get();
>>> g_autofree char *memory_backend = NULL;
>>> const char *events;
>>> - if (args->use_shmem) {
>>> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>>> - g_test_skip("/dev/shm is not supported");
>>> - return -1;
>>> - }
>>> - }
>>> -
>>> - dst_state = (QTestMigrationState) { };
>>> - src_state = (QTestMigrationState) { };
>>> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
>>> - src_state.suspend_me = args->suspend_me;
>>> -
>>> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
>>> memory_size = "150M";
>>> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> if (!qtest_has_machine(machine_alias)) {
>>> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
>>> g_test_skip(msg);
>>> - return -1;
>>> + return;
>>
>> A common pitfall is that g_test_skip() doesn't actually ends the
>> test. The -1 needs to be propagated up, otherwise the test will proceed
>> with the unsupported machine.
>
> Thanks.
> migrate_args() will return an error code.
> I'll send a V2 of this patch,
Do you prefer I send a patch with just the fix, if you have already
pulled the patches into your tree?
- Steve
> and fix the call to migrate_args in patch
> "cpr-exec test".
>
> - Steve
>
>>
>>> }
>>> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
>>> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> shmem_opts ? shmem_opts : "",
>>> args->opts_source ? args->opts_source : "",
>>> ignore_stderr);
>>> - if (!args->only_target) {
>>> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>>> - qtest_qmp_set_event_callback(*from,
>>> - migrate_watch_for_events,
>>> - &src_state);
>>> - }
>>> /*
>>> * If the monitor connection is deferred, enable events on the command line
>>> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> shmem_opts ? shmem_opts : "",
>>> args->opts_target ? args->opts_target : "",
>>> ignore_stderr);
>>> +
>>> + *from = cmd_source;
>>> + *to = cmd_target;
>>> +}
>>> +
>>> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> + MigrateStart *args)
>>> +{
>>> + g_autofree gchar *cmd_source = NULL;
>>> + g_autofree gchar *cmd_target = NULL;
>>> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>>> +
>>> + if (args->use_shmem) {
>>> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>>> + g_test_skip("/dev/shm is not supported");
>>> + return -1;
>>> + }
>>> + }
>>> +
>>> + dst_state = (QTestMigrationState) { };
>>> + src_state = (QTestMigrationState) { };
>>> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
>>> + src_state.suspend_me = args->suspend_me;
>>> +
>>> + migrate_args(&cmd_source, &cmd_target, uri, args);
>>> +
>>> + if (!args->only_target) {
>>> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>>> + qtest_qmp_set_event_callback(*from,
>>> + migrate_watch_for_events,
>>> + &src_state);
>>> + }
>>> +
>>> if (!args->only_source) {
>>> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
>>> !args->defer_target_connect);
>>> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>> * It's valid because QEMU has already opened this file
>>> */
>>> if (args->use_shmem) {
>>> + g_autofree char *shmem_path = test_shmem_path();
>>> unlink(shmem_path);
>>> }
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH V1 09/11] migration-test: migrate_args
2025-09-30 21:14 ` Steven Sistare
@ 2025-10-01 12:16 ` Fabiano Rosas
0 siblings, 0 replies; 30+ messages in thread
From: Fabiano Rosas @ 2025-10-01 12:16 UTC (permalink / raw)
To: Steven Sistare, qemu-devel; +Cc: Laurent Vivier, Paolo Bonzini, Peter Xu
Steven Sistare <steven.sistare@oracle.com> writes:
> On 9/30/2025 3:59 PM, Steven Sistare wrote:
>> On 9/30/2025 3:51 PM, Fabiano Rosas wrote:
>>> Steve Sistare <steven.sistare@oracle.com> writes:
>>>
>>>> Define the subroutine migrate_args to return the arguments that are
>>>> used to exec the source or target qemu process.
>>>>
>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>> ---
>>>> tests/qtest/migration/framework.h | 2 ++
>>>> tests/qtest/migration/framework.c | 64 ++++++++++++++++++++++++---------------
>>>> 2 files changed, 41 insertions(+), 25 deletions(-)
>>>>
>>>> diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
>>>> index 7ff3187..51a8a7e 100644
>>>> --- a/tests/qtest/migration/framework.h
>>>> +++ b/tests/qtest/migration/framework.h
>>>> @@ -226,6 +226,8 @@ typedef struct {
>>>> void wait_for_serial(const char *side);
>>>> void migrate_prepare_for_dirty_mem(QTestState *from);
>>>> void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
>>>> +
>>>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
>>>> int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> MigrateStart *args);
>>>> void migrate_end(QTestState *from, QTestState *to, bool test_dest);
>>>> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
>>>> index 8f9e359..2dfb1ee 100644
>>>> --- a/tests/qtest/migration/framework.c
>>>> +++ b/tests/qtest/migration/framework.c
>>>> @@ -258,13 +258,12 @@ static char *test_shmem_path(void)
>>>> return g_strdup_printf("/dev/shm/qemu-%d", getpid());
>>>> }
>>>> -int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> - MigrateStart *args)
>>>> +void migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
>>>> {
>>>> /* options for source and target */
>>>> g_autofree gchar *arch_opts = NULL;
>>>> - g_autofree gchar *cmd_source = NULL;
>>>> - g_autofree gchar *cmd_target = NULL;
>>>> + gchar *cmd_source = NULL;
>>>> + gchar *cmd_target = NULL;
>>>> const gchar *ignore_stderr;
>>>> g_autofree char *shmem_opts = NULL;
>>>> g_autofree char *shmem_path = NULL;
>>>> @@ -273,23 +272,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> const char *memory_size;
>>>> const char *machine_alias, *machine_opts = "";
>>>> g_autofree char *machine = NULL;
>>>> - const char *bootpath;
>>>> - g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>>>> + const char *bootpath = bootfile_get();
>>>> g_autofree char *memory_backend = NULL;
>>>> const char *events;
>>>> - if (args->use_shmem) {
>>>> - if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>>>> - g_test_skip("/dev/shm is not supported");
>>>> - return -1;
>>>> - }
>>>> - }
>>>> -
>>>> - dst_state = (QTestMigrationState) { };
>>>> - src_state = (QTestMigrationState) { };
>>>> - bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
>>>> - src_state.suspend_me = args->suspend_me;
>>>> -
>>>> if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
>>>> memory_size = "150M";
>>>> @@ -365,7 +351,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> if (!qtest_has_machine(machine_alias)) {
>>>> g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
>>>> g_test_skip(msg);
>>>> - return -1;
>>>> + return;
>>>
>>> A common pitfall is that g_test_skip() doesn't actually ends the
>>> test. The -1 needs to be propagated up, otherwise the test will proceed
>>> with the unsupported machine.
>>
>> Thanks.
>> migrate_args() will return an error code.
>> I'll send a V2 of this patch,
>
> Do you prefer I send a patch with just the fix, if you have already
> pulled the patches into your tree?
>
Yeah, could be.
> - Steve
>
>> and fix the call to migrate_args in patch
>> "cpr-exec test".
>>
>> - Steve
>>
>>>
>>>> }
>>>> machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
>>>> @@ -386,12 +372,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> shmem_opts ? shmem_opts : "",
>>>> args->opts_source ? args->opts_source : "",
>>>> ignore_stderr);
>>>> - if (!args->only_target) {
>>>> - *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>>>> - qtest_qmp_set_event_callback(*from,
>>>> - migrate_watch_for_events,
>>>> - &src_state);
>>>> - }
>>>> /*
>>>> * If the monitor connection is deferred, enable events on the command line
>>>> @@ -415,6 +395,39 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> shmem_opts ? shmem_opts : "",
>>>> args->opts_target ? args->opts_target : "",
>>>> ignore_stderr);
>>>> +
>>>> + *from = cmd_source;
>>>> + *to = cmd_target;
>>>> +}
>>>> +
>>>> +int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> + MigrateStart *args)
>>>> +{
>>>> + g_autofree gchar *cmd_source = NULL;
>>>> + g_autofree gchar *cmd_target = NULL;
>>>> + g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
>>>> +
>>>> + if (args->use_shmem) {
>>>> + if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
>>>> + g_test_skip("/dev/shm is not supported");
>>>> + return -1;
>>>> + }
>>>> + }
>>>> +
>>>> + dst_state = (QTestMigrationState) { };
>>>> + src_state = (QTestMigrationState) { };
>>>> + bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
>>>> + src_state.suspend_me = args->suspend_me;
>>>> +
>>>> + migrate_args(&cmd_source, &cmd_target, uri, args);
>>>> +
>>>> + if (!args->only_target) {
>>>> + *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
>>>> + qtest_qmp_set_event_callback(*from,
>>>> + migrate_watch_for_events,
>>>> + &src_state);
>>>> + }
>>>> +
>>>> if (!args->only_source) {
>>>> *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
>>>> !args->defer_target_connect);
>>>> @@ -428,6 +441,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
>>>> * It's valid because QEMU has already opened this file
>>>> */
>>>> if (args->use_shmem) {
>>>> + g_autofree char *shmem_path = test_shmem_path();
>>>> unlink(shmem_path);
>>>> }
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2025-10-01 12:18 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-19 14:12 [PATCH V1 00/11] cpr-exec test Steve Sistare
2025-09-19 14:12 ` [PATCH V1 01/11] tests/qtest: export qtest_qemu_binary Steve Sistare
2025-09-29 14:47 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 02/11] tests/qtest: qtest_qemu_args Steve Sistare
2025-09-29 14:51 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 03/11] tests/qtest: qtest_create_test_state Steve Sistare
2025-09-29 14:52 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 04/11] tests/qtest: qtest_qemu_spawn_func Steve Sistare
2025-09-29 14:57 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 05/11] tests/qtest: qtest_init_after_exec Steve Sistare
2025-09-29 14:59 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 06/11] migration-test: only_source option Steve Sistare
2025-09-29 20:27 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 07/11] migration-test: shm path accessor Steve Sistare
2025-09-29 20:28 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 08/11] migration-test: misc exports Steve Sistare
2025-09-19 14:12 ` [PATCH V1 09/11] migration-test: migrate_args Steve Sistare
2025-09-29 20:32 ` Fabiano Rosas
2025-09-30 14:35 ` Steven Sistare
2025-09-30 19:51 ` Fabiano Rosas
2025-09-30 19:59 ` Steven Sistare
2025-09-30 21:14 ` Steven Sistare
2025-10-01 12:16 ` Fabiano Rosas
2025-09-19 14:12 ` [PATCH V1 10/11] migration-test: strv parameter Steve Sistare
2025-09-19 14:12 ` [PATCH V1 11/11] migration-test: test cpr-exec Steve Sistare
2025-09-30 17:08 ` Peter Xu
2025-09-30 18:23 ` Steven Sistare
2025-09-30 19:02 ` Peter Xu
2025-09-30 19:07 ` Steven Sistare
2025-09-30 14:35 ` [PATCH V1 00/11] cpr-exec test Fabiano Rosas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).