migration: Plug memory leaks after migrate_set_error()

migrate_set_error(s, err) stores a copy of @err in @s.  The original
@err is not freed.  Most callers free it immediately.  Some callers
free it later, or pass it on.  And some leak it.  Fix those.

Perhaps migrate_set_error(s, err) should take ownership of @err.  The
callers that free it immediately would become simpler, and avoid a
copy and a deallocation.  The others would have to pass
error_copy(err).

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Link: https://lore.kernel.org/r/20251115083500.2753895-2-armbru@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
Markus Armbruster 2025-11-15 09:34:58 +01:00 committed by Peter Xu
parent 911bdd34ca
commit 93817ec396
2 changed files with 4 additions and 1 deletions

View file

@ -159,11 +159,12 @@ static void cpr_exec_cb(void *opaque)
error_report_err(error_copy(err)); error_report_err(error_copy(err));
migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED); migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
migrate_set_error(s, err); migrate_set_error(s, err);
error_free(err);
err = NULL;
/* Note, we can go from state COMPLETED to FAILED */ /* Note, we can go from state COMPLETED to FAILED */
migration_call_notifiers(s, MIG_EVENT_PRECOPY_FAILED, NULL); migration_call_notifiers(s, MIG_EVENT_PRECOPY_FAILED, NULL);
err = NULL;
if (!migration_block_activate(&err)) { if (!migration_block_activate(&err)) {
/* error was already reported */ /* error was already reported */
error_free(err); error_free(err);

View file

@ -964,6 +964,7 @@ bool multifd_send_setup(void)
if (!multifd_new_send_channel_create(p, &local_err)) { if (!multifd_new_send_channel_create(p, &local_err)) {
migrate_set_error(s, local_err); migrate_set_error(s, local_err);
error_free(local_err);
ret = -1; ret = -1;
} }
} }
@ -988,6 +989,7 @@ bool multifd_send_setup(void)
ret = multifd_send_state->ops->send_setup(p, &local_err); ret = multifd_send_state->ops->send_setup(p, &local_err);
if (ret) { if (ret) {
migrate_set_error(s, local_err); migrate_set_error(s, local_err);
error_free(local_err);
goto err; goto err;
} }
assert(p->iov); assert(p->iov);