# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID b128f55ca05ccda7298b0725c62f30ca8d1a3c8f
# Parent 131051c090088dcbeedde71b41a6cb9e4fd60c69
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@xxxxxxxxxxxxxxx>
diff -r 131051c09008 -r b128f55ca05c
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Apr 6
14:22:46 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Apr 6
14:24:00 2006
@@ -277,6 +277,7 @@
set_bit(__HYPERVISOR_mmu_update, hypercall_permission_map);
set_bit(__HYPERVISOR_mmuext_op, hypercall_permission_map);
set_bit(__HYPERVISOR_xen_version, hypercall_permission_map);
+ set_bit(__HYPERVISOR_sched_op, hypercall_permission_map);
privcmd_intf = create_xen_proc_entry("privcmd", 0400);
if (privcmd_intf != NULL)
diff -r 131051c09008 -r b128f55ca05c tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Thu Apr 6 14:22:46 2006
+++ b/tools/ioemu/target-i386-dm/helper2.c Thu Apr 6 14:24:00 2006
@@ -409,12 +409,20 @@
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, errno %d\n", sts, errno);
+ else
+ fprintf(logfile, "Issued domain %d poweroff\n", domid);
+ xc_interface_close(xcHandle);
+ }
}
fd_set wakeup_rfds;
@@ -480,13 +488,24 @@
static void qemu_hvm_reset(void *unused)
{
- char cmd[64];
-
- /* pause domain first, to avoid repeated reboot request*/
- xc_domain_pause(xc_handle, domid);
-
- sprintf(cmd, "xm shutdown -R %d", domid);
- system(cmd);
+ int xcHandle;
+ int sts;
+
+ /* pause domain first, to avoid repeated reboot request*/
+ xc_domain_pause(xc_handle, domid);
+
+ 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 131051c09008 -r b128f55ca05c tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu Apr 6 14:22:46 2006
+++ b/tools/ioemu/vl.c Thu Apr 6 14:24:00 2006
@@ -2556,8 +2556,10 @@
return -1;
}
+#if 0 /* Generates lots of log file output - turn on for debugging */
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 131051c09008 -r b128f55ca05c tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Thu Apr 6 14:22:46 2006
+++ b/tools/libxc/xc_domain.c Thu Apr 6 14:24:00 2006
@@ -57,6 +57,35 @@
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)
+{
+ int ret = -1;
+ sched_remote_shutdown_t arg;
+ DECLARE_HYPERCALL;
+
+ hypercall.op = __HYPERVISOR_sched_op;
+ hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
+ hypercall.arg[1] = (unsigned long)&arg;
+ arg.domain_id = domid;
+ arg.reason = reason;
+
+ if ( mlock(&arg, sizeof(arg)) != 0 )
+ {
+ PERROR("Could not lock memory for Xen hypercall");
+ goto out1;
+ }
+
+ ret = do_xen_hypercall(xc_handle, &hypercall);
+
+ safe_munlock(&arg, sizeof(arg));
+
+ out1:
+ return ret;
+}
+
int xc_vcpu_setaffinity(int xc_handle,
uint32_t domid,
diff -r 131051c09008 -r b128f55ca05c tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Apr 6 14:22:46 2006
+++ b/tools/libxc/xenctrl.h Thu Apr 6 14:24:00 2006
@@ -206,6 +206,21 @@
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,
int vcpu,
diff -r 131051c09008 -r b128f55ca05c xen/common/schedule.c
--- a/xen/common/schedule.c Thu Apr 6 14:22:46 2006
+++ b/xen/common/schedule.c Thu Apr 6 14:24:00 2006
@@ -413,6 +413,30 @@
break;
}
+ case SCHEDOP_remote_shutdown:
+ {
+ struct domain *d;
+ struct sched_remote_shutdown sched_remote_shutdown;
+
+ if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&sched_remote_shutdown, arg, 1) )
+ break;
+
+ ret = -ESRCH;
+ d = find_domain_by_id(sched_remote_shutdown.domain_id);
+ if ( d == NULL )
+ break;
+
+ domain_shutdown(d, (u8)sched_remote_shutdown.reason);
+ put_domain(d);
+ ret = 0;
+
+ break;
+ }
+
default:
ret = -ENOSYS;
}
diff -r 131051c09008 -r b128f55ca05c xen/include/public/sched.h
--- a/xen/include/public/sched.h Thu Apr 6 14:22:46 2006
+++ b/xen/include/public/sched.h Thu Apr 6 14:24:00 2006
@@ -65,6 +65,19 @@
DEFINE_GUEST_HANDLE(sched_poll_t);
/*
+ * Declare a shutdown for another domain. The main use of this function is
+ * in interpreting shutdown requests and reasons for fully-virtualized
+ * domains. A para-virtualized domain may use SCHEDOP_shutdown directly.
+ * @arg == pointer to sched_remote_shutdown structure.
+ */
+#define SCHEDOP_remote_shutdown 4
+typedef struct sched_remote_shutdown {
+ domid_t domain_id; /* Remote domain ID */
+ unsigned int reason; /* SHUTDOWN_xxx reason */
+} sched_remote_shutdown_t;
+DEFINE_GUEST_HANDLE(sched_remote_shutdown_t);
+
+/*
* Reason codes for SCHEDOP_shutdown. These may be interpreted by control
* software to determine the appropriate action. For the most part, Xen does
* not care about the shutdown code.
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|