[libvirt] [PATCH] Log virRun command output, return with error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The attached patch adds some extra logging to the
virRun command. The full argv is now logged with
DEBUG, as well as the commands stdout and stderr
(if anything is found).

Also, if the command returns an error, we raise
the stderr content with the reported error msg.
This will significantly help with debugging certain
issues, particularly with the storage driver which
makes heavy use of virRun.

Thanks,
Cole
diff --git a/src/util.c b/src/util.c
index ca14be1..d0fa38d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -54,6 +54,9 @@
 #include "memory.h"
 #include "util-lib.c"
 
+#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
+#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)
+
 #ifndef NSIG
 # define NSIG 32
 #endif
@@ -404,10 +407,19 @@ int
 virRun(virConnectPtr conn,
        const char *const*argv,
        int *status) {
-    int childpid, exitstatus, ret;
+    int childpid, exitstatus, ret, i;
+    int errfd = -1, outfd = -1;
+    char out[256] = "\0", err[256] = "\0", cmd[512] = "\0";;
+
+    /* Log argv */
+    for (i = 0; argv[i] != NULL; ++i) {
+        strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
+        strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1);
+    }
+    DEBUG("Running command '%s'", cmd);
 
     if ((ret = virExec(conn, argv, NULL, NULL,
-                       &childpid, -1, NULL, NULL, VIR_EXEC_NONE)) < 0)
+                       &childpid, -1, &outfd, &errfd, VIR_EXEC_NONE)) < 0)
         return ret;
 
     while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR);
@@ -418,16 +430,31 @@ virRun(virConnectPtr conn,
         return -1;
     }
 
+    /* Log command output */
+    if (outfd) {
+        ret = saferead(outfd, out, sizeof(out)-1);
+        err[ret < 0 ? 0 : ret] = '\0';
+        if (*out)
+            DEBUG("Command stdout: %s", out);
+    }
+    if (errfd) {
+        ret = saferead(errfd, err, sizeof(err)-1);
+        err[ret < 0 ? 0 : ret] = '\0';
+        if (*err)
+            DEBUG("Command stderr: %s", err);
+    }
+
     if (status == NULL) {
         errno = EINVAL;
         if (WIFEXITED(exitstatus) && WEXITSTATUS(exitstatus) == 0)
             return 0;
 
         ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("%s exited with non-zero status %d and signal %d"),
+                    _("%s exited with non-zero status %d and signal %d: %s"),
                     argv[0],
                     WIFEXITED(exitstatus) ? WEXITSTATUS(exitstatus) : 0,
-                    WIFSIGNALED(exitstatus) ? WTERMSIG(exitstatus) : 0);
+                    WIFSIGNALED(exitstatus) ? WTERMSIG(exitstatus) : 0,
+                    err);
         return -1;
     } else {
         *status = exitstatus;
--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]