[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Fix checkpointing - add save/restore support to the xenbus driver.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 76794dad0aafd6e22341791338395ebe749f62a6
# Parent  a75db157d12fe183e00a62028cdcc08377c4a8f6
Fix checkpointing - add save/restore support to the xenbus driver.
- Add xenbus driver suspend/resume functions
- Change xenbus irq to not be shared
- Translate store mfn in suspend record to pfn and back
- Make tools re-introduce the domain to the store
Signed-off-by: Rusty Russel <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r a75db157d12f -r 76794dad0aaf 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Aug  2 09:26:30 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Aug  2 17:12:36 2005
@@ -16,6 +16,7 @@
 #include <asm-xen/xen-public/dom0_ops.h>
 #include <asm-xen/linux-public/suspend.h>
 #include <asm-xen/queues.h>
+#include <asm-xen/xenbus.h>
 
 void machine_restart(char * __unused)
 {
@@ -114,6 +115,8 @@
 
     time_suspend();
 
+    xenbus_suspend();
+
     ctrl_if_suspend();
 
     irq_suspend();
@@ -152,6 +155,8 @@
     irq_resume();
 
     ctrl_if_resume();
+
+    xenbus_resume();
 
     time_resume();
 
diff -r a75db157d12f -r 76794dad0aaf 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Tue Aug  2 
09:26:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Tue Aug  2 
17:12:36 2005
@@ -36,6 +36,8 @@
 #include <linux/err.h>
 #include "xenbus_comms.h"
 
+static unsigned int xb_irq;
+
 #define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head))
 struct ringbuf_head
 {
@@ -202,14 +204,17 @@
        return 0;
 }
 
-/* Set up interrpt handler off store event channel. */
+/* Set up interrupt handler off store event channel. */
 int xb_init_comms(void)
 {
-       int err, irq;
-
-       irq = bind_evtchn_to_irq(xen_start_info.store_evtchn);
-
-       err = request_irq(irq, wake_waiting, SA_SHIRQ, "xenbus", &xb_waitq);
+       int err;
+
+       if (!xen_start_info.store_evtchn)
+               return 0;
+
+       xb_irq = bind_evtchn_to_irq(xen_start_info.store_evtchn);
+
+       err = request_irq(xb_irq, wake_waiting, 0, "xenbus", &xb_waitq);
        if (err) {
                printk(KERN_ERR "XENBUS request irq failed %i\n", err);
                unbind_evtchn_from_irq(xen_start_info.store_evtchn);
@@ -222,3 +227,13 @@
 
        return 0;
 }
+
+void xb_suspend_comms(void)
+{
+
+       if (!xen_start_info.store_evtchn)
+               return;
+
+       free_irq(xb_irq, &xb_waitq);
+       unbind_evtchn_from_irq(xen_start_info.store_evtchn);
+}
diff -r a75db157d12f -r 76794dad0aaf 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h    Tue Aug  2 
09:26:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h    Tue Aug  2 
17:12:36 2005
@@ -3,6 +3,7 @@
 #define _XENBUS_COMMS_H
 int xs_init(void);
 int xb_init_comms(void);
+void xb_suspend_comms(void);
 
 /* Low level routines. */
 int xb_write(const void *data, unsigned len);
diff -r a75db157d12f -r 76794dad0aaf 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Aug  2 
09:26:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Aug  2 
17:12:36 2005
@@ -295,6 +295,19 @@
        .callback = dev_changed,
 };
 
+void xenbus_suspend(void)
+{
+       /* We keep lock, so no comms can happen as page moves. */
+       down(&xenbus_lock);
+       xb_suspend_comms();
+}
+
+void xenbus_resume(void)
+{
+       xb_init_comms();
+       up(&xenbus_lock);
+}
+
 /* called from a thread in privcmd/privcmd.c */
 int do_xenbus_probe(void *unused)
 {
diff -r a75db157d12f -r 76794dad0aaf 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Aug  2 09:26:30 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Aug  2 17:12:36 2005
@@ -115,4 +115,8 @@
 int register_xenbus_watch(struct xenbus_watch *watch);
 void unregister_xenbus_watch(struct xenbus_watch *watch);
 
+/* Called from xen core code. */
+void xenbus_suspend(void);
+void xenbus_resume(void);
+
 #endif /* _ASM_XEN_XENBUS_H */
diff -r a75db157d12f -r 76794dad0aaf tools/libxc/xc.h
--- a/tools/libxc/xc.h  Tue Aug  2 09:26:30 2005
+++ b/tools/libxc/xc.h  Tue Aug  2 17:12:36 2005
@@ -279,9 +279,12 @@
  * @parm fd the file descriptor to restore a domain from
  * @parm dom the id of the domain
  * @parm nr_pfns the number of pages
+ * @parm store_evtchn the store event channel for this domain to use
+ * @parm store_mfn returned with the mfn of the store page
  * @return 0 on success, -1 on failure
  */
-int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns);
+int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
+                    unsigned int store_evtchn, unsigned long *store_mfn);
 
 int xc_linux_build(int xc_handle,
                    u32 domid,
diff -r a75db157d12f -r 76794dad0aaf tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Tue Aug  2 09:26:30 2005
+++ b/tools/libxc/xc_linux_restore.c    Tue Aug  2 17:12:36 2005
@@ -48,7 +48,8 @@
     return r;
 }
 
-int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns)
+int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
+                    unsigned int store_evtchn, unsigned long *store_mfn)
 {
     dom0_op_t op;
     int rc = 1, i, n, k;
@@ -464,10 +465,13 @@
     }
     ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
     p_srec = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_WRITE, mfn);
+        xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
     p_srec->resume_info.nr_pages    = nr_pfns;
     p_srec->resume_info.shared_info = shared_info_frame << PAGE_SHIFT;
     p_srec->resume_info.flags       = 0;
+    *store_mfn = p_srec->resume_info.store_mfn   =
+       pfn_to_mfn_table[p_srec->resume_info.store_mfn];
+    p_srec->resume_info.store_evtchn = store_evtchn;
     munmap(p_srec, PAGE_SIZE);
 
     /* Uncanonicalise each GDT frame number. */
diff -r a75db157d12f -r 76794dad0aaf tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Tue Aug  2 09:26:30 2005
+++ b/tools/libxc/xc_linux_save.c       Tue Aug  2 17:12:36 2005
@@ -20,7 +20,7 @@
 #define DEBUG 0
 
 #if 1
-#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
+#define ERR(_f, _a...) do { fprintf(stderr, _f , ## _a); fflush(stderr); } 
while (0)
 #else
 #define ERR(_f, _a...) ((void)0)
 #endif
@@ -643,6 +643,22 @@
         goto out;
     }
 
+    /* Map the suspend-record MFN to pin it. The page must be owned by 
+       dom for this to succeed. */
+    p_srec = xc_map_foreign_range(xc_handle, dom,
+                                   sizeof(*p_srec), PROT_READ | PROT_WRITE, 
+                                   ctxt.user_regs.esi);
+    if (!p_srec){
+        ERR("Couldn't map suspend record");
+        goto out;
+    }
+
+    /* Canonicalize store mfn. */
+    if ( !translate_mfn_to_pfn(&p_srec->resume_info.store_mfn) ) {
+       ERR("Store frame is not in range of pseudophys map");
+       goto out;
+    }
+
     print_stats( xc_handle, dom, 0, &stats, 0 );
 
     /* Now write out each data page, canonicalising page tables as we go... */
@@ -983,16 +999,6 @@
        }
     }
 
