aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/xend/lib/domain_controller.h159
-rwxr-xr-xtools/xend/lib/main.py8
-rw-r--r--tools/xend/lib/utils.c24
-rw-r--r--tools/xend/setup.py3
4 files changed, 163 insertions, 31 deletions
diff --git a/tools/xend/lib/domain_controller.h b/tools/xend/lib/domain_controller.h
index 14f970dd04..eec8402e5f 100644
--- a/tools/xend/lib/domain_controller.h
+++ b/tools/xend/lib/domain_controller.h
@@ -56,14 +56,90 @@ typedef struct {
#define CMSG_BLKIF_BE 1 /* Block-device backend */
#define CMSG_BLKIF_FE 2 /* Block-device frontend */
+
+/******************************************************************************
+ * CONSOLE DEFINITIONS
+ */
+
/*
* Subtypes for console messages.
*/
#define CMSG_CONSOLE_DATA 0
+
+/******************************************************************************
+ * BLOCK-INTERFACE FRONTEND DEFINITIONS
+ */
+
+/* Messages from domain controller to guest. */
+#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED 0
+
+/* Messages from guest to domain controller. */
+#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED 32
+#define CMSG_BLKIF_FE_INTERFACE_UP 33
+#define CMSG_BLKIF_FE_INTERFACE_DOWN 34
+
+/* These are used by both front-end and back-end drivers. */
+#define blkif_vdev_t u16
+#define blkif_pdev_t u16
+#define blkif_sector_t u64
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
+ * Notify a guest about a status change on one of its block interfaces.
+ * If the interface is DESTROYED or DOWN then the interface is disconnected:
+ * 1. The shared-memory frame is available for reuse.
+ * 2. Any unacknowledged messgaes pending on the interface were dropped.
+ */
+#define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
+#define BLKIF_INTERFACE_STATUS_DOWN 1 /* Interface exists but is down. */
+#define BLKIF_INTERFACE_STATUS_UP 2 /* Interface exists and is up. */
+typedef struct {
+ unsigned int handle;
+ unsigned int status;
+ unsigned int evtchn; /* status == BLKIF_INTERFACE_STATUS_UP */
+} blkif_fe_interface_status_changed_t;
+
/*
- * Subtypes for block-device messages.
+ * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the front-end driver is DOWN or UP.
+ * When the driver goes DOWN then the controller will send no more
+ * status-change notifications. When the driver comes UP then the controller
+ * will send a notification for each interface that currently exists.
+ * If the driver goes DOWN while interfaces are still UP, the domain
+ * will automatically take the interfaces DOWN.
*/
+#define BLKIF_DRIVER_STATUS_DOWN 0
+#define BLKIF_DRIVER_STATUS_UP 1
+typedef struct {
+ unsigned int status; /* BLKIF_DRIVER_STATUS_??? */
+} blkif_fe_driver_status_changed_t;
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_UP:
+ * If successful, the domain controller will acknowledge with a STATUS_UP
+ * message.
+ */
+typedef struct {
+ unsigned int handle;
+ unsigned long shmem_frame;
+} blkif_fe_interface_up_t;
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_DOWN:
+ * If successful, the domain controller will acknowledge with a STATUS_DOWN
+ * message.
+ */
+typedef struct {
+ unsigned int handle;
+} blkif_fe_interface_down_t;
+
+
+/******************************************************************************
+ * BLOCK-INTERFACE BACKEND DEFINITIONS
+ */
+
+/* Messages from domain controller. */
#define CMSG_BLKIF_BE_CREATE 0 /* Create a new block-device interface. */
#define CMSG_BLKIF_BE_DESTROY 1 /* Destroy a block-device interface. */
#define CMSG_BLKIF_BE_VBD_CREATE 2 /* Create a new VBD for an interface. */
@@ -71,14 +147,13 @@ typedef struct {
#define CMSG_BLKIF_BE_VBD_GROW 4 /* Append an extent to a given VBD. */
#define CMSG_BLKIF_BE_VBD_SHRINK 5 /* Remove last extent from a given VBD. */
+/* Messages to domain controller. */
+#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
+
/*
- * Message request/response defintions for block-device messages.
+ * Message request/response definitions for block-device messages.
*/
-#define blkif_vdev_t u16
-#define blkif_pdev_t u16
-#define blkif_sector_t u64
-
typedef struct {
blkif_pdev_t device;
blkif_sector_t sector_start;
@@ -86,21 +161,36 @@ typedef struct {
} blkif_extent_t;
/* Non-specific 'okay' return. */
-#define BLKIF_STATUS_OKAY 0
+#define BLKIF_BE_STATUS_OKAY 0
/* Non-specific 'error' return. */
-#define BLKIF_STATUS_ERROR 1
+#define BLKIF_BE_STATUS_ERROR 1
/* The following are specific error returns. */
-#define BLKIF_STATUS_INTERFACE_EXISTS 2
-#define BLKIF_STATUS_INTERFACE_NOT_FOUND 3
+#define BLKIF_BE_STATUS_INTERFACE_EXISTS 2
+#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
+#define BLKIF_BE_STATUS_VBD_EXISTS 4
+#define BLKIF_BE_STATUS_VBD_NOT_FOUND 5
+#define BLKIF_BE_STATUS_OUT_OF_MEMORY 6
+#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND 7
+#define BLKIF_BE_STATUS_MAPPING_ERROR 8
/* This macro can be used to create an array of descriptive error strings. */
-#define BLKIF_STATUS_ERRORS { \
- "Okay", \
- "Non-specific error", \
- "Interface already exists", \
- "Interface not found" }
+#define BLKIF_BE_STATUS_ERRORS { \
+ "Okay", \
+ "Non-specific error", \
+ "Interface already exists", \
+ "Interface not found", \
+ "VBD already exists", \
+ "VBD not found", \
+ "Out of memory", \
+ "Extent not found for VBD", \
+ "Could not map domain memory" }
-/* CMSG_BLKIF_CREATE */
+/*
+ * CMSG_BLKIF_BE_CREATE:
+ * When the driver sends a successful response then the interface is fully
+ * set up. The controller will send an UP notification to the front-end
+ * driver.
+ */
typedef struct {
/* IN */
domid_t domid; /* Domain attached to new interface. */
@@ -109,18 +199,23 @@ typedef struct {
unsigned long shmem_frame; /* Page cont. shared comms window. */
/* OUT */
unsigned int status;
-} blkif_create_t;
+} blkif_be_create_t;
-/* CMSG_BLKIF_DESTROY */
+/*
+ * CMSG_BLKIF_BE_DESTROY:
+ * When the driver sends a successful response then the interface is fully
+ * torn down. The controller will send a DOWN notification to the front-end
+ * driver.
+ */
typedef struct {
/* IN */
domid_t domid; /* Identify interface to be destroyed. */
unsigned int blkif_handle; /* ...ditto... */
/* OUT */
unsigned int status;
-} blkif_destroy_t;
+} blkif_be_destroy_t;
-/* CMSG_BLKIF_VBD_CREATE */
+/* CMSG_BLKIF_BE_VBD_CREATE */
typedef struct {
/* IN */
domid_t domid; /* Identify blkdev interface. */
@@ -129,9 +224,9 @@ typedef struct {
int readonly; /* Non-zero -> VBD isn't writeable. */
/* OUT */
unsigned int status;
-} blkif_vbd_create_t;
+} blkif_be_vbd_create_t;
-/* CMSG_BLKIF_VBD_DESTROY */
+/* CMSG_BLKIF_BE_VBD_DESTROY */
typedef struct {
/* IN */
domid_t domid; /* Identify blkdev interface. */
@@ -139,9 +234,9 @@ typedef struct {
blkif_vdev_t vdevice; /* Interface-specific id of the VBD. */
/* OUT */
unsigned int status;
-} blkif_vbd_destroy_t;
+} blkif_be_vbd_destroy_t;
-/* CMSG_BLKIF_VBD_GROW */
+/* CMSG_BLKIF_BE_VBD_GROW */
typedef struct {
/* IN */
domid_t domid; /* Identify blkdev interface. */
@@ -150,9 +245,9 @@ typedef struct {
blkif_extent_t extent; /* Physical extent to append to VBD. */
/* OUT */
unsigned int status;
-} blkif_vbd_grow_t;
+} blkif_be_vbd_grow_t;
-/* CMSG_BLKIF_VBD_SHRINK */
+/* CMSG_BLKIF_BE_VBD_SHRINK */
typedef struct {
/* IN */
domid_t domid; /* Identify blkdev interface. */
@@ -160,6 +255,16 @@ typedef struct {
blkif_vdev_t vdevice; /* Interface-specific id of the VBD. */
/* OUT */
unsigned int status;
-} blkif_vbd_shrink_t;
+} blkif_be_vbd_shrink_t;
+
+/*
+ * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the back-end driver is DOWN or UP.
+ * If the driver goes DOWN while interfaces are still UP, the domain
+ * will automatically send DOWN notifications.
+ */
+typedef struct {
+ unsigned int status; /* BLKIF_DRIVER_STATUS_??? */
+} blkif_be_driver_status_changed;
#endif /* __DOMAIN_CONTROLLER_H__ */
diff --git a/tools/xend/lib/main.py b/tools/xend/lib/main.py
index 4b243b3307..4dd26ca8c5 100755
--- a/tools/xend/lib/main.py
+++ b/tools/xend/lib/main.py
@@ -44,6 +44,14 @@ def daemon_loop():
# notifications.
notifier = xend.utils.notifier()
+ # The DOM0 control interface is not set up via the management interface.
+ # Note that console messages don't come our way (actually, only driver
+ # back-ends should use the DOM0 control interface). We therefore don't
+ # need to set up console structures.
+ xend.utils.port(0)
+ xend.main.notifier.bind(port.local_port)
+ xend.main.control_list[port.local_port] = (port, 0, 0, 0)
+
##
## MAIN LOOP
##
diff --git a/tools/xend/lib/utils.c b/tools/xend/lib/utils.c
index 4883ec1a46..c28d682ec9 100644
--- a/tools/xend/lib/utils.c
+++ b/tools/xend/lib/utils.c
@@ -22,6 +22,8 @@
#include <signal.h>
#include <xc.h>
+#include <asm-xen/proc_cmd.h>
+
#include <hypervisor-if.h>
#include "domain_controller.h"
@@ -684,8 +686,23 @@ static PyObject *xu_port_new(PyObject *self, PyObject *args)
goto fail2;
}
- if ( xc_evtchn_bind_interdomain(xup->xc_handle,
- DOMID_SELF, dom, &port1, &port2) != 0 )
+ if ( dom == 0ULL )
+ {
+ /*
+ * The control-interface event channel for DOM0 is already set up.
+ * We use an ioctl to discover the port at our end of the channel.
+ */
+ port1 = ioctl(xup->xc_handle, IOCTL_PRIVCMD_INITDOMAIN_EVTCHN, NULL);
+ port2 = -1; /* We don't need the remote end of the DOM0 link. */
+ if ( port1 < 0 )
+ {
+ PyErr_SetString(port_error, "Could not open channel to DOM0");
+ goto fail3;
+ }
+ }
+ else if ( xc_evtchn_bind_interdomain(xup->xc_handle,
+ DOMID_SELF, dom,
+ &port1, &port2) != 0 )
{
PyErr_SetString(port_error, "Could not open channel to domain");
goto fail3;
@@ -744,7 +761,8 @@ static void xu_port_dealloc(PyObject *self)
{
xu_port_object *xup = (xu_port_object *)self;
unmap_control_interface(xup->mem_fd, xup->interface);
- (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
+ if ( xup->remote_dom != 0ULL )
+ (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
(void)xc_interface_close(xup->xc_handle);
(void)close(xup->mem_fd);
PyObject_Del(self);
diff --git a/tools/xend/setup.py b/tools/xend/setup.py
index 1f39cb4572..5567d7093c 100644
--- a/tools/xend/setup.py
+++ b/tools/xend/setup.py
@@ -4,7 +4,8 @@ from distutils.core import setup, Extension
utils = Extension("utils",
extra_compile_args = ["-fno-strict-aliasing"],
include_dirs = ["../xc/lib",
- "../../xen/include/hypervisor-ifs"],
+ "../../xen/include/hypervisor-ifs",
+ "../../xenolinux-sparse/include"],
library_dirs = ["../xc/lib"],
libraries = ["xc"],
sources = ["lib/utils.c"])