Qtest pull request
- Fix for qtest_get_machines QEMU var caching - Fixes for migration-test in --without-default-devices build - Preparation patches for cpr-exec test -----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmjdoeoQHGZhcm9zYXNA c3VzZS5kZQAKCRDHmNx0G+wxnUGMEACQuy8eGVnh7ni9rDpJxyyUoKAKlNI9+7c+ 2bi/e+pT26Od5/ExznVOoDlEFFoogQZiVDqxZ3wBB0SziEn41+Wm8SSV6Tto7eNy qqVZuYymWUY+MmAeL7RKY+EuVV3Y1a/2lS+w04dCSQYrWf9rr9AX8xdDDln/ebqm F1sUhVKO7PA05O3Sw6M1G32l27r6WCsVRliz46gl5MHmmWe4YRR72Eoi3gTsXIkT CiEmT9EjOkHykSkgekiN+jgLiAO1pwcaU7Cf4ENhYouBjW9kL46LCmMS+7pcQ1LG 2UuXhR3+Ws0ukAUmcJthMRMssjy0OGr845DjiTmOFnbiiUKX9CysuTIIlM+xbDN4 m/IomtxXAnEncQcUO4vgv81eyGFRtn/Mx9Zdo/x8dtNc6Lh62zqsMj7lp8sjatR/ DScPTRCRxAUQiY6YMIrJH38m7XLyIaG+oCzg1+EBllmHLoQTtPE4hQHz4MDRj0RA aKAvQsucQ/8LxHV9va4W5epVrdP54Yw040QbTnN5XdH4U06yv4pfpBnCw4RYFPj2 l5TZSNE2WmjeOfT/FERjJWXEXbvcEWoPZMWOc0r1qYGqEAhIui69n//H28EZ2DAE QEzNJLBqu4t7U+pw5h1QW5YFdkVZIfmDOx3+SlA/tNcLTQ/a2gzAWkr0AKIzddH9 ZOGP6b4wFw== =OSa5 -----END PGP SIGNATURE----- Merge tag 'qtest-20251001-pull-request' of https://gitlab.com/farosas/qemu into staging Qtest pull request - Fix for qtest_get_machines QEMU var caching - Fixes for migration-test in --without-default-devices build - Preparation patches for cpr-exec test # -----BEGIN PGP SIGNATURE----- # # iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmjdoeoQHGZhcm9zYXNA # c3VzZS5kZQAKCRDHmNx0G+wxnUGMEACQuy8eGVnh7ni9rDpJxyyUoKAKlNI9+7c+ # 2bi/e+pT26Od5/ExznVOoDlEFFoogQZiVDqxZ3wBB0SziEn41+Wm8SSV6Tto7eNy # qqVZuYymWUY+MmAeL7RKY+EuVV3Y1a/2lS+w04dCSQYrWf9rr9AX8xdDDln/ebqm # F1sUhVKO7PA05O3Sw6M1G32l27r6WCsVRliz46gl5MHmmWe4YRR72Eoi3gTsXIkT # CiEmT9EjOkHykSkgekiN+jgLiAO1pwcaU7Cf4ENhYouBjW9kL46LCmMS+7pcQ1LG # 2UuXhR3+Ws0ukAUmcJthMRMssjy0OGr845DjiTmOFnbiiUKX9CysuTIIlM+xbDN4 # m/IomtxXAnEncQcUO4vgv81eyGFRtn/Mx9Zdo/x8dtNc6Lh62zqsMj7lp8sjatR/ # DScPTRCRxAUQiY6YMIrJH38m7XLyIaG+oCzg1+EBllmHLoQTtPE4hQHz4MDRj0RA # aKAvQsucQ/8LxHV9va4W5epVrdP54Yw040QbTnN5XdH4U06yv4pfpBnCw4RYFPj2 # l5TZSNE2WmjeOfT/FERjJWXEXbvcEWoPZMWOc0r1qYGqEAhIui69n//H28EZ2DAE # QEzNJLBqu4t7U+pw5h1QW5YFdkVZIfmDOx3+SlA/tNcLTQ/a2gzAWkr0AKIzddH9 # ZOGP6b4wFw== # =OSa5 # -----END PGP SIGNATURE----- # gpg: Signature made Wed 01 Oct 2025 02:49:30 PM PDT # gpg: using RSA key AA1B48B0A22326A5A4C364CFC798DC741BEC319D # gpg: issuer "farosas@suse.de" # gpg: Good signature from "Fabiano Rosas <farosas@suse.de>" [unknown] # gpg: aka "Fabiano Almeida Rosas <fabiano.rosas@suse.com>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: AA1B 48B0 A223 26A5 A4C3 64CF C798 DC74 1BEC 319D * tag 'qtest-20251001-pull-request' of https://gitlab.com/farosas/qemu: migration-test: strv parameter migration-test: migrate_args migration-test: misc exports migration-test: shm path accessor migration-test: only_source option tests/qtest: qtest_init_after_exec tests/qtest: qtest_qemu_spawn_func tests/qtest: qtest_create_test_state tests/qtest: qtest_qemu_args tests/qtest: export qtest_qemu_binary tests/qtest: optimize qtest_get_machines tests/qtest/migration: Fix cpr-tests in case the machine is not available tests/qtest: Add missing checks for the availability of machines Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
517e9b4862
12 changed files with 217 additions and 79 deletions
|
|
@ -2864,7 +2864,7 @@ int main(int argc, char *argv[])
|
|||
test_acpi_riscv64_virt_tcg_acpi_spcr);
|
||||
}
|
||||
} else if (strcmp(arch, "loongarch64") == 0) {
|
||||
if (has_tcg) {
|
||||
if (has_tcg && qtest_has_machine("virt")) {
|
||||
qtest_add_func("acpi/virt", test_acpi_loongarch64_virt);
|
||||
qtest_add_func("acpi/virt/topology",
|
||||
test_acpi_loongarch64_virt_topology);
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ int main(int argc, char **argv)
|
|||
qtest_cb_for_every_machine(add_pseries_test_case, g_test_quick());
|
||||
} else if (g_str_equal(arch, "s390x")) {
|
||||
qtest_cb_for_every_machine(add_s390x_test_case, g_test_quick());
|
||||
} else if (g_str_equal(arch, "loongarch64")) {
|
||||
} else if (g_str_equal(arch, "loongarch64") && qtest_has_machine("virt")) {
|
||||
add_loongarch_test_case("virt");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -409,30 +409,30 @@ 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_create_test_state(int pid)
|
||||
{
|
||||
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("");
|
||||
|
||||
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,
|
||||
void *opaque)
|
||||
{
|
||||
int pid;
|
||||
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);
|
||||
|
||||
qtest_add_abrt_handler(kill_qemu_hook_func, s);
|
||||
g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
|
||||
|
||||
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
|
||||
|
|
@ -455,10 +455,10 @@ static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
|
|||
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)
|
||||
|
|
@ -466,14 +466,48 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
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 +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,
|
||||
"-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 = 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);
|
||||
|
|
@ -555,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)
|
||||
|
|
@ -578,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);
|
||||
|
|
@ -592,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 *qts)
|
||||
{
|
||||
void *opaque = (void *)&qts->qemu_pid;
|
||||
QTestState *s;
|
||||
|
||||
s = qtest_init_internal(NULL, NULL, true, qtest_attach_qemu, opaque);
|
||||
qts->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);
|
||||
|
|
@ -1630,7 +1672,8 @@ static void qtest_free_machine_list(struct MachInfo *machines)
|
|||
static struct MachInfo *qtest_get_machines(const char *var)
|
||||
{
|
||||
static struct MachInfo *machines;
|
||||
static char *qemu_var;
|
||||
static char *qemu_bin;
|
||||
const char *new_qemu_bin;
|
||||
QDict *response, *minfo;
|
||||
QList *list;
|
||||
const QListEntry *p;
|
||||
|
|
@ -1639,9 +1682,10 @@ static struct MachInfo *qtest_get_machines(const char *var)
|
|||
QTestState *qts;
|
||||
int idx;
|
||||
|
||||
if (g_strcmp0(qemu_var, var)) {
|
||||
g_free(qemu_var);
|
||||
qemu_var = g_strdup(var);
|
||||
new_qemu_bin = qtest_qemu_binary(var);
|
||||
if (g_strcmp0(qemu_bin, new_qemu_bin)) {
|
||||
g_free(qemu_bin);
|
||||
qemu_bin = g_strdup(new_qemu_bin);
|
||||
|
||||
/* new qemu, clear the cache */
|
||||
qtest_free_machine_list(machines);
|
||||
|
|
@ -1654,7 +1698,7 @@ static struct MachInfo *qtest_get_machines(const char *var)
|
|||
|
||||
silence_spawn_log = !g_test_verbose();
|
||||
|
||||
qts = qtest_init_ext(qemu_var, "-machine none", NULL, true);
|
||||
qts = qtest_init_ext(var, "-machine none", NULL, true);
|
||||
response = qtest_qmp(qts, "{ 'execute': 'query-machines' }");
|
||||
g_assert(response);
|
||||
list = qdict_get_qlist(response, "return");
|
||||
|
|
|
|||
|
|
@ -47,6 +47,31 @@ 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_after_exec:
|
||||
* @qts: the previous QEMU state
|
||||
*
|
||||
* Return a test state representing new QEMU after @qts exec's it.
|
||||
*/
|
||||
QTestState *qtest_init_after_exec(QTestState *qts);
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -68,3 +68,8 @@ char *bootfile_create(const char *arch, const char *dir, bool suspend_me)
|
|||
|
||||
return bootpath;
|
||||
}
|
||||
|
||||
char *bootfile_get(void)
|
||||
{
|
||||
return bootpath;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ static void test_mode_transfer_common(bool incoming_defer)
|
|||
.start_hook = test_mode_transfer_start,
|
||||
};
|
||||
|
||||
test_precopy_common(&args);
|
||||
if (test_precopy_common(&args) < 0) {
|
||||
close(cpr_sockfd);
|
||||
unlink(cpr_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_mode_transfer(void)
|
||||
|
|
|
|||
|
|
@ -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,20 +246,26 @@ 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;
|
||||
}
|
||||
|
||||
int migrate_start(QTestState **from, QTestState **to, const char *uri,
|
||||
MigrateStart *args)
|
||||
static char *test_shmem_path(void)
|
||||
{
|
||||
return g_strdup_printf("/dev/shm/qemu-%d", getpid());
|
||||
}
|
||||
|
||||
int 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;
|
||||
|
|
@ -268,23 +274,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";
|
||||
|
||||
|
|
@ -340,7 +333,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",
|
||||
|
|
@ -381,12 +374,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
|
||||
|
|
@ -410,21 +397,62 @@ 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);
|
||||
|
||||
*from = cmd_source;
|
||||
*to = cmd_target;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (migrate_args(&cmd_source, &cmd_target, uri, args)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
qtest_qmp_set_event_callback(*to,
|
||||
migrate_watch_for_events,
|
||||
&dst_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove shmem file immediately to avoid memory leak in test failed case.
|
||||
* 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);
|
||||
}
|
||||
|
||||
migrate_start_set_capabilities(*from, *to, args);
|
||||
migrate_start_set_capabilities(*from,
|
||||
args->only_source ? NULL : *to,
|
||||
args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -736,7 +764,7 @@ void test_postcopy_recovery_common(MigrateCommon *args)
|
|||
migrate_postcopy_complete(from, to, args);
|
||||
}
|
||||
|
||||
void test_precopy_common(MigrateCommon *args)
|
||||
int test_precopy_common(MigrateCommon *args)
|
||||
{
|
||||
QTestState *from, *to;
|
||||
void *data_hook = NULL;
|
||||
|
|
@ -746,7 +774,7 @@ void test_precopy_common(MigrateCommon *args)
|
|||
g_assert(!args->cpr_channel || args->connect_channels);
|
||||
|
||||
if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (args->start_hook) {
|
||||
|
|
@ -869,6 +897,8 @@ finish:
|
|||
}
|
||||
|
||||
migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void file_dirty_offset_region(void)
|
||||
|
|
@ -994,6 +1024,11 @@ QTestMigrationState *get_src(void)
|
|||
return &src_state;
|
||||
}
|
||||
|
||||
QTestMigrationState *get_dst(void)
|
||||
{
|
||||
return &dst_state;
|
||||
}
|
||||
|
||||
MigrationTestEnv *migration_get_env(void)
|
||||
{
|
||||
static MigrationTestEnv *env;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -221,13 +223,15 @@ 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);
|
||||
|
||||
int 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);
|
||||
|
||||
void test_postcopy_common(MigrateCommon *args);
|
||||
void test_postcopy_recovery_common(MigrateCommon *args);
|
||||
void test_precopy_common(MigrateCommon *args);
|
||||
int test_precopy_common(MigrateCommon *args);
|
||||
void test_file_common(MigrateCommon *args, bool stop_src);
|
||||
void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
|
||||
QTestState *to,
|
||||
|
|
@ -235,6 +239,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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ int main(int argc, char **argv)
|
|||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
qtest_add_func("/cpu/csr", run_test_csr);
|
||||
if (qtest_has_machine("virt")) {
|
||||
qtest_add_func("/cpu/csr", run_test_csr);
|
||||
}
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue