[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |