[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 09/27] migration: add reporting of errors for out
From: |
Daniel P. Berrange |
Subject: |
[Qemu-devel] [PATCH v2 09/27] migration: add reporting of errors for outgoing migration |
Date: |
Tue, 16 Feb 2016 16:15:00 +0000 |
Currently if an app 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
total time: 0 milliseconds
error description: Error connecting to socket: Connection refused
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
Signed-off-by: Daniel P. Berrange <address@hidden>
---
hmp.c | 8 ++++++++
include/migration/migration.h | 5 ++++-
include/qapi/error.h | 2 +-
migration/migration.c | 12 +++++++++---
migration/rdma.c | 10 +++-------
migration/tcp.c | 2 +-
migration/unix.c | 2 +-
qapi-schema.json | 5 ++++-
trace-events | 2 +-
util/error.c | 2 +-
10 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/hmp.c b/hmp.c
index c6419da..56428aa 100644
--- a/hmp.c
+++ b/hmp.c
@@ -33,6 +33,7 @@
#include "ui/console.h"
#include "block/qapi.h"
#include "qemu-io.h"
+#include "qemu/error-report.h"
#ifdef CONFIG_SPICE
#include <spice/enums.h>
@@ -238,6 +239,10 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
info->x_cpu_throttle_percentage);
}
+ if (info->has_error_desc) {
+ monitor_printf(mon, "error description: %s\n", info->error_desc);
+ }
+
qapi_free_MigrationInfo(info);
qapi_free_MigrationCapabilityStatusList(caps);
}
@@ -1519,6 +1524,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 63cc4ef..5d476e6 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -168,6 +168,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);
@@ -204,7 +207,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 e64fe54..39a2830 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -142,7 +142,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 f3519e5..bf6f93e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -681,6 +681,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;
@@ -853,12 +857,14 @@ 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);
+ error_free(s->error);
+ s->error = error_copy(error);
notifier_list_notify(&migration_state_notifiers, s);
}
@@ -1051,7 +1057,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 187fc1c..cd33d90 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3487,16 +3487,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) {
@@ -3504,7 +3502,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;
@@ -3516,7 +3514,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 e888a4e..48904e0 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 8d04897..d88af56 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -484,6 +484,8 @@
# throttled during auto-converge. This is only present when auto-converge
# has started throttling guest cpus. (Since 2.5)
#
+# @error-desc: the error description string, when @status == 'failed' (Since
2.6)
+#
# Since: 0.14.0
##
{ 'struct': 'MigrationInfo',
@@ -494,7 +496,8 @@
'*expected-downtime': 'int',
'*downtime': 'int',
'*setup-time': 'int',
- '*x-cpu-throttle-percentage': 'int'} }
+ '*x-cpu-throttle-percentage': 'int',
+ '*error-desc': 'str'} }
##
# @query-migrate
diff --git a/trace-events b/trace-events
index f986c81..4c94e33 100644
--- a/trace-events
+++ b/trace-events
@@ -1489,7 +1489,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 471b8b3..f134a6d 100644
--- a/util/error.c
+++ b/util/error.c
@@ -218,7 +218,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.0
- [Qemu-devel] [PATCH v2 06/27] migration: force QEMUFile to blocking mode for outgoing migration, (continued)
- [Qemu-devel] [PATCH v2 06/27] migration: force QEMUFile to blocking mode for outgoing migration, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 10/27] migration: convert post-copy to use QIOChannelBuffer, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 11/27] migration: convert unix socket protocol to use QIOChannel, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 13/27] migration: convert tcp socket protocol to use QIOChannel, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 08/27] migration: add helpers for creating QEMUFile from a QIOChannel, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 12/27] migration: rename unix.c to socket.c, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 14/27] migration: convert fd socket protocol to use QIOChannel, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 16/27] migration: convert RDMA to use QIOChannel interface, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 18/27] migration: delete QEMUFile buffer implementation, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 19/27] migration: delete QEMUSizedBuffer struct, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 09/27] migration: add reporting of errors for outgoing migration,
Daniel P. Berrange <=
- [Qemu-devel] [PATCH v2 15/27] migration: convert exec socket protocol to use QIOChannel, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 20/27] migration: delete QEMUFile sockets implementation, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 24/27] migration: define 'tls-creds' and 'tls-hostname' migration parameters, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 17/27] migration: convert savevm to use QIOChannel for writing to files, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 22/27] migration: move definition of struct QEMUFile back into qemu-file.c, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 21/27] migration: delete QEMUFile stdio implementation, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 25/27] migration: add support for encrypting data with TLS, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 26/27] migration: remove support for non-iovec based write handlers, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 23/27] migration: don't use an array for storing migrate parameters, Daniel P. Berrange, 2016/02/16
- [Qemu-devel] [PATCH v2 27/27] migration: remove qemu_get_fd method from QEMUFile, Daniel P. Berrange, 2016/02/16