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-devel

[Xen-devel] [PATCH 01 of 11] Add callbacks for suspend, postcopy and pre

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 01 of 11] Add callbacks for suspend, postcopy and preresume in xc_domain_save
From: Brendan Cully <brendan@xxxxxxxxx>
Date: Thu, 05 Nov 2009 14:58:26 -0800
Cc: andy@xxxxxxxxx
Delivery-date: Thu, 05 Nov 2009 15:02:30 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1257461905@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1257461905@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.3.1+336-38deec407f8d
# HG changeset patch
# User Brendan Cully <brendan@xxxxxxxxx>
# Date 1240355494 25200
# Node ID d325cdd95abb5f675e3d63fa9cc59ca89271489a
# Parent  ac9d4ba48b8334f0adc3a928be4e48d2e6fdebd1
Add callbacks for suspend, postcopy and preresume in xc_domain_save.
This makes it possible to perform repeated checkpoints.

Signed-off-by: Brendan Cully <brendan@xxxxxxxxx>

diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -332,11 +332,11 @@
     return -1;
 }
 
-
-static int suspend_and_state(int (*suspend)(void), int xc_handle, int io_fd,
-                             int dom, xc_dominfo_t *info)
+static int suspend_and_state(int (*suspend)(void*), void* data,
+                             int xc_handle, int io_fd, int dom,
+                             xc_dominfo_t *info)
 {
-    if ( !(*suspend)() )
+    if ( !(*suspend)(data) )
     {
         ERROR("Suspend request failed");
         return -1;
@@ -742,13 +742,14 @@
 }
 
 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),
+                   uint32_t max_factor, uint32_t flags,
+                   struct save_callbacks* callbacks,
                    int hvm, void (*switch_qemu_logdirty)(int, unsigned))
 {
     xc_dominfo_t info;
     DECLARE_DOMCTL;
 
-    int rc = 1, frc, i, j, last_iter, iter = 0;
+    int rc = 1, frc, i, j, last_iter = 0, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
     int race = 0, sent_last_iter, skip_this_iter;
@@ -864,7 +865,8 @@
     else
     {
         /* This is a non-live suspend. Suspend the domain .*/
-        if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
+        if ( suspend_and_state(callbacks->suspend, callbacks->data, xc_handle,
+                               io_fd, dom, &info) )
         {
             ERROR("Domain appears not to have suspended");
             goto out;
@@ -992,6 +994,7 @@
         goto out;
     }
 
+  copypages:
     /* Now write out each data page, canonicalising page tables as we go... */
     for ( ; ; )
     {
@@ -1305,7 +1308,8 @@
                 DPRINTF("Start last iteration\n");
                 last_iter = 1;
 
-                if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
+                if ( suspend_and_state(callbacks->suspend, callbacks->data,
+                                       xc_handle, io_fd, dom, &info) )
                 {
                     ERROR("Domain appears not to have suspended");
                     goto out;
@@ -1586,6 +1590,39 @@
     rc = 0;
 
  out:
+    if ( !rc && callbacks->postcopy )
+        callbacks->postcopy(callbacks->data);
+
+    /* Flush last write and discard cache for file. */
+    discard_file_cache(io_fd, 1 /* flush */);
+
+    /* checkpoint_cb can spend arbitrarily long in between rounds */
+    if (!rc && callbacks->checkpoint &&
+        callbacks->checkpoint(callbacks->data) > 0)
+    {
+        /* reset stats timer */
+        print_stats(xc_handle, dom, 0, &stats, 0);
+
+        rc = 1;
+        /* last_iter = 1; */
+        if ( suspend_and_state(callbacks->suspend, callbacks->data, xc_handle,
+                               io_fd, dom, &info) )
+        {
+            ERROR("Domain appears not to have suspended");
+            goto out;
+        }
+        DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
+        print_stats(xc_handle, dom, 0, &stats, 1);
+
+        if ( xc_shadow_control(xc_handle, dom,
+                               XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
+                               p2m_size, NULL, 0, &stats) != p2m_size )
+        {
+            ERROR("Error flushing shadow PT");
+        }
+
+        goto copypages;
+    }
 
     if ( tmem_saved != 0 && live )
         xc_tmem_save_done(xc_handle, dom);
@@ -1600,9 +1637,6 @@
             switch_qemu_logdirty(dom, 0);
     }
 
-    /* Flush last write and discard cache for file. */
-    discard_file_cache(io_fd, 1 /* flush */);
-
     if ( live_shinfo )
         munmap(live_shinfo, PAGE_SIZE);
 
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -14,6 +14,19 @@
 #define XCFLAGS_HVM       4
 #define XCFLAGS_STDVGA    8
 
+/* callbacks provided by xc_domain_save */
+struct save_callbacks {
+    int (*suspend)(void* data);
+    /* callback to rendezvous with external checkpoint functions */
+    int (*postcopy)(void* data);
+    /* returns:
+     * 0: terminate checkpointing gracefully
+     * 1: take another checkpoint */
+    int (*checkpoint)(void* data);
+
+    /* to be provided as the first argument to each callback function */
+    void* data;
+};
 
 /**
  * This function will save a running domain.
@@ -25,8 +38,8 @@
  */
 int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
-                   int (*suspend)(void), int hvm,
-                   void (*switch_qemu_logdirty)(int, unsigned)); /* HVM only */
+                   struct save_callbacks* callbacks,
+                   int hvm, void (*switch_qemu_logdirty)(int, unsigned)); /* 
HVM only */
 
 
 /**
diff --git a/tools/xcutils/xc_save.c b/tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -71,7 +71,7 @@
     return 1;
 }
 
-static int suspend(void)
+static int suspend(void* data)
 {
     unsigned long sx_state = 0;
 
@@ -166,6 +166,7 @@
 {
     unsigned int maxit, max_f;
     int io_fd, ret, port;
+    struct save_callbacks callbacks;
 
     if (argc != 6)
         errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
@@ -202,8 +203,10 @@
                        "using slow path");
         }
     }
+    memset(&callbacks, 0, sizeof(callbacks));
+    callbacks.suspend = suspend;
     ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, 
-                         &suspend, !!(si.flags & XCFLAGS_HVM),
+                         &callbacks, !!(si.flags & XCFLAGS_HVM),
                          &switch_qemu_logdirty);
 
     if (si.suspend_evtchn > 0)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel