[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Move the suspend event channel function to libxc, it will use the
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1237376966 0 # Node ID a5f497f02e344d92a28c9a170749a83689d94808 # Parent f00e5d83b9ecb5ba9be48ec53bd7536fe85118bf 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 <yunhong.jiang@xxxxxxxxx> --- tools/libxc/xc_domain_save.c | 109 ++++++++++++++++++++++++++++++++++++++++ tools/libxc/xenguest.h | 6 ++ tools/xcutils/xc_save.c | 116 +++++++++---------------------------------- tools/xenstore/xs.c | 25 +++++++++ tools/xenstore/xs.h | 1 5 files changed, 166 insertions(+), 91 deletions(-) diff -r f00e5d83b9ec -r a5f497f02e34 tools/libxc/xc_domain_save.c --- a/tools/libxc/xc_domain_save.c Wed Mar 18 11:48:48 2009 +0000 +++ b/tools/libxc/xc_domain_save.c Wed Mar 18 11:49:26 2009 +0000 @@ -744,7 +744,114 @@ static xen_pfn_t *map_and_save_p2m_table return success ? p2m : NULL; } - +#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d" +static int lock_suspend_event(void) +{ + int fd; + mode_t mask; + char buf[128]; + + mask = umask(022); + fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666); + if (fd < 0) + { + ERROR("Can't create lock file for suspend event channel\n"); + return -EINVAL; + } + umask(mask); + snprintf(buf, sizeof(buf), "%10ld", (long)getpid()); + + write(fd, buf, strlen(buf)); + close(fd); + + return 0; +} + +static int unlock_suspend_event(void) +{ + int fd, pid, n; + char buf[128]; + + fd = open(SUSPEND_LOCK_FILE, O_RDWR); + + if (fd < 0) + return -EINVAL; + + n = read(fd, buf, 127); + + close(fd); + + if (n > 0) + { + sscanf(buf, "%d", &pid); + /* We are the owner, so we can simply delete the file */ + if (pid == getpid()) + { + unlink(SUSPEND_LOCK_FILE); + return 0; + } + } + + return -EPERM; +} + +int xc_await_suspend(int xce, int suspend_evtchn) +{ + int rc; + + do { + rc = xc_evtchn_pending(xce); + if (rc < 0) { + ERROR("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) + ERROR("failed to unmask suspend notification channel: %d", rc); + + return 0; +} + +int xc_suspend_evtchn_release(int xce, int suspend_evtchn) +{ + if (suspend_evtchn >= 0) + xc_evtchn_unbind(xce, suspend_evtchn); + + return unlock_suspend_event(); +} + +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port) +{ + int rc, suspend_evtchn = -1; + + if (lock_suspend_event()) + return -EINVAL; + + suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); + if (suspend_evtchn < 0) { + ERROR("failed to bind suspend event channel: %d", suspend_evtchn); + goto cleanup; + } + + rc = xc_domain_subscribe_for_suspend(xc, domid, port); + if (rc < 0) { + ERROR("failed to subscribe to domain: %d", rc); + goto cleanup; + } + + /* event channel is pending immediately after binding */ + xc_await_suspend(xce, suspend_evtchn); + + return suspend_evtchn; + +cleanup: + if (suspend_evtchn > 0) + xc_suspend_evtchn_release(xce, suspend_evtchn); + + return -1; +} int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags, int (*suspend)(void), diff -r f00e5d83b9ec -r a5f497f02e34 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Wed Mar 18 11:48:48 2009 +0000 +++ b/tools/libxc/xenguest.h Wed Mar 18 11:49:26 2009 +0000 @@ -142,4 +142,10 @@ int xc_hvm_build_mem(int xc_handle, const char *image_buffer, unsigned long image_size); +int xc_suspend_evtchn_release(int xce, int suspend_evtchn); + +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port); + +int xc_await_suspend(int xce, int suspend_evtchn); + #endif /* XENGUEST_H */ diff -r f00e5d83b9ec -r a5f497f02e34 tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Wed Mar 18 11:48:48 2009 +0000 +++ b/tools/xcutils/xc_save.c Wed Mar 18 11:49:26 2009 +0000 @@ -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, u 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); - - xc_evtchn_close(si.xce); + if (si.suspend_evtchn > 0) + xc_suspend_evtchn_release(si.xce, si.suspend_evtchn); + + if (si.xce > 0) + xc_evtchn_close(si.xce); xc_interface_close(si.xc_fd); diff -r f00e5d83b9ec -r a5f497f02e34 tools/xenstore/xs.c --- a/tools/xenstore/xs.c Wed Mar 18 11:48:48 2009 +0000 +++ b/tools/xenstore/xs.c Wed Mar 18 11:49:26 2009 +0000 @@ -802,6 +802,31 @@ bool xs_is_domain_introduced(struct xs_h return rc; } +int xs_suspend_evtchn_port(int domid) +{ + char path[128]; + char *portstr; + int port; + unsigned int plen; + struct xs_handle *xs; + + xs = xs_daemon_open(); + if (!xs) + 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) + return -1; + + port = atoi(portstr); + free(portstr); + + return port; +} + /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len) diff -r f00e5d83b9ec -r a5f497f02e34 tools/xenstore/xs.h --- a/tools/xenstore/xs.h Wed Mar 18 11:48:48 2009 +0000 +++ b/tools/xenstore/xs.h Wed Mar 18 11:49:26 2009 +0000 @@ -163,6 +163,7 @@ char *xs_debug_command(struct xs_handle char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len); +int xs_suspend_evtchn_port(int domid); #endif /* _XS_H */ /* _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |