Add code to make handling domain poweroff/reboot symmetrical
between paravirtualized and fully virtualized.
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.
It would be useful if all shutdown/reboot operations were
symmetrical from domain 0's point of view. One approach
would be to redefine sched_op to handle other domains than
the current domain, but this seemed excessive. Another
approach, which is what this patch implements, adds
a DOM0 hypervisor call very similar to the existing
DOM0_DESTROYDOMAIN, called DOM0_SHUTDOWNDOMAIN, which handles
the shutdown and reason -- basically, just like a
paravirtualized system.
Like DOM0_DESTROYDOMAIN, add a xenctrl wrapper, and have qemu
call it.
With this change, both domain types shutdown/reboot using
the same dom0 management logic. All control decisions are
removed from qemu, which now simply handles the request
and reason. At a very high level, the flow is "notify of
shutdown and reason", "send VIRQ_DOM_EXC", process, and
destroy domain. Paravirtualized and fully-virtualized
domains would differ slightly in the first step of
notification. Paravirtualized continues to use sched_op,
fully virtualized uses DOM0_SHUTDOWNDOMAIN. The rest
of the steps would be identical in both cases.
Or, back to the opening sentence, make the operations as
symmetrical as possible.
(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@xxxxxxxxxxxxxxx)
--
------------------------------------------------------------------------
Ben Thomas Virtual Iron Software
bthomas@xxxxxxxxxxxxxxx Tower 1, Floor 2
978-849-1214 900 Chelmsford Street
Lowell, MA 01851
diff -r 4ad317429111 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Sun Apr 2 16:16:53 2006 +0100
+++ b/tools/ioemu/target-i386-dm/helper2.c Mon Apr 3 11:22:29 2006 -0400
@@ -409,12 +409,20 @@ void
void
destroy_hvm_domain(void)
{
- extern FILE* logfile;
- char destroy_cmd[32];
-
- sprintf(destroy_cmd, "xm destroy %d", domid);
- if (system(destroy_cmd) == -1)
- fprintf(logfile, "%s failed.!\n", destroy_cmd);
+ int xcHandle;
+ int sts;
+
+ xcHandle = xc_interface_open();
+ if (xcHandle < 0)
+ fprintf(logfile, "Cannot acquire xenctrl handle\n");
+ else {
+ sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_poweroff);
+ if (sts != 0)
+ fprintf(logfile, "? xc_domain_shutdown failed to issue poweroff, sts
%d\n", sts);
+ else
+ fprintf(logfile, "Issued domain %d poweroff\n", domid);
+ xc_interface_close(xcHandle);
+ }
}
fd_set wakeup_rfds;
@@ -480,13 +488,24 @@ int main_loop(void)
static void qemu_hvm_reset(void *unused)
{
- char cmd[64];
+ int xcHandle;
+ int sts;
/* pause domain first, to avoid repeated reboot request*/
xc_domain_pause(xc_handle, domid);
- sprintf(cmd, "xm shutdown -R %d", domid);
- system(cmd);
+ xcHandle = xc_interface_open();
+ if (xcHandle < 0)
+ fprintf(logfile, "Cannot acquire xenctrl handle\n");
+ else {
+ sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
+ if (sts != 0)
+ fprintf(logfile, "? xc_domain_shutdown failed to issue reboot, sts
%d\n", sts);
+ else
+ fprintf(logfile, "Issued domain %d reboot\n", domid);
+ xc_interface_close(xcHandle);
+ }
+
}
CPUState * cpu_init()
diff -r 4ad317429111 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Sun Apr 2 16:16:53 2006 +0100
+++ b/tools/ioemu/vl.c Mon Apr 3 11:22:29 2006 -0400
@@ -2556,8 +2556,10 @@ static int set_mm_mapping(int xc_handle,
return -1;
}
+#if 0 /* Enable for debugging -- generates many lines in log file */
for (i = 0; i < nr_pages; i++)
fprintf(stderr, "set_map result i %x result %lx\n", i,
extent_start[i]);
+#endif
return 0;
}
diff -r 4ad317429111 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Sun Apr 2 16:16:53 2006 +0100
+++ b/tools/libxc/xc_domain.c Mon Apr 3 11:22:29 2006 -0400
@@ -55,6 +55,17 @@ int xc_domain_destroy(int xc_handle,
DECLARE_DOM0_OP;
op.cmd = DOM0_DESTROYDOMAIN;
op.u.destroydomain.domain = (domid_t)domid;
+ return do_dom0_op(xc_handle, &op);
+}
+
+int xc_domain_shutdown(int xc_handle,
+ uint32_t domid,
+ int reason)
+{
+ DECLARE_DOM0_OP;
+ op.cmd = DOM0_SHUTDOWNDOMAIN;
+ op.u.shutdowndomain.domain = (domid_t)domid;
+ op.u.shutdowndomain.shutdown_reason = reason;
return do_dom0_op(xc_handle, &op);
}
diff -r 4ad317429111 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Sun Apr 2 16:16:53 2006 +0100
+++ b/tools/libxc/xenctrl.h Mon Apr 3 11:22:29 2006 -0400
@@ -205,6 +205,21 @@ int xc_domain_unpause(int xc_handle,
*/
int xc_domain_destroy(int xc_handle,
uint32_t domid);
+
+/**
+ * This function will shutdown a domain. This is intended for use in
+ * fully-virtualized domains where this operation is analogous to the
+ * sched_op operations in a paravirtualized domain. The caller is
+ * expected to give the reason for the shutdown.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id to destroy
+ * @parm reason is the reason (SHUTDOWN_xxx) for the shutdown
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_shutdown(int xc_handle,
+ uint32_t domid,
+ int reason);
int xc_vcpu_setaffinity(int xc_handle,
uint32_t domid,
diff -r 4ad317429111 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c Sun Apr 2 16:16:53 2006 +0100
+++ b/xen/common/dom0_ops.c Mon Apr 3 11:22:29 2006 -0400
@@ -682,6 +682,23 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t)
break;
#endif
+ case DOM0_SHUTDOWNDOMAIN:
+ {
+ struct domain *d = find_domain_by_id(op->u.shutdowndomain.domain);
+ ret = -ESRCH;
+ if ( d != NULL )
+ {
+ ret = -EINVAL;
+ if ( d != current->domain )
+ {
+ domain_shutdown(d, op->u.shutdowndomain.shutdown_reason);
+ ret = 0;
+ }
+ put_domain(d);
+ }
+ }
+ break;
+
default:
ret = arch_do_dom0_op(op, u_dom0_op);
break;
diff -r 4ad317429111 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Sun Apr 2 16:16:53 2006 +0100
+++ b/xen/include/public/dom0_ops.h Mon Apr 3 11:22:29 2006 -0400
@@ -470,6 +470,15 @@ typedef struct dom0_hypercall_init {
unsigned long mfn; /* machine frame to be initialised */
} dom0_hypercall_init_t;
DEFINE_GUEST_HANDLE(dom0_hypercall_init_t);
+
+#define DOM0_SHUTDOWNDOMAIN 49
+typedef struct dom0_shutdowndomain {
+ /* IN variables. */
+ domid_t domain; /* domain to be affected */
+ int shutdown_reason; /* SHUTDOWN_xxx reason code */
+} dom0_shutdowndomain_t;
+
+DEFINE_GUEST_HANDLE(dom0_shutdowndomain_t);
typedef struct dom0_op {
uint32_t cmd;
@@ -512,6 +521,7 @@ typedef struct dom0_op {
struct dom0_irq_permission irq_permission;
struct dom0_iomem_permission iomem_permission;
struct dom0_hypercall_init hypercall_init;
+ struct dom0_shutdowndomain shutdowndomain;
uint8_t pad[128];
} u;
} dom0_op_t;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|