WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Move the suspend event channel function t

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Move the suspend event channel function to libxc, it will use the
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 18 Mar 2009 07:25:17 -0700
Delivery-date: Wed, 18 Mar 2009 07:26:19 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Move the suspend event channel function to libxc, it will use the, Xen patchbot-unstable <=