From: Amit Shah <amit.shah@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Juan Quintela <quintela@redhat.com>,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
"Daniel P. Berrange" <berrange@redhat.com>,
qemu list <qemu-devel@nongnu.org>,
Amit Shah <amit.shah@redhat.com>
Subject: [Qemu-devel] [PULL 10/28] migration: add reporting of errors for outgoing migration
Date: Thu, 26 May 2016 11:42:01 +0530 [thread overview]
Message-ID: <d59ce6f34434bf47a9b26138c908650bf9a24be1.1464242913.git.amit.shah@redhat.com> (raw)
In-Reply-To: <cover.1464242913.git.amit.shah@redhat.com>
In-Reply-To: <cover.1464242913.git.amit.shah@redhat.com>
From: "Daniel P. Berrange" <berrange@redhat.com>
Currently if an application initiates an outgoing migration,
it may or may not, get an error reported back on failure. If
the error occurs synchronously to the 'migrate' command
execution, the client app will see the error message. This
is the case for DNS lookup failures. If the error occurs
asynchronously to the monitor command though, the error
will be thrown away and the client left guessing about
what went wrong. This is the case for failure to connect
to the TCP server (eg due to wrong port, or firewall
rules, or other similar errors).
In the future we'll be adding more scope for errors to
happen asynchronously with the TLS protocol handshake.
TLS errors are hard to diagnose even when they are well
reported, so discarding errors entirely will make it
impossible to debug TLS connection problems.
Management apps which do migration are already using
'query-migrate' / 'info migrate' to check up on progress
of background migration operations and to see their end
status. This is a fine place to also include the error
message when things go wrong.
This patch thus adds an 'error-desc' field to the
MigrationInfo struct, which will be populated when
the 'status' is set to 'failed':
(qemu) migrate -d tcp:localhost:9001
(qemu) info migrate
capabilities: xbzrle: off rdma-pin-all: off auto-converge: off zero-blocks: off compress: off events: off x-postcopy-ram: off
Migration status: failed (Error connecting to socket: Connection refused)
total time: 0 milliseconds
In the HMP, when doing non-detached migration, it is
also possible to display this error message directly
to the app.
(qemu) migrate tcp:localhost:9001
Error connecting to socket: Connection refused
Or with QMP
{
"execute": "query-migrate",
"arguments": {}
}
{
"return": {
"status": "failed",
"error-desc": "address resolution failed for myhost:9000: No address associated with hostname"
}
}
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <1461751518-12128-11-git-send-email-berrange@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hmp.c | 13 ++++++++++++-
include/migration/migration.h | 5 ++++-
include/qapi/error.h | 2 +-
migration/migration.c | 15 ++++++++++++---
migration/rdma.c | 10 +++-------
migration/tcp.c | 2 +-
migration/unix.c | 2 +-
qapi-schema.json | 7 ++++++-
trace-events | 2 +-
util/error.c | 2 +-
10 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/hmp.c b/hmp.c
index 9f9bcf9..a464ca9 100644
--- a/hmp.c
+++ b/hmp.c
@@ -35,6 +35,7 @@
#include "block/qapi.h"
#include "qemu-io.h"
#include "qemu/cutils.h"
+#include "qemu/error-report.h"
#ifdef CONFIG_SPICE
#include <spice/enums.h>
@@ -168,8 +169,15 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
}
if (info->has_status) {
- monitor_printf(mon, "Migration status: %s\n",
+ monitor_printf(mon, "Migration status: %s",
MigrationStatus_lookup[info->status]);
+ if (info->status == MIGRATION_STATUS_FAILED &&
+ info->has_error_desc) {
+ monitor_printf(mon, " (%s)\n", info->error_desc);
+ } else {
+ monitor_printf(mon, "\n");
+ }
+
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->total_time);
if (info->has_expected_downtime) {
@@ -1533,6 +1541,9 @@ static void hmp_migrate_status_cb(void *opaque)
if (status->is_block_migration) {
monitor_printf(status->mon, "\n");
}
+ if (info->has_error_desc) {
+ error_report("%s", info->error_desc);
+ }
monitor_resume(status->mon);
timer_del(status->timer);
g_free(status);
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 87ad577..d24c6ef 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -171,6 +171,9 @@ struct MigrationState
QSIMPLEQ_HEAD(src_page_requests, MigrationSrcPageRequest) src_page_requests;
/* The RAMBlock used in the last src_page_request */
RAMBlock *last_req_rb;
+
+ /* The last error that occurred */
+ Error *error;
};
void migrate_set_state(int *state, int old_state, int new_state);
@@ -207,7 +210,7 @@ void rdma_start_outgoing_migration(void *opaque, const char *host_port, Error **
void rdma_start_incoming_migration(const char *host_port, Error **errp);
-void migrate_fd_error(MigrationState *s);
+void migrate_fd_error(MigrationState *s, const Error *error);
void migrate_fd_connect(MigrationState *s);
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 11be232..0576659 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -134,7 +134,7 @@ typedef enum ErrorClass {
/*
* Get @err's human-readable error message.
*/
-const char *error_get_pretty(Error *err);
+const char *error_get_pretty(const Error *err);
/*
* Get @err's error class.
diff --git a/migration/migration.c b/migration/migration.c
index c960e16..1420ccc 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -691,6 +691,10 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_FAILED:
info->has_status = true;
+ if (s->error) {
+ info->has_error_desc = true;
+ info->error_desc = g_strdup(error_get_pretty(s->error));
+ }
break;
case MIGRATION_STATUS_CANCELLED:
info->has_status = true;
@@ -863,12 +867,15 @@ static void migrate_fd_cleanup(void *opaque)
notifier_list_notify(&migration_state_notifiers, s);
}
-void migrate_fd_error(MigrationState *s)
+void migrate_fd_error(MigrationState *s, const Error *error)
{
- trace_migrate_fd_error();
+ trace_migrate_fd_error(error ? error_get_pretty(error) : "");
assert(s->to_dst_file == NULL);
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
MIGRATION_STATUS_FAILED);
+ if (!s->error) {
+ s->error = error_copy(error);
+ }
notifier_list_notify(&migration_state_notifiers, s);
}
@@ -967,6 +974,8 @@ MigrationState *migrate_init(const MigrationParams *params)
s->postcopy_after_devices = false;
s->migration_thread_running = false;
s->last_req_rb = NULL;
+ error_free(s->error);
+ s->error = NULL;
migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
@@ -1076,7 +1085,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
}
if (local_err) {
- migrate_fd_error(s);
+ migrate_fd_error(s, local_err);
error_propagate(errp, local_err);
return;
}
diff --git a/migration/rdma.c b/migration/rdma.c
index 0d067a1..f8578b9 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3489,16 +3489,14 @@ void rdma_start_outgoing_migration(void *opaque,
const char *host_port, Error **errp)
{
MigrationState *s = opaque;
- Error *local_err = NULL, **temp = &local_err;
- RDMAContext *rdma = qemu_rdma_data_init(host_port, &local_err);
+ RDMAContext *rdma = qemu_rdma_data_init(host_port, errp);
int ret = 0;
if (rdma == NULL) {
- ERROR(temp, "Failed to initialize RDMA data structures! %d", ret);
goto err;
}
- ret = qemu_rdma_source_init(rdma, &local_err,
+ ret = qemu_rdma_source_init(rdma, errp,
s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]);
if (ret) {
@@ -3506,7 +3504,7 @@ void rdma_start_outgoing_migration(void *opaque,
}
trace_rdma_start_outgoing_migration_after_rdma_source_init();
- ret = qemu_rdma_connect(rdma, &local_err);
+ ret = qemu_rdma_connect(rdma, errp);
if (ret) {
goto err;
@@ -3518,7 +3516,5 @@ void rdma_start_outgoing_migration(void *opaque,
migrate_fd_connect(s);
return;
err:
- error_propagate(errp, local_err);
g_free(rdma);
- migrate_fd_error(s);
}
diff --git a/migration/tcp.c b/migration/tcp.c
index e1fa7f8..d0e0db9 100644
--- a/migration/tcp.c
+++ b/migration/tcp.c
@@ -40,7 +40,7 @@ static void tcp_wait_for_connect(int fd, Error *err, void *opaque)
if (fd < 0) {
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
s->to_dst_file = NULL;
- migrate_fd_error(s);
+ migrate_fd_error(s, err);
} else {
DPRINTF("migrate connect success\n");
s->to_dst_file = qemu_fopen_socket(fd, "wb");
diff --git a/migration/unix.c b/migration/unix.c
index d9aac36..b3537fd 100644
--- a/migration/unix.c
+++ b/migration/unix.c
@@ -40,7 +40,7 @@ static void unix_wait_for_connect(int fd, Error *err, void *opaque)
if (fd < 0) {
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
s->to_dst_file = NULL;
- migrate_fd_error(s);
+ migrate_fd_error(s, err);
} else {
DPRINTF("migrate connect success\n");
s->to_dst_file = qemu_fopen_socket(fd, "wb");
diff --git a/qapi-schema.json b/qapi-schema.json
index 9a322d1..e8c0353 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -484,6 +484,10 @@
# throttled during auto-converge. This is only present when auto-converge
# has started throttling guest cpus. (Since 2.7)
#
+# @error-desc: #optional the human readable error description string, when
+# @status is 'failed'. Clients should not attempt to parse the
+# error strings. (Since 2.6)
+#
# Since: 0.14.0
##
{ 'struct': 'MigrationInfo',
@@ -494,7 +498,8 @@
'*expected-downtime': 'int',
'*downtime': 'int',
'*setup-time': 'int',
- '*cpu-throttle-percentage': 'int'} }
+ '*cpu-throttle-percentage': 'int',
+ '*error-desc': 'str'} }
##
# @query-migrate
diff --git a/trace-events b/trace-events
index b53c354..1ef4a9a 100644
--- a/trace-events
+++ b/trace-events
@@ -1481,7 +1481,7 @@ await_return_path_close_on_source_close(void) ""
await_return_path_close_on_source_joining(void) ""
migrate_set_state(int new_state) "new state %d"
migrate_fd_cleanup(void) ""
-migrate_fd_error(void) ""
+migrate_fd_error(const char *error_desc) "error=%s"
migrate_fd_cancel(void) ""
migrate_handle_rp_req_pages(const char *rbname, size_t start, size_t len) "in %s at %zx len %zx"
migrate_pending(uint64_t size, uint64_t max, uint64_t post, uint64_t nonpost) "pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 " nonpost=%" PRIu64 ")"
diff --git a/util/error.c b/util/error.c
index cae2511..9c40b1f 100644
--- a/util/error.c
+++ b/util/error.c
@@ -217,7 +217,7 @@ ErrorClass error_get_class(const Error *err)
return err->err_class;
}
-const char *error_get_pretty(Error *err)
+const char *error_get_pretty(const Error *err)
{
return err->msg;
}
--
2.5.5
next prev parent reply other threads:[~2016-05-26 6:13 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-26 6:11 [Qemu-devel] [PULL 00/28] migration: support for TLS Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 01/28] s390: use FILE instead of QEMUFile for creating text file Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 02/28] io: avoid double-free when closing QIOChannelBuffer Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 03/28] migration: remove use of qemu_bufopen from vmstate tests Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 04/28] migration: ensure qemu_fflush() always writes full data amount Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 05/28] migration: split migration hooks out of QEMUFileOps Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 06/28] migration: introduce set_blocking function in QEMUFileOps Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 07/28] migration: force QEMUFile to blocking mode for outgoing migration Amit Shah
2016-05-26 6:11 ` [Qemu-devel] [PULL 08/28] migration: introduce a new QEMUFile impl based on QIOChannel Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 09/28] migration: add helpers for creating QEMUFile from a QIOChannel Amit Shah
2016-05-26 6:12 ` Amit Shah [this message]
2016-05-26 15:00 ` [Qemu-devel] [PULL 10/28] migration: add reporting of errors for outgoing migration Eric Blake
2016-05-31 15:16 ` Daniel P. Berrange
2016-06-06 8:38 ` Paolo Bonzini
2016-05-26 6:12 ` [Qemu-devel] [PULL 11/28] migration: convert post-copy to use QIOChannelBuffer Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 12/28] migration: convert unix socket protocol to use QIOChannel Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 13/28] migration: rename unix.c to socket.c Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 14/28] migration: convert tcp socket protocol to use QIOChannel Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 15/28] migration: convert fd " Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 16/28] migration: convert exec " Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 17/28] migration: convert RDMA to use QIOChannel interface Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 18/28] migration: convert savevm to use QIOChannel for writing to files Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 19/28] migration: delete QEMUFile buffer implementation Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 20/28] migration: delete QEMUSizedBuffer struct Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 21/28] migration: delete QEMUFile sockets implementation Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 22/28] migration: delete QEMUFile stdio implementation Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 23/28] migration: move definition of struct QEMUFile back into qemu-file.c Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 24/28] migration: don't use an array for storing migrate parameters Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 25/28] migration: define 'tls-creds' and 'tls-hostname' migration parameters Amit Shah
2016-05-26 15:05 ` Eric Blake
2016-05-27 10:02 ` Amit Shah
2016-05-31 9:22 ` Daniel P. Berrange
2016-05-26 6:12 ` [Qemu-devel] [PULL 26/28] migration: add support for encrypting data with TLS Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 27/28] migration: remove support for non-iovec based write handlers Amit Shah
2016-05-26 6:12 ` [Qemu-devel] [PULL 28/28] migration: remove qemu_get_fd method from QEMUFile Amit Shah
2016-05-26 16:29 ` [Qemu-devel] [PULL 00/28] migration: support for TLS Peter Maydell
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=d59ce6f34434bf47a9b26138c908650bf9a24be1.1464242913.git.amit.shah@redhat.com \
--to=amit.shah@redhat.com \
--cc=berrange@redhat.com \
--cc=dgilbert@redhat.com \
--cc=peter.maydell@linaro.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).