The interface allows qemudMonitorSendCont() to report errors that are not overridden by its callers. Also fix a potential infinite loop in qemuDomainCoreDump() if sending cont repeatedly fails. Changes since the first submission: - Suport reporting errors that are not overridden by callers. --- src/qemu_driver.c | 78 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 7a2e581..d654651 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -28,6 +28,7 @@ #include <dirent.h> #include <limits.h> #include <string.h> +#include <stdbool.h> #include <stdio.h> #include <strings.h> #include <stdarg.h> @@ -135,6 +136,9 @@ static int qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *extraPrompt, int scm_fd, char **reply); +static int qemudMonitorSendCont(virConnectPtr conn, + const virDomainObjPtr vm, + bool *error_reported); static int qemudDomainSetMemoryBalloon(virConnectPtr conn, virDomainObjPtr vm, unsigned long newmem); @@ -1225,7 +1229,6 @@ static int qemudInitCpus(virConnectPtr conn, virDomainObjPtr vm, const char *migrateFrom) { - char *info = NULL; #if HAVE_SCHED_GETAFFINITY cpu_set_t mask; int i, maxcpu = QEMUD_CPUMASK_LEN; @@ -1260,13 +1263,15 @@ qemudInitCpus(virConnectPtr conn, #endif /* HAVE_SCHED_GETAFFINITY */ if (migrateFrom == NULL) { + bool error_reported; + /* Allow the CPUS to start executing */ - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("resume operation failed")); + if (qemudMonitorSendCont(conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("resume operation failed")); return -1; } - VIR_FREE(info); } return 0; @@ -2457,6 +2462,20 @@ qemudMonitorCommand(const virDomainObjPtr vm, return qemudMonitorCommandWithFd(vm, cmd, -1, reply); } +static int +qemudMonitorSendCont(virConnectPtr conn ATTRIBUTE_UNUSED, + const virDomainObjPtr vm, + bool *error_reported) { + char *reply; + + *error_reported = false; + if (qemudMonitorCommand(vm, "cont", &reply) < 0) + return -1; + qemudDebug ("%s: cont reply: %s", vm->def->name, info); + VIR_FREE(reply); + return 0; +} + static virDrvOpenStatus qemudOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { @@ -2941,7 +2960,6 @@ cleanup: static int qemudDomainResume(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; - char *info; virDomainObjPtr vm; int ret = -1; virDomainEventPtr event = NULL; @@ -2962,17 +2980,18 @@ static int qemudDomainResume(virDomainPtr dom) { goto cleanup; } if (vm->state == VIR_DOMAIN_PAUSED) { - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("resume operation failed")); + bool error_reported; + + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("resume operation failed")); goto cleanup; } vm->state = VIR_DOMAIN_RUNNING; - qemudDebug("Reply %s", info); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); - VIR_FREE(info); } if (virDomainSaveStatus(dom->conn, driver->stateDir, vm) < 0) goto cleanup; @@ -3663,13 +3682,13 @@ cleanup: will support synchronous operations so we always get here after the migration is complete. */ if (resume && paused) { - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("resuming after dump failed")); - goto cleanup; + bool error_reported; + + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("resuming after dump failed")); } - DEBUG ("%s: cont reply: %s", vm->def->name, info); - VIR_FREE(info); } if (vm) virDomainObjUnlock(vm); @@ -4147,13 +4166,14 @@ static int qemudDomainRestore(virConnectPtr conn, /* If it was running before, resume it now. */ if (header.was_running) { - char *info; - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("failed to resume domain")); + bool error_reported; + + if (qemudMonitorSendCont(conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("failed to resume domain")); goto cleanup; } - VIR_FREE(info); vm->state = VIR_DOMAIN_RUNNING; } ret = 0; @@ -6591,14 +6611,11 @@ qemudDomainMigratePerform (virDomainPtr dom, ret = 0; cleanup: - /* Note that we have to free info *first*, since we are re-using the - * variable below (and otherwise might cause a memory leak) - */ - VIR_FREE(info); - if (paused) { + bool error_reported; + /* we got here through some sort of failure; start the domain again */ - if (qemudMonitorCommand (vm, "cont", &info) < 0) { + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { /* Hm, we already know we are in error here. We don't want to * overwrite the previous error, though, so we just throw something * to the logs and hope for the best @@ -6606,16 +6623,13 @@ cleanup: VIR_ERROR(_("Failed to resume guest %s after failure\n"), vm->def->name); } - else { - DEBUG ("%s: cont reply: %s", vm->def->name, info); - VIR_FREE(info); - } event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_MIGRATED); } + VIR_FREE(info); if (vm) virDomainObjUnlock(vm); if (event) -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list