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