From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: peterx@redhat.com,
Leonardo Bras Soares Passos <lsoaresp@redhat.com>,
Fabiano Rosas <farosas@suse.de>,
Juan Quintela <quintela@redhat.com>,
Lukas Straub <lukasstraub2@web.de>
Subject: [PATCH 1/7] migration: Let migrate_set_error() take ownership
Date: Wed, 28 Jun 2023 17:49:56 -0400 [thread overview]
Message-ID: <20230628215002.73546-2-peterx@redhat.com> (raw)
In-Reply-To: <20230628215002.73546-1-peterx@redhat.com>
migrate_set_error() used one error_copy() so it always copy an error.
However that's not the major use case - the major use case is one would
like to pass the error to migrate_set_error() without further touching the
error.
It can be proved if we see most of the callers are freeing the error
explicitly right afterwards. There're a few outliers (only if when the
caller) where we can use error_copy() explicitly there.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
migration/migration.h | 6 +++---
migration/channel.c | 1 -
migration/migration.c | 20 ++++++++++++++------
migration/multifd.c | 10 ++++------
migration/postcopy-ram.c | 1 -
migration/ram.c | 1 -
6 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/migration/migration.h b/migration/migration.h
index 721b1c9473..32f87e3834 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -468,8 +468,8 @@ bool migration_has_all_channels(void);
uint64_t migrate_max_downtime(void);
-void migrate_set_error(MigrationState *s, const Error *error);
-void migrate_fd_error(MigrationState *s, const Error *error);
+void migrate_set_error(MigrationState *s, Error *error);
+void migrate_fd_error(MigrationState *s, Error *error);
void migrate_fd_connect(MigrationState *s, Error *error_in);
@@ -513,7 +513,7 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
void migration_make_urgent_request(void);
void migration_consume_urgent_request(void);
bool migration_rate_limit(void);
-void migration_cancel(const Error *error);
+void migration_cancel(Error *error);
void populate_vfio_info(MigrationInfo *info);
void postcopy_temp_page_reset(PostcopyTmpPage *tmp_page);
diff --git a/migration/channel.c b/migration/channel.c
index ca3319a309..48b3f6abd6 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -90,7 +90,6 @@ void migration_channel_connect(MigrationState *s,
}
}
migrate_fd_connect(s, error);
- error_free(error);
}
diff --git a/migration/migration.c b/migration/migration.c
index 203d40d4c9..13dccc4c12 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -160,7 +160,7 @@ void migration_object_init(void)
dirty_bitmap_mig_init();
}
-void migration_cancel(const Error *error)
+void migration_cancel(Error *error)
{
if (error) {
migrate_set_error(current_migration, error);
@@ -1197,11 +1197,20 @@ static void migrate_fd_cleanup_bh(void *opaque)
object_unref(OBJECT(s));
}
-void migrate_set_error(MigrationState *s, const Error *error)
+/*
+ * Set error for current migration state. The `error' ownership will be
+ * moved from the caller to MigrationState, so the caller doesn't need to
+ * free the error.
+ *
+ * If the caller still needs to reference the `error' passed in, one should
+ * use error_copy() explicitly.
+ */
+void migrate_set_error(MigrationState *s, Error *error)
{
QEMU_LOCK_GUARD(&s->error_mutex);
if (!s->error) {
- s->error = error_copy(error);
+ /* Record the first error triggered */
+ s->error = error;
}
}
@@ -1214,7 +1223,7 @@ static void migrate_error_free(MigrationState *s)
}
}
-void migrate_fd_error(MigrationState *s, const Error *error)
+void migrate_fd_error(MigrationState *s, Error *error)
{
trace_migrate_fd_error(error_get_pretty(error));
assert(s->to_dst_file == NULL);
@@ -1678,7 +1687,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
if (!(has_resume && resume)) {
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
}
- migrate_fd_error(s, local_err);
+ migrate_fd_error(s, error_copy(local_err));
error_propagate(errp, local_err);
return;
}
@@ -2595,7 +2604,6 @@ static MigThrError migration_detect_error(MigrationState *s)
if (local_error) {
migrate_set_error(s, local_error);
- error_free(local_error);
}
if (state == MIGRATION_STATUS_POSTCOPY_ACTIVE && ret) {
diff --git a/migration/multifd.c b/migration/multifd.c
index 3387d8277f..62bc2dbf49 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -551,7 +551,6 @@ void multifd_save_cleanup(void)
multifd_send_state->ops->send_cleanup(p, &local_err);
if (local_err) {
migrate_set_error(migrate_get_current(), local_err);
- error_free(local_err);
}
}
qemu_sem_destroy(&multifd_send_state->channels_ready);
@@ -750,7 +749,6 @@ out:
if (local_err) {
trace_multifd_send_error(p->id);
multifd_send_terminate_threads(local_err);
- error_free(local_err);
}
/*
@@ -883,7 +881,6 @@ static void multifd_new_send_channel_cleanup(MultiFDSendParams *p,
*/
p->quit = true;
object_unref(OBJECT(ioc));
- error_free(err);
}
static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
@@ -1148,7 +1145,6 @@ static void *multifd_recv_thread(void *opaque)
if (local_err) {
multifd_recv_terminate_threads(local_err);
- error_free(local_err);
}
qemu_mutex_lock(&p->mutex);
p->running = false;
@@ -1240,7 +1236,8 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
id = multifd_recv_initial_packet(ioc, &local_err);
if (id < 0) {
- multifd_recv_terminate_threads(local_err);
+ /* Copy local error because we'll also return it to caller */
+ multifd_recv_terminate_threads(error_copy(local_err));
error_propagate_prepend(errp, local_err,
"failed to receive packet"
" via multifd channel %d: ",
@@ -1253,7 +1250,8 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
if (p->c != NULL) {
error_setg(&local_err, "multifd: received id '%d' already setup'",
id);
- multifd_recv_terminate_threads(local_err);
+ /* Copy local error because we'll also return it to caller */
+ multifd_recv_terminate_threads(error_copy(local_err));
error_propagate(errp, local_err);
return;
}
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 5615ec29eb..6f6fb52bf1 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -1594,7 +1594,6 @@ postcopy_preempt_send_channel_done(MigrationState *s,
{
if (local_err) {
migrate_set_error(s, local_err);
- error_free(local_err);
} else {
migration_ioc_register_yank(ioc);
s->postcopy_qemufile_src = qemu_file_new_output(ioc);
diff --git a/migration/ram.c b/migration/ram.c
index 5283a75f02..ba4890563d 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4267,7 +4267,6 @@ static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host,
*/
error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr);
migration_cancel(err);
- error_free(err);
}
switch (ps) {
--
2.41.0
next prev parent reply other threads:[~2023-06-28 21:50 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-28 21:49 [PATCH 0/7] migration: Better error handling in return path thread Peter Xu
2023-06-28 21:49 ` Peter Xu [this message]
2023-06-28 21:49 ` [PATCH 2/7] migration: Introduce migrate_has_error() Peter Xu
2023-06-28 21:49 ` [PATCH 3/7] migration: Refactor error handling in source return path Peter Xu
2023-06-28 22:51 ` Fabiano Rosas
2023-06-28 21:49 ` [PATCH 4/7] migration: Deliver return path file error to migrate state too Peter Xu
2023-06-28 22:52 ` Fabiano Rosas
2023-06-28 21:50 ` [PATCH 5/7] migration: Display error in query-migrate irrelevant of status Peter Xu
2023-06-28 23:01 ` Fabiano Rosas
2023-06-29 19:56 ` Peter Xu
2023-06-28 21:50 ` [PATCH 6/7] qemufile: Always return a verbose error Peter Xu
2023-06-28 21:50 ` [PATCH 7/7] migration: Provide explicit error message for file shutdowns Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230628215002.73546-2-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=farosas@suse.de \
--cc=lsoaresp@redhat.com \
--cc=lukasstraub2@web.de \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.