Migration pull request

- Steve's cleanup of unused variable
 - Peter Maydell's fixes for several leaks in migration-test
 - Fabiano's flexibilization of multifd data structures for device
   state migration
 - Arman Nabiev's fix for ppc e500 migration
 - Thomas' fix for migration-test vs. --without-default-devices
 -----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmbYVXwQHGZhcm9zYXNA
 c3VzZS5kZQAKCRDHmNx0G+wxnRucEAC1vo046UGdUmbb4PaF5vKAg97io6RB2nrH
 HMz56Yc0AcAKRUGwe2Z80e2jY8B6zi8Ha8b9l7cVsej095eGCF+tINIL4wRX4lHm
 alDY/LkhuqjE5g5c/DaeTztyBOFLvdWHPU5eJyDOC9r7kSlnUcL1gAslH23b8uL0
 xvhPVKaTWjGIzNL1q/XfBr1WgRGqfD6dYb32HJDTq85yOnUT5sEr55aoEEu0euKh
 MYbXPmi5AMbrp8nP21kzUopX8iYERRdoKwhF0ZssciGi/qJVevH70tNdbDEQSxyp
 +vtP54TnL3LrzD4uY5Snng9zT9h0QrZujY79OEcxu20U0s29OQaudWkIjp7yLLUv
 UnPZHS+bIyaS53DdpV94GKGGBX1wrjGC/sn8eGYzmb2yMlMjLTBoE8L5r9cadshX
 XTeF4MtKGqaS3xDM2fIgACHHFl6qr/l0nENspv0raFzpf9Jx/WbpekghvTuWN6/B
 pZHnoOTNiAqXS/Rnyy829vsQ0Pw4hi6wx79Z73RP+35ubZTgTmOsQx9f2FjuEh6k
 JS+q9k4VJ+nntUWsYn4GS1Jlt+FXJ2hfzNj1NNFN4xLT1oioc6pCHsQyV7SBArB1
 ml2zYyfKCTC3riIRhcv/ew6OcKbhHcPFOpd/v0y40LO3mx8S0LZnUWXkcrl3XIZS
 Mj5CBdlFgA==
 =SRN4
 -----END PGP SIGNATURE-----

Merge tag 'migration-20240904-pull-request' of https://gitlab.com/farosas/qemu into staging

Migration pull request

- Steve's cleanup of unused variable
- Peter Maydell's fixes for several leaks in migration-test
- Fabiano's flexibilization of multifd data structures for device
  state migration
- Arman Nabiev's fix for ppc e500 migration
- Thomas' fix for migration-test vs. --without-default-devices

# -----BEGIN PGP SIGNATURE-----
#
# iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmbYVXwQHGZhcm9zYXNA
# c3VzZS5kZQAKCRDHmNx0G+wxnRucEAC1vo046UGdUmbb4PaF5vKAg97io6RB2nrH
# HMz56Yc0AcAKRUGwe2Z80e2jY8B6zi8Ha8b9l7cVsej095eGCF+tINIL4wRX4lHm
# alDY/LkhuqjE5g5c/DaeTztyBOFLvdWHPU5eJyDOC9r7kSlnUcL1gAslH23b8uL0
# xvhPVKaTWjGIzNL1q/XfBr1WgRGqfD6dYb32HJDTq85yOnUT5sEr55aoEEu0euKh
# MYbXPmi5AMbrp8nP21kzUopX8iYERRdoKwhF0ZssciGi/qJVevH70tNdbDEQSxyp
# +vtP54TnL3LrzD4uY5Snng9zT9h0QrZujY79OEcxu20U0s29OQaudWkIjp7yLLUv
# UnPZHS+bIyaS53DdpV94GKGGBX1wrjGC/sn8eGYzmb2yMlMjLTBoE8L5r9cadshX
# XTeF4MtKGqaS3xDM2fIgACHHFl6qr/l0nENspv0raFzpf9Jx/WbpekghvTuWN6/B
# pZHnoOTNiAqXS/Rnyy829vsQ0Pw4hi6wx79Z73RP+35ubZTgTmOsQx9f2FjuEh6k
# JS+q9k4VJ+nntUWsYn4GS1Jlt+FXJ2hfzNj1NNFN4xLT1oioc6pCHsQyV7SBArB1
# ml2zYyfKCTC3riIRhcv/ew6OcKbhHcPFOpd/v0y40LO3mx8S0LZnUWXkcrl3XIZS
# Mj5CBdlFgA==
# =SRN4
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 04 Sep 2024 13:41:32 BST
# 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: This key 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 'migration-20240904-pull-request' of https://gitlab.com/farosas/qemu: (34 commits)
  tests/qtest/migration: Add a check for the availability of the "pc" machine
  target/ppc: Fix migration of CPUs with TLB_EMB TLB type
  migration/multifd: Add documentation for multifd methods
  migration/multifd: Add a couple of asserts for p->iov
  migration/multifd: Fix p->iov leak in multifd-uadk.c
  migration/multifd: Stop changing the packet on recv side
  migration/multifd: Make MultiFDMethods const
  migration/multifd: Move nocomp code into multifd-nocomp.c
  migration/multifd: Register nocomp ops dynamically
  migration/multifd: Standardize on multifd ops names
  migration/multifd: Allow multifd sync without flush
  migration/multifd: Replace multifd_send_state->pages with client data
  migration/multifd: Don't send ram data during SYNC
  migration/multifd: Isolate ram pages packet data
  migration/multifd: Remove total pages tracing
  migration/multifd: Move pages accounting into multifd_send_zero_page_detect()
  migration/multifd: Replace p->pages with an union pointer
  migration/multifd: Make MultiFDPages_t:offset a flexible array member
  migration/multifd: Introduce MultiFDSendData
  migration/multifd: Pass in MultiFDPages_t to file_write_ramblock_iov
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-09-06 12:33:07 +01:00
commit becd694497
21 changed files with 773 additions and 931 deletions

