diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/xend/lib/domain_controller.h | 159 | ||||
-rwxr-xr-x | tools/xend/lib/main.py | 8 | ||||
-rw-r--r-- | tools/xend/lib/utils.c | 24 | ||||
-rw-r--r-- | tools/xend/setup.py | 3 |
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"]) |