savevm: Improve error message for blocked migration

If an internal snapshot can't be saved because migration is blocked
(most commonly probably because of AHCI), we had a really bad error
message:

$ echo -e "savevm foo\nquit" | qemu -M q35 /tmp/test.qcow2 -monitor stdio
QEMU 2.2.50 monitor - type 'help' for more information
(qemu) savevm foo
Error -22 while writing VM
(qemu) quit

This patch converts qemu_savevm_state() to the Error infrastructure so
that a useful error pointing to the problematic device is produced now:

$ echo -e "savevm foo\nquit" | qemu -M q35 /tmp/test.qcow2 -monitor stdio
QEMU 2.2.50 monitor - type 'help' for more information
(qemu) savevm foo
State blocked by non-migratable device '0000:00:1f.2/ich9_ahci'
(qemu) quit

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1423574702-23072-1-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Kevin Wolf 2015-02-10 14:25:02 +01:00 committed by Stefan Hajnoczi
parent 141cabe6f1
commit 5d80448c3f
1 changed files with 7 additions and 4 deletions

View File

@ -821,7 +821,7 @@ void qemu_savevm_state_cancel(void)
} }
} }
static int qemu_savevm_state(QEMUFile *f) static int qemu_savevm_state(QEMUFile *f, Error **errp)
{ {
int ret; int ret;
MigrationParams params = { MigrationParams params = {
@ -829,7 +829,7 @@ static int qemu_savevm_state(QEMUFile *f)
.shared = 0 .shared = 0
}; };
if (qemu_savevm_state_blocked(NULL)) { if (qemu_savevm_state_blocked(errp)) {
return -EINVAL; return -EINVAL;
} }
@ -850,6 +850,7 @@ static int qemu_savevm_state(QEMUFile *f)
} }
if (ret != 0) { if (ret != 0) {
qemu_savevm_state_cancel(); qemu_savevm_state_cancel();
error_setg_errno(errp, -ret, "Error while writing VM state");
} }
return ret; return ret;
} }
@ -1102,6 +1103,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
qemu_timeval tv; qemu_timeval tv;
struct tm tm; struct tm tm;
const char *name = qdict_get_try_str(qdict, "name"); const char *name = qdict_get_try_str(qdict, "name");
Error *local_err = NULL;
/* Verify if there is a device that doesn't support snapshots and is writable */ /* Verify if there is a device that doesn't support snapshots and is writable */
bs = NULL; bs = NULL;
@ -1160,11 +1162,12 @@ void do_savevm(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "Could not open VM state file\n"); monitor_printf(mon, "Could not open VM state file\n");
goto the_end; goto the_end;
} }
ret = qemu_savevm_state(f); ret = qemu_savevm_state(f, &local_err);
vm_state_size = qemu_ftell(f); vm_state_size = qemu_ftell(f);
qemu_fclose(f); qemu_fclose(f);
if (ret < 0) { if (ret < 0) {
monitor_printf(mon, "Error %d while writing VM\n", ret); monitor_printf(mon, "%s\n", error_get_pretty(local_err));
error_free(local_err);
goto the_end; goto the_end;
} }