View file

@ -514,7 +514,12 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
kill(s->qemu_pid, SIGSTOP);
}
#endif
return s;
/* ask endianness of the target */
s->big_endian = qtest_query_target_endianness(s);
return s;
}
QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
@ -522,21 +527,11 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
return qtest_init_internal(qtest_qemu_binary(NULL), extra_args);
}
QTestState *qtest_init_with_env_no_handshake(const char *var,
const char *extra_args)
{
return qtest_init_internal(qtest_qemu_binary(var), extra_args);
}
QTestState *qtest_init_with_env(const char *var, const char *extra_args)
{
QTestState *s = qtest_init_internal(qtest_qemu_binary(var), extra_args);
QDict *greeting;
/* ask endianness of the target */
s->big_endian = qtest_query_target_endianness(s);
/* Read the QMP greeting and then do the handshake */
greeting = qtest_qmp_receive(s);
qobject_unref(greeting);

View file

@ -68,8 +68,6 @@ QTestState *qtest_init(const char *extra_args);
*/
QTestState *qtest_init_with_env(const char *var, const char *extra_args);
QTestState *qtest_init_with_env_no_handshake(const char *var,
const char *extra_args);
/**
* qtest_init_without_qmp_handshake:
* @extra_args: other arguments to pass to QEMU. CAUTION: these

View file

@ -82,11 +82,10 @@ static QDict *SocketAddress_to_qdict(SocketAddress *addr)
return dict;
}
static SocketAddress *migrate_get_socket_address(QTestState *who)
static SocketAddressList *migrate_get_socket_address(QTestState *who)
{
QDict *rsp;
SocketAddressList *addrs;
SocketAddress *addr;
Visitor *iv = NULL;
QObject *object;
@ -95,36 +94,35 @@ static SocketAddress *migrate_get_socket_address(QTestState *who)
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;
return addrs;
}
static char *
migrate_get_connect_uri(QTestState *who)
{
SocketAddress *addrs;
SocketAddressList *addrs;
char *connect_uri;
addrs = migrate_get_socket_address(who);
connect_uri = SocketAddress_to_str(addrs);
connect_uri = SocketAddress_to_str(addrs->value);
qapi_free_SocketAddress(addrs);
qapi_free_SocketAddressList(addrs);
return connect_uri;
}
static QDict *
migrate_get_connect_qdict(QTestState *who)
{
SocketAddress *addrs;
SocketAddressList *addrs;
QDict *connect_qdict;
addrs = migrate_get_socket_address(who);
connect_qdict = SocketAddress_to_qdict(addrs);
connect_qdict = SocketAddress_to_qdict(addrs->value);
qapi_free_SocketAddress(addrs);
qapi_free_SocketAddressList(addrs);
return connect_qdict;
}
@ -144,7 +142,7 @@ static void migrate_set_ports(QTestState *to, QList *channel_list)
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));
qdict_put_str(addrdict, "port", addr_port);
}
}

View file

@ -64,7 +64,6 @@ static QTestMigrationState dst_state;
#define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */
#define ANALYZE_SCRIPT "scripts/analyze-migration.py"
#define VMSTATE_CHECKER_SCRIPT "scripts/vmstate-static-checker.py"
#define QEMU_VM_FILE_MAGIC 0x5145564d
#define FILE_TEST_FILENAME "migfile"
@ -146,6 +145,9 @@ static char *bootpath;
static void bootfile_delete(void)
{
if (!bootpath) {
return;
}
unlink(bootpath);
g_free(bootpath);
bootpath = NULL;
@ -157,10 +159,7 @@ static void bootfile_create(char *dir, bool suspend_me)
unsigned char *content;
size_t len;
if (bootpath) {
bootfile_delete();
}
bootfile_delete();
bootpath = g_strdup_printf("%s/bootsect", dir);
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
/* the assembled x86 boot sector should be exactly one sector large */
@ -1062,12 +1061,15 @@ test_migrate_tls_x509_start_common(QTestState *from,
QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
QCRYPTO_TLS_TEST_CLIENT_NAME,
data->clientcert);
test_tls_deinit_cert(&servercertreq);
}
TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
data->servercert,
args->certhostname,
args->certipaddr);
test_tls_deinit_cert(&clientcertreq);
test_tls_deinit_cert(&cacertreq);
qtest_qmp_assert_success(from,
"{ 'execute': 'object-add',"
@ -1692,85 +1694,6 @@ static void test_analyze_script(void)
test_migrate_end(from, to, false);
cleanup("migfile");
}
static void test_vmstate_checker_script(void)
{
g_autofree gchar *cmd_src = NULL;
g_autofree gchar *cmd_dst = NULL;
g_autofree gchar *vmstate_src = NULL;
g_autofree gchar *vmstate_dst = NULL;
const char *machine_alias, *machine_opts = "";
g_autofree char *machine = NULL;
const char *arch = qtest_get_arch();
int pid, wstatus;
const char *python = g_getenv("PYTHON");
if (!getenv(QEMU_ENV_SRC) && !getenv(QEMU_ENV_DST)) {
g_test_skip("Test needs two different QEMU versions");
return;
}
if (!python) {
g_test_skip("PYTHON variable not set");
return;
}
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
if (g_str_equal(arch, "i386")) {
machine_alias = "pc";
} else {
machine_alias = "q35";
}
} else if (g_str_equal(arch, "s390x")) {
machine_alias = "s390-ccw-virtio";
} else if (strcmp(arch, "ppc64") == 0) {
machine_alias = "pseries";
} else if (strcmp(arch, "aarch64") == 0) {
machine_alias = "virt";
} else {
g_assert_not_reached();
}
if (!qtest_has_machine(machine_alias)) {
g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
g_test_skip(msg);
return;
}
machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
QEMU_ENV_DST);
vmstate_src = g_strdup_printf("%s/vmstate-src", tmpfs);
vmstate_dst = g_strdup_printf("%s/vmstate-dst", tmpfs);
cmd_dst = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
machine, machine_opts, vmstate_dst);
cmd_src = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
machine, machine_opts, vmstate_src);
qtest_init_with_env_no_handshake(QEMU_ENV_SRC, cmd_src);
qtest_init_with_env_no_handshake(QEMU_ENV_DST, cmd_dst);
pid = fork();
if (!pid) {
close(1);
open("/dev/null", O_WRONLY);
execl(python, python, VMSTATE_CHECKER_SCRIPT,
"-s", vmstate_src,
"-d", vmstate_dst,
NULL);
g_assert_not_reached();
}
g_assert(waitpid(pid, &wstatus, 0) == pid);
if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
g_test_message("Failed to run vmstate-static-checker.py");
g_test_fail();
}
cleanup("vmstate-src");
cleanup("vmstate-dst");
}
#endif
static void test_precopy_common(MigrateCommon *args)
@ -2395,6 +2318,7 @@ static void multifd_mapped_ram_fdset_end(QTestState *from, QTestState *to,
g_assert(qdict_haskey(resp, "return"));
fdsets = qdict_get_qlist(resp, "return");
g_assert(fdsets && qlist_empty(fdsets));
qobject_unref(resp);
}
static void *multifd_mapped_ram_fdset_dio(QTestState *from, QTestState *to)
@ -3318,6 +3242,7 @@ static void test_multifd_tcp_cancel(void)
/* Make sure QEMU process "to" exited */
qtest_set_expected_status(to, EXIT_FAILURE);
qtest_wait_qemu(to);
qtest_quit(to);
args = (MigrateStart){
.only_target = true,
@ -3397,15 +3322,18 @@ static QDict *query_vcpu_dirty_limit(QTestState *who)
static bool calc_dirtyrate_ready(QTestState *who)
{
QDict *rsp_return;
gchar *status;
const char *status;
bool ready;
rsp_return = query_dirty_rate(who);
g_assert(rsp_return);
status = g_strdup(qdict_get_str(rsp_return, "status"));
status = qdict_get_str(rsp_return, "status");
g_assert(status);
ready = g_strcmp0(status, "measuring");
qobject_unref(rsp_return);
return g_strcmp0(status, "measuring");
return ready;
}
static void wait_for_calc_dirtyrate_complete(QTestState *who,
@ -3428,7 +3356,7 @@ static void wait_for_calc_dirtyrate_complete(QTestState *who,
static int64_t get_dirty_rate(QTestState *who)
{
QDict *rsp_return;
gchar *status;
const char *status;
QList *rates;
const QListEntry *entry;
QDict *rate;
@ -3437,7 +3365,7 @@ static int64_t get_dirty_rate(QTestState *who)
rsp_return = query_dirty_rate(who);
g_assert(rsp_return);
status = g_strdup(qdict_get_str(rsp_return, "status"));
status = qdict_get_str(rsp_return, "status");
g_assert(status);
g_assert_cmpstr(status, ==, "measured");
@ -3823,8 +3751,6 @@ int main(int argc, char **argv)
migration_test_add("/migration/bad_dest", test_baddest);
#ifndef _WIN32
migration_test_add("/migration/analyze-script", test_analyze_script);
migration_test_add("/migration/vmstate-checker-script",
test_vmstate_checker_script);
#endif
if (is_x86) {
@ -4026,8 +3952,10 @@ int main(int argc, char **argv)
if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) {
migration_test_add("/migration/dirty_ring",
test_precopy_unix_dirty_ring);
migration_test_add("/migration/vcpu_dirty_limit",
test_vcpu_dirty_limit);
if (qtest_has_machine("pc")) {
migration_test_add("/migration/vcpu_dirty_limit",
test_vcpu_dirty_limit);
}
}
ret = g_test_run();

View file

@ -135,6 +135,7 @@ void test_tls_init(const char *keyfile)
void test_tls_cleanup(const char *keyfile)
{
asn1_delete_structure(&pkix_asn1);
gnutls_x509_privkey_deinit(privkey);
unlink(keyfile);
}
@ -502,8 +503,7 @@ void test_tls_write_cert_chain(const char *filename,
g_free(buffer);
}
void test_tls_discard_cert(QCryptoTLSTestCertReq *req)
void test_tls_deinit_cert(QCryptoTLSTestCertReq *req)
{
if (!req->crt) {
return;
@ -511,6 +511,15 @@ void test_tls_discard_cert(QCryptoTLSTestCertReq *req)
gnutls_x509_crt_deinit(req->crt);
req->crt = NULL;
}
void test_tls_discard_cert(QCryptoTLSTestCertReq *req)
{
if (!req->crt) {
return;
}
test_tls_deinit_cert(req);
if (getenv("QEMU_TEST_DEBUG_CERTS") == NULL) {
unlink(req->filename);

View file

@ -73,6 +73,12 @@ void test_tls_generate_cert(QCryptoTLSTestCertReq *req,
void test_tls_write_cert_chain(const char *filename,
gnutls_x509_crt_t *certs,
size_t ncerts);
/*
* Deinitialize the QCryptoTLSTestCertReq, but don't delete the certificate
* file on disk. (The caller is then responsible for doing that themselves.
*/
void test_tls_deinit_cert(QCryptoTLSTestCertReq *req);
/* Deinit the QCryptoTLSTestCertReq, and delete the certificate file */
void test_tls_discard_cert(QCryptoTLSTestCertReq *req);
void test_tls_init(const char *keyfile);