From cce99fb1320455ab2f67bee05b823f37b33c1afd Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 18 Mar 2009 11:49:26 +0000 Subject: Move the suspend event channel function to libxc, it will use the /var/lib/xen/suspend_evtchn_lock.d to protect the access. Signed-off-by: Jiang Yunhong --- tools/xcutils/xc_save.c | 114 +++++++++++------------------------------------- 1 file changed, 25 insertions(+), 89 deletions(-) (limited to 'tools/xcutils') diff --git a/tools/xcutils/xc_save.c b/tools/xcutils/xc_save.c index 0202d88720..d38bea409e 100644 --- a/tools/xcutils/xc_save.c +++ b/tools/xcutils/xc_save.c @@ -46,83 +46,6 @@ static int compat_suspend(void) !strncmp(ans, "done\n", 5)); } -static int suspend_evtchn_release(int xce, int suspend_evtchn) -{ - if (suspend_evtchn >= 0) - xc_evtchn_unbind(xce, suspend_evtchn); - - return 0; -} - -static int await_suspend(int xce, int suspend_evtchn) -{ - int rc; - - do { - rc = xc_evtchn_pending(xce); - if (rc < 0) { - warnx("error polling suspend notification channel: %d", rc); - return -1; - } - } while (rc != suspend_evtchn); - - /* harmless for one-off suspend */ - if (xc_evtchn_unmask(xce, suspend_evtchn) < 0) - warnx("failed to unmask suspend notification channel: %d", rc); - - return 0; -} - -static int suspend_evtchn_init(int xc, int xce, int domid) -{ - struct xs_handle *xs; - char path[128]; - char *portstr; - unsigned int plen; - int port; - int rc, suspend_evtchn = -1; - - xs = xs_daemon_open(); - if (!xs) { - warnx("failed to get xenstore handle"); - return -1; - } - sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid); - portstr = xs_read(xs, XBT_NULL, path, &plen); - xs_daemon_close(xs); - - if (!portstr || !plen) { - warnx("could not read suspend event channel"); - return -1; - } - - port = atoi(portstr); - free(portstr); - - suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); - if (suspend_evtchn < 0) { - warnx("failed to bind suspend event channel: %d", si.suspend_evtchn); - goto cleanup; - } - - rc = xc_domain_subscribe_for_suspend(xc, domid, port); - if (rc < 0) { - warnx("failed to subscribe to domain: %d", rc); - goto cleanup; - } - - /* event channel is pending immediately after binding */ - await_suspend(xce, suspend_evtchn); - - return suspend_evtchn; - -cleanup: - if (suspend_evtchn > 0) - suspend_evtchn_release(xce, suspend_evtchn); - - return -1; -} - /** * Issue a suspend request to a dedicated event channel in the guest, and * receive the acknowledgement from the subscribe event channel. */ @@ -136,7 +59,7 @@ static int evtchn_suspend(void) return 0; } - if (await_suspend(si.xce, si.suspend_evtchn) < 0) { + if (xc_await_suspend(si.xce, si.suspend_evtchn) < 0) { warnx("suspend failed"); return 0; } @@ -289,12 +212,11 @@ static void *init_qemu_maps(int domid, unsigned int bitmap_size) return seg; } - int main(int argc, char **argv) { unsigned int maxit, max_f; - int io_fd, ret; + int io_fd, ret, port; if (argc != 6) errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); @@ -309,23 +231,37 @@ main(int argc, char **argv) max_f = atoi(argv[4]); si.flags = atoi(argv[5]); + si.suspend_evtchn = si.xce = -1; si.xce = xc_evtchn_open(); if (si.xce < 0) - errx(1, "failed to open event channel handle"); - - si.suspend_evtchn = suspend_evtchn_init(si.xc_fd, si.xce, si.domid); - - if (si.suspend_evtchn < 0) - warnx("suspend event channel initialization failed, using slow path"); - + warnx("failed to open event channel handle"); + + if (si.xce > 0) + { + port = xs_suspend_evtchn_port(si.domid); + + if (port < 0) + warnx("faield to get the suspend evtchn port\n"); + else + { + si.suspend_evtchn = + xc_suspend_evtchn_init(si.xc_fd, si.xce, si.domid, port); + + if (si.suspend_evtchn < 0) + warnx("suspend event channel initialization failed" + "using slow path"); + } + } ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, &suspend, !!(si.flags & XCFLAGS_HVM), &init_qemu_maps, &qemu_flip_buffer); - suspend_evtchn_release(si.xce, si.suspend_evtchn); + if (si.suspend_evtchn > 0) + xc_suspend_evtchn_release(si.xce, si.suspend_evtchn); - xc_evtchn_close(si.xce); + if (si.xce > 0) + xc_evtchn_close(si.xce); xc_interface_close(si.xc_fd); -- cgit v1.2.3