-    /* Map the suspend-record MFN to pin it. The page must be owned by 
-       dom for this to succeed. */
-    p_srec = xc_map_foreign_range(xc_handle, dom,
-                                   sizeof(*p_srec), PROT_READ, 
-                                   ctxt.user_regs.esi);
-    if (!p_srec){
-        ERR("Couldn't map suspend record");
-        goto out;
-    }
-
     if (nr_pfns != p_srec->nr_pfns )
     {
        ERR("Suspend record nr_pfns unexpected (%ld != %ld)",
diff -r a75db157d12f -r 76794dad0aaf tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Tue Aug  2 09:26:30 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Tue Aug  2 17:12:36 2005
@@ -6,6 +6,7 @@
 
 import errno
 import os
+import re
 import select
 import sxp
 from string import join
@@ -64,6 +65,13 @@
                 if l.rstrip() == "suspend":
                     log.info("suspending %d" % dominfo.id)
                     xd.domain_shutdown(dominfo.id, reason='suspend')
+                    if dominfo.store_channel:
+                        try:
+                            dominfo.db.releaseDomain(dominfo.id)
+                        except Exception, ex:
+                            log.warning("error in domain release on xenstore: 
%s",
+                                        ex)
+                            pass
                     dominfo.state_wait("suspended")
                     log.info("suspend %d done" % dominfo.id)
                     child.tochild.write("done\n")
@@ -76,6 +84,11 @@
     if child.wait() != 0:
         raise XendError("xc_save failed: %s" % lasterr)
 
+    if dominfo.store_channel:
+        dominfo.store_channel.close()
+        dominfo.db['store_channel'].delete()
+        dominfo.db.saveDB(save=True)
+        dominfo.store_channel = None
     xd.domain_destroy(dominfo.id)
     return None
 
@@ -107,8 +120,13 @@
         raise XendError(
             "not a valid guest state file: pfn count out of range")
 
+    if dominfo.store_channel:
+        evtchn = dominfo.store_channel.port2
+    else:
+        evtchn = 0
+
     cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
-           str(dominfo.id), str(nr_pfns)]
+           str(dominfo.id), str(nr_pfns), str(evtchn)]
     log.info("[xc_restore] " + join(cmd))
     child = xPopen3(cmd, True, -1, [fd, xc.handle()])
     child.tochild.close()
@@ -128,7 +146,21 @@
                 lasterr = l.rstrip()
             if fd == child.fromchild.fileno():
                 l = child.fromchild.readline()
-                log.info(l.rstrip())
+                while l:
+                    m = re.match(r"^(store-mfn) (\d+)\n$", l)
+                    if m:
+                        if dominfo.store_channel:
+                            dominfo.store_mfn = int(m.group(2))
+                            if dominfo.store_mfn >= 0:
+                                dominfo.db.introduceDomain(dominfo.id,
+                                                           dominfo.store_mfn,
+                                                           
dominfo.store_channel)
+                            dominfo.exportToDB(save=True, sync=True))
+                    log.info(l.rstrip())
+                    try:
+                        l = child.fromchild.readline()
+                    except:
+                        l = None
         if filter(lambda (fd, event): event & select.POLLHUP, r):
             break
 
diff -r a75db157d12f -r 76794dad0aaf tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c        Tue Aug  2 09:26:30 2005
+++ b/tools/xcutils/xc_restore.c        Tue Aug  2 17:12:36 2005
@@ -16,15 +16,23 @@
 int
 main(int argc, char **argv)
 {
-    unsigned int xc_fd, io_fd, domid, nr_pfns;
+    unsigned int xc_fd, io_fd, domid, nr_pfns, evtchn;
+    int ret;
+    unsigned long mfn;
 
-    if (argc != 5)
-       errx(1, "usage: %s xcfd iofd domid nr_pfns", argv[0]);
+    if (argc != 6)
+       errx(1, "usage: %s xcfd iofd domid nr_pfns evtchn", argv[0]);
 
     xc_fd = atoi(argv[1]);
     io_fd = atoi(argv[2]);
     domid = atoi(argv[3]);
     nr_pfns = atoi(argv[4]);
+    evtchn = atoi(argv[5]);
 
-    return xc_linux_restore(xc_fd, io_fd, domid, nr_pfns);
+    ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, evtchn, &mfn);
+    if (ret == 0) {
+       printf("store-mfn %li\n", mfn);
+       fflush(stdout);
+    }
+    return ret;
 }

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.