[libvirt] [PATCH] Log virRun command output, return with error
Chris Lalancette
clalance at redhat.com
Wed Sep 24 06:29:32 UTC 2008
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
More information about the libvir-list
mailing list