[Libvir] PATCH: 1/4 Changing handling of monitor line endings

Daniel P. Berrange berrange at redhat.com
Tue Oct 16 20:48:48 UTC 2007


To avoid the callers having to remember to use \r instead of \n, this patch
removes the need for ading a line ending to monitor commands. We now will
automatically send the neccessary line ending from the qemuMonitorCommand
method directly. It also adds logging of monitor output for debugging when
things go wrong when a command.

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r 700d68c399ee src/qemu_driver.c
--- a/src/qemu_driver.c	Tue Oct 16 15:17:14 2007 -0400
+++ b/src/qemu_driver.c	Tue Oct 16 15:21:05 2007 -0400
@@ -1311,10 +1311,12 @@ static int qemudMonitorCommand(struct qe
                                char **reply) {
     int size = 0;
     char *buf = NULL;
-
-    if (write(vm->monitor, cmd, strlen(cmd)) < 0) {
-        return -1;
-    }
+    size_t cmdlen = strlen(cmd);
+
+    if (safewrite(vm->monitor, cmd, cmdlen) != cmdlen)
+        return -1;
+    if (safewrite(vm->monitor, "\r", 1) != 1)
+        return -1;
 
     *reply = NULL;
 
@@ -1328,32 +1330,24 @@ static int qemudMonitorCommand(struct qe
             int got = read(vm->monitor, data, sizeof(data));
             char *b;
 
-            if (got == 0) {
-                if (buf)
-                    free(buf);
-                return -1;
-            }
+            if (got == 0)
+                goto error;
             if (got < 0) {
                 if (errno == EINTR)
                     continue;
                 if (errno == EAGAIN)
                     break;
-
-                if (buf)
-                    free(buf);
-                return -1;
+                goto error;
             }
-            if (!(b = realloc(buf, size+got+1))) {
-                free(buf);
-                return -1;
-            }
+            if (!(b = realloc(buf, size+got+1)))
+                goto error;
+
             buf = b;
             memmove(buf+size, data, got);
             buf[size+got] = '\0';
             size += got;
         }
-        if (buf)
-            qemudDebug("Mon [%s]", buf);
+
         /* Look for QEMU prompt to indicate completion */
         if (buf && ((tmp = strstr(buf, "\n(qemu) ")) != NULL)) {
             tmp[0] = '\0';
@@ -1364,14 +1358,27 @@ static int qemudMonitorCommand(struct qe
         if (poll(&fd, 1, -1) < 0) {
             if (errno == EINTR)
                 goto pollagain;
-
-            free(buf);
-            return -1;
-        }
-    }
+            goto error;
+        }
+    }
+
+    /* Log, but ignore failures to write logfile for VM */
+    if (safewrite(vm->logfile, buf, strlen(buf)) < 0)
+        qemudLog(QEMUD_WARN, "Unable to log VM console data: %s",
+                 strerror(errno));
 
     *reply = buf;
     return 0;
+
+ error:
+    if (buf) {
+        /* Log, but ignore failures to write logfile for VM */
+        if (safewrite(vm->logfile, buf, strlen(buf)) < 0)
+            qemudLog(QEMUD_WARN, "Unable to log VM console data: %s",
+                     strerror(errno));
+        free(buf);
+    }
+    return -1;
 }
 
 
@@ -1806,7 +1813,7 @@ static int qemudDomainSuspend(virDomainP
     if (vm->state == VIR_DOMAIN_PAUSED)
         return 0;
 
-    if (qemudMonitorCommand(driver, vm, "stop\r", &info) < 0) {
+    if (qemudMonitorCommand(driver, vm, "stop", &info) < 0) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "suspend operation failed");
         return -1;
     }
@@ -1831,7 +1838,7 @@ static int qemudDomainResume(virDomainPt
     }
     if (vm->state == VIR_DOMAIN_RUNNING)
         return 0;
-    if (qemudMonitorCommand(driver, vm, "cont\r", &info) < 0) {
+    if (qemudMonitorCommand(driver, vm, "cont", &info) < 0) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "resume operation failed");
         return -1;
     }
@@ -2063,7 +2070,7 @@ static int qemudDomainSave(virDomainPtr 
     }
     if (asprintf (&command, "migrate \"exec:"
                   "dd of='%s' oflag=append conv=notrunc 2>/dev/null"
-                  "\"\r", safe_path) == -1) {
+                  "\"", safe_path) == -1) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "out of memory");
         free(safe_path);
@@ -2190,7 +2197,7 @@ static int qemudDomainRestore(virConnect
     /* If it was running before, resume it now. */
     if (header.was_running) {
         char *info;
-        if (qemudMonitorCommand(driver, vm, "cont\r", &info) < 0) {
+        if (qemudMonitorCommand(driver, vm, "cont", &info) < 0) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
                              "failed to resume domain");
             return -1;


More information about the libvir-list mailing list