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 second submission:
- Handle one more, newly added, "cont" command
---
src/qemu_driver.c | 89 +++++++++++++++++++++++++++++++----------------------
1 files changed, 52 insertions(+), 37 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index adce809..b1a1c6a 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;
@@ -2582,6 +2587,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) {
@@ -3066,7 +3085,6 @@ cleanup:
static int qemudDomainResume(virDomainPtr dom) {
struct qemud_driver *driver = dom->conn->privateData;
- char *info;
virDomainObjPtr vm;
int ret = -1;
virDomainEventPtr event = NULL;
@@ -3087,17 +3105,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;
@@ -3788,13 +3807,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);
@@ -4272,13 +4291,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;
virDomainSaveStatus(conn, driver->stateDir, vm);
}
@@ -6950,14 +6970,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
@@ -6965,16 +6982,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)
@@ -6997,7 +7011,6 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
virDomainObjPtr vm;
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
- char *info = NULL;
qemuDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dname);
@@ -7011,18 +7024,20 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
* object, but if no, clean up the empty qemu process.
*/
if (retcode == 0) {
+ bool error_reported;
+
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
/* run 'cont' on the destination, which allows migration on qemu
* >= 0.10.6 to work properly. This isn't strictly necessary on
* older qemu's, but it also doesn't hurt anything there
*/
- if (qemudMonitorCommand(vm, "cont", &info) < 0) {
- qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- "%s", _("resume operation failed"));
+ if (qemudMonitorSendCont(dconn, vm, &error_reported) < 0) {
+ if (!error_reported)
+ qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("resume operation
failed"));
goto cleanup;
}
- VIR_FREE(info);
vm->state = VIR_DOMAIN_RUNNING;
event = virDomainEventNewFromObj(vm,
--
1.6.2.5