direct-io.hg

changeset 9560:b128f55ca05c

Add code to make handling domain poweroff/reboot symmetrical between
paravirtualized and fully virtualized. This approach uses the new
sched_op to handle other domains than the current domain. The new
code, SCHEDOP_remote_shutdown, is very much like SCHEDOP_shutdown, but
is called with the id of the domain which is to be shut down. This
allows fully virtualized shutdown and para-virtualized shutdown to be
identical from that point forward.

A paravirtualized domain uses sched_op to shut down and set the reason
code. This will send a VIRQ_DOM_EXC, which can be handled in dom0 by
control software. In some ways, this resembles SIGCHILD/waitpid, and
is a reasonable model.

The fully virtualized case has qemu invoke xm directly. This is a
different path than paravirtualized. It also removes decision and
policy making choices from the rest of the control software and places
it within qemu. When any dom0 logic eventually gets a VIRQ_DOM_EXC,
the information about the domain is gone having been destroyed by xm.

A libxenctrl wrapper, xc_shutdown_domain has been added and qemu now
calls it.

As a freebie, #if 0 some very verbose logging code in qemu. Totally
unrelated, but as long as I was there...

Signed-off-by: Ben Thomas <ben@virtualiron.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 06 15:24:00 2006 +0100 (2006-04-06)
parents 131051c09008
children e568bfe66a52
files linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/libxc/xc_domain.c tools/libxc/xenctrl.h xen/common/schedule.c xen/include/public/sched.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Thu Apr 06 15:22:46 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Thu Apr 06 15:24:00 2006 +0100
     1.3 @@ -277,6 +277,7 @@ static int __init privcmd_init(void)
     1.4  	set_bit(__HYPERVISOR_mmu_update,       hypercall_permission_map);
     1.5  	set_bit(__HYPERVISOR_mmuext_op,        hypercall_permission_map);
     1.6  	set_bit(__HYPERVISOR_xen_version,      hypercall_permission_map);
     1.7 +	set_bit(__HYPERVISOR_sched_op,         hypercall_permission_map);
     1.8  
     1.9  	privcmd_intf = create_xen_proc_entry("privcmd", 0400);
    1.10  	if (privcmd_intf != NULL)
     2.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Apr 06 15:22:46 2006 +0100
     2.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Apr 06 15:24:00 2006 +0100
     2.3 @@ -409,12 +409,20 @@ int xc_handle;
     2.4  void
     2.5  destroy_hvm_domain(void)
     2.6  {
     2.7 -    extern FILE* logfile;
     2.8 -    char destroy_cmd[32];
     2.9 -
    2.10 -    sprintf(destroy_cmd, "xm destroy %d", domid);
    2.11 -    if (system(destroy_cmd) == -1)
    2.12 -        fprintf(logfile, "%s failed.!\n", destroy_cmd);
    2.13 +   int xcHandle;
    2.14 +   int sts;
    2.15 + 
    2.16 +   xcHandle = xc_interface_open();
    2.17 +   if (xcHandle < 0)
    2.18 +     fprintf(logfile, "Cannot acquire xenctrl handle\n");
    2.19 +   else {
    2.20 +     sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_poweroff);
    2.21 +     if (sts != 0)
    2.22 +       fprintf(logfile, "? xc_domain_shutdown failed to issue poweroff, sts %d, errno %d\n", sts, errno);
    2.23 +     else
    2.24 +       fprintf(logfile, "Issued domain %d poweroff\n", domid);
    2.25 +     xc_interface_close(xcHandle);
    2.26 +   }
    2.27  }
    2.28  
    2.29  fd_set wakeup_rfds;
    2.30 @@ -480,13 +488,24 @@ int main_loop(void)
    2.31  
    2.32  static void qemu_hvm_reset(void *unused)
    2.33  {
    2.34 -    char cmd[64];
    2.35 +   int xcHandle;
    2.36 +   int sts;
    2.37 +
    2.38 +   /* pause domain first, to avoid repeated reboot request*/
    2.39 +   xc_domain_pause(xc_handle, domid);
    2.40  
    2.41 -    /* pause domain first, to avoid repeated reboot request*/
    2.42 -    xc_domain_pause(xc_handle, domid);
    2.43 -
    2.44 -    sprintf(cmd, "xm shutdown -R %d", domid);
    2.45 -    system(cmd);
    2.46 +   xcHandle = xc_interface_open();
    2.47 +   if (xcHandle < 0)
    2.48 +     fprintf(logfile, "Cannot acquire xenctrl handle\n");
    2.49 +   else {
    2.50 +     sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
    2.51 +     if (sts != 0)
    2.52 +       fprintf(logfile, "? xc_domain_shutdown failed to issue reboot, sts %d\n", sts);
    2.53 +     else
    2.54 +       fprintf(logfile, "Issued domain %d reboot\n", domid);
    2.55 +     xc_interface_close(xcHandle);
    2.56 +   }
    2.57 + 
    2.58  }
    2.59  
    2.60  CPUState * cpu_init()
     3.1 --- a/tools/ioemu/vl.c	Thu Apr 06 15:22:46 2006 +0100
     3.2 +++ b/tools/ioemu/vl.c	Thu Apr 06 15:24:00 2006 +0100
     3.3 @@ -2556,8 +2556,10 @@ static int set_mm_mapping(int xc_handle,
     3.4          return -1;
     3.5      }
     3.6  
     3.7 +#if 0 /* Generates lots of log file output - turn on for debugging */
     3.8      for (i = 0; i < nr_pages; i++)
     3.9          fprintf(stderr, "set_map result i %x result %lx\n", i, extent_start[i]);
    3.10 +#endif
    3.11  
    3.12      return 0;
    3.13  }
     4.1 --- a/tools/libxc/xc_domain.c	Thu Apr 06 15:22:46 2006 +0100
     4.2 +++ b/tools/libxc/xc_domain.c	Thu Apr 06 15:24:00 2006 +0100
     4.3 @@ -58,6 +58,35 @@ int xc_domain_destroy(int xc_handle,
     4.4      return do_dom0_op(xc_handle, &op);
     4.5  }
     4.6  
     4.7 +int xc_domain_shutdown(int xc_handle,
     4.8 +                       uint32_t domid,
     4.9 +                       int reason)
    4.10 +{
    4.11 +    int ret = -1;
    4.12 +    sched_remote_shutdown_t arg;
    4.13 +    DECLARE_HYPERCALL;
    4.14 +
    4.15 +    hypercall.op     = __HYPERVISOR_sched_op;
    4.16 +    hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
    4.17 +    hypercall.arg[1] = (unsigned long)&arg;
    4.18 +    arg.domain_id = domid;
    4.19 +    arg.reason = reason;
    4.20 +
    4.21 +    if ( mlock(&arg, sizeof(arg)) != 0 )
    4.22 +    {
    4.23 +        PERROR("Could not lock memory for Xen hypercall");
    4.24 +        goto out1;
    4.25 +    }
    4.26 +
    4.27 +    ret = do_xen_hypercall(xc_handle, &hypercall);
    4.28 +
    4.29 +    safe_munlock(&arg, sizeof(arg));
    4.30 +
    4.31 + out1:
    4.32 +    return ret;
    4.33 +}
    4.34 +
    4.35 +
    4.36  int xc_vcpu_setaffinity(int xc_handle,
    4.37                          uint32_t domid, 
    4.38                          int vcpu,
     5.1 --- a/tools/libxc/xenctrl.h	Thu Apr 06 15:22:46 2006 +0100
     5.2 +++ b/tools/libxc/xenctrl.h	Thu Apr 06 15:24:00 2006 +0100
     5.3 @@ -206,6 +206,21 @@ int xc_domain_unpause(int xc_handle,
     5.4  int xc_domain_destroy(int xc_handle, 
     5.5                        uint32_t domid);
     5.6  
     5.7 +/**
     5.8 + * This function will shutdown a domain. This is intended for use in
     5.9 + * fully-virtualized domains where this operation is analogous to the
    5.10 + * sched_op operations in a paravirtualized domain. The caller is
    5.11 + * expected to give the reason for the shutdown.
    5.12 + *
    5.13 + * @parm xc_handle a handle to an open hypervisor interface
    5.14 + * @parm domid the domain id to destroy
    5.15 + * @parm reason is the reason (SHUTDOWN_xxx) for the shutdown
    5.16 + * @return 0 on success, -1 on failure
    5.17 + */
    5.18 +int xc_domain_shutdown(int xc_handle, 
    5.19 +                       uint32_t domid,
    5.20 +                       int reason);
    5.21 +
    5.22  int xc_vcpu_setaffinity(int xc_handle,
    5.23                          uint32_t domid,
    5.24                          int vcpu,
     6.1 --- a/xen/common/schedule.c	Thu Apr 06 15:22:46 2006 +0100
     6.2 +++ b/xen/common/schedule.c	Thu Apr 06 15:24:00 2006 +0100
     6.3 @@ -413,6 +413,30 @@ long do_sched_op(int cmd, GUEST_HANDLE(v
     6.4          break;
     6.5      }
     6.6  
     6.7 +    case SCHEDOP_remote_shutdown:
     6.8 +    {
     6.9 +        struct domain *d;
    6.10 +        struct sched_remote_shutdown sched_remote_shutdown;
    6.11 +
    6.12 +        if ( !IS_PRIV(current->domain) )
    6.13 +            return -EPERM;
    6.14 +
    6.15 +        ret = -EFAULT;
    6.16 +        if ( copy_from_guest(&sched_remote_shutdown, arg, 1) )
    6.17 +            break;
    6.18 +
    6.19 +        ret = -ESRCH;
    6.20 +        d = find_domain_by_id(sched_remote_shutdown.domain_id);
    6.21 +        if ( d == NULL )
    6.22 +            break;
    6.23 +
    6.24 +        domain_shutdown(d, (u8)sched_remote_shutdown.reason);
    6.25 +        put_domain(d);
    6.26 +        ret = 0;
    6.27 +
    6.28 +        break;
    6.29 +    }
    6.30 +
    6.31      default:
    6.32          ret = -ENOSYS;
    6.33      }
     7.1 --- a/xen/include/public/sched.h	Thu Apr 06 15:22:46 2006 +0100
     7.2 +++ b/xen/include/public/sched.h	Thu Apr 06 15:24:00 2006 +0100
     7.3 @@ -65,6 +65,19 @@ typedef struct sched_poll {
     7.4  DEFINE_GUEST_HANDLE(sched_poll_t);
     7.5  
     7.6  /*
     7.7 + * Declare a shutdown for another domain. The main use of this function is
     7.8 + * in interpreting shutdown requests and reasons for fully-virtualized
     7.9 + * domains.  A para-virtualized domain may use SCHEDOP_shutdown directly.
    7.10 + * @arg == pointer to sched_remote_shutdown structure.
    7.11 + */
    7.12 +#define SCHEDOP_remote_shutdown        4
    7.13 +typedef struct sched_remote_shutdown {
    7.14 +    domid_t domain_id;         /* Remote domain ID */
    7.15 +    unsigned int reason;       /* SHUTDOWN_xxx reason */
    7.16 +} sched_remote_shutdown_t;
    7.17 +DEFINE_GUEST_HANDLE(sched_remote_shutdown_t);
    7.18 +
    7.19 +/*
    7.20   * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
    7.21   * software to determine the appropriate action. For the most part, Xen does
    7.22   * not care about the shutdown code.