[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xm reboot/shutdown/sysrq to HVM domain
Okay, I've checked this one in as 12036:eb3fe0620e3d of xen-unstable. Thanks! Steven. > Sorry, the previous patch had a problem on dom0 boot. > I have modified the patch to fix it and tested xm reboot/shutdown/sysrq > to both of PV and HVM domain. > > To make reboot on HVM domain work correctly, the following patch is needed: > http://lists.xensource.com/archives/html/xen-devel/2006-10/msg01184.html > > Regards, > > Tetsu Yamamoto > > Signed-off-by: Tetsu Yamamoto <yamamoto.tetsu@xxxxxxxxxxxxxx> > > Tetsu Yamamoto wrote: > > Hi Steven, > > > > Thank you for your comments. > > > > The attached is modified patch based on your comments. > > > > The functions which can not be used from the module on HVM domain are > > moved to the new file machine_reboot.c, and several #ifdefs are removed. > > However, reboot.c still has two parts of #ifdef CONFIG_XEN because some > > functions called in common functions are not EXPORT_SYMBOL: > > - sys_reboot > > - Some functions called in __do_suspend > > > > Regards, > > > > Tetsu Yamamoto > > > > Signed-off-by: Tetsu Yamamoto <yamamoto.tetsu@xxxxxxxxxxxxxx> > > > > Steven Smith wrote: > >>>>> This patch enhances 'xm reboot'/'xm shutdown' commands to > >>>>> reboot/shutdown guest Linux on HVM domain as gracefully as para-Linux. > >>>>> In addtion, sysrq key signal can be sent to HVM domain by 'xm sysrq' > >>>>> command. > >>>> Thanks, that's really useful. I have a couple of comments about the > >>>> patch, though: > >>>> > >>>> -- It looks like you had some problems with ctrl_alt_del(), and instead > >>>> used kill_proc(cad_pid, SIGINT, 1). What was the reason for this? > >>> The symbol ctrl_alt_del() can't be found when it is used in loadable > >>> module. On build, the warning message is shown that ctrl_alt_del() is > >>> undefined, and on loading, the error message is shown that it is unknown > >>> symbol. I'm not sure why this happens, but I tried kill_proc(), which > >>> is called in ctrl_alt_del(), it works correctly. > >> Ah, okay, ctrl_alt_del isn't an EXPORT_SYMBOL. That's unfortunate, > >> and this looks like a sensible work-around. > >> > >>>> -- You've introduced a lot of #ifdefs into reboot.c. It might be > >>>> easier to just split the file in two; did you look at this at all? > >>> reboot.c has common process to deal with reboot/shutdown/sysrq for > >>> para-linux (built in kernel) and full-linux (loadable module), so I > >>> think that it would be better to be one file in consideration of code > >>> maintenance. > >> I'm not talking about duplicating the code. As far as I can see, you > >> share the following functions with PV reboot.c: > >> > >> -- shutdown_process > >> -- __shutdown_handler > >> -- shutdown_handler > >> -- sysrq_handler > >> -- setup_shutdown_event > >> -- setup_shutdown_watcher > >> > >> You don't share: > >> > >> -- machine_emergency_restart > >> -- machine_restart > >> -- machine_halt > >> -- machine_power_off > >> -- switch_idle_mm > >> -- pre_suspend > >> -- post_suspend > >> -- __do_suspend > >> -- kthread_create_on_cpu > >> > >> To put it another way, your patch #if's out more than half the file. > >> Given that, I think the code would be more maintainable if you moved > >> machine_* and __do_suspend to a new file, perhaps machine_reboot.c. > >> > >>>> -- You set reboot_module from within a xenbus transaction. I don't > >>>> think that's necessary, since xenbus_writes are supposed to be > >>>> atomic anyway. > >>> The reason why I use xenbus_write is that I could not find other > >>> interface to write xenstore through xenbus module for HVM. I'm not sure > >>> which interface you suggest to use, but for example, xb_write() is not > >>> exported, so it can not be called from reboot module. If I should use > >>> other interface, please let me know. > >> I'm not objecting to the use of xenbus_write, but the use of > >> xenbus_transaction_start: you're only doing one write, so you can just > >> go xenbus_write(XBT_NULL, "control", "reboot_module", "installed") > >> rather than having the loop in setup_shutdown_event. > >> > >> I'm also not sure why this is #ifndef CONFIG_XEN. It seems like it > >> would be a good idea to set reboot_module in PV domains as well, just > >> for consistency. > >> > >>> +#ifndef CONFIG_XEN > >>> +MODULE_LICENSE("Dual BSD/GPL"); > >>> +#endif /* !CONFIG_XEN */ > >> Does this actually need the #ifdefs? If we're CONFIG_XEN, we're not a > >> module, so MODULE_LICENSE gets preprocessored away, doesn't it? > >> > >>> static int shutdown_process(void *__unused) > >>> { > >>> @@ -222,12 +232,17 @@ static int shutdown_process(void *__unus > >>> > >>> if ((shutting_down == SHUTDOWN_POWEROFF) || > >>> (shutting_down == SHUTDOWN_HALT)) { > >>> +#ifdef CONFIG_XEN > >>> if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) { > >>> sys_reboot(LINUX_REBOOT_MAGIC1, > >>> LINUX_REBOOT_MAGIC2, > >>> LINUX_REBOOT_CMD_POWER_OFF, > >>> NULL); > >>> } > >>> +#else /* !CONFIG_XEN */ > >>> + call_usermodehelper_keys("/sbin/poweroff", poweroff_argv, envp, > > NULL, 0); > >>> + > >>> +#endif /* !CONFIG_XEN */ > >> Hmm... it might make sense to use call_usermodehelper_keys in the > >> CONFIG_XEN case. Did you try that? > >> > >>> static void __shutdown_handler(void *unused) > >>> { > >>> int err; > >>> > >>> +#ifdef CONFIG_XEN > >>> if (shutting_down != SHUTDOWN_SUSPEND) > >>> err = kernel_thread(shutdown_process, NULL, > >>> CLONE_FS | CLONE_FILES); > >>> else > >>> err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0); > >>> > >>> +#else /* !CONFIG_XEN */ > >>> + err = kernel_thread(shutdown_process, NULL, > >>> + CLONE_FS | CLONE_FILES); > >>> +#endif /* !CONFIG_XEN */ > >>> + > >> I don't understand why this was necessary. Surely __do_suspend just > >> returns an error if called from non-CONFIG_XEN? > >> > >> Steven. > > > > > > > > ------------------------------------------------------------------------ > > > > diff -r 38f9bd7a4ce6 linux-2.6-xen-sparse/drivers/xen/core/Makefile > > --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Tue Oct 03 > > 11:39:22 2006 +0100 > > +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Mon Oct 16 > > 19:43:51 2006 +0900 > > @@ -9,5 +9,5 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug > > obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o > > obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o > > obj-$(CONFIG_XEN_SKBUFF) += skbuff.o > > -obj-$(CONFIG_XEN_REBOOT) += reboot.o > > +obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o > > obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o > > diff -r 38f9bd7a4ce6 linux-2.6-xen-sparse/drivers/xen/core/reboot.c > > --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Tue Oct 03 > > 11:39:22 2006 +0100 > > +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Wed Oct 18 > > 15:46:31 2006 +0900 > > @@ -1,215 +1,19 @@ > > #define __KERNEL_SYSCALLS__ > > #include <linux/version.h> > > #include <linux/kernel.h> > > -#include <linux/mm.h> > > #include <linux/unistd.h> > > #include <linux/module.h> > > #include <linux/reboot.h> > > #include <linux/sysrq.h> > > -#include <linux/stringify.h> > > -#include <asm/irq.h> > > -#include <asm/mmu_context.h> > > -#include <xen/evtchn.h> > > #include <asm/hypervisor.h> > > -#include <xen/interface/dom0_ops.h> > > #include <xen/xenbus.h> > > -#include <linux/cpu.h> > > #include <linux/kthread.h> > > -#include <xen/gnttab.h> > > -#include <xen/xencons.h> > > -#include <xen/cpu_hotplug.h> > > +#include <xen/reboot.h> > > > > -extern void ctrl_alt_del(void); > > +MODULE_LICENSE("Dual BSD/GPL"); > > > > -#define SHUTDOWN_INVALID -1 > > -#define SHUTDOWN_POWEROFF 0 > > -#define SHUTDOWN_SUSPEND 2 > > -/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only > > - * report a crash, not be instructed to crash! > > - * HALT is the same as POWEROFF, as far as we're concerned. The tools use > > - * the distinction when we return the reason code to them. > > - */ > > -#define SHUTDOWN_HALT 4 > > - > > -#if defined(__i386__) || defined(__x86_64__) > > - > > -/* > > - * Power off function, if any > > - */ > > -void (*pm_power_off)(void); > > -EXPORT_SYMBOL(pm_power_off); > > - > > -void machine_emergency_restart(void) > > -{ > > - /* We really want to get pending console data out before we die. */ > > - xencons_force_flush(); > > - HYPERVISOR_shutdown(SHUTDOWN_reboot); > > -} > > - > > -void machine_restart(char * __unused) > > -{ > > - machine_emergency_restart(); > > -} > > - > > -void machine_halt(void) > > -{ > > - machine_power_off(); > > -} > > - > > -void machine_power_off(void) > > -{ > > - /* We really want to get pending console data out before we die. */ > > - xencons_force_flush(); > > - if (pm_power_off) > > - pm_power_off(); > > - HYPERVISOR_shutdown(SHUTDOWN_poweroff); > > -} > > - > > -int reboot_thru_bios = 0; /* for dmi_scan.c */ > > -EXPORT_SYMBOL(machine_restart); > > -EXPORT_SYMBOL(machine_halt); > > -EXPORT_SYMBOL(machine_power_off); > > - > > -#endif /* defined(__i386__) || defined(__x86_64__) */ > > - > > -/****************************************************************************** > > - * Stop/pickle callback handling. > > - */ > > - > > -/* Ignore multiple shutdown requests. */ > > -static int shutting_down = SHUTDOWN_INVALID; > > static void __shutdown_handler(void *unused); > > static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); > > - > > -#if defined(__i386__) || defined(__x86_64__) > > - > > -/* Ensure we run on the idle task page tables so that we will > > - switch page tables before running user space. This is needed > > - on architectures with separate kernel and user page tables > > - because the user page table pointer is not saved/restored. */ > > -static void switch_idle_mm(void) > > -{ > > - struct mm_struct *mm = current->active_mm; > > - > > - if (mm == &init_mm) > > - return; > > - > > - atomic_inc(&init_mm.mm_count); > > - switch_mm(mm, &init_mm, current); > > - current->active_mm = &init_mm; > > - mmdrop(mm); > > -} > > - > > -static void pre_suspend(void) > > -{ > > - HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; > > - clear_fixmap(FIX_SHARED_INFO); > > - > > - xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); > > - xen_start_info->console.domU.mfn = > > - mfn_to_pfn(xen_start_info->console.domU.mfn); > > -} > > - > > -static void post_suspend(void) > > -{ > > - int i, j, k, fpp; > > - extern unsigned long max_pfn; > > - extern unsigned long *pfn_to_mfn_frame_list_list; > > - extern unsigned long *pfn_to_mfn_frame_list[]; > > - > > - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); > > - > > - HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); > > - > > - memset(empty_zero_page, 0, PAGE_SIZE); > > - > > - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = > > - virt_to_mfn(pfn_to_mfn_frame_list_list); > > - > > - fpp = PAGE_SIZE/sizeof(unsigned long); > > - for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { > > - if ((j % fpp) == 0) { > > - k++; > > - pfn_to_mfn_frame_list_list[k] = > > - virt_to_mfn(pfn_to_mfn_frame_list[k]); > > - j = 0; > > - } > > - pfn_to_mfn_frame_list[k][j] = > > - virt_to_mfn(&phys_to_machine_mapping[i]); > > - } > > - HYPERVISOR_shared_info->arch.max_pfn = max_pfn; > > -} > > - > > -#else /* !(defined(__i386__) || defined(__x86_64__)) */ > > - > > -#define switch_idle_mm() ((void)0) > > -#define mm_pin_all() ((void)0) > > -#define pre_suspend() ((void)0) > > -#define post_suspend() ((void)0) > > - > > -#endif > > - > > -static int __do_suspend(void *ignore) > > -{ > > - int err; > > - > > - extern void time_resume(void); > > - > > - BUG_ON(smp_processor_id() != 0); > > - BUG_ON(in_interrupt()); > > - > > -#if defined(__i386__) || defined(__x86_64__) > > - if (xen_feature(XENFEAT_auto_translated_physmap)) { > > - printk(KERN_WARNING "Cannot suspend in " > > - "auto_translated_physmap mode.\n"); > > - return -EOPNOTSUPP; > > - } > > -#endif > > - > > - err = smp_suspend(); > > - if (err) > > - return err; > > - > > - xenbus_suspend(); > > - > > - preempt_disable(); > > - > > - mm_pin_all(); > > - local_irq_disable(); > > - preempt_enable(); > > - > > - gnttab_suspend(); > > - > > - pre_suspend(); > > - > > - /* > > - * We'll stop somewhere inside this hypercall. When it returns, > > - * we'll start resuming after the restore. > > - */ > > - HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); > > - > > - shutting_down = SHUTDOWN_INVALID; > > - > > - post_suspend(); > > - > > - gnttab_resume(); > > - > > - irq_resume(); > > - > > - time_resume(); > > - > > - switch_idle_mm(); > > - > > - local_irq_enable(); > > - > > - xencons_resume(); > > - > > - xenbus_resume(); > > - > > - smp_resume(); > > - > > - return err; > > -} > > > > static int shutdown_process(void *__unused) > > { > > @@ -222,11 +26,13 @@ static int shutdown_process(void *__unus > > > > if ((shutting_down == SHUTDOWN_POWEROFF) || > > (shutting_down == SHUTDOWN_HALT)) { > > - if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) { > > + if (call_usermodehelper_keys("/sbin/poweroff", poweroff_argv, > > envp, NULL, 0) < 0) { > > +#ifdef CONFIG_XEN > > sys_reboot(LINUX_REBOOT_MAGIC1, > > LINUX_REBOOT_MAGIC2, > > LINUX_REBOOT_CMD_POWER_OFF, > > NULL); > > +#endif /* CONFIG_XEN */ > > } > > } > > > > @@ -235,29 +41,21 @@ static int shutdown_process(void *__unus > > return 0; > > } > > > > -static int kthread_create_on_cpu(int (*f)(void *arg), > > - void *arg, > > - const char *name, > > - int cpu) > > -{ > > - struct task_struct *p; > > - p = kthread_create(f, arg, name); > > - if (IS_ERR(p)) > > - return PTR_ERR(p); > > - kthread_bind(p, cpu); > > - wake_up_process(p); > > - return 0; > > -} > > > > static void __shutdown_handler(void *unused) > > { > > int err; > > > > +#ifdef CONFIG_XEN > > if (shutting_down != SHUTDOWN_SUSPEND) > > err = kernel_thread(shutdown_process, NULL, > > CLONE_FS | CLONE_FILES); > > else > > err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0); > > +#else /* !CONFIG_XEN */ > > + err = kernel_thread(shutdown_process, NULL, > > + CLONE_FS | CLONE_FILES); > > +#endif /* !CONFIG_XEN */ > > > > if (err < 0) { > > printk(KERN_WARNING "Error creating shutdown process (%d): " > > @@ -272,6 +70,8 @@ static void shutdown_handler(struct xenb > > char *str; > > struct xenbus_transaction xbt; > > int err; > > + > > + int cad_pid = 1; > > > > if (shutting_down != SHUTDOWN_INVALID) > > return; > > @@ -298,7 +98,7 @@ static void shutdown_handler(struct xenb > > if (strcmp(str, "poweroff") == 0) > > shutting_down = SHUTDOWN_POWEROFF; > > else if (strcmp(str, "reboot") == 0) > > - ctrl_alt_del(); > > + kill_proc(cad_pid, SIGINT, 1); > > else if (strcmp(str, "suspend") == 0) > > shutting_down = SHUTDOWN_SUSPEND; > > else if (strcmp(str, "halt") == 0) > > @@ -378,6 +178,9 @@ static int __init setup_shutdown_event(v > > .notifier_call = setup_shutdown_watcher > > }; > > register_xenstore_notifier(&xenstore_notifier); > > + > > + xenbus_write(XBT_NIL, "control", "reboot_module", "installed"); > > + > > return 0; > > } > > > > diff -r 38f9bd7a4ce6 tools/python/xen/xend/image.py > > --- a/tools/python/xen/xend/image.py Tue Oct 03 11:39:22 2006 +0100 > > +++ b/tools/python/xen/xend/image.py Mon Oct 16 18:52:49 2006 +0900 > > @@ -281,6 +281,7 @@ class HVMImageHandler(ImageHandler): > > log.debug("apic = %d", self.apic) > > > > self.register_shutdown_watch() > > + self.register_reboot_module_watch() > > > > return xc.hvm_build(dom = self.vm.getDomid(), > > image = self.kernel, > > @@ -383,6 +384,7 @@ class HVMImageHandler(ImageHandler): > > > > def destroy(self): > > self.unregister_shutdown_watch(); > > + self.unregister_reboot_module_watch(); > > import signal > > if not self.pid: > > return > > @@ -425,6 +427,39 @@ class HVMImageHandler(ImageHandler): > > vm.refreshShutdown(vm.info) > > > > return 1 # Keep watching > > + > > + def register_reboot_module_watch(self): > > + """ add xen store watch on control/reboot_module """ > > + self.rebootModuleWatch = xswatch(self.vm.dompath + > > "/control/reboot_module", \ > > + self.hvm_reboot_module) > > + log.debug("hvm reboot module watch registered") > > + > > + def unregister_reboot_module_watch(self): > > + """Remove the watch on the control/reboot_module, if any. Nothrow > > + guarantee.""" > > + > > + try: > > + if self.rebootModuleWatch: > > + self.rebootModuleWatch.unwatch() > > + except: > > + log.exception("Unwatching hvm reboot module watch failed.") > > + self.rebootModuleWatch = None > > + log.debug("hvm reboot module watch unregistered") > > + > > + def hvm_reboot_module(self, _): > > + """ watch call back on node control/reboot_module, > > + if node changed, this function will be called > > + """ > > + xd = xen.xend.XendDomain.instance() > > + vm = xd.domain_lookup( self.vm.getDomid() ) > > + > > + reboot_module_status = vm.readDom('control/reboot_module') > > + log.debug("hvm_reboot_module fired, module status=%s", > > reboot_module_status) > > + if reboot_module_status == 'installed': > > + self.unregister_shutdown_watch() > > + > > + return 1 # Keep watching > > + > > > > class IA64_HVM_ImageHandler(HVMImageHandler): > > > > diff -r 38f9bd7a4ce6 unmodified_drivers/linux-2.6/Makefile > > --- a/unmodified_drivers/linux-2.6/Makefile Tue Oct 03 11:39:22 2006 +0100 > > +++ b/unmodified_drivers/linux-2.6/Makefile Mon Oct 16 18:52:49 2006 +0900 > > @@ -4,3 +4,4 @@ obj-m += xenbus/ > > obj-m += xenbus/ > > obj-m += blkfront/ > > obj-m += netfront/ > > +obj-m += util/ > > diff -r 38f9bd7a4ce6 unmodified_drivers/linux-2.6/mkbuildtree > > --- a/unmodified_drivers/linux-2.6/mkbuildtree Tue Oct 03 11:39:22 > > 2006 +0100 > > +++ b/unmodified_drivers/linux-2.6/mkbuildtree Mon Oct 16 18:52:49 > > 2006 +0900 > > @@ -14,6 +14,7 @@ ln -sf ${XL}/drivers/xen/core/gnttab.c p > > ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci > > ln -sf ${XL}/drivers/xen/core/features.c platform-pci > > ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus > > +ln -sf ${XL}/drivers/xen/core/reboot.c util > > > > mkdir -p include > > mkdir -p include/xen > > diff -r 38f9bd7a4ce6 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Mon Oct > > 16 21:55:32 2006 +0900 > > @@ -0,0 +1,206 @@ > > +#define __KERNEL_SYSCALLS__ > > +#include <linux/version.h> > > +#include <linux/kernel.h> > > +#include <linux/mm.h> > > +#include <linux/unistd.h> > > +#include <linux/module.h> > > +#include <linux/reboot.h> > > +#include <linux/sysrq.h> > > +#include <linux/stringify.h> > > +#include <asm/irq.h> > > +#include <asm/mmu_context.h> > > +#include <xen/evtchn.h> > > +#include <asm/hypervisor.h> > > +#include <xen/interface/dom0_ops.h> > > +#include <xen/xenbus.h> > > +#include <linux/cpu.h> > > +#include <linux/kthread.h> > > +#include <xen/gnttab.h> > > +#include <xen/xencons.h> > > +#include <xen/cpu_hotplug.h> > > +#include <xen/reboot.h> > > + > > +#if defined(__i386__) || defined(__x86_64__) > > + > > +/* > > + * Power off function, if any > > + */ > > +void (*pm_power_off)(void); > > +EXPORT_SYMBOL(pm_power_off); > > + > > +void machine_emergency_restart(void) > > +{ > > + /* We really want to get pending console data out before we die. */ > > + xencons_force_flush(); > > + HYPERVISOR_shutdown(SHUTDOWN_reboot); > > +} > > + > > +void machine_restart(char * __unused) > > +{ > > + machine_emergency_restart(); > > +} > > + > > +void machine_halt(void) > > +{ > > + machine_power_off(); > > +} > > + > > +void machine_power_off(void) > > +{ > > + /* We really want to get pending console data out before we die. */ > > + xencons_force_flush(); > > + if (pm_power_off) > > + pm_power_off(); > > + HYPERVISOR_shutdown(SHUTDOWN_poweroff); > > +} > > + > > +int reboot_thru_bios = 0; /* for dmi_scan.c */ > > +EXPORT_SYMBOL(machine_restart); > > +EXPORT_SYMBOL(machine_halt); > > +EXPORT_SYMBOL(machine_power_off); > > + > > +#endif /* defined(__i386__) || defined(__x86_64__) */ > > + > > +#if defined(__i386__) || defined(__x86_64__) > > + > > +/* Ensure we run on the idle task page tables so that we will > > + switch page tables before running user space. This is needed > > + on architectures with separate kernel and user page tables > > + because the user page table pointer is not saved/restored. */ > > +static void switch_idle_mm(void) > > +{ > > + struct mm_struct *mm = current->active_mm; > > + > > + if (mm == &init_mm) > > + return; > > + > > + atomic_inc(&init_mm.mm_count); > > + switch_mm(mm, &init_mm, current); > > + current->active_mm = &init_mm; > > + mmdrop(mm); > > +} > > + > > +static void pre_suspend(void) > > +{ > > + HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; > > + clear_fixmap(FIX_SHARED_INFO); > > + > > + xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); > > + xen_start_info->console.domU.mfn = > > + mfn_to_pfn(xen_start_info->console.domU.mfn); > > +} > > + > > +static void post_suspend(void) > > +{ > > + int i, j, k, fpp; > > + extern unsigned long max_pfn; > > + extern unsigned long *pfn_to_mfn_frame_list_list; > > + extern unsigned long *pfn_to_mfn_frame_list[]; > > + > > + set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); > > + > > + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); > > + > > + memset(empty_zero_page, 0, PAGE_SIZE); > > + > > + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = > > + virt_to_mfn(pfn_to_mfn_frame_list_list); > > + > > + fpp = PAGE_SIZE/sizeof(unsigned long); > > + for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { > > + if ((j % fpp) == 0) { > > + k++; > > + pfn_to_mfn_frame_list_list[k] = > > + virt_to_mfn(pfn_to_mfn_frame_list[k]); > > + j = 0; > > + } > > + pfn_to_mfn_frame_list[k][j] = > > + virt_to_mfn(&phys_to_machine_mapping[i]); > > + } > > + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; > > +} > > + > > +#else /* !(defined(__i386__) || defined(__x86_64__)) */ > > + > > +#define switch_idle_mm() ((void)0) > > +#define mm_pin_all() ((void)0) > > +#define pre_suspend() ((void)0) > > +#define post_suspend() ((void)0) > > + > > +#endif > > + > > +int __do_suspend(void *ignore) > > +{ > > + int err; > > + > > + extern void time_resume(void); > > + > > + BUG_ON(smp_processor_id() != 0); > > + BUG_ON(in_interrupt()); > > + > > +#if defined(__i386__) || defined(__x86_64__) > > + if (xen_feature(XENFEAT_auto_translated_physmap)) { > > + printk(KERN_WARNING "Cannot suspend in " > > + "auto_translated_physmap mode.\n"); > > + return -EOPNOTSUPP; > > + } > > +#endif > > + > > + err = smp_suspend(); > > + if (err) > > + return err; > > + > > + xenbus_suspend(); > > + > > + preempt_disable(); > > + > > + mm_pin_all(); > > + local_irq_disable(); > > + preempt_enable(); > > + > > + gnttab_suspend(); > > + > > + pre_suspend(); > > + > > + /* > > + * We'll stop somewhere inside this hypercall. When it returns, > > + * we'll start resuming after the restore. > > + */ > > + HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); > > + > > + shutting_down = SHUTDOWN_INVALID; > > + > > + post_suspend(); > > + > > + gnttab_resume(); > > + > > + irq_resume(); > > + > > + time_resume(); > > + > > + switch_idle_mm(); > > + > > + local_irq_enable(); > > + > > + xencons_resume(); > > + > > + xenbus_resume(); > > + > > + smp_resume(); > > + > > + return err; > > +} > > + > > +int kthread_create_on_cpu(int (*f)(void *arg), > > + void *arg, > > + const char *name, > > + int cpu) > > +{ > > + struct task_struct *p; > > + p = kthread_create(f, arg, name); > > + if (IS_ERR(p)) > > + return PTR_ERR(p); > > + kthread_bind(p, cpu); > > + wake_up_process(p); > > + return 0; > > +} > > diff -r 38f9bd7a4ce6 linux-2.6-xen-sparse/include/xen/reboot.h > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/linux-2.6-xen-sparse/include/xen/reboot.h Mon Oct 16 22:35:22 > > 2006 +0900 > > @@ -0,0 +1,19 @@ > > +#define SHUTDOWN_INVALID -1 > > +#define SHUTDOWN_POWEROFF 0 > > +#define SHUTDOWN_SUSPEND 2 > > +/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only > > + * report a crash, not be instructed to crash! > > + * HALT is the same as POWEROFF, as far as we're concerned. The tools use > > + * the distinction when we return the reason code to them. > > + */ > > +#define SHUTDOWN_HALT 4 > > + > > +/****************************************************************************** > > + * Stop/pickle callback handling. > > + */ > > + > > +/* Ignore multiple shutdown requests. */ > > +static int shutting_down = SHUTDOWN_INVALID; > > + > > +int kthread_create_on_cpu(int (*f)(void *), void *, const char *, int); > > +int __do_suspend(void *); > > > > > > ------------------------------------------------------------------------ > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@xxxxxxxxxxxxxxxxxxx > > http://lists.xensource.com/xen-devel > > > diff -r 4a320d26fc24 linux-2.6-xen-sparse/drivers/xen/core/Makefile > --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Thu Oct 26 16:56:16 > 2006 +0100 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Fri Oct 27 17:02:19 > 2006 +0900 > @@ -9,5 +9,5 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug > obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o > obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o > obj-$(CONFIG_XEN_SKBUFF) += skbuff.o > -obj-$(CONFIG_XEN_REBOOT) += reboot.o > +obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o > obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o > diff -r 4a320d26fc24 linux-2.6-xen-sparse/drivers/xen/core/reboot.c > --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Thu Oct 26 16:56:16 > 2006 +0100 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri Oct 27 17:03:46 > 2006 +0900 > @@ -1,215 +1,19 @@ > #define __KERNEL_SYSCALLS__ > #include <linux/version.h> > #include <linux/kernel.h> > -#include <linux/mm.h> > #include <linux/unistd.h> > #include <linux/module.h> > #include <linux/reboot.h> > #include <linux/sysrq.h> > -#include <linux/stringify.h> > -#include <asm/irq.h> > -#include <asm/mmu_context.h> > -#include <xen/evtchn.h> > #include <asm/hypervisor.h> > -#include <xen/interface/dom0_ops.h> > #include <xen/xenbus.h> > -#include <linux/cpu.h> > #include <linux/kthread.h> > -#include <xen/gnttab.h> > -#include <xen/xencons.h> > -#include <xen/cpu_hotplug.h> > +#include <xen/reboot.h> > > -extern void ctrl_alt_del(void); > +MODULE_LICENSE("Dual BSD/GPL"); > > -#define SHUTDOWN_INVALID -1 > -#define SHUTDOWN_POWEROFF 0 > -#define SHUTDOWN_SUSPEND 2 > -/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only > - * report a crash, not be instructed to crash! > - * HALT is the same as POWEROFF, as far as we're concerned. The tools use > - * the distinction when we return the reason code to them. > - */ > -#define SHUTDOWN_HALT 4 > - > -#if defined(__i386__) || defined(__x86_64__) > - > -/* > - * Power off function, if any > - */ > -void (*pm_power_off)(void); > -EXPORT_SYMBOL(pm_power_off); > - > -void machine_emergency_restart(void) > -{ > - /* We really want to get pending console data out before we die. */ > - xencons_force_flush(); > - HYPERVISOR_shutdown(SHUTDOWN_reboot); > -} > - > -void machine_restart(char * __unused) > -{ > - machine_emergency_restart(); > -} > - > -void machine_halt(void) > -{ > - machine_power_off(); > -} > - > -void machine_power_off(void) > -{ > - /* We really want to get pending console data out before we die. */ > - xencons_force_flush(); > - if (pm_power_off) > - pm_power_off(); > - HYPERVISOR_shutdown(SHUTDOWN_poweroff); > -} > - > -int reboot_thru_bios = 0; /* for dmi_scan.c */ > -EXPORT_SYMBOL(machine_restart); > -EXPORT_SYMBOL(machine_halt); > -EXPORT_SYMBOL(machine_power_off); > - > -#endif /* defined(__i386__) || defined(__x86_64__) */ > - > -/****************************************************************************** > - * Stop/pickle callback handling. > - */ > - > -/* Ignore multiple shutdown requests. */ > -static int shutting_down = SHUTDOWN_INVALID; > static void __shutdown_handler(void *unused); > static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); > - > -#if defined(__i386__) || defined(__x86_64__) > - > -/* Ensure we run on the idle task page tables so that we will > - switch page tables before running user space. This is needed > - on architectures with separate kernel and user page tables > - because the user page table pointer is not saved/restored. */ > -static void switch_idle_mm(void) > -{ > - struct mm_struct *mm = current->active_mm; > - > - if (mm == &init_mm) > - return; > - > - atomic_inc(&init_mm.mm_count); > - switch_mm(mm, &init_mm, current); > - current->active_mm = &init_mm; > - mmdrop(mm); > -} > - > -static void pre_suspend(void) > -{ > - HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; > - clear_fixmap(FIX_SHARED_INFO); > - > - xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); > - xen_start_info->console.domU.mfn = > - mfn_to_pfn(xen_start_info->console.domU.mfn); > -} > - > -static void post_suspend(void) > -{ > - int i, j, k, fpp; > - extern unsigned long max_pfn; > - extern unsigned long *pfn_to_mfn_frame_list_list; > - extern unsigned long *pfn_to_mfn_frame_list[]; > - > - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); > - > - HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); > - > - memset(empty_zero_page, 0, PAGE_SIZE); > - > - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = > - virt_to_mfn(pfn_to_mfn_frame_list_list); > - > - fpp = PAGE_SIZE/sizeof(unsigned long); > - for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { > - if ((j % fpp) == 0) { > - k++; > - pfn_to_mfn_frame_list_list[k] = > - virt_to_mfn(pfn_to_mfn_frame_list[k]); > - j = 0; > - } > - pfn_to_mfn_frame_list[k][j] = > - virt_to_mfn(&phys_to_machine_mapping[i]); > - } > - HYPERVISOR_shared_info->arch.max_pfn = max_pfn; > -} > - > -#else /* !(defined(__i386__) || defined(__x86_64__)) */ > - > -#define switch_idle_mm() ((void)0) > -#define mm_pin_all() ((void)0) > -#define pre_suspend() ((void)0) > -#define post_suspend() ((void)0) > - > -#endif > - > -static int __do_suspend(void *ignore) > -{ > - int err; > - > - extern void time_resume(void); > - > - BUG_ON(smp_processor_id() != 0); > - BUG_ON(in_interrupt()); > - > -#if defined(__i386__) || defined(__x86_64__) > - if (xen_feature(XENFEAT_auto_translated_physmap)) { > - printk(KERN_WARNING "Cannot suspend in " > - "auto_translated_physmap mode.\n"); > - return -EOPNOTSUPP; > - } > -#endif > - > - err = smp_suspend(); > - if (err) > - return err; > - > - xenbus_suspend(); > - > - preempt_disable(); > - > - mm_pin_all(); > - local_irq_disable(); > - preempt_enable(); > - > - gnttab_suspend(); > - > - pre_suspend(); > - > - /* > - * We'll stop somewhere inside this hypercall. When it returns, > - * we'll start resuming after the restore. > - */ > - HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); > - > - shutting_down = SHUTDOWN_INVALID; > - > - post_suspend(); > - > - gnttab_resume(); > - > - irq_resume(); > - > - time_resume(); > - > - switch_idle_mm(); > - > - local_irq_enable(); > - > - xencons_resume(); > - > - xenbus_resume(); > - > - smp_resume(); > - > - return err; > -} > > static int shutdown_process(void *__unused) > { > @@ -222,11 +26,13 @@ static int shutdown_process(void *__unus > > if ((shutting_down == SHUTDOWN_POWEROFF) || > (shutting_down == SHUTDOWN_HALT)) { > - if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) { > + if (call_usermodehelper_keys("/sbin/poweroff", poweroff_argv, > envp, NULL, 0) < 0) { > +#ifdef CONFIG_XEN > sys_reboot(LINUX_REBOOT_MAGIC1, > LINUX_REBOOT_MAGIC2, > LINUX_REBOOT_CMD_POWER_OFF, > NULL); > +#endif /* CONFIG_XEN */ > } > } > > @@ -235,29 +41,21 @@ static int shutdown_process(void *__unus > return 0; > } > > -static int kthread_create_on_cpu(int (*f)(void *arg), > - void *arg, > - const char *name, > - int cpu) > -{ > - struct task_struct *p; > - p = kthread_create(f, arg, name); > - if (IS_ERR(p)) > - return PTR_ERR(p); > - kthread_bind(p, cpu); > - wake_up_process(p); > - return 0; > -} > > static void __shutdown_handler(void *unused) > { > int err; > > +#ifdef CONFIG_XEN > if (shutting_down != SHUTDOWN_SUSPEND) > err = kernel_thread(shutdown_process, NULL, > CLONE_FS | CLONE_FILES); > else > err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0); > +#else /* !CONFIG_XEN */ > + err = kernel_thread(shutdown_process, NULL, > + CLONE_FS | CLONE_FILES); > +#endif /* !CONFIG_XEN */ > > if (err < 0) { > printk(KERN_WARNING "Error creating shutdown process (%d): " > @@ -272,6 +70,8 @@ static void shutdown_handler(struct xenb > char *str; > struct xenbus_transaction xbt; > int err; > + > + int cad_pid = 1; > > if (shutting_down != SHUTDOWN_INVALID) > return; > @@ -298,7 +98,7 @@ static void shutdown_handler(struct xenb > if (strcmp(str, "poweroff") == 0) > shutting_down = SHUTDOWN_POWEROFF; > else if (strcmp(str, "reboot") == 0) > - ctrl_alt_del(); > + kill_proc(cad_pid, SIGINT, 1); > else if (strcmp(str, "suspend") == 0) > shutting_down = SHUTDOWN_SUSPEND; > else if (strcmp(str, "halt") == 0) > @@ -378,6 +178,11 @@ static int __init setup_shutdown_event(v > .notifier_call = setup_shutdown_watcher > }; > register_xenstore_notifier(&xenstore_notifier); > + > + if (!is_initial_xendomain()) { > + xenbus_write(XBT_NIL, "control", "reboot_module", "installed"); > + } > + > return 0; > } > > diff -r 4a320d26fc24 tools/python/xen/xend/image.py > --- a/tools/python/xen/xend/image.py Thu Oct 26 16:56:16 2006 +0100 > +++ b/tools/python/xen/xend/image.py Fri Oct 27 17:02:19 2006 +0900 > @@ -282,6 +282,7 @@ class HVMImageHandler(ImageHandler): > log.debug("apic = %d", self.apic) > > self.register_shutdown_watch() > + self.register_reboot_module_watch() > > return xc.hvm_build(dom = self.vm.getDomid(), > image = self.kernel, > @@ -422,6 +423,7 @@ class HVMImageHandler(ImageHandler): > > def destroy(self): > self.unregister_shutdown_watch(); > + self.unregister_reboot_module_watch(); > if not self.pid: > return > os.kill(self.pid, signal.SIGKILL) > @@ -463,6 +465,39 @@ class HVMImageHandler(ImageHandler): > vm.refreshShutdown(vm.info) > > return 1 # Keep watching > + > + def register_reboot_module_watch(self): > + """ add xen store watch on control/reboot_module """ > + self.rebootModuleWatch = xswatch(self.vm.dompath + > "/control/reboot_module", \ > + self.hvm_reboot_module) > + log.debug("hvm reboot module watch registered") > + > + def unregister_reboot_module_watch(self): > + """Remove the watch on the control/reboot_module, if any. Nothrow > + guarantee.""" > + > + try: > + if self.rebootModuleWatch: > + self.rebootModuleWatch.unwatch() > + except: > + log.exception("Unwatching hvm reboot module watch failed.") > + self.rebootModuleWatch = None > + log.debug("hvm reboot module watch unregistered") > + > + def hvm_reboot_module(self, _): > + """ watch call back on node control/reboot_module, > + if node changed, this function will be called > + """ > + xd = xen.xend.XendDomain.instance() > + vm = xd.domain_lookup( self.vm.getDomid() ) > + > + reboot_module_status = vm.readDom('control/reboot_module') > + log.debug("hvm_reboot_module fired, module status=%s", > reboot_module_status) > + if reboot_module_status == 'installed': > + self.unregister_shutdown_watch() > + > + return 1 # Keep watching > + > > class IA64_HVM_ImageHandler(HVMImageHandler): > > diff -r 4a320d26fc24 unmodified_drivers/linux-2.6/Makefile > --- a/unmodified_drivers/linux-2.6/Makefile Thu Oct 26 16:56:16 2006 +0100 > +++ b/unmodified_drivers/linux-2.6/Makefile Fri Oct 27 17:02:19 2006 +0900 > @@ -4,3 +4,4 @@ obj-m += xenbus/ > obj-m += xenbus/ > obj-m += blkfront/ > obj-m += netfront/ > +obj-m += util/ > diff -r 4a320d26fc24 unmodified_drivers/linux-2.6/mkbuildtree > --- a/unmodified_drivers/linux-2.6/mkbuildtree Thu Oct 26 16:56:16 > 2006 +0100 > +++ b/unmodified_drivers/linux-2.6/mkbuildtree Fri Oct 27 17:02:19 > 2006 +0900 > @@ -22,6 +22,7 @@ ln -sf ${XL}/drivers/xen/core/gnttab.c p > ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci > ln -sf ${XL}/drivers/xen/core/features.c platform-pci > ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus > +ln -sf ${XL}/drivers/xen/core/reboot.c util > > mkdir -p include > mkdir -p include/xen > diff -r 4a320d26fc24 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Fri Oct 27 > 17:02:19 2006 +0900 > @@ -0,0 +1,206 @@ > +#define __KERNEL_SYSCALLS__ > +#include <linux/version.h> > +#include <linux/kernel.h> > +#include <linux/mm.h> > +#include <linux/unistd.h> > +#include <linux/module.h> > +#include <linux/reboot.h> > +#include <linux/sysrq.h> > +#include <linux/stringify.h> > +#include <asm/irq.h> > +#include <asm/mmu_context.h> > +#include <xen/evtchn.h> > +#include <asm/hypervisor.h> > +#include <xen/interface/dom0_ops.h> > +#include <xen/xenbus.h> > +#include <linux/cpu.h> > +#include <linux/kthread.h> > +#include <xen/gnttab.h> > +#include <xen/xencons.h> > +#include <xen/cpu_hotplug.h> > +#include <xen/reboot.h> > + > +#if defined(__i386__) || defined(__x86_64__) > + > +/* > + * Power off function, if any > + */ > +void (*pm_power_off)(void); > +EXPORT_SYMBOL(pm_power_off); > + > +void machine_emergency_restart(void) > +{ > + /* We really want to get pending console data out before we die. */ > + xencons_force_flush(); > + HYPERVISOR_shutdown(SHUTDOWN_reboot); > +} > + > +void machine_restart(char * __unused) > +{ > + machine_emergency_restart(); > +} > + > +void machine_halt(void) > +{ > + machine_power_off(); > +} > + > +void machine_power_off(void) > +{ > + /* We really want to get pending console data out before we die. */ > + xencons_force_flush(); > + if (pm_power_off) > + pm_power_off(); > + HYPERVISOR_shutdown(SHUTDOWN_poweroff); > +} > + > +int reboot_thru_bios = 0; /* for dmi_scan.c */ > +EXPORT_SYMBOL(machine_restart); > +EXPORT_SYMBOL(machine_halt); > +EXPORT_SYMBOL(machine_power_off); > + > +#endif /* defined(__i386__) || defined(__x86_64__) */ > + > +#if defined(__i386__) || defined(__x86_64__) > + > +/* Ensure we run on the idle task page tables so that we will > + switch page tables before running user space. This is needed > + on architectures with separate kernel and user page tables > + because the user page table pointer is not saved/restored. */ > +static void switch_idle_mm(void) > +{ > + struct mm_struct *mm = current->active_mm; > + > + if (mm == &init_mm) > + return; > + > + atomic_inc(&init_mm.mm_count); > + switch_mm(mm, &init_mm, current); > + current->active_mm = &init_mm; > + mmdrop(mm); > +} > + > +static void pre_suspend(void) > +{ > + HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; > + clear_fixmap(FIX_SHARED_INFO); > + > + xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); > + xen_start_info->console.domU.mfn = > + mfn_to_pfn(xen_start_info->console.domU.mfn); > +} > + > +static void post_suspend(void) > +{ > + int i, j, k, fpp; > + extern unsigned long max_pfn; > + extern unsigned long *pfn_to_mfn_frame_list_list; > + extern unsigned long *pfn_to_mfn_frame_list[]; > + > + set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); > + > + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); > + > + memset(empty_zero_page, 0, PAGE_SIZE); > + > + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = > + virt_to_mfn(pfn_to_mfn_frame_list_list); > + > + fpp = PAGE_SIZE/sizeof(unsigned long); > + for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { > + if ((j % fpp) == 0) { > + k++; > + pfn_to_mfn_frame_list_list[k] = > + virt_to_mfn(pfn_to_mfn_frame_list[k]); > + j = 0; > + } > + pfn_to_mfn_frame_list[k][j] = > + virt_to_mfn(&phys_to_machine_mapping[i]); > + } > + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; > +} > + > +#else /* !(defined(__i386__) || defined(__x86_64__)) */ > + > +#define switch_idle_mm() ((void)0) > +#define mm_pin_all() ((void)0) > +#define pre_suspend() ((void)0) > +#define post_suspend() ((void)0) > + > +#endif > + > +int __do_suspend(void *ignore) > +{ > + int err; > + > + extern void time_resume(void); > + > + BUG_ON(smp_processor_id() != 0); > + BUG_ON(in_interrupt()); > + > +#if defined(__i386__) || defined(__x86_64__) > + if (xen_feature(XENFEAT_auto_translated_physmap)) { > + printk(KERN_WARNING "Cannot suspend in " > + "auto_translated_physmap mode.\n"); > + return -EOPNOTSUPP; > + } > +#endif > + > + err = smp_suspend(); > + if (err) > + return err; > + > + xenbus_suspend(); > + > + preempt_disable(); > + > + mm_pin_all(); > + local_irq_disable(); > + preempt_enable(); > + > + gnttab_suspend(); > + > + pre_suspend(); > + > + /* > + * We'll stop somewhere inside this hypercall. When it returns, > + * we'll start resuming after the restore. > + */ > + HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); > + > + shutting_down = SHUTDOWN_INVALID; > + > + post_suspend(); > + > + gnttab_resume(); > + > + irq_resume(); > + > + time_resume(); > + > + switch_idle_mm(); > + > + local_irq_enable(); > + > + xencons_resume(); > + > + xenbus_resume(); > + > + smp_resume(); > + > + return err; > +} > + > +int kthread_create_on_cpu(int (*f)(void *arg), > + void *arg, > + const char *name, > + int cpu) > +{ > + struct task_struct *p; > + p = kthread_create(f, arg, name); > + if (IS_ERR(p)) > + return PTR_ERR(p); > + kthread_bind(p, cpu); > + wake_up_process(p); > + return 0; > +} > diff -r 4a320d26fc24 linux-2.6-xen-sparse/include/xen/reboot.h > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/linux-2.6-xen-sparse/include/xen/reboot.h Fri Oct 27 17:02:19 > 2006 +0900 > @@ -0,0 +1,19 @@ > +#define SHUTDOWN_INVALID -1 > +#define SHUTDOWN_POWEROFF 0 > +#define SHUTDOWN_SUSPEND 2 > +/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only > + * report a crash, not be instructed to crash! > + * HALT is the same as POWEROFF, as far as we're concerned. The tools use > + * the distinction when we return the reason code to them. > + */ > +#define SHUTDOWN_HALT 4 > + > +/****************************************************************************** > + * Stop/pickle callback handling. > + */ > + > +/* Ignore multiple shutdown requests. */ > +static int shutting_down = SHUTDOWN_INVALID; > + > +int kthread_create_on_cpu(int (*f)(void *), void *, const char *, int); > +int __do_suspend(void *); > diff -r 4a320d26fc24 unmodified_drivers/linux-2.6/util/Kbuild > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/unmodified_drivers/linux-2.6/util/Kbuild Fri Oct 27 17:02:19 > 2006 +0900 > @@ -0,0 +1,3 @@ > +include $(M)/overrides.mk > + > +obj-m := reboot.o Attachment:
signature.asc _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |