Cole Robinson wrote:
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.
I think the idea is great. I'm a little worried about the implementation, though.
--- 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)
Leftover cruft, it looks like. It's not used anywhere, and you can just use
DEBUG() for the same thing.
+
#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);
+ }
What happens if you have enough arguments that you overrun 512 bytes in the cmd
array? I guess the sizeof(cmd) - strlen(cmd) - 1 will protect you from running
off the end of the buffer, but you'll truncate the output. There are some
examples elsewhere in the code (src/qemu_conf.c, I think) that properly build up
the whole thing; it's probably worthwhile to look there.
+ 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);
Don't you also want to close(outfd) here?
+ }
+ if (errfd) {
+ ret = saferead(errfd, err, sizeof(err)-1);
+ err[ret < 0 ? 0 : ret] = '\0';
+ if (*err)
+ DEBUG("Command stderr: %s", err);
Ditto for errfd.
Chris Lalancette