ia64/xen-unstable

changeset 12050:eb3fe0620e3d

[HVM][LINUX][TOOLS] Make xm {shutdown|reboot} do something sensible for HVM
domains with PV drivers loaded. This patch creates a new PV-on-HVM
module, reboot.ko, which, when loaded, creates control/reboot_module
in the store. The tools notice this, and disable the watch which would
normally destroy HVM domains which are the target of an xm shutdown
command, allowing the reboot module to shut the domain down cleanly.

Signed-off-by: Tetsu Yamamoto <yamamoto.tetsu@jp.fujitsu.com>

(Checkin comments by Steven Smith <sos22@cam.ac.uk>)
author Steven Smith <ssmith@xensource.com>
date Tue Oct 31 09:54:49 2006 +0000 (2006-10-31)
parents b21246720fde
children c3b004aef317
files linux-2.6-xen-sparse/drivers/xen/core/Makefile linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c linux-2.6-xen-sparse/drivers/xen/core/reboot.c linux-2.6-xen-sparse/include/xen/reboot.h tools/python/xen/xend/image.py unmodified_drivers/linux-2.6/Makefile unmodified_drivers/linux-2.6/mkbuildtree unmodified_drivers/linux-2.6/util/Kbuild
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Mon Oct 30 17:35:11 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Tue Oct 31 09:54:49 2006 +0000
     1.3 @@ -9,5 +9,5 @@ obj-$(CONFIG_SYSFS)		+= hypervisor_sysfs
     1.4  obj-$(CONFIG_HOTPLUG_CPU)	+= cpu_hotplug.o
     1.5  obj-$(CONFIG_XEN_SYSFS)		+= xen_sysfs.o
     1.6  obj-$(CONFIG_XEN_SKBUFF)	+= skbuff.o
     1.7 -obj-$(CONFIG_XEN_REBOOT)	+= reboot.o
     1.8 +obj-$(CONFIG_XEN_REBOOT)	+= reboot.o machine_reboot.o
     1.9  obj-$(CONFIG_XEN_SMPBOOT)	+= smpboot.o
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Tue Oct 31 09:54:49 2006 +0000
     2.3 @@ -0,0 +1,206 @@
     2.4 +#define __KERNEL_SYSCALLS__
     2.5 +#include <linux/version.h>
     2.6 +#include <linux/kernel.h>
     2.7 +#include <linux/mm.h>
     2.8 +#include <linux/unistd.h>
     2.9 +#include <linux/module.h>
    2.10 +#include <linux/reboot.h>
    2.11 +#include <linux/sysrq.h>
    2.12 +#include <linux/stringify.h>
    2.13 +#include <asm/irq.h>
    2.14 +#include <asm/mmu_context.h>
    2.15 +#include <xen/evtchn.h>
    2.16 +#include <asm/hypervisor.h>
    2.17 +#include <xen/interface/dom0_ops.h>
    2.18 +#include <xen/xenbus.h>
    2.19 +#include <linux/cpu.h>
    2.20 +#include <linux/kthread.h>
    2.21 +#include <xen/gnttab.h>
    2.22 +#include <xen/xencons.h>
    2.23 +#include <xen/cpu_hotplug.h>
    2.24 +#include <xen/reboot.h>
    2.25 +
    2.26 +#if defined(__i386__) || defined(__x86_64__)
    2.27 +
    2.28 +/*
    2.29 + * Power off function, if any
    2.30 + */
    2.31 +void (*pm_power_off)(void);
    2.32 +EXPORT_SYMBOL(pm_power_off);
    2.33 +
    2.34 +void machine_emergency_restart(void)
    2.35 +{
    2.36 +	/* We really want to get pending console data out before we die. */
    2.37 +	xencons_force_flush();
    2.38 +	HYPERVISOR_shutdown(SHUTDOWN_reboot);
    2.39 +}
    2.40 +
    2.41 +void machine_restart(char * __unused)
    2.42 +{
    2.43 +	machine_emergency_restart();
    2.44 +}
    2.45 +
    2.46 +void machine_halt(void)
    2.47 +{
    2.48 +	machine_power_off();
    2.49 +}
    2.50 +
    2.51 +void machine_power_off(void)
    2.52 +{
    2.53 +	/* We really want to get pending console data out before we die. */
    2.54 +	xencons_force_flush();
    2.55 +	if (pm_power_off)
    2.56 +		pm_power_off();
    2.57 +	HYPERVISOR_shutdown(SHUTDOWN_poweroff);
    2.58 +}
    2.59 +
    2.60 +int reboot_thru_bios = 0;	/* for dmi_scan.c */
    2.61 +EXPORT_SYMBOL(machine_restart);
    2.62 +EXPORT_SYMBOL(machine_halt);
    2.63 +EXPORT_SYMBOL(machine_power_off);
    2.64 +
    2.65 +#endif /* defined(__i386__) || defined(__x86_64__) */
    2.66 +
    2.67 +#if defined(__i386__) || defined(__x86_64__)
    2.68 +
    2.69 +/* Ensure we run on the idle task page tables so that we will
    2.70 +   switch page tables before running user space. This is needed
    2.71 +   on architectures with separate kernel and user page tables
    2.72 +   because the user page table pointer is not saved/restored. */
    2.73 +static void switch_idle_mm(void)
    2.74 +{
    2.75 +	struct mm_struct *mm = current->active_mm;
    2.76 +
    2.77 +	if (mm == &init_mm)
    2.78 +		return;
    2.79 +
    2.80 +	atomic_inc(&init_mm.mm_count);
    2.81 +	switch_mm(mm, &init_mm, current);
    2.82 +	current->active_mm = &init_mm;
    2.83 +	mmdrop(mm);
    2.84 +}
    2.85 +
    2.86 +static void pre_suspend(void)
    2.87 +{
    2.88 +	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    2.89 +	clear_fixmap(FIX_SHARED_INFO);
    2.90 +
    2.91 +	xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
    2.92 +	xen_start_info->console.domU.mfn =
    2.93 +		mfn_to_pfn(xen_start_info->console.domU.mfn);
    2.94 +}
    2.95 +
    2.96 +static void post_suspend(void)
    2.97 +{
    2.98 +	int i, j, k, fpp;
    2.99 +	extern unsigned long max_pfn;
   2.100 +	extern unsigned long *pfn_to_mfn_frame_list_list;
   2.101 +	extern unsigned long *pfn_to_mfn_frame_list[];
   2.102 +
   2.103 +	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   2.104 +
   2.105 +	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   2.106 +
   2.107 +	memset(empty_zero_page, 0, PAGE_SIZE);
   2.108 +
   2.109 +	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
   2.110 +		virt_to_mfn(pfn_to_mfn_frame_list_list);
   2.111 +
   2.112 +	fpp = PAGE_SIZE/sizeof(unsigned long);
   2.113 +	for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
   2.114 +		if ((j % fpp) == 0) {
   2.115 +			k++;
   2.116 +			pfn_to_mfn_frame_list_list[k] =
   2.117 +				virt_to_mfn(pfn_to_mfn_frame_list[k]);
   2.118 +			j = 0;
   2.119 +		}
   2.120 +		pfn_to_mfn_frame_list[k][j] =
   2.121 +			virt_to_mfn(&phys_to_machine_mapping[i]);
   2.122 +	}
   2.123 +	HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
   2.124 +}
   2.125 +
   2.126 +#else /* !(defined(__i386__) || defined(__x86_64__)) */
   2.127 +
   2.128 +#define switch_idle_mm()	((void)0)
   2.129 +#define mm_pin_all()		((void)0)
   2.130 +#define pre_suspend()		((void)0)
   2.131 +#define post_suspend()		((void)0)
   2.132 +
   2.133 +#endif
   2.134 +
   2.135 +int __do_suspend(void *ignore)
   2.136 +{
   2.137 +	int err;
   2.138 +
   2.139 +	extern void time_resume(void);
   2.140 +
   2.141 +	BUG_ON(smp_processor_id() != 0);
   2.142 +	BUG_ON(in_interrupt());
   2.143 +
   2.144 +#if defined(__i386__) || defined(__x86_64__)
   2.145 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   2.146 +		printk(KERN_WARNING "Cannot suspend in "
   2.147 +		       "auto_translated_physmap mode.\n");
   2.148 +		return -EOPNOTSUPP;
   2.149 +	}
   2.150 +#endif
   2.151 +
   2.152 +	err = smp_suspend();
   2.153 +	if (err)
   2.154 +		return err;
   2.155 +
   2.156 +	xenbus_suspend();
   2.157 +
   2.158 +	preempt_disable();
   2.159 +
   2.160 +	mm_pin_all();
   2.161 +	local_irq_disable();
   2.162 +	preempt_enable();
   2.163 +
   2.164 +	gnttab_suspend();
   2.165 +
   2.166 +	pre_suspend();
   2.167 +
   2.168 +	/*
   2.169 +	 * We'll stop somewhere inside this hypercall. When it returns,
   2.170 +	 * we'll start resuming after the restore.
   2.171 +	 */
   2.172 +	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
   2.173 +
   2.174 +	shutting_down = SHUTDOWN_INVALID;
   2.175 +
   2.176 +	post_suspend();
   2.177 +
   2.178 +	gnttab_resume();
   2.179 +
   2.180 +	irq_resume();
   2.181 +
   2.182 +	time_resume();
   2.183 +
   2.184 +	switch_idle_mm();
   2.185 +
   2.186 +	local_irq_enable();
   2.187 +
   2.188 +	xencons_resume();
   2.189 +
   2.190 +	xenbus_resume();
   2.191 +
   2.192 +	smp_resume();
   2.193 +
   2.194 +	return err;
   2.195 +}
   2.196 +
   2.197 +int kthread_create_on_cpu(int (*f)(void *arg),
   2.198 +				 void *arg,
   2.199 +				 const char *name,
   2.200 +				 int cpu)
   2.201 +{
   2.202 +	struct task_struct *p;
   2.203 +	p = kthread_create(f, arg, name);
   2.204 +	if (IS_ERR(p))
   2.205 +		return PTR_ERR(p);
   2.206 +	kthread_bind(p, cpu);
   2.207 +	wake_up_process(p);
   2.208 +	return 0;
   2.209 +}
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Mon Oct 30 17:35:11 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Tue Oct 31 09:54:49 2006 +0000
     3.3 @@ -1,216 +1,20 @@
     3.4  #define __KERNEL_SYSCALLS__
     3.5  #include <linux/version.h>
     3.6  #include <linux/kernel.h>
     3.7 -#include <linux/mm.h>
     3.8  #include <linux/unistd.h>
     3.9  #include <linux/module.h>
    3.10  #include <linux/reboot.h>
    3.11  #include <linux/sysrq.h>
    3.12 -#include <linux/stringify.h>
    3.13 -#include <asm/irq.h>
    3.14 -#include <asm/mmu_context.h>
    3.15 -#include <xen/evtchn.h>
    3.16  #include <asm/hypervisor.h>
    3.17 -#include <xen/interface/dom0_ops.h>
    3.18  #include <xen/xenbus.h>
    3.19 -#include <linux/cpu.h>
    3.20  #include <linux/kthread.h>
    3.21 -#include <xen/gnttab.h>
    3.22 -#include <xen/xencons.h>
    3.23 -#include <xen/cpu_hotplug.h>
    3.24 -
    3.25 -extern void ctrl_alt_del(void);
    3.26 -
    3.27 -#define SHUTDOWN_INVALID  -1
    3.28 -#define SHUTDOWN_POWEROFF  0
    3.29 -#define SHUTDOWN_SUSPEND   2
    3.30 -/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
    3.31 - * report a crash, not be instructed to crash!
    3.32 - * HALT is the same as POWEROFF, as far as we're concerned.  The tools use
    3.33 - * the distinction when we return the reason code to them.
    3.34 - */
    3.35 -#define SHUTDOWN_HALT      4
    3.36 -
    3.37 -#if defined(__i386__) || defined(__x86_64__)
    3.38 -
    3.39 -/*
    3.40 - * Power off function, if any
    3.41 - */
    3.42 -void (*pm_power_off)(void);
    3.43 -EXPORT_SYMBOL(pm_power_off);
    3.44 +#include <xen/reboot.h>
    3.45  
    3.46 -void machine_emergency_restart(void)
    3.47 -{
    3.48 -	/* We really want to get pending console data out before we die. */
    3.49 -	xencons_force_flush();
    3.50 -	HYPERVISOR_shutdown(SHUTDOWN_reboot);
    3.51 -}
    3.52 -
    3.53 -void machine_restart(char * __unused)
    3.54 -{
    3.55 -	machine_emergency_restart();
    3.56 -}
    3.57 -
    3.58 -void machine_halt(void)
    3.59 -{
    3.60 -	machine_power_off();
    3.61 -}
    3.62 +MODULE_LICENSE("Dual BSD/GPL");
    3.63  
    3.64 -void machine_power_off(void)
    3.65 -{
    3.66 -	/* We really want to get pending console data out before we die. */
    3.67 -	xencons_force_flush();
    3.68 -	if (pm_power_off)
    3.69 -		pm_power_off();
    3.70 -	HYPERVISOR_shutdown(SHUTDOWN_poweroff);
    3.71 -}
    3.72 -
    3.73 -int reboot_thru_bios = 0;	/* for dmi_scan.c */
    3.74 -EXPORT_SYMBOL(machine_restart);
    3.75 -EXPORT_SYMBOL(machine_halt);
    3.76 -EXPORT_SYMBOL(machine_power_off);
    3.77 -
    3.78 -#endif /* defined(__i386__) || defined(__x86_64__) */
    3.79 -
    3.80 -/******************************************************************************
    3.81 - * Stop/pickle callback handling.
    3.82 - */
    3.83 -
    3.84 -/* Ignore multiple shutdown requests. */
    3.85 -static int shutting_down = SHUTDOWN_INVALID;
    3.86  static void __shutdown_handler(void *unused);
    3.87  static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
    3.88  
    3.89 -#if defined(__i386__) || defined(__x86_64__)
    3.90 -
    3.91 -/* Ensure we run on the idle task page tables so that we will
    3.92 -   switch page tables before running user space. This is needed
    3.93 -   on architectures with separate kernel and user page tables
    3.94 -   because the user page table pointer is not saved/restored. */
    3.95 -static void switch_idle_mm(void)
    3.96 -{
    3.97 -	struct mm_struct *mm = current->active_mm;
    3.98 -
    3.99 -	if (mm == &init_mm)
   3.100 -		return;
   3.101 -
   3.102 -	atomic_inc(&init_mm.mm_count);
   3.103 -	switch_mm(mm, &init_mm, current);
   3.104 -	current->active_mm = &init_mm;
   3.105 -	mmdrop(mm);
   3.106 -}
   3.107 -
   3.108 -static void pre_suspend(void)
   3.109 -{
   3.110 -	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
   3.111 -	clear_fixmap(FIX_SHARED_INFO);
   3.112 -
   3.113 -	xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
   3.114 -	xen_start_info->console.domU.mfn =
   3.115 -		mfn_to_pfn(xen_start_info->console.domU.mfn);
   3.116 -}
   3.117 -
   3.118 -static void post_suspend(void)
   3.119 -{
   3.120 -	int i, j, k, fpp;
   3.121 -	extern unsigned long max_pfn;
   3.122 -	extern unsigned long *pfn_to_mfn_frame_list_list;
   3.123 -	extern unsigned long *pfn_to_mfn_frame_list[];
   3.124 -
   3.125 -	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   3.126 -
   3.127 -	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   3.128 -
   3.129 -	memset(empty_zero_page, 0, PAGE_SIZE);
   3.130 -
   3.131 -	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
   3.132 -		virt_to_mfn(pfn_to_mfn_frame_list_list);
   3.133 -
   3.134 -	fpp = PAGE_SIZE/sizeof(unsigned long);
   3.135 -	for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
   3.136 -		if ((j % fpp) == 0) {
   3.137 -			k++;
   3.138 -			pfn_to_mfn_frame_list_list[k] =
   3.139 -				virt_to_mfn(pfn_to_mfn_frame_list[k]);
   3.140 -			j = 0;
   3.141 -		}
   3.142 -		pfn_to_mfn_frame_list[k][j] =
   3.143 -			virt_to_mfn(&phys_to_machine_mapping[i]);
   3.144 -	}
   3.145 -	HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
   3.146 -}
   3.147 -
   3.148 -#else /* !(defined(__i386__) || defined(__x86_64__)) */
   3.149 -
   3.150 -#define switch_idle_mm()	((void)0)
   3.151 -#define mm_pin_all()		((void)0)
   3.152 -#define pre_suspend()		((void)0)
   3.153 -#define post_suspend()		((void)0)
   3.154 -
   3.155 -#endif
   3.156 -
   3.157 -static int __do_suspend(void *ignore)
   3.158 -{
   3.159 -	int err;
   3.160 -
   3.161 -	extern void time_resume(void);
   3.162 -
   3.163 -	BUG_ON(smp_processor_id() != 0);
   3.164 -	BUG_ON(in_interrupt());
   3.165 -
   3.166 -#if defined(__i386__) || defined(__x86_64__)
   3.167 -	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   3.168 -		printk(KERN_WARNING "Cannot suspend in "
   3.169 -		       "auto_translated_physmap mode.\n");
   3.170 -		return -EOPNOTSUPP;
   3.171 -	}
   3.172 -#endif
   3.173 -
   3.174 -	err = smp_suspend();
   3.175 -	if (err)
   3.176 -		return err;
   3.177 -
   3.178 -	xenbus_suspend();
   3.179 -
   3.180 -	preempt_disable();
   3.181 -
   3.182 -	mm_pin_all();
   3.183 -	local_irq_disable();
   3.184 -	preempt_enable();
   3.185 -
   3.186 -	gnttab_suspend();
   3.187 -
   3.188 -	pre_suspend();
   3.189 -
   3.190 -	/*
   3.191 -	 * We'll stop somewhere inside this hypercall. When it returns,
   3.192 -	 * we'll start resuming after the restore.
   3.193 -	 */
   3.194 -	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
   3.195 -
   3.196 -	shutting_down = SHUTDOWN_INVALID;
   3.197 -
   3.198 -	post_suspend();
   3.199 -
   3.200 -	gnttab_resume();
   3.201 -
   3.202 -	irq_resume();
   3.203 -
   3.204 -	time_resume();
   3.205 -
   3.206 -	switch_idle_mm();
   3.207 -
   3.208 -	local_irq_enable();
   3.209 -
   3.210 -	xencons_resume();
   3.211 -
   3.212 -	xenbus_resume();
   3.213 -
   3.214 -	smp_resume();
   3.215 -
   3.216 -	return err;
   3.217 -}
   3.218 -
   3.219  static int shutdown_process(void *__unused)
   3.220  {
   3.221  	static char *envp[] = { "HOME=/", "TERM=linux",
   3.222 @@ -222,11 +26,13 @@ static int shutdown_process(void *__unus
   3.223  
   3.224  	if ((shutting_down == SHUTDOWN_POWEROFF) ||
   3.225  	    (shutting_down == SHUTDOWN_HALT)) {
   3.226 -		if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
   3.227 +		if (call_usermodehelper_keys("/sbin/poweroff", poweroff_argv, envp, NULL, 0) < 0) {
   3.228 +#ifdef CONFIG_XEN
   3.229  			sys_reboot(LINUX_REBOOT_MAGIC1,
   3.230  				   LINUX_REBOOT_MAGIC2,
   3.231  				   LINUX_REBOOT_CMD_POWER_OFF,
   3.232  				   NULL);
   3.233 +#endif /* CONFIG_XEN */
   3.234  		}
   3.235  	}
   3.236  
   3.237 @@ -235,29 +41,21 @@ static int shutdown_process(void *__unus
   3.238  	return 0;
   3.239  }
   3.240  
   3.241 -static int kthread_create_on_cpu(int (*f)(void *arg),
   3.242 -				 void *arg,
   3.243 -				 const char *name,
   3.244 -				 int cpu)
   3.245 -{
   3.246 -	struct task_struct *p;
   3.247 -	p = kthread_create(f, arg, name);
   3.248 -	if (IS_ERR(p))
   3.249 -		return PTR_ERR(p);
   3.250 -	kthread_bind(p, cpu);
   3.251 -	wake_up_process(p);
   3.252 -	return 0;
   3.253 -}
   3.254  
   3.255  static void __shutdown_handler(void *unused)
   3.256  {
   3.257  	int err;
   3.258  
   3.259 +#ifdef CONFIG_XEN
   3.260  	if (shutting_down != SHUTDOWN_SUSPEND)
   3.261  		err = kernel_thread(shutdown_process, NULL,
   3.262  				    CLONE_FS | CLONE_FILES);
   3.263  	else
   3.264  		err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0);
   3.265 +#else /* !CONFIG_XEN */
   3.266 +		err = kernel_thread(shutdown_process, NULL,
   3.267 +				    CLONE_FS | CLONE_FILES);
   3.268 +#endif /* !CONFIG_XEN */
   3.269  
   3.270  	if (err < 0) {
   3.271  		printk(KERN_WARNING "Error creating shutdown process (%d): "
   3.272 @@ -273,6 +71,8 @@ static void shutdown_handler(struct xenb
   3.273  	struct xenbus_transaction xbt;
   3.274  	int err;
   3.275  
   3.276 +	int cad_pid = 1; 
   3.277 +
   3.278  	if (shutting_down != SHUTDOWN_INVALID)
   3.279  		return;
   3.280  
   3.281 @@ -298,7 +98,7 @@ static void shutdown_handler(struct xenb
   3.282  	if (strcmp(str, "poweroff") == 0)
   3.283  		shutting_down = SHUTDOWN_POWEROFF;
   3.284  	else if (strcmp(str, "reboot") == 0)
   3.285 -		ctrl_alt_del();
   3.286 +		kill_proc(cad_pid, SIGINT, 1);
   3.287  	else if (strcmp(str, "suspend") == 0)
   3.288  		shutting_down = SHUTDOWN_SUSPEND;
   3.289  	else if (strcmp(str, "halt") == 0)
   3.290 @@ -378,6 +178,11 @@ static int __init setup_shutdown_event(v
   3.291  		.notifier_call = setup_shutdown_watcher
   3.292  	};
   3.293  	register_xenstore_notifier(&xenstore_notifier);
   3.294 +
   3.295 +	if (!is_initial_xendomain()) {
   3.296 +		xenbus_write(XBT_NIL, "control", "reboot_module", "installed");
   3.297 +	}
   3.298 +
   3.299  	return 0;
   3.300  }
   3.301  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/linux-2.6-xen-sparse/include/xen/reboot.h	Tue Oct 31 09:54:49 2006 +0000
     4.3 @@ -0,0 +1,19 @@
     4.4 +#define SHUTDOWN_INVALID  -1
     4.5 +#define SHUTDOWN_POWEROFF  0
     4.6 +#define SHUTDOWN_SUSPEND   2
     4.7 +/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
     4.8 + * report a crash, not be instructed to crash!
     4.9 + * HALT is the same as POWEROFF, as far as we're concerned.  The tools use
    4.10 + * the distinction when we return the reason code to them.
    4.11 + */
    4.12 +#define SHUTDOWN_HALT      4
    4.13 +
    4.14 +/******************************************************************************
    4.15 + * Stop/pickle callback handling.
    4.16 + */
    4.17 +
    4.18 +/* Ignore multiple shutdown requests. */
    4.19 +static int shutting_down = SHUTDOWN_INVALID;
    4.20 +
    4.21 +int kthread_create_on_cpu(int (*f)(void *), void *, const char *, int);
    4.22 +int __do_suspend(void *);
     5.1 --- a/tools/python/xen/xend/image.py	Mon Oct 30 17:35:11 2006 +0000
     5.2 +++ b/tools/python/xen/xend/image.py	Tue Oct 31 09:54:49 2006 +0000
     5.3 @@ -282,6 +282,7 @@ class HVMImageHandler(ImageHandler):
     5.4          log.debug("apic           = %d", self.apic)
     5.5  
     5.6          self.register_shutdown_watch()
     5.7 +        self.register_reboot_module_watch()
     5.8  
     5.9          return xc.hvm_build(dom            = self.vm.getDomid(),
    5.10                              image          = self.kernel,
    5.11 @@ -416,6 +417,7 @@ class HVMImageHandler(ImageHandler):
    5.12  
    5.13      def destroy(self):
    5.14          self.unregister_shutdown_watch();
    5.15 +        self.unregister_reboot_module_watch();
    5.16          if not self.pid:
    5.17              return
    5.18          os.kill(self.pid, signal.SIGKILL)
    5.19 @@ -458,6 +460,39 @@ class HVMImageHandler(ImageHandler):
    5.20  
    5.21          return 1 # Keep watching
    5.22  
    5.23 +    def register_reboot_module_watch(self):
    5.24 +        """ add xen store watch on control/reboot_module """
    5.25 +        self.rebootModuleWatch = xswatch(self.vm.dompath + "/control/reboot_module", \
    5.26 +                                    self.hvm_reboot_module)
    5.27 +        log.debug("hvm reboot module watch registered")
    5.28 +
    5.29 +    def unregister_reboot_module_watch(self):
    5.30 +        """Remove the watch on the control/reboot_module, if any. Nothrow
    5.31 +        guarantee."""
    5.32 +
    5.33 +        try:
    5.34 +            if self.rebootModuleWatch:
    5.35 +                self.rebootModuleWatch.unwatch()
    5.36 +        except:
    5.37 +            log.exception("Unwatching hvm reboot module watch failed.")
    5.38 +        self.rebootModuleWatch = None
    5.39 +        log.debug("hvm reboot module watch unregistered")
    5.40 +
    5.41 +    def hvm_reboot_module(self, _):
    5.42 +        """ watch call back on node control/reboot_module,
    5.43 +            if node changed, this function will be called
    5.44 +        """
    5.45 +        xd = xen.xend.XendDomain.instance()
    5.46 +        vm = xd.domain_lookup( self.vm.getDomid() )
    5.47 +
    5.48 +        reboot_module_status = vm.readDom('control/reboot_module')
    5.49 +        log.debug("hvm_reboot_module fired, module status=%s", reboot_module_status)
    5.50 +        if reboot_module_status == 'installed':
    5.51 +            self.unregister_shutdown_watch()
    5.52 +
    5.53 +        return 1 # Keep watching
    5.54 +
    5.55 +
    5.56  class IA64_HVM_ImageHandler(HVMImageHandler):
    5.57  
    5.58      ostype = "hvm"
     6.1 --- a/unmodified_drivers/linux-2.6/Makefile	Mon Oct 30 17:35:11 2006 +0000
     6.2 +++ b/unmodified_drivers/linux-2.6/Makefile	Tue Oct 31 09:54:49 2006 +0000
     6.3 @@ -4,3 +4,4 @@ obj-m += platform-pci/
     6.4  obj-m += xenbus/
     6.5  obj-m += blkfront/
     6.6  obj-m += netfront/
     6.7 +obj-m += util/
     7.1 --- a/unmodified_drivers/linux-2.6/mkbuildtree	Mon Oct 30 17:35:11 2006 +0000
     7.2 +++ b/unmodified_drivers/linux-2.6/mkbuildtree	Tue Oct 31 09:54:49 2006 +0000
     7.3 @@ -22,6 +22,7 @@ done
     7.4  ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci
     7.5  ln -sf ${XL}/drivers/xen/core/features.c platform-pci
     7.6  ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus
     7.7 +ln -sf ${XL}/drivers/xen/core/reboot.c util
     7.8  
     7.9  mkdir -p include
    7.10  mkdir -p include/xen
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/unmodified_drivers/linux-2.6/util/Kbuild	Tue Oct 31 09:54:49 2006 +0000
     8.3 @@ -0,0 +1,3 @@
     8.4 +include $(M)/overrides.mk
     8.5 +
     8.6 +obj-m := reboot.o