direct-io.hg

changeset 1688:4be513273145

bitkeeper revision 1.1041.5.13 (40eae953qXVB0VAXac-t2uDXq-tS9Q)

Tidy up remote shutdown handling in xenolinux.
author kaf24@scramble.cl.cam.ac.uk
date Tue Jul 06 18:02:59 2004 +0000 (2004-07-06)
parents 59e06517a011
children 57c047484acc
files linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Tue Jul 06 16:05:41 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Tue Jul 06 18:02:59 2004 +0000
     1.3 @@ -8,6 +8,8 @@
     1.4   * This file handles the architecture-dependent parts of initialization
     1.5   */
     1.6  
     1.7 +#define __KERNEL_SYSCALLS__
     1.8 +static int errno;
     1.9  #include <linux/errno.h>
    1.10  #include <linux/sched.h>
    1.11  #include <linux/kernel.h>
    1.12 @@ -30,6 +32,7 @@
    1.13  #include <linux/highmem.h>
    1.14  #include <linux/bootmem.h>
    1.15  #include <linux/seq_file.h>
    1.16 +#include <linux/reboot.h>
    1.17  #include <asm/processor.h>
    1.18  #include <linux/console.h>
    1.19  #include <linux/module.h>
    1.20 @@ -1148,10 +1151,10 @@ void __init cpu_init (void)
    1.21  
    1.22  #include <asm/suspend.h>
    1.23  
    1.24 -/* Treat multiple suspend requests as a single one. */
    1.25 -static int suspending;
    1.26 +/* Ignore multiple shutdown requests. */
    1.27 +static int shutting_down = -1;
    1.28  
    1.29 -static void suspend_task(void *unused)
    1.30 +static void __do_suspend(void)
    1.31  {
    1.32      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
    1.33      extern void blkdev_suspend(void);
    1.34 @@ -1220,7 +1223,7 @@ static void suspend_task(void *unused)
    1.35  
    1.36      HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
    1.37  
    1.38 -    suspending = 0; 
    1.39 +    shutting_down = -1; 
    1.40  
    1.41      memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
    1.42  
    1.43 @@ -1272,25 +1275,78 @@ static void suspend_task(void *unused)
    1.44          free_page((unsigned long)suspend_record);
    1.45  }
    1.46  
    1.47 -static struct tq_struct suspend_tq;
    1.48 +static int shutdown_process(void *__unused)
    1.49 +{
    1.50 +    static char *envp[] = { "HOME=/", "TERM=linux", 
    1.51 +                            "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
    1.52 +    static char *restart_argv[]  = { "/sbin/shutdown", "-r", "now", NULL };
    1.53 +    static char *poweroff_argv[] = { "/sbin/halt",     "-p",        NULL };
    1.54 +
    1.55 +    extern asmlinkage long sys_reboot(int magic1, int magic2,
    1.56 +                                      unsigned int cmd, void *arg);
    1.57 +
    1.58 +    daemonize();
    1.59 +
    1.60 +    switch ( shutting_down )
    1.61 +    {
    1.62 +    case CMSG_SHUTDOWN_POWEROFF:
    1.63 +        if ( execve("/sbin/halt", poweroff_argv, envp) < 0 )
    1.64 +        {
    1.65 +            sys_reboot(LINUX_REBOOT_MAGIC1,
    1.66 +                       LINUX_REBOOT_MAGIC2,
    1.67 +                       LINUX_REBOOT_CMD_POWER_OFF,
    1.68 +                       NULL);
    1.69 +        }
    1.70 +        break;
    1.71 +
    1.72 +    case CMSG_SHUTDOWN_REBOOT:
    1.73 +        if ( execve("/sbin/shutdown", restart_argv, envp) < 0 )
    1.74 +        {
    1.75 +            sys_reboot(LINUX_REBOOT_MAGIC1,
    1.76 +                       LINUX_REBOOT_MAGIC2,
    1.77 +                       LINUX_REBOOT_CMD_RESTART,
    1.78 +                       NULL);
    1.79 +        }
    1.80 +        break;
    1.81 +    }
    1.82 +
    1.83 +    return 0;
    1.84 +}
    1.85 +
    1.86 +static void __shutdown_handler(void *unused)
    1.87 +{
    1.88 +    int err;
    1.89 +
    1.90 +    if ( shutting_down != CMSG_SHUTDOWN_SUSPEND )
    1.91 +    {
    1.92 +        err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
    1.93 +        if ( err < 0 )
    1.94 +            printk(KERN_ALERT "Error creating shutdown process!\n");
    1.95 +        else
    1.96 +            shutting_down = -1; /* could try again */
    1.97 +    }
    1.98 +    else
    1.99 +    {
   1.100 +        __do_suspend();
   1.101 +    }
   1.102 +}
   1.103  
   1.104  static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
   1.105  {
   1.106 -    if ( msg->subtype != CMSG_SHUTDOWN_SUSPEND )
   1.107 +    static struct tq_struct shutdown_tq;
   1.108 +
   1.109 +    if ( (shutting_down == -1) &&
   1.110 +         ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
   1.111 +          (msg->subtype == CMSG_SHUTDOWN_REBOOT) ||
   1.112 +          (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) )
   1.113      {
   1.114 -        extern void ctrl_alt_del(void);
   1.115 -        ctrl_if_send_response(msg);
   1.116 -        ctrl_alt_del();
   1.117 -    }
   1.118 -    else if ( !suspending )
   1.119 -    {
   1.120 -	suspending = 1;
   1.121 -	suspend_tq.routine = suspend_task;
   1.122 -	schedule_task(&suspend_tq);	
   1.123 +        shutting_down = msg->subtype;
   1.124 +        shutdown_tq.routine = __shutdown_handler;
   1.125 +        schedule_task(&shutdown_tq);
   1.126      }
   1.127      else
   1.128      {
   1.129 -	printk(KERN_ALERT"Ignore queued suspend request\n");
   1.130 +	printk("Ignore spurious shutdown request\n");
   1.131      }
   1.132  
   1.133      ctrl_if_send_response(msg);