mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
Migration pull for 9.1
- Het's new test cases for "channels" - Het's fix for a typo for vsock parsing - Cedric's VFIO error report series - Cedric's one more patch for dirty-bitmap error reports - Zhijian's rdma deprecation patch - Yuan's zeropage optimization to fix double faults on anon mem - Zhijian's COLO fix on a crash -----BEGIN PGP SIGNATURE----- iIgEABYKADAWIQS5GE3CDMRX2s990ak7X8zN86vXBgUCZig4HxIccGV0ZXJ4QHJl ZGhhdC5jb20ACgkQO1/MzfOr1wbQiwD/V5nSJzSuAG4Ra1Fjo+LRG2TT6qk8eNCi fIytehSw6cYA/0wqarxOF0tr7ikeyhtG3w4xFf44kk6KcPkoVSl1tqoL =pJmQ -----END PGP SIGNATURE----- Merge tag 'migration-20240423-pull-request' of https://gitlab.com/peterx/qemu into staging Migration pull for 9.1 - Het's new test cases for "channels" - Het's fix for a typo for vsock parsing - Cedric's VFIO error report series - Cedric's one more patch for dirty-bitmap error reports - Zhijian's rdma deprecation patch - Yuan's zeropage optimization to fix double faults on anon mem - Zhijian's COLO fix on a crash # -----BEGIN PGP SIGNATURE----- # # iIgEABYKADAWIQS5GE3CDMRX2s990ak7X8zN86vXBgUCZig4HxIccGV0ZXJ4QHJl # ZGhhdC5jb20ACgkQO1/MzfOr1wbQiwD/V5nSJzSuAG4Ra1Fjo+LRG2TT6qk8eNCi # fIytehSw6cYA/0wqarxOF0tr7ikeyhtG3w4xFf44kk6KcPkoVSl1tqoL # =pJmQ # -----END PGP SIGNATURE----- # gpg: Signature made Tue 23 Apr 2024 03:37:19 PM PDT # gpg: using EDDSA key B9184DC20CC457DACF7DD1A93B5FCCCDF3ABD706 # gpg: issuer "peterx@redhat.com" # gpg: Good signature from "Peter Xu <xzpeter@gmail.com>" [unknown] # gpg: aka "Peter Xu <peterx@redhat.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: B918 4DC2 0CC4 57DA CF7D D1A9 3B5F CCCD F3AB D706 * tag 'migration-20240423-pull-request' of https://gitlab.com/peterx/qemu: (26 commits) migration/colo: Fix bdrv_graph_rdlock_main_loop: Assertion `!qemu_in_coroutine()' failed. migration/multifd: solve zero page causing multiple page faults migration: Add Error** argument to add_bitmaps_to_list() migration: Modify ram_init_bitmaps() to report dirty tracking errors migration: Add Error** argument to xbzrle_init() migration: Add Error** argument to ram_state_init() memory: Add Error** argument to the global_dirty_log routines migration: Introduce ram_bitmaps_destroy() memory: Add Error** argument to .log_global_start() handler migration: Add Error** argument to .load_setup() handler migration: Add Error** argument to .save_setup() handler migration: Add Error** argument to qemu_savevm_state_setup() migration: Add Error** argument to vmstate_save() migration: Always report an error in ram_save_setup() migration: Always report an error in block_save_setup() vfio: Always report an error in vfio_save_setup() s390/stattrib: Add Error** argument to set_migrationmode() handler tests/qtest/migration: Fix typo for vsock in SocketAddress_to_str tests/qtest/migration: Add negative tests to validate migration QAPIs tests/qtest/migration: Add multifd_tcp_plain test using list of channels instead of uri ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
88daa112d4
28 changed files with 558 additions and 216 deletions
|
@ -13,6 +13,11 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qemu/ctype.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qapi/qapi-visit-sockets.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
#include "migration-helpers.h"
|
||||
|
||||
|
@ -24,6 +29,127 @@
|
|||
*/
|
||||
#define MIGRATION_STATUS_WAIT_TIMEOUT 120
|
||||
|
||||
static char *SocketAddress_to_str(SocketAddress *addr)
|
||||
{
|
||||
switch (addr->type) {
|
||||
case SOCKET_ADDRESS_TYPE_INET:
|
||||
return g_strdup_printf("tcp:%s:%s",
|
||||
addr->u.inet.host,
|
||||
addr->u.inet.port);
|
||||
case SOCKET_ADDRESS_TYPE_UNIX:
|
||||
return g_strdup_printf("unix:%s",
|
||||
addr->u.q_unix.path);
|
||||
case SOCKET_ADDRESS_TYPE_FD:
|
||||
return g_strdup_printf("fd:%s", addr->u.fd.str);
|
||||
case SOCKET_ADDRESS_TYPE_VSOCK:
|
||||
return g_strdup_printf("vsock:%s:%s",
|
||||
addr->u.vsock.cid,
|
||||
addr->u.vsock.port);
|
||||
default:
|
||||
return g_strdup("unknown address type");
|
||||
}
|
||||
}
|
||||
|
||||
static QDict *SocketAddress_to_qdict(SocketAddress *addr)
|
||||
{
|
||||
QDict *dict = qdict_new();
|
||||
|
||||
switch (addr->type) {
|
||||
case SOCKET_ADDRESS_TYPE_INET:
|
||||
qdict_put_str(dict, "type", "inet");
|
||||
qdict_put_str(dict, "host", addr->u.inet.host);
|
||||
qdict_put_str(dict, "port", addr->u.inet.port);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_UNIX:
|
||||
qdict_put_str(dict, "type", "unix");
|
||||
qdict_put_str(dict, "path", addr->u.q_unix.path);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_FD:
|
||||
qdict_put_str(dict, "type", "fd");
|
||||
qdict_put_str(dict, "str", addr->u.fd.str);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_VSOCK:
|
||||
qdict_put_str(dict, "type", "vsock");
|
||||
qdict_put_str(dict, "cid", addr->u.vsock.cid);
|
||||
qdict_put_str(dict, "port", addr->u.vsock.port);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
static SocketAddress *migrate_get_socket_address(QTestState *who)
|
||||
{
|
||||
QDict *rsp;
|
||||
SocketAddressList *addrs;
|
||||
SocketAddress *addr;
|
||||
Visitor *iv = NULL;
|
||||
QObject *object;
|
||||
|
||||
rsp = migrate_query(who);
|
||||
object = qdict_get(rsp, "socket-address");
|
||||
|
||||
iv = qobject_input_visitor_new(object);
|
||||
visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
|
||||
addr = addrs->value;
|
||||
visit_free(iv);
|
||||
|
||||
qobject_unref(rsp);
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char *
|
||||
migrate_get_connect_uri(QTestState *who)
|
||||
{
|
||||
SocketAddress *addrs;
|
||||
char *connect_uri;
|
||||
|
||||
addrs = migrate_get_socket_address(who);
|
||||
connect_uri = SocketAddress_to_str(addrs);
|
||||
|
||||
qapi_free_SocketAddress(addrs);
|
||||
return connect_uri;
|
||||
}
|
||||
|
||||
static QDict *
|
||||
migrate_get_connect_qdict(QTestState *who)
|
||||
{
|
||||
SocketAddress *addrs;
|
||||
QDict *connect_qdict;
|
||||
|
||||
addrs = migrate_get_socket_address(who);
|
||||
connect_qdict = SocketAddress_to_qdict(addrs);
|
||||
|
||||
qapi_free_SocketAddress(addrs);
|
||||
return connect_qdict;
|
||||
}
|
||||
|
||||
static void migrate_set_ports(QTestState *to, QList *channel_list)
|
||||
{
|
||||
QDict *addr;
|
||||
QListEntry *entry;
|
||||
const char *addr_port = NULL;
|
||||
|
||||
addr = migrate_get_connect_qdict(to);
|
||||
|
||||
QLIST_FOREACH_ENTRY(channel_list, entry) {
|
||||
QDict *channel = qobject_to(QDict, qlist_entry_obj(entry));
|
||||
QDict *addrdict = qdict_get_qdict(channel, "addr");
|
||||
|
||||
if (qdict_haskey(addrdict, "port") &&
|
||||
qdict_haskey(addr, "port") &&
|
||||
(strcmp(qdict_get_str(addrdict, "port"), "0") == 0)) {
|
||||
addr_port = qdict_get_str(addr, "port");
|
||||
qdict_put_str(addrdict, "port", g_strdup(addr_port));
|
||||
}
|
||||
}
|
||||
|
||||
qobject_unref(addr);
|
||||
}
|
||||
|
||||
bool migrate_watch_for_events(QTestState *who, const char *name,
|
||||
QDict *event, void *opaque)
|
||||
{
|
||||
|
@ -43,7 +169,8 @@ bool migrate_watch_for_events(QTestState *who, const char *name,
|
|||
return false;
|
||||
}
|
||||
|
||||
void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...)
|
||||
void migrate_qmp_fail(QTestState *who, const char *uri,
|
||||
const char *channels, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
QDict *args, *err;
|
||||
|
@ -53,7 +180,15 @@ void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...)
|
|||
va_end(ap);
|
||||
|
||||
g_assert(!qdict_haskey(args, "uri"));
|
||||
qdict_put_str(args, "uri", uri);
|
||||
if (uri) {
|
||||
qdict_put_str(args, "uri", uri);
|
||||
}
|
||||
|
||||
g_assert(!qdict_haskey(args, "channels"));
|
||||
if (channels) {
|
||||
QObject *channels_obj = qobject_from_json(channels, &error_abort);
|
||||
qdict_put_obj(args, "channels", channels_obj);
|
||||
}
|
||||
|
||||
err = qtest_qmp_assert_failure_ref(
|
||||
who, "{ 'execute': 'migrate', 'arguments': %p}", args);
|
||||
|
@ -68,17 +203,32 @@ void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...)
|
|||
* Arguments are built from @fmt... (formatted like
|
||||
* qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
|
||||
*/
|
||||
void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...)
|
||||
void migrate_qmp(QTestState *who, QTestState *to, const char *uri,
|
||||
const char *channels, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
QDict *args;
|
||||
g_autofree char *connect_uri = NULL;
|
||||
|
||||
va_start(ap, fmt);
|
||||
args = qdict_from_vjsonf_nofail(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
g_assert(!qdict_haskey(args, "uri"));
|
||||
qdict_put_str(args, "uri", uri);
|
||||
if (uri) {
|
||||
qdict_put_str(args, "uri", uri);
|
||||
} else if (!channels) {
|
||||
connect_uri = migrate_get_connect_uri(to);
|
||||
qdict_put_str(args, "uri", connect_uri);
|
||||
}
|
||||
|
||||
g_assert(!qdict_haskey(args, "channels"));
|
||||
if (channels) {
|
||||
QObject *channels_obj = qobject_from_json(channels, &error_abort);
|
||||
QList *channel_list = qobject_to(QList, channels_obj);
|
||||
migrate_set_ports(to, channel_list);
|
||||
qdict_put_obj(args, "channels", channels_obj);
|
||||
}
|
||||
|
||||
qtest_qmp_assert_success(who,
|
||||
"{ 'execute': 'migrate', 'arguments': %p}", args);
|
||||
|
|
|
@ -25,15 +25,17 @@ typedef struct QTestMigrationState {
|
|||
bool migrate_watch_for_events(QTestState *who, const char *name,
|
||||
QDict *event, void *opaque);
|
||||
|
||||
G_GNUC_PRINTF(3, 4)
|
||||
void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...);
|
||||
G_GNUC_PRINTF(5, 6)
|
||||
void migrate_qmp(QTestState *who, QTestState *to, const char *uri,
|
||||
const char *channels, const char *fmt, ...);
|
||||
|
||||
G_GNUC_PRINTF(3, 4)
|
||||
void migrate_incoming_qmp(QTestState *who, const char *uri,
|
||||
const char *fmt, ...);
|
||||
|
||||
G_GNUC_PRINTF(3, 4)
|
||||
void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...);
|
||||
G_GNUC_PRINTF(4, 5)
|
||||
void migrate_qmp_fail(QTestState *who, const char *uri,
|
||||
const char *channels, const char *fmt, ...);
|
||||
|
||||
void migrate_set_capability(QTestState *who, const char *capability,
|
||||
bool value);
|
||||
|
|
|
@ -13,16 +13,12 @@
|
|||
#include "qemu/osdep.h"
|
||||
|
||||
#include "libqtest.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "chardev/char.h"
|
||||
#include "qapi/qapi-visit-sockets.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/qobject-output-visitor.h"
|
||||
#include "crypto/tlscredspsk.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
|
||||
|
@ -369,50 +365,6 @@ static void cleanup(const char *filename)
|
|||
unlink(path);
|
||||
}
|
||||
|
||||
static char *SocketAddress_to_str(SocketAddress *addr)
|
||||
{
|
||||
switch (addr->type) {
|
||||
case SOCKET_ADDRESS_TYPE_INET:
|
||||
return g_strdup_printf("tcp:%s:%s",
|
||||
addr->u.inet.host,
|
||||
addr->u.inet.port);
|
||||
case SOCKET_ADDRESS_TYPE_UNIX:
|
||||
return g_strdup_printf("unix:%s",
|
||||
addr->u.q_unix.path);
|
||||
case SOCKET_ADDRESS_TYPE_FD:
|
||||
return g_strdup_printf("fd:%s", addr->u.fd.str);
|
||||
case SOCKET_ADDRESS_TYPE_VSOCK:
|
||||
return g_strdup_printf("tcp:%s:%s",
|
||||
addr->u.vsock.cid,
|
||||
addr->u.vsock.port);
|
||||
default:
|
||||
return g_strdup("unknown address type");
|
||||
}
|
||||
}
|
||||
|
||||
static char *migrate_get_socket_address(QTestState *who, const char *parameter)
|
||||
{
|
||||
QDict *rsp;
|
||||
char *result;
|
||||
SocketAddressList *addrs;
|
||||
Visitor *iv = NULL;
|
||||
QObject *object;
|
||||
|
||||
rsp = migrate_query(who);
|
||||
object = qdict_get(rsp, parameter);
|
||||
|
||||
iv = qobject_input_visitor_new(object);
|
||||
visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
|
||||
visit_free(iv);
|
||||
|
||||
/* we are only using a single address */
|
||||
result = SocketAddress_to_str(addrs->value);
|
||||
|
||||
qapi_free_SocketAddressList(addrs);
|
||||
qobject_unref(rsp);
|
||||
return result;
|
||||
}
|
||||
|
||||
static long long migrate_get_parameter_int(QTestState *who,
|
||||
const char *parameter)
|
||||
{
|
||||
|
@ -703,6 +655,13 @@ typedef struct {
|
|||
*/
|
||||
const char *connect_uri;
|
||||
|
||||
/*
|
||||
* Optional: JSON-formatted list of src QEMU URIs. If a port is
|
||||
* defined as '0' in any QDict key a value of '0' will be
|
||||
* automatically converted to the correct destination port.
|
||||
*/
|
||||
const char *connect_channels;
|
||||
|
||||
/* Optional: callback to run at start to set migration parameters */
|
||||
TestMigrateStartHook start_hook;
|
||||
/* Optional: callback to run at finish to cleanup */
|
||||
|
@ -1349,8 +1308,7 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
|
|||
wait_for_serial("src_serial");
|
||||
wait_for_suspend(from, &src_state);
|
||||
|
||||
g_autofree char *uri = migrate_get_socket_address(to, "socket-address");
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, NULL, NULL, "{}");
|
||||
|
||||
migrate_wait_for_dirty_mem(from, to);
|
||||
|
||||
|
@ -1500,7 +1458,7 @@ static void postcopy_recover_fail(QTestState *from, QTestState *to)
|
|||
g_assert_cmpint(ret, ==, 1);
|
||||
|
||||
migrate_recover(to, "fd:fd-mig");
|
||||
migrate_qmp(from, "fd:fd-mig", "{'resume': true}");
|
||||
migrate_qmp(from, to, "fd:fd-mig", NULL, "{'resume': true}");
|
||||
|
||||
/*
|
||||
* Make sure both QEMU instances will go into RECOVER stage, then test
|
||||
|
@ -1588,7 +1546,7 @@ static void test_postcopy_recovery_common(MigrateCommon *args)
|
|||
* Try to rebuild the migration channel using the resume flag and
|
||||
* the newly created channel
|
||||
*/
|
||||
migrate_qmp(from, uri, "{'resume': true}");
|
||||
migrate_qmp(from, to, uri, NULL, "{'resume': true}");
|
||||
|
||||
/* Restore the postcopy bandwidth to unlimited */
|
||||
migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
|
||||
|
@ -1669,7 +1627,7 @@ static void test_baddest(void)
|
|||
if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
|
||||
return;
|
||||
}
|
||||
migrate_qmp(from, "tcp:127.0.0.1:0", "{}");
|
||||
migrate_qmp(from, to, "tcp:127.0.0.1:0", NULL, "{}");
|
||||
wait_for_migration_fail(from, false);
|
||||
test_migrate_end(from, to, false);
|
||||
}
|
||||
|
@ -1708,7 +1666,7 @@ static void test_analyze_script(void)
|
|||
uri = g_strdup_printf("exec:cat > %s", file);
|
||||
|
||||
migrate_ensure_converge(from);
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, uri, NULL, "{}");
|
||||
wait_for_migration_complete(from);
|
||||
|
||||
pid = fork();
|
||||
|
@ -1733,7 +1691,6 @@ static void test_precopy_common(MigrateCommon *args)
|
|||
{
|
||||
QTestState *from, *to;
|
||||
void *data_hook = NULL;
|
||||
g_autofree char *connect_uri = NULL;
|
||||
|
||||
if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
|
||||
return;
|
||||
|
@ -1766,18 +1723,12 @@ static void test_precopy_common(MigrateCommon *args)
|
|||
}
|
||||
}
|
||||
|
||||
if (!args->connect_uri) {
|
||||
connect_uri = migrate_get_socket_address(to, "socket-address");
|
||||
} else {
|
||||
connect_uri = g_strdup(args->connect_uri);
|
||||
}
|
||||
|
||||
if (args->result == MIG_TEST_QMP_ERROR) {
|
||||
migrate_qmp_fail(from, connect_uri, "{}");
|
||||
migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
migrate_qmp(from, connect_uri, "{}");
|
||||
migrate_qmp(from, to, args->connect_uri, args->connect_channels, "{}");
|
||||
|
||||
if (args->result != MIG_TEST_SUCCEED) {
|
||||
bool allow_active = args->result == MIG_TEST_FAIL;
|
||||
|
@ -1843,7 +1794,6 @@ static void test_file_common(MigrateCommon *args, bool stop_src)
|
|||
{
|
||||
QTestState *from, *to;
|
||||
void *data_hook = NULL;
|
||||
g_autofree char *connect_uri = g_strdup(args->connect_uri);
|
||||
|
||||
if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
|
||||
return;
|
||||
|
@ -1869,18 +1819,18 @@ static void test_file_common(MigrateCommon *args, bool stop_src)
|
|||
}
|
||||
|
||||
if (args->result == MIG_TEST_QMP_ERROR) {
|
||||
migrate_qmp_fail(from, connect_uri, "{}");
|
||||
migrate_qmp_fail(from, args->connect_uri, NULL, "{}");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
migrate_qmp(from, connect_uri, "{}");
|
||||
migrate_qmp(from, to, args->connect_uri, NULL, "{}");
|
||||
wait_for_migration_complete(from);
|
||||
|
||||
/*
|
||||
* We need to wait for the source to finish before starting the
|
||||
* destination.
|
||||
*/
|
||||
migrate_incoming_qmp(to, connect_uri, "{}");
|
||||
migrate_incoming_qmp(to, args->connect_uri, "{}");
|
||||
wait_for_migration_complete(to);
|
||||
|
||||
if (stop_src) {
|
||||
|
@ -2029,7 +1979,7 @@ static void test_ignore_shared(void)
|
|||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, uri, NULL, "{}");
|
||||
|
||||
migrate_wait_for_dirty_mem(from, to);
|
||||
|
||||
|
@ -2568,7 +2518,7 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
|
|||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, uri, NULL, "{}");
|
||||
|
||||
if (should_fail) {
|
||||
qtest_set_expected_status(to, EXIT_FAILURE);
|
||||
|
@ -2621,6 +2571,55 @@ static void test_validate_uuid_dst_not_set(void)
|
|||
do_test_validate_uuid(&args, false);
|
||||
}
|
||||
|
||||
static void do_test_validate_uri_channel(MigrateCommon *args)
|
||||
{
|
||||
QTestState *from, *to;
|
||||
|
||||
if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
/*
|
||||
* 'uri' and 'channels' validation is checked even before the migration
|
||||
* starts.
|
||||
*/
|
||||
migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
|
||||
test_migrate_end(from, to, false);
|
||||
}
|
||||
|
||||
static void test_validate_uri_channels_both_set(void)
|
||||
{
|
||||
MigrateCommon args = {
|
||||
.start = {
|
||||
.hide_stderr = true,
|
||||
},
|
||||
.listen_uri = "defer",
|
||||
.connect_uri = "tcp:127.0.0.1:0",
|
||||
.connect_channels = "[ { 'channel-type': 'main',"
|
||||
" 'addr': { 'transport': 'socket',"
|
||||
" 'type': 'inet',"
|
||||
" 'host': '127.0.0.1',"
|
||||
" 'port': '0' } } ]",
|
||||
};
|
||||
|
||||
do_test_validate_uri_channel(&args);
|
||||
}
|
||||
|
||||
static void test_validate_uri_channels_none_set(void)
|
||||
{
|
||||
MigrateCommon args = {
|
||||
.start = {
|
||||
.hide_stderr = true,
|
||||
},
|
||||
.listen_uri = "defer",
|
||||
};
|
||||
|
||||
do_test_validate_uri_channel(&args);
|
||||
}
|
||||
|
||||
/*
|
||||
* The way auto_converge works, we need to do too many passes to
|
||||
* run this test. Auto_converge logic is only run once every
|
||||
|
@ -2671,7 +2670,7 @@ static void test_migrate_auto_converge(void)
|
|||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, uri, NULL, "{}");
|
||||
|
||||
/* Wait for throttling begins */
|
||||
percentage = 0;
|
||||
|
@ -2778,7 +2777,7 @@ test_migrate_precopy_tcp_multifd_zstd_start(QTestState *from,
|
|||
}
|
||||
#endif /* CONFIG_ZSTD */
|
||||
|
||||
static void test_multifd_tcp_none(void)
|
||||
static void test_multifd_tcp_uri_none(void)
|
||||
{
|
||||
MigrateCommon args = {
|
||||
.listen_uri = "defer",
|
||||
|
@ -2823,6 +2822,21 @@ static void test_multifd_tcp_no_zero_page(void)
|
|||
test_precopy_common(&args);
|
||||
}
|
||||
|
||||
static void test_multifd_tcp_channels_none(void)
|
||||
{
|
||||
MigrateCommon args = {
|
||||
.listen_uri = "defer",
|
||||
.start_hook = test_migrate_precopy_tcp_multifd_start,
|
||||
.live = true,
|
||||
.connect_channels = "[ { 'channel-type': 'main',"
|
||||
" 'addr': { 'transport': 'socket',"
|
||||
" 'type': 'inet',"
|
||||
" 'host': '127.0.0.1',"
|
||||
" 'port': '0' } } ]",
|
||||
};
|
||||
test_precopy_common(&args);
|
||||
}
|
||||
|
||||
static void test_multifd_tcp_zlib(void)
|
||||
{
|
||||
MigrateCommon args = {
|
||||
|
@ -3017,7 +3031,6 @@ static void test_multifd_tcp_cancel(void)
|
|||
.hide_stderr = true,
|
||||
};
|
||||
QTestState *from, *to, *to2;
|
||||
g_autofree char *uri = NULL;
|
||||
|
||||
if (test_migrate_start(&from, &to, "defer", &args)) {
|
||||
return;
|
||||
|
@ -3038,9 +3051,7 @@ static void test_multifd_tcp_cancel(void)
|
|||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
uri = migrate_get_socket_address(to, "socket-address");
|
||||
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, NULL, NULL, "{}");
|
||||
|
||||
migrate_wait_for_dirty_mem(from, to);
|
||||
|
||||
|
@ -3065,14 +3076,11 @@ static void test_multifd_tcp_cancel(void)
|
|||
/* Start incoming migration from the 1st socket */
|
||||
migrate_incoming_qmp(to2, "tcp:127.0.0.1:0", "{}");
|
||||
|
||||
g_free(uri);
|
||||
uri = migrate_get_socket_address(to2, "socket-address");
|
||||
|
||||
wait_for_migration_status(from, "cancelled", NULL);
|
||||
|
||||
migrate_ensure_non_converge(from);
|
||||
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to2, NULL, NULL, "{}");
|
||||
|
||||
migrate_wait_for_dirty_mem(from, to2);
|
||||
|
||||
|
@ -3405,7 +3413,7 @@ static void test_migrate_dirty_limit(void)
|
|||
migrate_dirty_limit_wait_showup(from, dirtylimit_period, dirtylimit_value);
|
||||
|
||||
/* Start migrate */
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, args.connect_uri, NULL, "{}");
|
||||
|
||||
/* Wait for dirty limit throttle begin */
|
||||
throttle_us_per_full = 0;
|
||||
|
@ -3446,7 +3454,7 @@ static void test_migrate_dirty_limit(void)
|
|||
}
|
||||
|
||||
/* Start migrate */
|
||||
migrate_qmp(from, uri, "{}");
|
||||
migrate_qmp(from, to, args.connect_uri, NULL, "{}");
|
||||
|
||||
/* Wait for dirty limit throttle begin */
|
||||
throttle_us_per_full = 0;
|
||||
|
@ -3720,6 +3728,10 @@ int main(int argc, char **argv)
|
|||
test_validate_uuid_src_not_set);
|
||||
migration_test_add("/migration/validate_uuid_dst_not_set",
|
||||
test_validate_uuid_dst_not_set);
|
||||
migration_test_add("/migration/validate_uri/channels/both_set",
|
||||
test_validate_uri_channels_both_set);
|
||||
migration_test_add("/migration/validate_uri/channels/none_set",
|
||||
test_validate_uri_channels_none_set);
|
||||
/*
|
||||
* See explanation why this test is slow on function definition
|
||||
*/
|
||||
|
@ -3732,8 +3744,10 @@ int main(int argc, char **argv)
|
|||
test_migrate_dirty_limit);
|
||||
}
|
||||
}
|
||||
migration_test_add("/migration/multifd/tcp/plain/none",
|
||||
test_multifd_tcp_none);
|
||||
migration_test_add("/migration/multifd/tcp/uri/plain/none",
|
||||
test_multifd_tcp_uri_none);
|
||||
migration_test_add("/migration/multifd/tcp/channels/plain/none",
|
||||
test_multifd_tcp_channels_none);
|
||||
migration_test_add("/migration/multifd/tcp/plain/zero-page/legacy",
|
||||
test_multifd_tcp_zero_page_legacy);
|
||||
migration_test_add("/migration/multifd/tcp/plain/zero-page/none",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue