Olaf Hering
2013-Feb-15 20:07 UTC
[PATCH] tools/xc: print messages from xc_save with xc_report
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1360958742 -3600 # Node ID 83a05c99299d60197fbb7eac219054b371d61eff # Parent 6ff99ddc4c41af31863393cd2239bc03fb63642c tools/xc: print messages from xc_save with xc_report Make use of xc_report in xc_save to log also pid if some error occoured. Rework code in switch_qemu_logdirty, fix memleak. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 6ff99ddc4c41 -r 83a05c99299d tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -119,6 +119,7 @@ void xc_report_progress_step(xc_interfac /* anamorphic macros: struct xc_interface *xch must be in scope */ +#define WPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_WARN,0, _f , ## _a) #define IPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_INFO,0, _f , ## _a) #define DPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DETAIL,0, _f , ## _a) #define DBGPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DEBUG,0, _f , ## _a) diff -r 6ff99ddc4c41 -r 83a05c99299d tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c +++ b/tools/xcutils/xc_restore.c @@ -56,6 +56,7 @@ main(int argc, char **argv) if ( ret == 0 ) { + /* xend expects this output, part of protocol */ printf("store-mfn %li\n", store_mfn); if ( !hvm ) printf("console-mfn %li\n", console_mfn); diff -r 6ff99ddc4c41 -r 83a05c99299d tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c +++ b/tools/xcutils/xc_save.c @@ -7,6 +7,7 @@ * */ +#define _GNU_SOURCE #include <err.h> #include <stdlib.h> #include <stdint.h> @@ -19,6 +20,7 @@ #include <fcntl.h> #include <err.h> +#include <xc_private.h> #include <xenstore.h> #include <xenctrl.h> #include <xenguest.h> @@ -51,16 +53,17 @@ static int compat_suspend(void) * receive the acknowledgement from the subscribe event channel. */ static int evtchn_suspend(void) { + xc_interface *xch = si.xch; int rc; rc = xc_evtchn_notify(si.xce, si.suspend_evtchn); if (rc < 0) { - warnx("failed to notify suspend request channel: %d", rc); + WPRINTF("failed to notify suspend request channel: %d", rc); return 0; } if (xc_await_suspend(si.xch, si.xce, si.suspend_evtchn) < 0) { - warnx("suspend failed"); + WPRINTF("suspend failed"); return 0; } @@ -104,61 +107,66 @@ static int suspend(void* data) static int switch_qemu_logdirty(int domid, unsigned int enable, void *data) { + xc_interface *xch = si.xch; struct xs_handle *xs; - char *path, *p, *ret_str, *cmd_str, **watch; + char *path, *p, *ret_str, **watch; + const char *cmd_str; unsigned int len; + int ret, again; struct timeval tv; fd_set fdset; - if ((xs = xs_daemon_open()) == NULL) - errx(1, "Couldn''t contact xenstore"); - if (!(path = strdup("/local/domain/0/device-model/"))) - errx(1, "can''t get domain path in store"); - if (!(path = realloc(path, strlen(path) - + 10 - + strlen("/logdirty/cmd") + 1))) - errx(1, "no memory for constructing xenstore path"); - snprintf(path + strlen(path), 11, "%i", domid); - strcat(path, "/logdirty/"); - p = path + strlen(path); + if ((xs = xs_daemon_open()) == NULL) { + PERROR("Couldn''t contact xenstore"); + exit(1); + } + ret = asprintf(&path, "/local/domain/0/device-model/%i/logdirty/ret", domid); + if (ret < 0) { + ERROR("no memory for constructing xenstore path"); + exit(1); + } + p = path + ret - 3; /* Watch for qemu''s return value */ - strcpy(p, "ret"); - if (!xs_watch(xs, path, "qemu-logdirty-ret")) - errx(1, "can''t set watch in store (%s)\n", path); + if (!xs_watch(xs, path, "qemu-logdirty-ret")) { + PERROR("can''t set watch in store (%s)", path); + exit(1); + } - if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) - errx(1, "can''t get logdirty cmd path in store"); + cmd_str = enable ? "enable" : "disable"; - /* Tell qemu that we want it to start logging dirty page to Xen */ + /* Tell qemu that we want it to start logging dirty pages to Xen */ strcpy(p, "cmd"); - if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) - errx(1, "can''t write to store path (%s)\n", - path); + if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) { + PERROR("can''t write to store path (%s)", path); + exit(1); + } - /* Wait a while for qemu to signal that it has service logdirty command */ - read_again: - tv.tv_sec = 5; - tv.tv_usec = 0; - FD_ZERO(&fdset); - FD_SET(xs_fileno(xs), &fdset); + /* Wait a while for qemu to signal that it has serviced logdirty command */ + do { + tv.tv_sec = 5; + tv.tv_usec = 0; + FD_ZERO(&fdset); + FD_SET(xs_fileno(xs), &fdset); + errno = 0; - if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) - errx(1, "timed out waiting for qemu logdirty response.\n"); - - watch = xs_read_watch(xs, &len); - free(watch); - - strcpy(p, "ret"); - ret_str = xs_read(xs, XBT_NULL, path, &len); - if (ret_str == NULL || strcmp(ret_str, cmd_str)) + if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) { + PERROR("timed out waiting for qemu logdirty response."); + exit(1); + } + + watch = xs_read_watch(xs, &len); + free(watch); + + strcpy(p, "ret"); + ret_str = xs_read(xs, XBT_NULL, path, &len); + again = ret_str == NULL || strcmp(ret_str, cmd_str); + free(ret_str); /* Watch fired but value is not yet right */ - goto read_again; + } while (again); free(path); - free(cmd_str); - free(ret_str); return 0; } @@ -166,6 +174,7 @@ static int switch_qemu_logdirty(int domi int main(int argc, char **argv) { + xc_interface *xch; unsigned int maxit, max_f, lflags; int io_fd, ret, port; struct save_callbacks callbacks; @@ -186,26 +195,26 @@ main(int argc, char **argv) lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL; lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS; l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags); - si.xch = xc_interface_open(l, 0, 0); + xch = si.xch = xc_interface_open(l, 0, 0); if (!si.xch) errx(1, "failed to open control interface"); si.xce = xc_evtchn_open(NULL, 0); if (si.xce == NULL) - warnx("failed to open event channel handle"); + WPRINTF("failed to open event channel handle"); else { port = xs_suspend_evtchn_port(si.domid); if (port < 0) - warnx("failed to get the suspend evtchn port\n"); + WPRINTF("failed to get the suspend evtchn port\n"); else { si.suspend_evtchn xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port); if (si.suspend_evtchn < 0) - warnx("suspend event channel initialization failed, " + WPRINTF("suspend event channel initialization failed, " "using slow path"); } }
Olaf Hering
2013-Feb-15 20:36 UTC
Re: [PATCH] tools/xc: print messages from xc_save with xc_report
On Fri, Feb 15, Olaf Hering wrote:> +++ b/tools/xcutils/xc_save.c> si.xce = xc_evtchn_open(NULL, 0); > if (si.xce == NULL) > - warnx("failed to open event channel handle"); > + WPRINTF("failed to open event channel handle"); > else > { > port = xs_suspend_evtchn_port(si.domid); > > if (port < 0) > - warnx("failed to get the suspend evtchn port\n"); > + WPRINTF("failed to get the suspend evtchn port\n"); > else > { > si.suspend_evtchn > xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port); > > if (si.suspend_evtchn < 0) > - warnx("suspend event channel initialization failed, " > + WPRINTF("suspend event channel initialization failed, " > "using slow path"); > }Is this path well tested, or should these three be fatal errors? Olaf