ia64/xen-unstable

changeset 3034:877279a4160b

bitkeeper revision 1.1159.170.45 (419cb897jRheBdVSsNm7oNbz_Q4DeQ)

Bring x2d2 to latest headers. Quite some fixes to make it compile.
author bren@anvil.research
date Thu Nov 18 14:58:31 2004 +0000 (2004-11-18)
parents 032a1cbbba37
children f25437a7e267
files .rootkeys tools/x2d2/Makefile tools/x2d2/cntrl_con.c tools/x2d2/domain_controller.h tools/x2d2/main.c tools/x2d2/minixend.c tools/x2d2/minixend.h
line diff
     1.1 --- a/.rootkeys	Thu Nov 18 13:13:56 2004 +0000
     1.2 +++ b/.rootkeys	Thu Nov 18 14:58:31 2004 +0000
     1.3 @@ -531,8 +531,7 @@ 41013a83z27rKvWIxAfUBMVZ1eDCDg tools/sv/
     1.4  40fcefb3zGC9XNBkSwTEobCoq8YClA tools/sv/inc/style.css
     1.5  4194e861IgTabTt8HOuh143QIJFD1Q tools/x2d2/Makefile
     1.6  4194e861M2gcBz4i94cQYpqzi8n6UA tools/x2d2/cntrl_con.c
     1.7 -4194e861xToz-o2KH6VT_CPJqVGMCg tools/x2d2/domain_controller.h
     1.8 -4194e8612TrrMvC8ZlA4h2ZYCPWz4g tools/x2d2/main.c
     1.9 +4194e8612TrrMvC8ZlA4h2ZYCPWz4g tools/x2d2/minixend.c
    1.10  4194e861x2eqNCD61RYPCUEBVdMYuw tools/x2d2/minixend.h
    1.11  4194e861A4V9VbD_FYmgXpYEj5YwVg tools/x2d2/util.c
    1.12  403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile
     2.1 --- a/tools/x2d2/Makefile	Thu Nov 18 13:13:56 2004 +0000
     2.2 +++ b/tools/x2d2/Makefile	Thu Nov 18 14:58:31 2004 +0000
     2.3 @@ -1,10 +1,22 @@
     2.4 -CFLAGS+=-Wall -g -Werror
     2.5 +XEN_ROOT=../..
     2.6 +include $(XEN_ROOT)/tools/Make.defs
     2.7  
     2.8 -SRCS=main.c cntrl_con.c util.c
     2.9 +CC       = gcc
    2.10 +CFLAGS   = -Wall -Werror -g
    2.11 +
    2.12 +CFLAGS  += -I $(XEN_XC)
    2.13 +CFLAGS  += -I $(XEN_LIBXC)
    2.14 +CFLAGS  += -I $(XEN_LIBXUTIL)
    2.15  
    2.16 -all: minixend
    2.17 +HDRS     = $(wildcard *.h)
    2.18 +OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
    2.19 +
    2.20 +BIN      = minixend
    2.21  
    2.22 -#$(SRCS): minixend.h
    2.23 +all: $(BIN)
    2.24  
    2.25 -minixend: $(subst .c,.o,$(SRCS))
    2.26 -	gcc $^ -o $@ $(LDFLAGS) -lxc -lpthread
    2.27 +clean:
    2.28 +	$(RM) *.a *.so *.o *.rpm $(BIN)
    2.29 +
    2.30 +$(BIN): $(OBJS)
    2.31 +	$(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil -lpthread
     3.1 --- a/tools/x2d2/cntrl_con.c	Thu Nov 18 13:13:56 2004 +0000
     3.2 +++ b/tools/x2d2/cntrl_con.c	Thu Nov 18 14:58:31 2004 +0000
     3.3 @@ -40,7 +40,6 @@ domain_created(const char *name, int mem
     3.4  
     3.5  	pthread_mutex_init(&d->mux, NULL);
     3.6  	pthread_cond_init(&d->cond, NULL);
     3.7 -
     3.8  	pthread_create(&d->thread, NULL, domain_thread_func, d);
     3.9  
    3.10  	list_insert_after(&d->domain_list, &head_domain);
    3.11 @@ -164,7 +163,7 @@ create_command_handler(struct open_conne
    3.12  		send_message(oc, "E01 failed to parse %s\n", args);
    3.13  		return;
    3.14  	}
    3.15 -	r = xc_domain_create(xc_handle, mem_kb, name, -1, 0, &domid);
    3.16 +	r = xc_domain_create(xc_handle, mem_kb, -1, 0, &domid);
    3.17  	if (r < 0) {
    3.18  		send_message(oc, "E02 creating domain (%s)\n",
    3.19  			     strerror(errno));
    3.20 @@ -377,8 +376,8 @@ destroy_command_handler(struct open_conn
    3.21  
    3.22  	r = xc_domain_destroy(xc_handle, domid);
    3.23  	if (r < 0) {
    3.24 -		send_message(oc, "E19 error destroying domain %d: %s\n",
    3.25 -			     domid, sys_errlist[errno]);
    3.26 +		send_message( oc, "E19 error destroying domain %d: %s\n",
    3.27 +			      domid, strerror(errno) );
    3.28  		return;
    3.29  	}
    3.30  	d->state = DOM_STATE_DEAD;
     4.1 --- a/tools/x2d2/domain_controller.h	Thu Nov 18 13:13:56 2004 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,562 +0,0 @@
     4.4 -/******************************************************************************
     4.5 - * domain_controller.h
     4.6 - * 
     4.7 - * Interface to server controller (e.g., 'xend'). This header file defines the 
     4.8 - * interface that is shared with guest OSes.
     4.9 - * 
    4.10 - * Copyright (c) 2004, K A Fraser
    4.11 - */
    4.12 -
    4.13 -/* I've copied this from the xen source pool as getting Xen and
    4.14 -   userspace headers to play nicely together is beyond me -- sos22 */
    4.15 -#define PACKED __attribute__ ((packed))
    4.16 -typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
    4.17 -#define __MEMORY_PADDING(_X) u32 __pad_ ## _X
    4.18 -#define _MEMORY_PADDING(_X)  __MEMORY_PADDING(_X)
    4.19 -#define MEMORY_PADDING       _MEMORY_PADDING(__LINE__)
    4.20 -typedef u16 domid_t;
    4.21 -
    4.22 -/*
    4.23 - * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be
    4.24 - * interpreted by control software to determine the appropriate action. These 
    4.25 - * are only really advisories: the controller can actually do as it likes.
    4.26 - */
    4.27 -#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
    4.28 -#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
    4.29 -#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
    4.30 -
    4.31 -
    4.32 -/*
    4.33 - * CONTROLLER MESSAGING INTERFACE.
    4.34 - */
    4.35 -
    4.36 -typedef struct {
    4.37 -    u8 type;     /*  0: echoed in response */
    4.38 -    u8 subtype;  /*  1: echoed in response */
    4.39 -    u8 id;       /*  2: echoed in response */
    4.40 -    u8 length;   /*  3: number of bytes in 'msg' */
    4.41 -    u8 msg[60];  /*  4: type-specific message data */
    4.42 -} PACKED control_msg_t; /* 64 bytes */
    4.43 -
    4.44 -#define CONTROL_RING_SIZE 8
    4.45 -typedef u32 CONTROL_RING_IDX;
    4.46 -#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1))
    4.47 -
    4.48 -typedef struct {
    4.49 -    control_msg_t tx_ring[CONTROL_RING_SIZE];   /*    0: guest -> controller */
    4.50 -    control_msg_t rx_ring[CONTROL_RING_SIZE];   /*  512: controller -> guest */
    4.51 -    CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */
    4.52 -    CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */
    4.53 -} PACKED control_if_t; /* 1040 bytes */
    4.54 -
    4.55 -/*
    4.56 - * Top-level command types.
    4.57 - */
    4.58 -#define CMSG_CONSOLE        0  /* Console                 */
    4.59 -#define CMSG_BLKIF_BE       1  /* Block-device backend    */
    4.60 -#define CMSG_BLKIF_FE       2  /* Block-device frontend   */
    4.61 -#define CMSG_NETIF_BE       3  /* Network-device backend  */
    4.62 -#define CMSG_NETIF_FE       4  /* Network-device frontend */
    4.63 -#define CMSG_SHUTDOWN       6  /* Shutdown messages       */
    4.64 -#define CMSG_PDB_BE         7  /* PDB backend.            */
    4.65 -#define CMSG_PDB_FE         8  /* PDB frontend.           */
    4.66 -
    4.67 -/******************************************************************************
    4.68 - * CONSOLE DEFINITIONS
    4.69 - */
    4.70 -
    4.71 -/*
    4.72 - * Subtypes for console messages.
    4.73 - */
    4.74 -#define CMSG_CONSOLE_DATA       0
    4.75 -
    4.76 -
    4.77 -/******************************************************************************
    4.78 - * BLOCK-INTERFACE FRONTEND DEFINITIONS
    4.79 - */
    4.80 -
    4.81 -/* Messages from domain controller to guest. */
    4.82 -#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED   0
    4.83 -
    4.84 -/* Messages from guest to domain controller. */
    4.85 -#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED     32
    4.86 -#define CMSG_BLKIF_FE_INTERFACE_CONNECT         33
    4.87 -#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT      34
    4.88 -
    4.89 -/* These are used by both front-end and back-end drivers. */
    4.90 -#define blkif_vdev_t   u16
    4.91 -#define blkif_pdev_t   u16
    4.92 -#define blkif_sector_t u64
    4.93 -
    4.94 -/*
    4.95 - * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
    4.96 - *  Notify a guest about a status change on one of its block interfaces.
    4.97 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
    4.98 - *   1. The shared-memory frame is available for reuse.
    4.99 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   4.100 - */
   4.101 -#define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   4.102 -#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   4.103 -#define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   4.104 -typedef struct {
   4.105 -    u32 handle; /*  0 */
   4.106 -    u32 status; /*  4 */
   4.107 -    u16 evtchn; /*  8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
   4.108 -} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */
   4.109 -
   4.110 -/*
   4.111 - * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
   4.112 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   4.113 - *  When the driver goes DOWN then the controller will send no more
   4.114 - *  status-change notifications. When the driver comes UP then the controller
   4.115 - *  will send a notification for each interface that currently exists.
   4.116 - *  If the driver goes DOWN while interfaces are still UP, the domain
   4.117 - *  will automatically take the interfaces DOWN.
   4.118 - */
   4.119 -#define BLKIF_DRIVER_STATUS_DOWN   0
   4.120 -#define BLKIF_DRIVER_STATUS_UP     1
   4.121 -typedef struct {
   4.122 -    /* IN */
   4.123 -    u32 status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   4.124 -    /* OUT */
   4.125 -    /*
   4.126 -     * Tells driver how many interfaces it should expect to immediately
   4.127 -     * receive notifications about.
   4.128 -     */
   4.129 -    u32 nr_interfaces; /*  4 */
   4.130 -} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
   4.131 -
   4.132 -/*
   4.133 - * CMSG_BLKIF_FE_INTERFACE_CONNECT:
   4.134 - *  If successful, the domain controller will acknowledge with a
   4.135 - *  STATUS_CONNECTED message.
   4.136 - */
   4.137 -typedef struct {
   4.138 -    u32      handle;      /*  0 */
   4.139 -    u32      __pad;
   4.140 -    memory_t shmem_frame; /*  8 */
   4.141 -    MEMORY_PADDING;
   4.142 -} PACKED blkif_fe_interface_connect_t; /* 16 bytes */
   4.143 -
   4.144 -/*
   4.145 - * CMSG_BLKIF_FE_INTERFACE_DISCONNECT:
   4.146 - *  If successful, the domain controller will acknowledge with a
   4.147 - *  STATUS_DISCONNECTED message.
   4.148 - */
   4.149 -typedef struct {
   4.150 -    u32 handle; /*  0 */
   4.151 -} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */
   4.152 -
   4.153 -
   4.154 -/******************************************************************************
   4.155 - * BLOCK-INTERFACE BACKEND DEFINITIONS
   4.156 - */
   4.157 -
   4.158 -/* Messages from domain controller. */
   4.159 -#define CMSG_BLKIF_BE_CREATE      0  /* Create a new block-device interface. */
   4.160 -#define CMSG_BLKIF_BE_DESTROY     1  /* Destroy a block-device interface.    */
   4.161 -#define CMSG_BLKIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   4.162 -#define CMSG_BLKIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   4.163 -#define CMSG_BLKIF_BE_VBD_CREATE  4  /* Create a new VBD for an interface.   */
   4.164 -#define CMSG_BLKIF_BE_VBD_DESTROY 5  /* Delete a VBD from an interface.      */
   4.165 -#define CMSG_BLKIF_BE_VBD_GROW    6  /* Append an extent to a given VBD.     */
   4.166 -#define CMSG_BLKIF_BE_VBD_SHRINK  7  /* Remove last extent from a given VBD. */
   4.167 -
   4.168 -/* Messages to domain controller. */
   4.169 -#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
   4.170 -
   4.171 -/*
   4.172 - * Message request/response definitions for block-device messages.
   4.173 - */
   4.174 -
   4.175 -typedef struct {
   4.176 -    blkif_sector_t sector_start;   /*  0 */
   4.177 -    blkif_sector_t sector_length;  /*  8 */
   4.178 -    blkif_pdev_t   device;         /* 16 */
   4.179 -    u16            __pad;          /* 18 */
   4.180 -} PACKED blkif_extent_t; /* 20 bytes */
   4.181 -
   4.182 -/* Non-specific 'okay' return. */
   4.183 -#define BLKIF_BE_STATUS_OKAY                0
   4.184 -/* Non-specific 'error' return. */
   4.185 -#define BLKIF_BE_STATUS_ERROR               1
   4.186 -/* The following are specific error returns. */
   4.187 -#define BLKIF_BE_STATUS_INTERFACE_EXISTS    2
   4.188 -#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   4.189 -#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4
   4.190 -#define BLKIF_BE_STATUS_VBD_EXISTS          5
   4.191 -#define BLKIF_BE_STATUS_VBD_NOT_FOUND       6
   4.192 -#define BLKIF_BE_STATUS_OUT_OF_MEMORY       7
   4.193 -#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND    8
   4.194 -#define BLKIF_BE_STATUS_MAPPING_ERROR       9
   4.195 -
   4.196 -/* This macro can be used to create an array of descriptive error strings. */
   4.197 -#define BLKIF_BE_STATUS_ERRORS {    \
   4.198 -    "Okay",                         \
   4.199 -    "Non-specific error",           \
   4.200 -    "Interface already exists",     \
   4.201 -    "Interface not found",          \
   4.202 -    "Interface is still connected", \
   4.203 -    "VBD already exists",           \
   4.204 -    "VBD not found",                \
   4.205 -    "Out of memory",                \
   4.206 -    "Extent not found for VBD",     \
   4.207 -    "Could not map domain memory" }
   4.208 -
   4.209 -/*
   4.210 - * CMSG_BLKIF_BE_CREATE:
   4.211 - *  When the driver sends a successful response then the interface is fully
   4.212 - *  created. The controller will send a DOWN notification to the front-end
   4.213 - *  driver.
   4.214 - */
   4.215 -typedef struct { 
   4.216 -    /* IN */
   4.217 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   4.218 -    u16        __pad;
   4.219 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   4.220 -    /* OUT */
   4.221 -    u32        status;        /*  8 */
   4.222 -} PACKED blkif_be_create_t; /* 12 bytes */
   4.223 -
   4.224 -/*
   4.225 - * CMSG_BLKIF_BE_DESTROY:
   4.226 - *  When the driver sends a successful response then the interface is fully
   4.227 - *  torn down. The controller will send a DESTROYED notification to the
   4.228 - *  front-end driver.
   4.229 - */
   4.230 -typedef struct { 
   4.231 -    /* IN */
   4.232 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   4.233 -    u16        __pad;
   4.234 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   4.235 -    /* OUT */
   4.236 -    u32        status;        /*  8 */
   4.237 -} PACKED blkif_be_destroy_t; /* 12 bytes */
   4.238 -
   4.239 -/*
   4.240 - * CMSG_BLKIF_BE_CONNECT:
   4.241 - *  When the driver sends a successful response then the interface is fully
   4.242 - *  connected. The controller will send a CONNECTED notification to the
   4.243 - *  front-end driver.
   4.244 - */
   4.245 -typedef struct { 
   4.246 -    /* IN */
   4.247 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   4.248 -    u16        __pad;
   4.249 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   4.250 -    memory_t   shmem_frame;   /*  8: Page cont. shared comms window.     */
   4.251 -    MEMORY_PADDING;
   4.252 -    u32        evtchn;        /* 16: Event channel for notifications.    */
   4.253 -    /* OUT */
   4.254 -    u32        status;        /* 20 */
   4.255 -} PACKED blkif_be_connect_t;  /* 24 bytes */
   4.256 -
   4.257 -/*
   4.258 - * CMSG_BLKIF_BE_DISCONNECT:
   4.259 - *  When the driver sends a successful response then the interface is fully
   4.260 - *  disconnected. The controller will send a DOWN notification to the front-end
   4.261 - *  driver.
   4.262 - */
   4.263 -typedef struct { 
   4.264 -    /* IN */
   4.265 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   4.266 -    u16        __pad;
   4.267 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   4.268 -    /* OUT */
   4.269 -    u32        status;        /*  8 */
   4.270 -} PACKED blkif_be_disconnect_t; /* 12 bytes */
   4.271 -
   4.272 -/* CMSG_BLKIF_BE_VBD_CREATE */
   4.273 -typedef struct { 
   4.274 -    /* IN */
   4.275 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   4.276 -    u16        __pad;
   4.277 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   4.278 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id for this VBD. */
   4.279 -    u16        readonly;      /* 10: Non-zero -> VBD isn't writable.     */
   4.280 -    /* OUT */
   4.281 -    u32        status;        /* 12 */
   4.282 -} PACKED blkif_be_vbd_create_t; /* 16 bytes */
   4.283 -
   4.284 -/* CMSG_BLKIF_BE_VBD_DESTROY */
   4.285 -typedef struct {
   4.286 -    /* IN */
   4.287 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   4.288 -    u16        __pad0;        /*  2 */
   4.289 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   4.290 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   4.291 -    u16        __pad1;        /* 10 */
   4.292 -    /* OUT */
   4.293 -    u32        status;        /* 12 */
   4.294 -} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
   4.295 -
   4.296 -/* CMSG_BLKIF_BE_VBD_GROW */
   4.297 -typedef struct { 
   4.298 -    /* IN */
   4.299 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   4.300 -    u16        __pad0;        /*  2 */
   4.301 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   4.302 -    blkif_extent_t extent;    /*  8: Physical extent to append to VBD.   */
   4.303 -    blkif_vdev_t vdevice;     /* 28: Interface-specific id of the VBD.   */
   4.304 -    u16        __pad1;        /* 30 */
   4.305 -    /* OUT */
   4.306 -    u32        status;        /* 32 */
   4.307 -} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
   4.308 -
   4.309 -/* CMSG_BLKIF_BE_VBD_SHRINK */
   4.310 -typedef struct { 
   4.311 -    /* IN */
   4.312 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   4.313 -    u16        __pad0;        /*  2 */
   4.314 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   4.315 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   4.316 -    u16        __pad1;        /* 10 */
   4.317 -    /* OUT */
   4.318 -    u32        status;        /* 12 */
   4.319 -} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
   4.320 -
   4.321 -/*
   4.322 - * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
   4.323 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   4.324 - *  If the driver goes DOWN while interfaces are still UP, the controller
   4.325 - *  will automatically send DOWN notifications.
   4.326 - */
   4.327 -typedef struct {
   4.328 -    u32        status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   4.329 -} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
   4.330 -
   4.331 -
   4.332 -/******************************************************************************
   4.333 - * NETWORK-INTERFACE FRONTEND DEFINITIONS
   4.334 - */
   4.335 -
   4.336 -/* Messages from domain controller to guest. */
   4.337 -#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED   0
   4.338 -
   4.339 -/* Messages from guest to domain controller. */
   4.340 -#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED     32
   4.341 -#define CMSG_NETIF_FE_INTERFACE_CONNECT         33
   4.342 -#define CMSG_NETIF_FE_INTERFACE_DISCONNECT      34
   4.343 -
   4.344 -/*
   4.345 - * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
   4.346 - *  Notify a guest about a status change on one of its network interfaces.
   4.347 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
   4.348 - *   1. The shared-memory frame is available for reuse.
   4.349 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   4.350 - */
   4.351 -#define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   4.352 -#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   4.353 -#define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   4.354 -typedef struct {
   4.355 -    u32        handle; /*  0 */
   4.356 -    u32        status; /*  4 */
   4.357 -    u16        evtchn; /*  8: status == NETIF_INTERFACE_STATUS_CONNECTED */
   4.358 -    u8         mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
   4.359 -} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */
   4.360 -
   4.361 -/*
   4.362 - * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   4.363 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   4.364 - *  When the driver goes DOWN then the controller will send no more
   4.365 - *  status-change notifications. When the driver comes UP then the controller
   4.366 - *  will send a notification for each interface that currently exists.
   4.367 - *  If the driver goes DOWN while interfaces are still UP, the domain
   4.368 - *  will automatically take the interfaces DOWN.
   4.369 - */
   4.370 -#define NETIF_DRIVER_STATUS_DOWN   0
   4.371 -#define NETIF_DRIVER_STATUS_UP     1
   4.372 -typedef struct {
   4.373 -    /* IN */
   4.374 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   4.375 -    /* OUT */
   4.376 -    /*
   4.377 -     * Tells driver how many interfaces it should expect to immediately
   4.378 -     * receive notifications about.
   4.379 -     */
   4.380 -    u32        nr_interfaces; /*  4 */
   4.381 -} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
   4.382 -
   4.383 -/*
   4.384 - * CMSG_NETIF_FE_INTERFACE_CONNECT:
   4.385 - *  If successful, the domain controller will acknowledge with a
   4.386 - *  STATUS_CONNECTED message.
   4.387 - */
   4.388 -typedef struct {
   4.389 -    u32        handle;         /*  0 */
   4.390 -    u32        __pad;          /*  4 */
   4.391 -    memory_t   tx_shmem_frame; /*  8 */
   4.392 -    MEMORY_PADDING;
   4.393 -    memory_t   rx_shmem_frame; /* 16 */
   4.394 -    MEMORY_PADDING;
   4.395 -} PACKED netif_fe_interface_connect_t; /* 24 bytes */
   4.396 -
   4.397 -/*
   4.398 - * CMSG_NETIF_FE_INTERFACE_DISCONNECT:
   4.399 - *  If successful, the domain controller will acknowledge with a
   4.400 - *  STATUS_DISCONNECTED message.
   4.401 - */
   4.402 -typedef struct {
   4.403 -    u32        handle;        /*  0 */
   4.404 -} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */
   4.405 -
   4.406 -
   4.407 -/******************************************************************************
   4.408 - * NETWORK-INTERFACE BACKEND DEFINITIONS
   4.409 - */
   4.410 -
   4.411 -/* Messages from domain controller. */
   4.412 -#define CMSG_NETIF_BE_CREATE      0  /* Create a new net-device interface. */
   4.413 -#define CMSG_NETIF_BE_DESTROY     1  /* Destroy a net-device interface.    */
   4.414 -#define CMSG_NETIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   4.415 -#define CMSG_NETIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   4.416 -
   4.417 -/* Messages to domain controller. */
   4.418 -#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
   4.419 -
   4.420 -/*
   4.421 - * Message request/response definitions for net-device messages.
   4.422 - */
   4.423 -
   4.424 -/* Non-specific 'okay' return. */
   4.425 -#define NETIF_BE_STATUS_OKAY                0
   4.426 -/* Non-specific 'error' return. */
   4.427 -#define NETIF_BE_STATUS_ERROR               1
   4.428 -/* The following are specific error returns. */
   4.429 -#define NETIF_BE_STATUS_INTERFACE_EXISTS    2
   4.430 -#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   4.431 -#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4
   4.432 -#define NETIF_BE_STATUS_OUT_OF_MEMORY       5
   4.433 -#define NETIF_BE_STATUS_MAPPING_ERROR       6
   4.434 -
   4.435 -/* This macro can be used to create an array of descriptive error strings. */
   4.436 -#define NETIF_BE_STATUS_ERRORS {    \
   4.437 -    "Okay",                         \
   4.438 -    "Non-specific error",           \
   4.439 -    "Interface already exists",     \
   4.440 -    "Interface not found",          \
   4.441 -    "Interface is still connected", \
   4.442 -    "Out of memory",                \
   4.443 -    "Could not map domain memory" }
   4.444 -
   4.445 -/*
   4.446 - * CMSG_NETIF_BE_CREATE:
   4.447 - *  When the driver sends a successful response then the interface is fully
   4.448 - *  created. The controller will send a DOWN notification to the front-end
   4.449 - *  driver.
   4.450 - */
   4.451 -typedef struct { 
   4.452 -    /* IN */
   4.453 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   4.454 -    u16        __pad0;        /*  2 */
   4.455 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   4.456 -    u8         mac[6];        /*  8 */
   4.457 -    u16        __pad1;        /* 14 */
   4.458 -    /* OUT */
   4.459 -    u32        status;        /* 16 */
   4.460 -} PACKED netif_be_create_t; /* 20 bytes */
   4.461 -
   4.462 -/*
   4.463 - * CMSG_NETIF_BE_DESTROY:
   4.464 - *  When the driver sends a successful response then the interface is fully
   4.465 - *  torn down. The controller will send a DESTROYED notification to the
   4.466 - *  front-end driver.
   4.467 - */
   4.468 -typedef struct { 
   4.469 -    /* IN */
   4.470 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   4.471 -    u16        __pad;
   4.472 -    u32        netif_handle;  /*  4: ...ditto...                         */
   4.473 -    /* OUT */
   4.474 -    u32   status;             /*  8 */
   4.475 -} PACKED netif_be_destroy_t; /* 12 bytes */
   4.476 -
   4.477 -/*
   4.478 - * CMSG_NETIF_BE_CONNECT:
   4.479 - *  When the driver sends a successful response then the interface is fully
   4.480 - *  connected. The controller will send a CONNECTED notification to the
   4.481 - *  front-end driver.
   4.482 - */
   4.483 -typedef struct { 
   4.484 -    /* IN */
   4.485 -    domid_t    domid;          /*  0: Domain attached to new interface.   */
   4.486 -    u16        __pad0;         /*  2 */
   4.487 -    u32        netif_handle;   /*  4: Domain-specific interface handle.   */
   4.488 -    memory_t   tx_shmem_frame; /*  8: Page cont. tx shared comms window.  */
   4.489 -    MEMORY_PADDING;
   4.490 -    memory_t   rx_shmem_frame; /* 16: Page cont. rx shared comms window.  */
   4.491 -    MEMORY_PADDING;
   4.492 -    u16        evtchn;         /* 24: Event channel for notifications.    */
   4.493 -    u16        __pad1;         /* 26 */
   4.494 -    /* OUT */
   4.495 -    u32        status;         /* 28 */
   4.496 -} PACKED netif_be_connect_t; /* 32 bytes */
   4.497 -
   4.498 -/*
   4.499 - * CMSG_NETIF_BE_DISCONNECT:
   4.500 - *  When the driver sends a successful response then the interface is fully
   4.501 - *  disconnected. The controller will send a DOWN notification to the front-end
   4.502 - *  driver.
   4.503 - */
   4.504 -typedef struct { 
   4.505 -    /* IN */
   4.506 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   4.507 -    u16        __pad;
   4.508 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   4.509 -    /* OUT */
   4.510 -    u32        status;        /*  8 */
   4.511 -} PACKED netif_be_disconnect_t; /* 12 bytes */
   4.512 -
   4.513 -/*
   4.514 - * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
   4.515 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   4.516 - *  If the driver goes DOWN while interfaces are still UP, the domain
   4.517 - *  will automatically send DOWN notifications.
   4.518 - */
   4.519 -typedef struct {
   4.520 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   4.521 -} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
   4.522 -
   4.523 -
   4.524 -/******************************************************************************
   4.525 - * SHUTDOWN DEFINITIONS
   4.526 - */
   4.527 -
   4.528 -/*
   4.529 - * Subtypes for shutdown messages.
   4.530 - */
   4.531 -#define CMSG_SHUTDOWN_POWEROFF  0   /* Clean shutdown (SHUTDOWN_poweroff).   */
   4.532 -#define CMSG_SHUTDOWN_REBOOT    1   /* Clean shutdown (SHUTDOWN_reboot).     */
   4.533 -#define CMSG_SHUTDOWN_SUSPEND   2   /* Create suspend info, then             */
   4.534 -                                    /* SHUTDOWN_suspend.                     */
   4.535 -
   4.536 -/******************************************************************************
   4.537 - * PDB DEFINITIONS
   4.538 - */
   4.539 -
   4.540 -/* Notify the backend that a new frontend has connected. */
   4.541 -#define CMSG_PDB_BE_INTERFACE_CONNECTED 0
   4.542 -typedef struct {
   4.543 -    int assist_port;
   4.544 -    int event_port;
   4.545 -} pdb_be_connected_t;
   4.546 -
   4.547 -/* Notify the domain controller that the status of the backend has
   4.548 -   changed. */
   4.549 -#define CMSG_PDB_BE_DRIVER_STATUS_CHANGED 1
   4.550 -typedef struct {
   4.551 -    unsigned status;
   4.552 -#define PDB_DRIVER_STATUS_UP 1
   4.553 -    unsigned long event_page;
   4.554 -    unsigned long assist_page;
   4.555 -} pdb_be_driver_status_changed_t;
   4.556 -
   4.557 -/* Notify a front end that a back end just popped up. */
   4.558 -#define CMSG_PDB_FE_NEW_BE 0
   4.559 -typedef struct {
   4.560 -    int domain;
   4.561 -    int assist_evtchn;
   4.562 -    int event_evtchn;
   4.563 -    unsigned long assist_frame;
   4.564 -    unsigned long event_frame;
   4.565 -} pdb_fe_new_be_t;
     5.1 --- a/tools/x2d2/main.c	Thu Nov 18 13:13:56 2004 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,1015 +0,0 @@
     5.4 -#define _GNU_SOURCE
     5.5 -
     5.6 -#include <sys/types.h>
     5.7 -#include <sys/fcntl.h>
     5.8 -#include <sys/ioctl.h>
     5.9 -#include <sys/mman.h>
    5.10 -#include <sys/select.h>
    5.11 -#include <sys/socket.h>
    5.12 -#include <sys/wait.h>
    5.13 -#include <asm/page.h>
    5.14 -#include <assert.h>
    5.15 -#include <ctype.h>
    5.16 -#include <err.h>
    5.17 -#include <errno.h>
    5.18 -#include <netinet/in.h>
    5.19 -#include <printf.h>
    5.20 -#include <pthread.h>
    5.21 -#include <stdarg.h>
    5.22 -#include <stddef.h>
    5.23 -#include <stdio.h>
    5.24 -#include <stdlib.h>
    5.25 -#include <string.h>
    5.26 -#include <unistd.h>
    5.27 -
    5.28 -#include "minixend.h"
    5.29 -
    5.30 -#define NETWORK_SCRIPT "/etc/xen/scripts/network"
    5.31 -#define VIFBRIDGE_SCRIPT "/etc/xen/scripts/vif-bridge"
    5.32 -
    5.33 -#define MINIXEND_PORT 5123
    5.34 -
    5.35 -#define mb() asm volatile ("" ::: "memory")
    5.36 -
    5.37 -static void send_control_message(int type, int subtype, int id,
    5.38 -				 int size, void *payload,
    5.39 -				 struct domain *target);
    5.40 -
    5.41 -struct list_head
    5.42 -head_domain = LIST_HEAD(&head_domain);
    5.43 -
    5.44 -static struct list_head
    5.45 -head_connection = LIST_HEAD(&head_connection);
    5.46 -
    5.47 -struct list_head
    5.48 -head_console = LIST_HEAD(&head_console);
    5.49 -
    5.50 -#define foreach_open_connection(d)                                          \
    5.51 -foreach_item(d, &head_connection, struct open_connection, connection_list)
    5.52 -
    5.53 -/* Not modified after initial start up */
    5.54 -static struct domain *
    5.55 -dom0;
    5.56 -unsigned
    5.57 -xc_handle;
    5.58 -static int
    5.59 -listen_fd;
    5.60 -int
    5.61 -evtchn_fd;
    5.62 -
    5.63 -static struct list_head
    5.64 -head_event_receiver = LIST_HEAD(&head_event_receiver);
    5.65 -
    5.66 -struct event_receiver {
    5.67 -	struct list_head list;
    5.68 -	int id;
    5.69 -	pthread_cond_t cond;
    5.70 -};
    5.71 -
    5.72 -/* We're protected by the dom0 mutex in here */
    5.73 -static struct event_receiver *
    5.74 -allocate_event_receiver(struct domain *d)
    5.75 -{
    5.76 -	static int next_message_id;
    5.77 -	struct event_receiver *work;
    5.78 -
    5.79 -	assert(d == dom0);
    5.80 -	work = xmalloc(sizeof(*work));
    5.81 -	work->id = next_message_id++;
    5.82 -	pthread_cond_init(&work->cond, NULL);
    5.83 -
    5.84 -	list_insert_after(&work->list, &head_event_receiver);
    5.85 -
    5.86 -	return work;
    5.87 -}
    5.88 -
    5.89 -static struct event_receiver *
    5.90 -find_event_receiver(int id)
    5.91 -{
    5.92 -	struct event_receiver *work;
    5.93 -	foreach_item(work, &head_event_receiver, struct event_receiver, list)
    5.94 -		if (work->id == id)
    5.95 -			return work;
    5.96 -	return NULL;
    5.97 -}
    5.98 -
    5.99 -static void
   5.100 -release_event_receiver(struct event_receiver *w)
   5.101 -{
   5.102 -	list_remove(&w->list);
   5.103 -	pthread_cond_destroy(&w->cond);
   5.104 -	free(w);
   5.105 -}
   5.106 -
   5.107 -/* Send a message to dom0, and then block awaiting a reply. */
   5.108 -/* Make sure we don't hold any domain mutexs */
   5.109 -static void
   5.110 -send_dom0_message_block(control_msg_t *msg)
   5.111 -{
   5.112 -	CONTROL_RING_IDX c;
   5.113 -	struct event_receiver *er;
   5.114 -	control_msg_t buf;
   5.115 -
   5.116 -	PRINTF(0, "sending message to dom0 and blocking for reply.\n");
   5.117 -	pthread_mutex_lock(&dom0->mux);
   5.118 -	PRINTF(0, "got dom0 lock.\n");
   5.119 -	er = allocate_event_receiver(dom0);
   5.120 -	PRINTF(0, "allocated evetn receiver.\n");
   5.121 -	msg->id = er->id;
   5.122 -	PRINTF(1, "sending message with id %d\n", msg->id);
   5.123 -	send_control_message(msg->type, msg->subtype,
   5.124 -			     msg->id, msg->length, msg->msg, dom0);
   5.125 -	xc_evtchn_send(xc_handle, dom0->control_evtchn);
   5.126 -
   5.127 -	PRINTF(0, "waiting for reply\n");
   5.128 -	pthread_cond_wait(&er->cond, &dom0->mux);
   5.129 -	PRINTF(0, "got reply\n");
   5.130 -
   5.131 -	c = dom0->rx_resp_cons % CONTROL_RING_SIZE;
   5.132 -	memcpy(&buf, &dom0->ctrl_if->rx_ring[c], sizeof(buf));
   5.133 -	assert(msg->id == buf.id);
   5.134 -	assert(msg->type == buf.type);
   5.135 -	assert(msg->subtype == buf.subtype);
   5.136 -	memcpy(msg, &buf, sizeof(*msg));
   5.137 -	dom0->rx_resp_cons++;
   5.138 -
   5.139 -	release_event_receiver(er);
   5.140 -
   5.141 -	pthread_mutex_unlock(&dom0->mux);
   5.142 -
   5.143 -	PRINTF(1, "got reply to message with id %d\n", msg->id);
   5.144 -}
   5.145 -
   5.146 -/* Allocate an interdomain event channel.  event_ports[0] is the
   5.147 -   local event port number, event_ports[1] the remote */
   5.148 -int
   5.149 -allocate_event_channel(struct domain *d, int event_ports[2])
   5.150 -{
   5.151 -	return xc_evtchn_bind_interdomain(xc_handle, DOMID_SELF,
   5.152 -					  d->domid, event_ports,
   5.153 -					  event_ports+1);
   5.154 -}
   5.155 -
   5.156 -static void
   5.157 -accept_new_connection(void)
   5.158 -{
   5.159 -	int fd;
   5.160 -	struct open_connection *oc;
   5.161 -
   5.162 -	fd = accept(listen_fd, NULL, NULL);
   5.163 -	if (fd < 0)
   5.164 -		return;
   5.165 -	oc = xmalloc(sizeof(*oc));
   5.166 -	oc->fd = fd;
   5.167 -	oc->state = OC_STATE_CONNECTED;
   5.168 -	oc->buf_used = 0;
   5.169 -	oc->buf_allocated = 16;
   5.170 -	oc->buf = xmalloc(oc->buf_allocated);
   5.171 -	list_insert_after(&oc->connection_list, &head_connection);
   5.172 -}
   5.173 -
   5.174 -static void
   5.175 -closedown_connection(struct open_connection *oc)
   5.176 -{
   5.177 -	close(oc->fd);
   5.178 -	assert(oc->buf);
   5.179 -	free(oc->buf);
   5.180 -	free(oc);
   5.181 -}
   5.182 -
   5.183 -#if 0
   5.184 -/* Hackl for the benefit of domain replay */
   5.185 -static unsigned
   5.186 -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   5.187 -{
   5.188 -	if (!do_direct) {
   5.189 -		int rc;
   5.190 -		asm("int $0x80" : "=a" (rc)
   5.191 -		    : "0" (264), "b" (ptr), "c" (val), "d" (dom));
   5.192 -		if (rc < 0) {
   5.193 -			errno = -rc;
   5.194 -			rc = -1;
   5.195 -		}
   5.196 -		return rc;
   5.197 -	} else {
   5.198 -		*ptr = val;
   5.199 -		return 0;
   5.200 -	}
   5.201 -}
   5.202 -#else
   5.203 -static unsigned
   5.204 -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   5.205 -{
   5.206 -	*ptr = val;
   5.207 -	return 0;
   5.208 -}
   5.209 -#endif
   5.210 -
   5.211 -static void
   5.212 -send_control_reply(const control_msg_t *msg, struct domain *d)
   5.213 -{
   5.214 -	CONTROL_RING_IDX c;
   5.215 -
   5.216 -	PRINTF(3,"Control reply, type %d:%d, length %d.\n",
   5.217 -	       msg->type, msg->subtype, msg->length);
   5.218 -	c = d->ctrl_if->tx_resp_prod % CONTROL_RING_SIZE;
   5.219 -	memcpy(&d->ctrl_if->tx_ring[c], msg, sizeof(*msg));
   5.220 -	report_work(&d->ctrl_if->tx_resp_prod,
   5.221 -		    d->ctrl_if->tx_resp_prod + 1,
   5.222 -		    d->domid,
   5.223 -		    0);
   5.224 -	PRINTF(4,"tx_resp_prod %ld.\n", d->ctrl_if->tx_resp_prod);
   5.225 -	assert(!d->plugged);
   5.226 -}
   5.227 -
   5.228 -static void
   5.229 -send_trivial_control_reply(const control_msg_t *msg, struct domain *d)
   5.230 -{
   5.231 -	control_msg_t rep;
   5.232 -
   5.233 -	memset(&rep, 0, sizeof(rep));
   5.234 -	rep.type = msg->type;
   5.235 -	rep.subtype = msg->subtype;
   5.236 -	rep.id = msg->id;
   5.237 -	send_control_reply(&rep, d);
   5.238 -}
   5.239 -
   5.240 -static void
   5.241 -process_console_control_message(control_msg_t *m, struct domain *d)
   5.242 -{
   5.243 -	int off;
   5.244 -	int r;
   5.245 -
   5.246 -	if (m->subtype != CMSG_CONSOLE_DATA) {
   5.247 -		warnx("unknown console message subtype %d",
   5.248 -		      m->subtype);
   5.249 -		return;
   5.250 -	}
   5.251 -
   5.252 -	if (m->length > 60) {
   5.253 -		warnx("truncating message from domain %d (was length %d)",
   5.254 -		      d->domid, m->length);
   5.255 -		m->length = 60;
   5.256 -	}
   5.257 -	PRINTF(1, "DOM%d: %.*s\n", d->domid, m->length, m->msg);
   5.258 -	send_trivial_control_reply(m, d);
   5.259 -
   5.260 -	if (d->cc) {
   5.261 -		PRINTF(5, "Have a console connection.\n");
   5.262 -		if (d->cc->state == CC_STATE_CONNECTED) {
   5.263 -			PRINTF(5, "Console is connected, sending directly.\n");
   5.264 -			for (off = 0; off < m->length; off += r) {
   5.265 -				r = write(d->cc->fd, m->msg + off,
   5.266 -					  m->length - off);
   5.267 -				if (r <= 0) {
   5.268 -					d->cc->state = CC_STATE_ERROR;
   5.269 -					break;
   5.270 -				}
   5.271 -			}
   5.272 -		} else {
   5.273 -			PRINTF(5, "Console not connected, buffering.\n");
   5.274 -			if (d->cc->buf_allocated == 0) {
   5.275 -				d->cc->buf_allocated = 60;
   5.276 -				d->cc->buf = xmalloc(d->cc->buf_allocated);
   5.277 -				d->cc->buf_used = 0;
   5.278 -			} else if (d->cc->buf_allocated <
   5.279 -				   d->cc->buf_used + m->length) {
   5.280 -				d->cc->buf_allocated += 60;
   5.281 -				d->cc->buf = xrealloc(d->cc->buf,
   5.282 -						      d->cc->buf_allocated);
   5.283 -			}
   5.284 -			assert(d->cc->buf_allocated >=
   5.285 -			       d->cc->buf_used + m->length);
   5.286 -			memcpy(d->cc->buf + d->cc->buf_used,
   5.287 -			       m->msg,
   5.288 -			       m->length);
   5.289 -			d->cc->buf_used += m->length;
   5.290 -		}
   5.291 -	}
   5.292 -}
   5.293 -
   5.294 -static void
   5.295 -process_blkif_fe_message(control_msg_t *m, struct domain *d)
   5.296 -{
   5.297 -	switch (m->subtype) {
   5.298 -	default:
   5.299 -		warnx("unknown blkif front end message subtype %d",
   5.300 -		      m->subtype);
   5.301 -	}
   5.302 -}
   5.303 -
   5.304 -static void
   5.305 -send_control_message(int type, int subtype, int id,
   5.306 -		     int size, void *payload, struct domain *target)
   5.307 -{
   5.308 -	control_msg_t msg;
   5.309 -	CONTROL_RING_IDX c;
   5.310 -
   5.311 -	msg.type = type;
   5.312 -	msg.subtype = subtype;
   5.313 -	msg.id = id;
   5.314 -	msg.length = size;
   5.315 -	memcpy(msg.msg, payload, size);
   5.316 -
   5.317 -	c = target->ctrl_if->rx_req_prod % CONTROL_RING_SIZE;
   5.318 -	memcpy(&target->ctrl_if->rx_ring[c], &msg, sizeof(msg));
   5.319 -	report_work(&target->ctrl_if->rx_req_prod,
   5.320 -		    target->ctrl_if->rx_req_prod + 1,
   5.321 -		    target->domid,
   5.322 -		    0);
   5.323 -	assert(!target->plugged);
   5.324 -}
   5.325 -
   5.326 -/* Procedure for bringing a new netif front end up:
   5.327 -
   5.328 -   -- Front end sends us NETIF_FE_DRIVER_STATUS_CHANGED
   5.329 -   -- We send back end NETIF_BE_CREATE, wait for a reply
   5.330 -   -- Back end creates a new netif for us, replies
   5.331 -   -- We send front end a NETIF_FE_DRIVER_STATUS_CHANGED message saying
   5.332 -      how many interfaces we've created for it
   5.333 -   -- We send front end a NETIF_FE_INTERFACE_STATUS_CHANGED for each
   5.334 -      netif created
   5.335 -   -- Front end sends us a NETIF_FE_INTERFACE_CONNECT for each netif
   5.336 -*/
   5.337 -static void
   5.338 -handle_netif_fe_driver_status_changed(control_msg_t *m,
   5.339 -				      netif_fe_driver_status_changed_t *sh,
   5.340 -				      struct domain *d)
   5.341 -{
   5.342 -	netif_fe_interface_status_changed_t if_s;
   5.343 -	control_msg_t be_msg;
   5.344 -	netif_be_create_t *be = (void *)be_msg.msg;
   5.345 -	int r;
   5.346 -
   5.347 -	switch (sh->status) {
   5.348 -	case NETIF_DRIVER_STATUS_UP:
   5.349 -		/* Tell the back end about the new interface coming
   5.350 -		 * up. */
   5.351 -		if (d->created_netif_backend) {
   5.352 -			PRINTF(10, "Front end came up twice in dom %d -> reporting no interfaces this time around.\n", d->domid);
   5.353 -			sh->nr_interfaces = 0;
   5.354 -			send_control_reply(m, d);
   5.355 -			send_control_message(CMSG_NETIF_FE,
   5.356 -					     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   5.357 -					     1,
   5.358 -					     sizeof(*sh),
   5.359 -					     sh,
   5.360 -					     d);
   5.361 -			return;
   5.362 -		}
   5.363 -		be_msg.type = CMSG_NETIF_BE;
   5.364 -		be_msg.subtype = CMSG_NETIF_BE_CREATE;
   5.365 -		be_msg.id = d->domid;
   5.366 -		be_msg.length = sizeof(*be);
   5.367 -		be->domid = d->domid;
   5.368 -		be->netif_handle = 0;
   5.369 -		memcpy(be->mac, d->netif_mac, 6);
   5.370 -
   5.371 -		PRINTF(2,"Telling back end about new front end.\n");
   5.372 -		pthread_mutex_unlock(&d->mux);
   5.373 -		send_dom0_message_block(&be_msg);
   5.374 -		pthread_mutex_lock(&d->mux);
   5.375 -		PRINTF(3,"Done.\n");
   5.376 -
   5.377 -		if (be->status != NETIF_BE_STATUS_OKAY) {
   5.378 -			/* Uh oh... can't bring back end
   5.379 -			 * up. */
   5.380 -			sh->nr_interfaces = 0;
   5.381 -			send_control_reply(m, d);
   5.382 -			send_control_message(CMSG_NETIF_FE,
   5.383 -					     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   5.384 -					     1,
   5.385 -					     sizeof(*sh),
   5.386 -					     sh,
   5.387 -					     d);
   5.388 -			return;
   5.389 -		}
   5.390 -		d->created_netif_backend = 1;
   5.391 -
   5.392 -		r = our_system(VIFBRIDGE_SCRIPT " up domain=%s mac=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x vif=vif%d.0 bridge=xen-br0",
   5.393 -			       d->name,
   5.394 -			       d->netif_mac[0],
   5.395 -			       d->netif_mac[1],
   5.396 -			       d->netif_mac[2],
   5.397 -			       d->netif_mac[3],
   5.398 -			       d->netif_mac[4],
   5.399 -			       d->netif_mac[5],
   5.400 -			       d->domid);
   5.401 -		if (r != 0)
   5.402 -			warn("error %d running " VIFBRIDGE_SCRIPT, r);
   5.403 -
   5.404 -		/* Tell domain how many interfaces it has to deal
   5.405 -		 * with. */
   5.406 -		sh->nr_interfaces = 1;
   5.407 -		send_control_reply(m, d);
   5.408 -		send_control_message(CMSG_NETIF_FE,
   5.409 -				     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   5.410 -				     1,
   5.411 -				     sizeof(*sh),
   5.412 -				     sh,
   5.413 -				     d);
   5.414 -
   5.415 -		PRINTF(2,"Telling front end about its interfaces.\n");
   5.416 -		if_s.handle = 0;
   5.417 -		if_s.status = NETIF_INTERFACE_STATUS_DISCONNECTED;
   5.418 -		send_control_message(CMSG_NETIF_FE,
   5.419 -				     CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED,
   5.420 -				     1,
   5.421 -				     sizeof(if_s),
   5.422 -				     &if_s,
   5.423 -				     d);
   5.424 -		PRINTF(3,"Done.\n");
   5.425 -
   5.426 -		break;
   5.427 -	default:
   5.428 -		warnx("unknown netif status %ld", sh->status);
   5.429 -		break;
   5.430 -	}
   5.431 -}
   5.432 -
   5.433 -static void
   5.434 -handle_netif_fe_interface_connect(control_msg_t *m,
   5.435 -				  netif_fe_interface_connect_t *ic,
   5.436 -				  struct domain *d)
   5.437 -{
   5.438 -	control_msg_t be_msg;
   5.439 -	netif_be_connect_t *bmsg = (void *)be_msg.msg;
   5.440 -	netif_fe_interface_status_changed_t fmsg = {0};
   5.441 -	int evtchn_ports[2];
   5.442 -	int r;
   5.443 -
   5.444 -	PRINTF(4, "front end sent us an interface connect message.\n");
   5.445 -	send_trivial_control_reply(m, d);
   5.446 -
   5.447 -	r = xc_evtchn_bind_interdomain(xc_handle,
   5.448 -				       dom0->domid,
   5.449 -				       d->domid,
   5.450 -				       &evtchn_ports[0],
   5.451 -				       &evtchn_ports[1]);
   5.452 -	if (r < 0)
   5.453 -		err(1, "allocating network event channel");
   5.454 -
   5.455 -	be_msg.type = CMSG_NETIF_BE;
   5.456 -	be_msg.subtype = CMSG_NETIF_BE_CONNECT;
   5.457 -	be_msg.id = 0;
   5.458 -	be_msg.length = sizeof(*bmsg);
   5.459 -	bmsg->domid = d->domid;
   5.460 -	bmsg->netif_handle = ic->handle;
   5.461 -	bmsg->tx_shmem_frame = ic->tx_shmem_frame;
   5.462 -	bmsg->rx_shmem_frame = ic->rx_shmem_frame;
   5.463 -	bmsg->evtchn = evtchn_ports[0];
   5.464 -
   5.465 -	pthread_mutex_unlock(&d->mux);
   5.466 -	send_dom0_message_block(&be_msg);
   5.467 -	pthread_mutex_lock(&d->mux);
   5.468 -
   5.469 -	if (bmsg->status != NETIF_BE_STATUS_OKAY) {
   5.470 -		PRINTF(2, "error connected backend netif: %ld\n",
   5.471 -		       bmsg->status);
   5.472 -		abort(); /* Need to handle this */
   5.473 -	} else {
   5.474 -		PRINTF(3, "connect backend netif\n");
   5.475 -
   5.476 -		/* Tell the domain that we've connected it up. */
   5.477 -		fmsg.handle = ic->handle;
   5.478 -		fmsg.status = NETIF_INTERFACE_STATUS_CONNECTED;
   5.479 -		fmsg.evtchn = evtchn_ports[1];
   5.480 -		memcpy(fmsg.mac, d->netif_mac, 6);
   5.481 -
   5.482 -		send_control_message(CMSG_NETIF_FE,
   5.483 -				     CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED,
   5.484 -				     0,
   5.485 -				     sizeof(fmsg),
   5.486 -				     &fmsg,
   5.487 -				     d);
   5.488 -	}
   5.489 -}
   5.490 -
   5.491 -static void
   5.492 -process_netif_fe_message(control_msg_t *m, struct domain *d)
   5.493 -{
   5.494 -	switch (m->subtype) {
   5.495 -	case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   5.496 -	{
   5.497 -		netif_fe_driver_status_changed_t *sh =
   5.498 -			(netif_fe_driver_status_changed_t *)m->msg;
   5.499 -		handle_netif_fe_driver_status_changed(m, sh, d);
   5.500 -		break;
   5.501 -	}
   5.502 -	case CMSG_NETIF_FE_INTERFACE_CONNECT:
   5.503 -	{
   5.504 -		netif_fe_interface_connect_t *ic =
   5.505 -			(netif_fe_interface_connect_t *)m->msg;
   5.506 -		handle_netif_fe_interface_connect(m, ic, d);
   5.507 -		break;
   5.508 -	}
   5.509 -	default:
   5.510 -		warnx("unknown netif front end message subtype %d",
   5.511 -		      m->subtype);
   5.512 -	}
   5.513 -}
   5.514 -
   5.515 -static void
   5.516 -process_pdb_be_driver_status_changed_message(control_msg_t *msg,
   5.517 -					     pdb_be_driver_status_changed_t*pe,
   5.518 -					     struct domain *d)
   5.519 -{
   5.520 -	pdb_be_connected_t conn;
   5.521 -	pdb_fe_new_be_t new_be;
   5.522 -	int assist_channel[2];
   5.523 -	int event_channel[2];
   5.524 -	int r;
   5.525 -
   5.526 -	switch (pe->status) {
   5.527 -	case PDB_DRIVER_STATUS_UP:
   5.528 -		PRINTF(4, "creating event channel for PDB device\n");
   5.529 -		r = allocate_event_channel(d, assist_channel);
   5.530 -		r |= allocate_event_channel(d, event_channel);
   5.531 -		if (r < 0)
   5.532 -			abort(); /* XXX need to handle this */
   5.533 -
   5.534 -		send_trivial_control_reply(msg, d);
   5.535 -
   5.536 -		PRINTF(4, "informing front end of event channel\n");
   5.537 -		conn.assist_port = assist_channel[1];
   5.538 -		conn.event_port = event_channel[1];
   5.539 -		send_control_message(CMSG_PDB_BE,
   5.540 -				     CMSG_PDB_BE_INTERFACE_CONNECTED,
   5.541 -				     0,
   5.542 -				     sizeof(conn),
   5.543 -				     &conn,
   5.544 -				     d);
   5.545 -
   5.546 -		PRINTF(4, "informing back end of front end\n");
   5.547 -		new_be.domain = d->domid;
   5.548 -		new_be.assist_evtchn = assist_channel[0];
   5.549 -		new_be.event_evtchn = event_channel[0];
   5.550 -		new_be.assist_frame = pe->assist_page;
   5.551 -		new_be.event_frame = pe->event_page;
   5.552 -		send_control_message(CMSG_PDB_FE,
   5.553 -				     CMSG_PDB_FE_NEW_BE,
   5.554 -				     0,
   5.555 -				     sizeof(new_be),
   5.556 -				     &new_be,
   5.557 -				     dom0);
   5.558 -		break;
   5.559 -	default:
   5.560 -		warnx("unknown pdb status %d", pe->status);
   5.561 -	}
   5.562 -}
   5.563 -
   5.564 -static void
   5.565 -process_pdb_be_message(control_msg_t *msg, struct domain *d)
   5.566 -{
   5.567 -	switch (msg->subtype) {
   5.568 -	case CMSG_PDB_BE_DRIVER_STATUS_CHANGED:
   5.569 -	{
   5.570 -		pdb_be_driver_status_changed_t *pe =
   5.571 -			(pdb_be_driver_status_changed_t *)msg->msg;
   5.572 -		process_pdb_be_driver_status_changed_message(msg, pe, d);
   5.573 -		break;
   5.574 -	}
   5.575 -	default:
   5.576 -		warnx("unknown pdb back end message subtype %d",
   5.577 -		      msg->subtype);
   5.578 -	}
   5.579 -}
   5.580 -
   5.581 -static void
   5.582 -process_control_message(control_msg_t *msg, struct domain *d)
   5.583 -{
   5.584 -	control_msg_t m;
   5.585 -
   5.586 -	/* Don't want a malicous domain messing us about, so copy the
   5.587 -	   control mesasge into a local buffer. */
   5.588 -	memcpy(&m, msg, sizeof(m));
   5.589 -	switch (m.type) {
   5.590 -	case CMSG_CONSOLE:
   5.591 -		process_console_control_message(&m, d);
   5.592 -		break;
   5.593 -	case CMSG_BLKIF_FE:
   5.594 -		process_blkif_fe_message(&m, d);
   5.595 -		break;
   5.596 -	case CMSG_NETIF_FE:
   5.597 -		process_netif_fe_message(&m, d);
   5.598 -		break;
   5.599 -	case CMSG_PDB_BE:
   5.600 -		process_pdb_be_message(&m, d);
   5.601 -		break;
   5.602 -	default:
   5.603 -		warnx("unknown control message type %d", m.type);
   5.604 -	}
   5.605 -}
   5.606 -
   5.607 -static void
   5.608 -domain_did_control_event(struct domain *d)
   5.609 -{
   5.610 -	CONTROL_RING_IDX c;
   5.611 -
   5.612 -	/* Pick up and process control ring messages. */
   5.613 -	while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   5.614 -		c = d->tx_req_cons % CONTROL_RING_SIZE;
   5.615 -		process_control_message(&d->ctrl_if->tx_ring[c], d);
   5.616 -		d->tx_req_cons++;
   5.617 -		assert(d->tx_req_cons <= d->ctrl_if->tx_req_prod);
   5.618 -		PRINTF(5, "req_cons %ld, req_prod %ld.\n",
   5.619 -		       d->tx_req_cons, d->ctrl_if->tx_req_prod);
   5.620 -	}
   5.621 -
   5.622 -	/* Take any replies off, and discard them. */
   5.623 -	if (d->rx_resp_cons != d->ctrl_if->rx_resp_prod)
   5.624 -		PRINTF(1, "discard %ld events\n",
   5.625 -		       d->ctrl_if->rx_resp_prod -
   5.626 -		       d->rx_resp_cons);
   5.627 -	d->rx_resp_cons = d->ctrl_if->rx_resp_prod;
   5.628 -}
   5.629 -
   5.630 -/* This is the main function for domain control threads */
   5.631 -void *
   5.632 -domain_thread_func(void *D)
   5.633 -{
   5.634 -	struct domain *d = D;
   5.635 -	int r;
   5.636 -	CONTROL_RING_IDX old_resp_prod, old_req_prod;
   5.637 -
   5.638 -	pthread_mutex_lock(&d->mux);
   5.639 -	for (;;) {
   5.640 -		pthread_cond_wait(&d->cond, &d->mux);
   5.641 -
   5.642 -		old_resp_prod = d->ctrl_if->tx_resp_prod;
   5.643 -		old_req_prod = d->ctrl_if->rx_req_prod;
   5.644 -
   5.645 -		domain_did_control_event(d);
   5.646 -		if (d->cc && d->cc->in_buf_used != 0 && d->plugged == 0) {
   5.647 -			r = d->cc->in_buf_used;
   5.648 -			if (r > 60)
   5.649 -				r = 60;
   5.650 -			PRINTF(1, "Sending to domain: %.*s\n",
   5.651 -			       r, d->cc->in_buf);
   5.652 -			send_control_message(CMSG_CONSOLE,
   5.653 -					     CMSG_CONSOLE_DATA,
   5.654 -					     0,
   5.655 -					     r,
   5.656 -					     d->cc->in_buf,
   5.657 -					     d);
   5.658 -			memmove(d->cc->in_buf, d->cc->in_buf + r,
   5.659 -				d->cc->in_buf_used - r);
   5.660 -			d->cc->in_buf_used -= r;
   5.661 -		}
   5.662 -
   5.663 -		if (d->ctrl_if->tx_resp_prod != old_resp_prod ||
   5.664 -		    d->ctrl_if->rx_req_prod != old_req_prod)
   5.665 -			xc_evtchn_send(xc_handle, d->control_evtchn);
   5.666 -	}
   5.667 -}
   5.668 -
   5.669 -/* This is the only thing you can do with a domain structure if you're
   5.670 -   not in the thread which controls that domain.  Domain 0 is
   5.671 -   special. */
   5.672 -void
   5.673 -signal_domain(struct domain *d)
   5.674 -{
   5.675 -	CONTROL_RING_IDX c;
   5.676 -	int id;
   5.677 -	struct event_receiver *evt;
   5.678 -
   5.679 -	pthread_mutex_lock(&d->mux);
   5.680 -	if (d == dom0) {
   5.681 -		/* Take events off of dom0's control ring, and send
   5.682 -		   them to the event receivers. */
   5.683 -		while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   5.684 -			c = d->tx_req_cons % CONTROL_RING_SIZE;
   5.685 -			id = d->ctrl_if->tx_ring[c].id;
   5.686 -			evt = find_event_receiver(id);
   5.687 -			if (evt != NULL) {
   5.688 -				PRINTF(1, "delivering event id %d\n", evt->id);
   5.689 -				pthread_cond_broadcast(&evt->cond);
   5.690 -				pthread_mutex_unlock(&d->mux);
   5.691 -				pthread_yield();
   5.692 -				pthread_mutex_lock(&d->mux);
   5.693 -			} else {
   5.694 -				warnx("unexpected message id %d discarded",
   5.695 -				      id);
   5.696 -				d->tx_req_cons++;
   5.697 -			}
   5.698 -		}
   5.699 -		while (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) {
   5.700 -			c = d->rx_resp_cons % CONTROL_RING_SIZE;
   5.701 -			id = d->ctrl_if->rx_ring[c].id;
   5.702 -			evt = find_event_receiver(id);
   5.703 -			if (evt != NULL) {
   5.704 -				PRINTF(1, "delivering event rep id %d\n", evt->id);
   5.705 -				pthread_cond_broadcast(&evt->cond);
   5.706 -				pthread_mutex_unlock(&d->mux);
   5.707 -				pthread_yield();
   5.708 -				pthread_mutex_lock(&d->mux);
   5.709 -			} else {
   5.710 -				warnx("unexpected message reply id %d discarded",
   5.711 -				      id);
   5.712 -				d->rx_resp_cons++;
   5.713 -			}
   5.714 -		}
   5.715 -	} else {
   5.716 -		if (d->plugged) {
   5.717 -			d->event_pending = 1;
   5.718 -		} else {
   5.719 -			pthread_cond_broadcast(&d->cond);
   5.720 -		}
   5.721 -	}
   5.722 -	pthread_mutex_unlock(&d->mux);
   5.723 -}
   5.724 -
   5.725 -static void
   5.726 -handle_evtchn_event(void)
   5.727 -{
   5.728 -	short port;
   5.729 -	struct domain *d;
   5.730 -
   5.731 -	read(evtchn_fd, &port, sizeof(short));
   5.732 -	write(evtchn_fd, &port, sizeof(short));
   5.733 -	foreach_domain (d) {
   5.734 -		if (d->control_evtchn == port) {
   5.735 -			signal_domain(d);
   5.736 -			return;
   5.737 -		}
   5.738 -	}
   5.739 -	warnx("got an event on an unknown port %d", port);
   5.740 -}
   5.741 -
   5.742 -void *
   5.743 -map_domain_mem(struct domain *d, unsigned long mfn)
   5.744 -{
   5.745 -	return xc_map_foreign_range(xc_handle, d->domid,
   5.746 -				    PAGE_SIZE, PROT_READ | PROT_WRITE,
   5.747 -				    mfn);
   5.748 -}
   5.749 -
   5.750 -static void
   5.751 -handle_console_event(struct console_connection *cc)
   5.752 -{
   5.753 -	int r;
   5.754 -	int fd;
   5.755 -
   5.756 -	switch (cc->state) {
   5.757 -	case CC_STATE_ERROR:
   5.758 -		/* Errors shouldn't get here. */
   5.759 -		abort();
   5.760 -	case CC_STATE_PENDING:
   5.761 -		fd = accept(cc->fd, NULL, NULL);
   5.762 -		if (fd >= 0) {
   5.763 -			PRINTF(3, "Accepted console connection for domain %d",
   5.764 -			       cc->dom->domid);
   5.765 -			close(cc->fd);
   5.766 -			cc->fd = fd;
   5.767 -			cc->state = CC_STATE_CONNECTED;
   5.768 -			while (cc->buf_used != 0) {
   5.769 -				r = write(cc->fd,
   5.770 -					  cc->buf,
   5.771 -					  cc->buf_used);
   5.772 -				if (r <= 0) {
   5.773 -					cc->state = CC_STATE_ERROR;
   5.774 -					break;
   5.775 -				}
   5.776 -				memmove(cc->buf,
   5.777 -					cc->buf + r,
   5.778 -					cc->buf_used - r);
   5.779 -				cc->buf_used -= r;
   5.780 -			}
   5.781 -			free(cc->buf);
   5.782 -			cc->buf = NULL;
   5.783 -			cc->buf_allocated = 0;
   5.784 -		} else {
   5.785 -			PRINTF(1, "error %s accepting console", strerror(errno));
   5.786 -		}
   5.787 -		pthread_mutex_unlock(&cc->dom->mux);
   5.788 -		break;
   5.789 -	case CC_STATE_CONNECTED:
   5.790 -		if (cc->in_buf_allocated == 0) {
   5.791 -			assert(cc->in_buf_used == 0);
   5.792 -			cc->in_buf_allocated = 128;
   5.793 -			cc->in_buf = xmalloc(cc->in_buf_allocated);
   5.794 -		}
   5.795 -		if (cc->in_buf_used == cc->in_buf_allocated) {
   5.796 -			cc->in_buf_allocated *= 2;
   5.797 -			cc->in_buf = xrealloc(cc->in_buf, cc->in_buf_allocated);
   5.798 -		}
   5.799 -		r = read(cc->fd, cc->in_buf + cc->in_buf_used,
   5.800 -			 cc->in_buf_allocated - cc->in_buf_used);
   5.801 -		if (r <= 0) {
   5.802 -			cc->state = CC_STATE_ERROR;
   5.803 -		} else {
   5.804 -			cc->in_buf_used += r;
   5.805 -		}
   5.806 -		pthread_mutex_unlock(&cc->dom->mux);
   5.807 -		signal_domain(cc->dom);
   5.808 -		break;
   5.809 -	}
   5.810 -}
   5.811 -
   5.812 -static void
   5.813 -handle_connection_event(struct open_connection *oc)
   5.814 -{
   5.815 -	int r;
   5.816 -
   5.817 -	/* We know that some amount of data is ready and waiting for
   5.818 -	   us.  Slurp it in. */
   5.819 -	if (oc->buf_used == oc->buf_allocated) {
   5.820 -		oc->buf_allocated *= 2;
   5.821 -		oc->buf = xrealloc(oc->buf, oc->buf_allocated);
   5.822 -	}
   5.823 -	r = read(oc->fd, oc->buf + oc->buf_used,
   5.824 -		 oc->buf_allocated - oc->buf_used);
   5.825 -	if (r < 0) {
   5.826 -		warn("reading command from remote");
   5.827 -		oc->state = OC_STATE_ERROR;
   5.828 -	} else if (r == 0) {
   5.829 -		warnx("reading command from remote");
   5.830 -		oc->state = OC_STATE_ERROR;
   5.831 -	} else {
   5.832 -		oc->buf_used += r;
   5.833 -		if (strchr(oc->buf, '\n'))
   5.834 -			oc->state = OC_STATE_COMMAND_PENDING;
   5.835 -	}
   5.836 -}
   5.837 -
   5.838 -static void
   5.839 -get_and_process_event(void)
   5.840 -{
   5.841 -	fd_set read_fds, except_fds;
   5.842 -	struct open_connection *oc;
   5.843 -	struct console_connection *cc;
   5.844 -	int max_fd = listen_fd;
   5.845 -	int r;
   5.846 -	struct list_head *li, *temp_li;
   5.847 -
   5.848 -	FD_ZERO(&read_fds);
   5.849 -	FD_ZERO(&except_fds);
   5.850 -	FD_SET(listen_fd, &read_fds);
   5.851 -	FD_SET(evtchn_fd, &read_fds);
   5.852 -	if (evtchn_fd > max_fd)
   5.853 -		max_fd = evtchn_fd;
   5.854 -	foreach_open_connection(oc) {
   5.855 -		FD_SET(oc->fd, &read_fds);
   5.856 -		FD_SET(oc->fd, &except_fds);
   5.857 -		if (oc->fd > max_fd)
   5.858 -			max_fd = oc->fd;
   5.859 -	}
   5.860 -	foreach_console_connection(cc) {
   5.861 -		FD_SET(cc->fd, &read_fds);
   5.862 -		FD_SET(cc->fd, &except_fds);
   5.863 -		if (cc->fd > max_fd)
   5.864 -			max_fd = cc->fd;
   5.865 -	}
   5.866 -
   5.867 -	r = select(max_fd + 1, &read_fds, NULL, &except_fds, NULL);
   5.868 -	if (r < 0)
   5.869 -		err(1, "select");
   5.870 -	if (FD_ISSET(listen_fd, &read_fds)) {
   5.871 -		accept_new_connection();
   5.872 -	} else if (FD_ISSET(evtchn_fd, &read_fds))
   5.873 -		handle_evtchn_event();
   5.874 -
   5.875 -
   5.876 -	foreach_open_connection(oc) {
   5.877 -		if (FD_ISSET(oc->fd, &read_fds))
   5.878 -			handle_connection_event(oc);
   5.879 -		if (FD_ISSET(oc->fd, &except_fds))
   5.880 -			oc->state = OC_STATE_ERROR;
   5.881 -	}
   5.882 -	list_foreach_safe(&head_console, li, temp_li) {
   5.883 -		cc = list_item(li, struct console_connection, list);
   5.884 -		if (FD_ISSET(cc->fd, &read_fds))
   5.885 -			handle_console_event(cc);
   5.886 -		if (FD_ISSET(cc->fd, &except_fds) ||
   5.887 -		    cc->state == CC_STATE_ERROR) {
   5.888 -			PRINTF(1, "Cleaning up console connection");
   5.889 -			cc->dom->cc = NULL;
   5.890 -			list_remove(&cc->list);
   5.891 -			close(cc->fd);
   5.892 -			if (cc->buf_allocated != 0)
   5.893 -				free(cc->buf);
   5.894 -			if (cc->in_buf_allocated != 0)
   5.895 -				free(cc->in_buf);
   5.896 -			free(cc);
   5.897 -		}
   5.898 -	}
   5.899 -
   5.900 -	/* Run pending stuff on the open connections. */
   5.901 -	list_foreach_safe(&head_connection, li, temp_li) {
   5.902 -		oc = list_item(li, struct open_connection, connection_list);
   5.903 -		switch (oc->state) {
   5.904 -		case OC_STATE_ERROR:
   5.905 -			list_remove(&oc->connection_list);
   5.906 -			closedown_connection(oc);
   5.907 -			break;
   5.908 -		case OC_STATE_COMMAND_PENDING:
   5.909 -			process_command(oc);
   5.910 -			break;
   5.911 -		case OC_STATE_CONNECTED:
   5.912 -			/* Don't need to do anything */
   5.913 -			break;
   5.914 -		}
   5.915 -	}
   5.916 -}
   5.917 -
   5.918 -static int
   5.919 -start_listening(void)
   5.920 -{
   5.921 -	int sock;
   5.922 -	struct sockaddr_in inaddr;
   5.923 -
   5.924 -	sock = socket(PF_INET, SOCK_STREAM, 0);
   5.925 -	if (sock < 0)
   5.926 -		err(1, "creating socket");
   5.927 -	memset(&inaddr, 0, sizeof(inaddr));
   5.928 -	inaddr.sin_family = AF_INET;
   5.929 -	inaddr.sin_port = htons(MINIXEND_PORT);
   5.930 -
   5.931 -	if (bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
   5.932 -		err(1, "binding to port %d", MINIXEND_PORT);
   5.933 -	if (listen(sock, 5) < 0)
   5.934 -		err(1, "listening for connections");
   5.935 -
   5.936 -	return sock;
   5.937 -}
   5.938 -
   5.939 -static struct domain *
   5.940 -find_dom0(void)
   5.941 -{
   5.942 -	int r;
   5.943 -	xc_dominfo_t info;
   5.944 -	struct domain *work;
   5.945 -
   5.946 -	r = xc_domain_getinfo(xc_handle, 0, 1, &info);
   5.947 -	if (r < 0)
   5.948 -		err(1, "getting domain 0 information");
   5.949 -	work = xmalloc(sizeof(*work));
   5.950 -	work->control_evtchn = 2;
   5.951 -	if (ioctl(evtchn_fd, EVTCHN_BIND, 2) < 0)
   5.952 -		err(1, "binding to domain 0 control event channel");
   5.953 -
   5.954 -	work->domid = 0;
   5.955 -	work->name = xstrdup("dom0");
   5.956 -	work->mem_kb = info.max_memkb;
   5.957 -	work->state = DOM_STATE_RUNNING;
   5.958 -	work->shared_info_mfn = info.shared_info_frame;
   5.959 -
   5.960 -	work->shared_info = map_domain_mem(work, info.shared_info_frame);
   5.961 -	work->ctrl_if = (control_if_t *)((unsigned)work->shared_info + 2048);
   5.962 -	work->tx_req_cons = work->ctrl_if->tx_req_prod;
   5.963 -	work->rx_resp_cons = work->ctrl_if->rx_resp_prod;
   5.964 -
   5.965 -	pthread_mutex_init(&work->mux, NULL);
   5.966 -	pthread_cond_init(&work->cond, NULL);
   5.967 -
   5.968 -	list_insert_after(&work->domain_list, &head_domain);
   5.969 -
   5.970 -	return work;
   5.971 -}
   5.972 -
   5.973 -int
   5.974 -main(int argc, char *argv[])
   5.975 -{
   5.976 -	int r;
   5.977 -
   5.978 -	r = our_system(NETWORK_SCRIPT " start antispoof=no");
   5.979 -	if (r < 0)
   5.980 -		err(1, "running " NETWORK_SCRIPT);
   5.981 -	if (!WIFEXITED(r)) {
   5.982 -		if (WIFSIGNALED(r)) {
   5.983 -			errx(1, NETWORK_SCRIPT " killed by signal %d",
   5.984 -			     WTERMSIG(r));
   5.985 -		}
   5.986 -		errx(1, NETWORK_SCRIPT " terminated abnormally");
   5.987 -	}
   5.988 -	if (WEXITSTATUS(r) != 0)
   5.989 -		errx(1, NETWORK_SCRIPT " returned error status %d",
   5.990 -		     WEXITSTATUS(r));
   5.991 -
   5.992 -	xc_handle = xc_interface_open();
   5.993 -
   5.994 -	listen_fd = start_listening();
   5.995 -
   5.996 -	evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
   5.997 -	if (evtchn_fd < 0)
   5.998 -		err(1, "openning /dev/xen/evtchn");
   5.999 -
  5.1000 -	dom0 = find_dom0();
  5.1001 -
  5.1002 -	while (1) {
  5.1003 -		get_and_process_event();
  5.1004 -
  5.1005 -		PRINTF(5, "Dom0 ring state:\n");
  5.1006 -		PRINTF(5, "RX: req_prod %ld, resp_prod %ld, resp_cons %ld\n",
  5.1007 -		       dom0->ctrl_if->rx_req_prod,
  5.1008 -		       dom0->ctrl_if->rx_resp_prod,
  5.1009 -		       dom0->rx_resp_cons);
  5.1010 -		PRINTF(5, "TX: req_prod %ld, resp_prod %ld, req_cons %ld\n",
  5.1011 -		       dom0->ctrl_if->tx_req_prod,
  5.1012 -		       dom0->ctrl_if->tx_resp_prod,
  5.1013 -		       dom0->tx_req_cons);
  5.1014 -	}
  5.1015 -
  5.1016 -	return 0;
  5.1017 -}
  5.1018 -
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/x2d2/minixend.c	Thu Nov 18 14:58:31 2004 +0000
     6.3 @@ -0,0 +1,939 @@
     6.4 +#define _GNU_SOURCE
     6.5 +
     6.6 +#include <sys/types.h>
     6.7 +#include <sys/fcntl.h>
     6.8 +#include <sys/ioctl.h>
     6.9 +#include <sys/mman.h>
    6.10 +#include <sys/select.h>
    6.11 +#include <sys/socket.h>
    6.12 +#include <sys/wait.h>
    6.13 +#include <asm/page.h>
    6.14 +#include <assert.h>
    6.15 +#include <ctype.h>
    6.16 +#include <err.h>
    6.17 +#include <errno.h>
    6.18 +#include <netinet/in.h>
    6.19 +#include <printf.h>
    6.20 +#include <pthread.h>
    6.21 +#include <sched.h>
    6.22 +#include <stdarg.h>
    6.23 +#include <stddef.h>
    6.24 +#include <stdio.h>
    6.25 +#include <stdlib.h>
    6.26 +#include <string.h>
    6.27 +#include <unistd.h>
    6.28 +
    6.29 +#include "minixend.h"
    6.30 +
    6.31 +#define NETWORK_SCRIPT "/etc/xen/scripts/network"
    6.32 +#define VIFBRIDGE_SCRIPT "/etc/xen/scripts/vif-bridge"
    6.33 +
    6.34 +#define MINIXEND_PORT 5123
    6.35 +
    6.36 +#define mb() asm volatile ("" ::: "memory")
    6.37 +
    6.38 +static void send_control_message(int type, int subtype, int id,
    6.39 +				 int size, void *payload,
    6.40 +				 struct domain *target);
    6.41 +
    6.42 +struct list_head
    6.43 +head_domain = LIST_HEAD(&head_domain);
    6.44 +
    6.45 +static struct list_head
    6.46 +head_connection = LIST_HEAD(&head_connection);
    6.47 +
    6.48 +struct list_head
    6.49 +head_console = LIST_HEAD(&head_console);
    6.50 +
    6.51 +#define foreach_open_connection(d)                                          \
    6.52 +foreach_item(d, &head_connection, struct open_connection, connection_list)
    6.53 +
    6.54 +/* Not modified after initial start up */
    6.55 +static struct domain *dom0;
    6.56 +unsigned xc_handle;
    6.57 +static int listen_fd;
    6.58 +int evtchn_fd;
    6.59 +
    6.60 +static struct list_head
    6.61 +head_event_receiver = LIST_HEAD(&head_event_receiver);
    6.62 +
    6.63 +struct event_receiver {
    6.64 +	struct list_head list;
    6.65 +	int id;
    6.66 +	pthread_cond_t cond;
    6.67 +};
    6.68 +
    6.69 +/* We're protected by the dom0 mutex in here */
    6.70 +static struct event_receiver *
    6.71 +allocate_event_receiver(struct domain *d)
    6.72 +{
    6.73 +	static int next_message_id;
    6.74 +	struct event_receiver *work;
    6.75 +
    6.76 +	assert(d == dom0);
    6.77 +	work = xmalloc(sizeof(*work));
    6.78 +	work->id = next_message_id++;
    6.79 +	pthread_cond_init(&work->cond, NULL);
    6.80 +
    6.81 +	list_insert_after(&work->list, &head_event_receiver);
    6.82 +
    6.83 +	return work;
    6.84 +}
    6.85 +
    6.86 +static struct event_receiver *
    6.87 +find_event_receiver(int id)
    6.88 +{
    6.89 +	struct event_receiver *work;
    6.90 +	foreach_item(work, &head_event_receiver, struct event_receiver, list)
    6.91 +		if (work->id == id)
    6.92 +			return work;
    6.93 +	return NULL;
    6.94 +}
    6.95 +
    6.96 +static void
    6.97 +release_event_receiver(struct event_receiver *w)
    6.98 +{
    6.99 +	list_remove(&w->list);
   6.100 +	pthread_cond_destroy(&w->cond);
   6.101 +	free(w);
   6.102 +}
   6.103 +
   6.104 +/* Send a message to dom0, and then block awaiting a reply. */
   6.105 +/* Make sure we don't hold any domain mutexs */
   6.106 +static void
   6.107 +send_dom0_message_block(control_msg_t *msg)
   6.108 +{
   6.109 +	CONTROL_RING_IDX c;
   6.110 +	struct event_receiver *er;
   6.111 +	control_msg_t buf;
   6.112 +
   6.113 +	PRINTF(0, "sending message to dom0 and blocking for reply.\n");
   6.114 +	pthread_mutex_lock(&dom0->mux);
   6.115 +	PRINTF(0, "got dom0 lock.\n");
   6.116 +	er = allocate_event_receiver(dom0);
   6.117 +	PRINTF(0, "allocated evetn receiver.\n");
   6.118 +	msg->id = er->id;
   6.119 +	PRINTF(1, "sending message with id %d\n", msg->id);
   6.120 +	send_control_message(msg->type, msg->subtype,
   6.121 +			     msg->id, msg->length, msg->msg, dom0);
   6.122 +	xc_evtchn_send(xc_handle, dom0->control_evtchn);
   6.123 +
   6.124 +	PRINTF(0, "waiting for reply\n");
   6.125 +	pthread_cond_wait(&er->cond, &dom0->mux);
   6.126 +	PRINTF(0, "got reply\n");
   6.127 +
   6.128 +	c = dom0->rx_resp_cons % CONTROL_RING_SIZE;
   6.129 +	memcpy(&buf, &dom0->ctrl_if->rx_ring[c], sizeof(buf));
   6.130 +	assert(msg->id == buf.id);
   6.131 +	assert(msg->type == buf.type);
   6.132 +	assert(msg->subtype == buf.subtype);
   6.133 +	memcpy(msg, &buf, sizeof(*msg));
   6.134 +	dom0->rx_resp_cons++;
   6.135 +
   6.136 +	release_event_receiver(er);
   6.137 +
   6.138 +	pthread_mutex_unlock(&dom0->mux);
   6.139 +
   6.140 +	PRINTF(1, "got reply to message with id %d\n", msg->id);
   6.141 +}
   6.142 +
   6.143 +/* Allocate an interdomain event channel.  event_ports[0] is the
   6.144 +   local event port number, event_ports[1] the remote */
   6.145 +int
   6.146 +allocate_event_channel(struct domain *d, int event_ports[2])
   6.147 +{
   6.148 +	return xc_evtchn_bind_interdomain(xc_handle, DOMID_SELF,
   6.149 +					  d->domid, event_ports,
   6.150 +					  event_ports+1);
   6.151 +}
   6.152 +
   6.153 +static void
   6.154 +accept_new_connection(void)
   6.155 +{
   6.156 +	int fd;
   6.157 +	struct open_connection *oc;
   6.158 +
   6.159 +	fd = accept(listen_fd, NULL, NULL);
   6.160 +	if (fd < 0)
   6.161 +		return;
   6.162 +	oc = xmalloc(sizeof(*oc));
   6.163 +	oc->fd = fd;
   6.164 +	oc->state = OC_STATE_CONNECTED;
   6.165 +	oc->buf_used = 0;
   6.166 +	oc->buf_allocated = 16;
   6.167 +	oc->buf = xmalloc(oc->buf_allocated);
   6.168 +	list_insert_after(&oc->connection_list, &head_connection);
   6.169 +}
   6.170 +
   6.171 +static void
   6.172 +closedown_connection(struct open_connection *oc)
   6.173 +{
   6.174 +	close(oc->fd);
   6.175 +	assert(oc->buf);
   6.176 +	free(oc->buf);
   6.177 +	free(oc);
   6.178 +}
   6.179 +
   6.180 +#if 0
   6.181 +/* Hackl for the benefit of domain replay */
   6.182 +static unsigned
   6.183 +report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   6.184 +{
   6.185 +	if (!do_direct) {
   6.186 +		int rc;
   6.187 +		asm("int $0x80" : "=a" (rc)
   6.188 +		    : "0" (264), "b" (ptr), "c" (val), "d" (dom));
   6.189 +		if (rc < 0) {
   6.190 +			errno = -rc;
   6.191 +			rc = -1;
   6.192 +		}
   6.193 +		return rc;
   6.194 +	} else {
   6.195 +		*ptr = val;
   6.196 +		return 0;
   6.197 +	}
   6.198 +}
   6.199 +#else
   6.200 +static unsigned
   6.201 +report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   6.202 +{
   6.203 +	*ptr = val;
   6.204 +	return 0;
   6.205 +}
   6.206 +#endif
   6.207 +
   6.208 +static void
   6.209 +send_control_reply(const control_msg_t *msg, struct domain *d)
   6.210 +{
   6.211 +	CONTROL_RING_IDX c;
   6.212 +
   6.213 +	PRINTF(3,"Control reply, type %d:%d, length %d.\n",
   6.214 +	       msg->type, msg->subtype, msg->length);
   6.215 +	c = d->ctrl_if->tx_resp_prod % CONTROL_RING_SIZE;
   6.216 +	memcpy(&d->ctrl_if->tx_ring[c], msg, sizeof(*msg));
   6.217 +	report_work(&d->ctrl_if->tx_resp_prod,
   6.218 +		    d->ctrl_if->tx_resp_prod + 1,
   6.219 +		    d->domid,
   6.220 +		    0);
   6.221 +	PRINTF(4,"tx_resp_prod %ld.\n", d->ctrl_if->tx_resp_prod);
   6.222 +	assert(!d->plugged);
   6.223 +}
   6.224 +
   6.225 +static void
   6.226 +send_trivial_control_reply(const control_msg_t *msg, struct domain *d)
   6.227 +{
   6.228 +	control_msg_t rep;
   6.229 +
   6.230 +	memset(&rep, 0, sizeof(rep));
   6.231 +	rep.type = msg->type;
   6.232 +	rep.subtype = msg->subtype;
   6.233 +	rep.id = msg->id;
   6.234 +	send_control_reply(&rep, d);
   6.235 +}
   6.236 +
   6.237 +static void
   6.238 +process_console_control_message(control_msg_t *m, struct domain *d)
   6.239 +{
   6.240 +	int off;
   6.241 +	int r;
   6.242 +
   6.243 +	if (m->subtype != CMSG_CONSOLE_DATA) {
   6.244 +		warnx("unknown console message subtype %d",
   6.245 +		      m->subtype);
   6.246 +		return;
   6.247 +	}
   6.248 +
   6.249 +	if (m->length > 60) {
   6.250 +		warnx("truncating message from domain %d (was length %d)",
   6.251 +		      d->domid, m->length);
   6.252 +		m->length = 60;
   6.253 +	}
   6.254 +	PRINTF(1, "DOM%d: %.*s\n", d->domid, m->length, m->msg);
   6.255 +	send_trivial_control_reply(m, d);
   6.256 +
   6.257 +	if (d->cc) {
   6.258 +		PRINTF(5, "Have a console connection.\n");
   6.259 +		if (d->cc->state == CC_STATE_CONNECTED) {
   6.260 +			PRINTF(5, "Console is connected, sending directly.\n");
   6.261 +			for (off = 0; off < m->length; off += r) {
   6.262 +				r = write(d->cc->fd, m->msg + off,
   6.263 +					  m->length - off);
   6.264 +				if (r <= 0) {
   6.265 +					d->cc->state = CC_STATE_ERROR;
   6.266 +					break;
   6.267 +				}
   6.268 +			}
   6.269 +		} else {
   6.270 +			PRINTF(5, "Console not connected, buffering.\n");
   6.271 +			if (d->cc->buf_allocated == 0) {
   6.272 +				d->cc->buf_allocated = 60;
   6.273 +				d->cc->buf = xmalloc(d->cc->buf_allocated);
   6.274 +				d->cc->buf_used = 0;
   6.275 +			} else if (d->cc->buf_allocated <
   6.276 +				   d->cc->buf_used + m->length) {
   6.277 +				d->cc->buf_allocated += 60;
   6.278 +				d->cc->buf = xrealloc(d->cc->buf,
   6.279 +						      d->cc->buf_allocated);
   6.280 +			}
   6.281 +			assert(d->cc->buf_allocated >=
   6.282 +			       d->cc->buf_used + m->length);
   6.283 +			memcpy(d->cc->buf + d->cc->buf_used,
   6.284 +			       m->msg,
   6.285 +			       m->length);
   6.286 +			d->cc->buf_used += m->length;
   6.287 +		}
   6.288 +	}
   6.289 +}
   6.290 +
   6.291 +static void
   6.292 +process_blkif_fe_message(control_msg_t *m, struct domain *d)
   6.293 +{
   6.294 +	switch (m->subtype) {
   6.295 +	default:
   6.296 +		warnx("unknown blkif front end message subtype %d",
   6.297 +		      m->subtype);
   6.298 +	}
   6.299 +}
   6.300 +
   6.301 +static void
   6.302 +send_control_message(int type, int subtype, int id,
   6.303 +		     int size, void *payload, struct domain *target)
   6.304 +{
   6.305 +	control_msg_t msg;
   6.306 +	CONTROL_RING_IDX c;
   6.307 +
   6.308 +	msg.type = type;
   6.309 +	msg.subtype = subtype;
   6.310 +	msg.id = id;
   6.311 +	msg.length = size;
   6.312 +	memcpy(msg.msg, payload, size);
   6.313 +
   6.314 +	c = target->ctrl_if->rx_req_prod % CONTROL_RING_SIZE;
   6.315 +	memcpy(&target->ctrl_if->rx_ring[c], &msg, sizeof(msg));
   6.316 +	report_work(&target->ctrl_if->rx_req_prod,
   6.317 +		    target->ctrl_if->rx_req_prod + 1,
   6.318 +		    target->domid,
   6.319 +		    0);
   6.320 +	assert(!target->plugged);
   6.321 +}
   6.322 +
   6.323 +/* Procedure for bringing a new netif front end up:
   6.324 +
   6.325 +   -- Front end sends us NETIF_FE_DRIVER_STATUS_CHANGED
   6.326 +   -- We send back end NETIF_BE_CREATE, wait for a reply
   6.327 +   -- Back end creates a new netif for us, replies
   6.328 +   -- We send front end a NETIF_FE_DRIVER_STATUS_CHANGED message saying
   6.329 +      how many interfaces we've created for it
   6.330 +   -- We send front end a NETIF_FE_INTERFACE_STATUS_CHANGED for each
   6.331 +      netif created
   6.332 +   -- Front end sends us a NETIF_FE_INTERFACE_CONNECT for each netif
   6.333 +*/
   6.334 +static void
   6.335 +handle_netif_fe_driver_status(control_msg_t *m,
   6.336 +			      netif_fe_driver_status_t *sh,
   6.337 +			      struct domain *d)
   6.338 +{
   6.339 +	netif_fe_interface_status_t if_s;
   6.340 +	control_msg_t be_msg;
   6.341 +	netif_be_create_t *be = (void *)be_msg.msg;
   6.342 +	int r;
   6.343 +
   6.344 +	switch (sh->status) {
   6.345 +	case NETIF_DRIVER_STATUS_UP:
   6.346 +		/* Tell the back end about the new interface coming
   6.347 +		 * up. */
   6.348 +		if (d->created_netif_backend) {
   6.349 +			send_control_reply(m, d);
   6.350 +			send_control_message(CMSG_NETIF_FE,
   6.351 +					     CMSG_NETIF_FE_DRIVER_STATUS,
   6.352 +					     1,
   6.353 +					     sizeof(*sh),
   6.354 +					     sh,
   6.355 +					     d);
   6.356 +			return;
   6.357 +		}
   6.358 +		be_msg.type = CMSG_NETIF_BE;
   6.359 +		be_msg.subtype = CMSG_NETIF_BE_CREATE;
   6.360 +		be_msg.id = d->domid;
   6.361 +		be_msg.length = sizeof(*be);
   6.362 +		be->domid = d->domid;
   6.363 +		be->netif_handle = 0;
   6.364 +		memcpy(be->mac, d->netif_mac, 6);
   6.365 +
   6.366 +		PRINTF(2,"Telling back end about new front end.\n");
   6.367 +		pthread_mutex_unlock(&d->mux);
   6.368 +		send_dom0_message_block(&be_msg);
   6.369 +		pthread_mutex_lock(&d->mux);
   6.370 +		PRINTF(3,"Done.\n");
   6.371 +
   6.372 +		if (be->status != NETIF_BE_STATUS_OKAY) {
   6.373 +			/* Uh oh... can't bring back end
   6.374 +			 * up. */
   6.375 +			send_control_reply(m, d);
   6.376 +			send_control_message(CMSG_NETIF_FE,
   6.377 +					     CMSG_NETIF_FE_DRIVER_STATUS,
   6.378 +					     1,
   6.379 +					     sizeof(*sh),
   6.380 +					     sh,
   6.381 +					     d);
   6.382 +			return;
   6.383 +		}
   6.384 +		d->created_netif_backend = 1;
   6.385 +
   6.386 +		r = our_system(VIFBRIDGE_SCRIPT " up domain=%s mac=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x vif=vif%d.0 bridge=xen-br0",
   6.387 +			       d->name,
   6.388 +			       d->netif_mac[0],
   6.389 +			       d->netif_mac[1],
   6.390 +			       d->netif_mac[2],
   6.391 +			       d->netif_mac[3],
   6.392 +			       d->netif_mac[4],
   6.393 +			       d->netif_mac[5],
   6.394 +			       d->domid);
   6.395 +		if (r != 0)
   6.396 +			warn("error %d running " VIFBRIDGE_SCRIPT, r);
   6.397 +
   6.398 +		/* Tell domain how many interfaces it has to deal
   6.399 +		 * with. */
   6.400 +		send_control_reply(m, d);
   6.401 +		send_control_message(CMSG_NETIF_FE,
   6.402 +				     CMSG_NETIF_FE_DRIVER_STATUS,
   6.403 +				     1,
   6.404 +				     sizeof(*sh),
   6.405 +				     sh,
   6.406 +				     d);
   6.407 +
   6.408 +		PRINTF(2,"Telling front end about its interfaces.\n");
   6.409 +		if_s.handle = 0;
   6.410 +		if_s.status = NETIF_INTERFACE_STATUS_DISCONNECTED;
   6.411 +		send_control_message(CMSG_NETIF_FE,
   6.412 +				     CMSG_NETIF_FE_INTERFACE_STATUS,
   6.413 +				     1,
   6.414 +				     sizeof(if_s),
   6.415 +				     &if_s,
   6.416 +				     d);
   6.417 +		PRINTF(3,"Done.\n");
   6.418 +
   6.419 +		break;
   6.420 +	default:
   6.421 +		warnx("unknown netif status %ld", sh->status);
   6.422 +		break;
   6.423 +	}
   6.424 +}
   6.425 +
   6.426 +static void
   6.427 +handle_netif_fe_interface_connect(control_msg_t *m,
   6.428 +				  netif_fe_interface_connect_t *ic,
   6.429 +				  struct domain *d)
   6.430 +{
   6.431 +	control_msg_t be_msg;
   6.432 +	netif_be_connect_t *bmsg = (void *)be_msg.msg;
   6.433 +	netif_fe_interface_status_t fmsg = {0};
   6.434 +	int evtchn_ports[2];
   6.435 +	int r;
   6.436 +
   6.437 +	PRINTF(4, "front end sent us an interface connect message.\n");
   6.438 +	send_trivial_control_reply(m, d);
   6.439 +
   6.440 +	r = xc_evtchn_bind_interdomain(xc_handle,
   6.441 +				       dom0->domid,
   6.442 +				       d->domid,
   6.443 +				       &evtchn_ports[0],
   6.444 +				       &evtchn_ports[1]);
   6.445 +	if (r < 0)
   6.446 +		err(1, "allocating network event channel");
   6.447 +
   6.448 +	be_msg.type = CMSG_NETIF_BE;
   6.449 +	be_msg.subtype = CMSG_NETIF_BE_CONNECT;
   6.450 +	be_msg.id = 0;
   6.451 +	be_msg.length = sizeof(*bmsg);
   6.452 +	bmsg->domid = d->domid;
   6.453 +	bmsg->netif_handle = ic->handle;
   6.454 +	bmsg->tx_shmem_frame = ic->tx_shmem_frame;
   6.455 +	bmsg->rx_shmem_frame = ic->rx_shmem_frame;
   6.456 +	bmsg->evtchn = evtchn_ports[0];
   6.457 +
   6.458 +	pthread_mutex_unlock(&d->mux);
   6.459 +	send_dom0_message_block(&be_msg);
   6.460 +	pthread_mutex_lock(&d->mux);
   6.461 +
   6.462 +	if (bmsg->status != NETIF_BE_STATUS_OKAY) {
   6.463 +		PRINTF(2, "error connected backend netif: %ld\n",
   6.464 +		       bmsg->status);
   6.465 +		abort(); /* Need to handle this */
   6.466 +	} else {
   6.467 +		PRINTF(3, "connect backend netif\n");
   6.468 +
   6.469 +		/* Tell the domain that we've connected it up. */
   6.470 +		fmsg.handle = ic->handle;
   6.471 +		fmsg.status = NETIF_INTERFACE_STATUS_CONNECTED;
   6.472 +		fmsg.evtchn = evtchn_ports[1];
   6.473 +		memcpy(fmsg.mac, d->netif_mac, 6);
   6.474 +
   6.475 +		send_control_message(CMSG_NETIF_FE,
   6.476 +				     CMSG_NETIF_FE_INTERFACE_STATUS,
   6.477 +				     0,
   6.478 +				     sizeof(fmsg),
   6.479 +				     &fmsg,
   6.480 +				     d);
   6.481 +	}
   6.482 +}
   6.483 +
   6.484 +static void
   6.485 +process_netif_fe_message(control_msg_t *m, struct domain *d)
   6.486 +{
   6.487 +	switch (m->subtype) {
   6.488 +	case CMSG_NETIF_FE_DRIVER_STATUS:
   6.489 +	{
   6.490 +		netif_fe_driver_status_t *sh =
   6.491 +			(netif_fe_driver_status_t *)m->msg;
   6.492 +		handle_netif_fe_driver_status(m, sh, d);
   6.493 +		break;
   6.494 +	}
   6.495 +	case CMSG_NETIF_FE_INTERFACE_CONNECT:
   6.496 +	{
   6.497 +		netif_fe_interface_connect_t *ic =
   6.498 +			(netif_fe_interface_connect_t *)m->msg;
   6.499 +		handle_netif_fe_interface_connect(m, ic, d);
   6.500 +		break;
   6.501 +	}
   6.502 +	default:
   6.503 +		warnx("unknown netif front end message subtype %d",
   6.504 +		      m->subtype);
   6.505 +	}
   6.506 +}
   6.507 +
   6.508 +static void
   6.509 +process_control_message(control_msg_t *msg, struct domain *d)
   6.510 +{
   6.511 +	control_msg_t m;
   6.512 +
   6.513 +	/* Don't want a malicous domain messing us about, so copy the
   6.514 +	   control mesasge into a local buffer. */
   6.515 +	memcpy(&m, msg, sizeof(m));
   6.516 +	switch (m.type) {
   6.517 +	case CMSG_CONSOLE:
   6.518 +		process_console_control_message(&m, d);
   6.519 +		break;
   6.520 +	case CMSG_BLKIF_FE:
   6.521 +		process_blkif_fe_message(&m, d);
   6.522 +		break;
   6.523 +	case CMSG_NETIF_FE:
   6.524 +		process_netif_fe_message(&m, d);
   6.525 +		break;
   6.526 +	default:
   6.527 +		warnx("unknown control message type %d", m.type);
   6.528 +	}
   6.529 +}
   6.530 +
   6.531 +static void
   6.532 +domain_did_control_event(struct domain *d)
   6.533 +{
   6.534 +	CONTROL_RING_IDX c;
   6.535 +
   6.536 +	/* Pick up and process control ring messages. */
   6.537 +	while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   6.538 +		c = d->tx_req_cons % CONTROL_RING_SIZE;
   6.539 +		process_control_message(&d->ctrl_if->tx_ring[c], d);
   6.540 +		d->tx_req_cons++;
   6.541 +		assert(d->tx_req_cons <= d->ctrl_if->tx_req_prod);
   6.542 +		PRINTF(5, "req_cons %ld, req_prod %ld.\n",
   6.543 +		       d->tx_req_cons, d->ctrl_if->tx_req_prod);
   6.544 +	}
   6.545 +
   6.546 +	/* Take any replies off, and discard them. */
   6.547 +	if (d->rx_resp_cons != d->ctrl_if->rx_resp_prod)
   6.548 +		PRINTF(1, "discard %ld events\n",
   6.549 +		       d->ctrl_if->rx_resp_prod -
   6.550 +		       d->rx_resp_cons);
   6.551 +	d->rx_resp_cons = d->ctrl_if->rx_resp_prod;
   6.552 +}
   6.553 +
   6.554 +/* This is the main function for domain control threads */
   6.555 +void *
   6.556 +domain_thread_func(void *D)
   6.557 +{
   6.558 +	struct domain *d = D;
   6.559 +	int r;
   6.560 +	CONTROL_RING_IDX old_resp_prod, old_req_prod;
   6.561 +
   6.562 +	pthread_mutex_lock(&d->mux);
   6.563 +	for (;;) {
   6.564 +		pthread_cond_wait(&d->cond, &d->mux);
   6.565 +
   6.566 +		old_resp_prod = d->ctrl_if->tx_resp_prod;
   6.567 +		old_req_prod = d->ctrl_if->rx_req_prod;
   6.568 +
   6.569 +		domain_did_control_event(d);
   6.570 +		if (d->cc && d->cc->in_buf_used != 0 && d->plugged == 0) {
   6.571 +			r = d->cc->in_buf_used;
   6.572 +			if (r > 60)
   6.573 +				r = 60;
   6.574 +			PRINTF(1, "Sending to domain: %.*s\n",
   6.575 +			       r, d->cc->in_buf);
   6.576 +			send_control_message(CMSG_CONSOLE,
   6.577 +					     CMSG_CONSOLE_DATA,
   6.578 +					     0,
   6.579 +					     r,
   6.580 +					     d->cc->in_buf,
   6.581 +					     d);
   6.582 +			memmove(d->cc->in_buf, d->cc->in_buf + r,
   6.583 +				d->cc->in_buf_used - r);
   6.584 +			d->cc->in_buf_used -= r;
   6.585 +		}
   6.586 +
   6.587 +		if (d->ctrl_if->tx_resp_prod != old_resp_prod ||
   6.588 +		    d->ctrl_if->rx_req_prod != old_req_prod)
   6.589 +			xc_evtchn_send(xc_handle, d->control_evtchn);
   6.590 +	}
   6.591 +}
   6.592 +
   6.593 +/* This is the only thing you can do with a domain structure if you're
   6.594 +   not in the thread which controls that domain.  Domain 0 is
   6.595 +   special. */
   6.596 +void
   6.597 +signal_domain(struct domain *d)
   6.598 +{
   6.599 +	CONTROL_RING_IDX c;
   6.600 +	int id;
   6.601 +	struct event_receiver *evt;
   6.602 +
   6.603 +	pthread_mutex_lock(&d->mux);
   6.604 +	if (d == dom0) {
   6.605 +		/* Take events off of dom0's control ring, and send
   6.606 +		   them to the event receivers. */
   6.607 +		while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   6.608 +			c = d->tx_req_cons % CONTROL_RING_SIZE;
   6.609 +			id = d->ctrl_if->tx_ring[c].id;
   6.610 +			evt = find_event_receiver(id);
   6.611 +			if (evt != NULL) {
   6.612 +				PRINTF(1, "delivering event id %d\n", evt->id);
   6.613 +				pthread_cond_broadcast(&evt->cond);
   6.614 +				pthread_mutex_unlock(&d->mux);
   6.615 +				sched_yield();
   6.616 +				pthread_mutex_lock(&d->mux);
   6.617 +			} else {
   6.618 +				warnx("unexpected message id %d discarded",
   6.619 +				      id);
   6.620 +				d->tx_req_cons++;
   6.621 +			}
   6.622 +		}
   6.623 +		while (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) {
   6.624 +			c = d->rx_resp_cons % CONTROL_RING_SIZE;
   6.625 +			id = d->ctrl_if->rx_ring[c].id;
   6.626 +			evt = find_event_receiver(id);
   6.627 +			if (evt != NULL) {
   6.628 +				PRINTF(1, "delivering event rep id %d\n", evt->id);
   6.629 +				pthread_cond_broadcast(&evt->cond);
   6.630 +				pthread_mutex_unlock(&d->mux);
   6.631 +				sched_yield();
   6.632 +				pthread_mutex_lock(&d->mux);
   6.633 +			} else {
   6.634 +				warnx("unexpected message reply id %d discarded",
   6.635 +				      id);
   6.636 +				d->rx_resp_cons++;
   6.637 +			}
   6.638 +		}
   6.639 +	} else {
   6.640 +		if (d->plugged) {
   6.641 +			d->event_pending = 1;
   6.642 +		} else {
   6.643 +			pthread_cond_broadcast(&d->cond);
   6.644 +		}
   6.645 +	}
   6.646 +	pthread_mutex_unlock(&d->mux);
   6.647 +}
   6.648 +
   6.649 +static void
   6.650 +handle_evtchn_event(void)
   6.651 +{
   6.652 +	short port;
   6.653 +	struct domain *d;
   6.654 +
   6.655 +	read(evtchn_fd, &port, sizeof(short));
   6.656 +	write(evtchn_fd, &port, sizeof(short));
   6.657 +	foreach_domain (d) {
   6.658 +		if (d->control_evtchn == port) {
   6.659 +			signal_domain(d);
   6.660 +			return;
   6.661 +		}
   6.662 +	}
   6.663 +	warnx("got an event on an unknown port %d", port);
   6.664 +}
   6.665 +
   6.666 +void *
   6.667 +map_domain_mem(struct domain *d, unsigned long mfn)
   6.668 +{
   6.669 +	return xc_map_foreign_range(xc_handle, d->domid,
   6.670 +				    PAGE_SIZE, PROT_READ | PROT_WRITE,
   6.671 +				    mfn);
   6.672 +}
   6.673 +
   6.674 +static void
   6.675 +handle_console_event(struct console_connection *cc)
   6.676 +{
   6.677 +	int r;
   6.678 +	int fd;
   6.679 +
   6.680 +	switch (cc->state) {
   6.681 +	case CC_STATE_ERROR:
   6.682 +		/* Errors shouldn't get here. */
   6.683 +		abort();
   6.684 +	case CC_STATE_PENDING:
   6.685 +		fd = accept(cc->fd, NULL, NULL);
   6.686 +		if (fd >= 0) {
   6.687 +			PRINTF(3, "Accepted console connection for domain %d",
   6.688 +			       cc->dom->domid);
   6.689 +			close(cc->fd);
   6.690 +			cc->fd = fd;
   6.691 +			cc->state = CC_STATE_CONNECTED;
   6.692 +			while (cc->buf_used != 0) {
   6.693 +				r = write(cc->fd,
   6.694 +					  cc->buf,
   6.695 +					  cc->buf_used);
   6.696 +				if (r <= 0) {
   6.697 +					cc->state = CC_STATE_ERROR;
   6.698 +					break;
   6.699 +				}
   6.700 +				memmove(cc->buf,
   6.701 +					cc->buf + r,
   6.702 +					cc->buf_used - r);
   6.703 +				cc->buf_used -= r;
   6.704 +			}
   6.705 +			free(cc->buf);
   6.706 +			cc->buf = NULL;
   6.707 +			cc->buf_allocated = 0;
   6.708 +		} else {
   6.709 +			PRINTF(1, "error %s accepting console", strerror(errno));
   6.710 +		}
   6.711 +		pthread_mutex_unlock(&cc->dom->mux);
   6.712 +		break;
   6.713 +	case CC_STATE_CONNECTED:
   6.714 +		if (cc->in_buf_allocated == 0) {
   6.715 +			assert(cc->in_buf_used == 0);
   6.716 +			cc->in_buf_allocated = 128;
   6.717 +			cc->in_buf = xmalloc(cc->in_buf_allocated);
   6.718 +		}
   6.719 +		if (cc->in_buf_used == cc->in_buf_allocated) {
   6.720 +			cc->in_buf_allocated *= 2;
   6.721 +			cc->in_buf = xrealloc(cc->in_buf, cc->in_buf_allocated);
   6.722 +		}
   6.723 +		r = read(cc->fd, cc->in_buf + cc->in_buf_used,
   6.724 +			 cc->in_buf_allocated - cc->in_buf_used);
   6.725 +		if (r <= 0) {
   6.726 +			cc->state = CC_STATE_ERROR;
   6.727 +		} else {
   6.728 +			cc->in_buf_used += r;
   6.729 +		}
   6.730 +		pthread_mutex_unlock(&cc->dom->mux);
   6.731 +		signal_domain(cc->dom);
   6.732 +		break;
   6.733 +	}
   6.734 +}
   6.735 +
   6.736 +static void
   6.737 +handle_connection_event(struct open_connection *oc)
   6.738 +{
   6.739 +	int r;
   6.740 +
   6.741 +	/* We know that some amount of data is ready and waiting for
   6.742 +	   us.  Slurp it in. */
   6.743 +	if (oc->buf_used == oc->buf_allocated) {
   6.744 +		oc->buf_allocated *= 2;
   6.745 +		oc->buf = xrealloc(oc->buf, oc->buf_allocated);
   6.746 +	}
   6.747 +	r = read(oc->fd, oc->buf + oc->buf_used,
   6.748 +		 oc->buf_allocated - oc->buf_used);
   6.749 +	if (r < 0) {
   6.750 +		warn("reading command from remote");
   6.751 +		oc->state = OC_STATE_ERROR;
   6.752 +	} else if (r == 0) {
   6.753 +		warnx("reading command from remote");
   6.754 +		oc->state = OC_STATE_ERROR;
   6.755 +	} else {
   6.756 +		oc->buf_used += r;
   6.757 +		if (strchr(oc->buf, '\n'))
   6.758 +			oc->state = OC_STATE_COMMAND_PENDING;
   6.759 +	}
   6.760 +}
   6.761 +
   6.762 +static void
   6.763 +get_and_process_event(void)
   6.764 +{
   6.765 +	fd_set read_fds, except_fds;
   6.766 +	struct open_connection *oc;
   6.767 +	struct console_connection *cc;
   6.768 +	int max_fd = listen_fd;
   6.769 +	int r;
   6.770 +	struct list_head *li, *temp_li;
   6.771 +
   6.772 +	FD_ZERO(&read_fds);
   6.773 +	FD_ZERO(&except_fds);
   6.774 +	FD_SET(listen_fd, &read_fds);
   6.775 +	FD_SET(evtchn_fd, &read_fds);
   6.776 +	if (evtchn_fd > max_fd)
   6.777 +		max_fd = evtchn_fd;
   6.778 +	foreach_open_connection(oc) {
   6.779 +		FD_SET(oc->fd, &read_fds);
   6.780 +		FD_SET(oc->fd, &except_fds);
   6.781 +		if (oc->fd > max_fd)
   6.782 +			max_fd = oc->fd;
   6.783 +	}
   6.784 +	foreach_console_connection(cc) {
   6.785 +		FD_SET(cc->fd, &read_fds);
   6.786 +		FD_SET(cc->fd, &except_fds);
   6.787 +		if (cc->fd > max_fd)
   6.788 +			max_fd = cc->fd;
   6.789 +	}
   6.790 +
   6.791 +	r = select(max_fd + 1, &read_fds, NULL, &except_fds, NULL);
   6.792 +	if (r < 0)
   6.793 +		err(1, "select");
   6.794 +	if (FD_ISSET(listen_fd, &read_fds)) {
   6.795 +		accept_new_connection();
   6.796 +	} else if (FD_ISSET(evtchn_fd, &read_fds))
   6.797 +		handle_evtchn_event();
   6.798 +
   6.799 +
   6.800 +	foreach_open_connection(oc) {
   6.801 +		if (FD_ISSET(oc->fd, &read_fds))
   6.802 +			handle_connection_event(oc);
   6.803 +		if (FD_ISSET(oc->fd, &except_fds))
   6.804 +			oc->state = OC_STATE_ERROR;
   6.805 +	}
   6.806 +	list_foreach_safe(&head_console, li, temp_li) {
   6.807 +		cc = list_item(li, struct console_connection, list);
   6.808 +		if (FD_ISSET(cc->fd, &read_fds))
   6.809 +			handle_console_event(cc);
   6.810 +		if (FD_ISSET(cc->fd, &except_fds) ||
   6.811 +		    cc->state == CC_STATE_ERROR) {
   6.812 +			PRINTF(1, "Cleaning up console connection");
   6.813 +			cc->dom->cc = NULL;
   6.814 +			list_remove(&cc->list);
   6.815 +			close(cc->fd);
   6.816 +			if (cc->buf_allocated != 0)
   6.817 +				free(cc->buf);
   6.818 +			if (cc->in_buf_allocated != 0)
   6.819 +				free(cc->in_buf);
   6.820 +			free(cc);
   6.821 +		}
   6.822 +	}
   6.823 +
   6.824 +	/* Run pending stuff on the open connections. */
   6.825 +	list_foreach_safe(&head_connection, li, temp_li) {
   6.826 +		oc = list_item(li, struct open_connection, connection_list);
   6.827 +		switch (oc->state) {
   6.828 +		case OC_STATE_ERROR:
   6.829 +			list_remove(&oc->connection_list);
   6.830 +			closedown_connection(oc);
   6.831 +			break;
   6.832 +		case OC_STATE_COMMAND_PENDING:
   6.833 +			process_command(oc);
   6.834 +			break;
   6.835 +		case OC_STATE_CONNECTED:
   6.836 +			/* Don't need to do anything */
   6.837 +			break;
   6.838 +		}
   6.839 +	}
   6.840 +}
   6.841 +
   6.842 +static int
   6.843 +start_listening(void)
   6.844 +{
   6.845 +	int sock;
   6.846 +	struct sockaddr_in inaddr;
   6.847 +
   6.848 +	sock = socket(PF_INET, SOCK_STREAM, 0);
   6.849 +	if (sock < 0)
   6.850 +		err(1, "creating socket");
   6.851 +	memset(&inaddr, 0, sizeof(inaddr));
   6.852 +	inaddr.sin_family = AF_INET;
   6.853 +	inaddr.sin_port = htons(MINIXEND_PORT);
   6.854 +
   6.855 +	if (bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
   6.856 +		err(1, "binding to port %d", MINIXEND_PORT);
   6.857 +	if (listen(sock, 5) < 0)
   6.858 +		err(1, "listening for connections");
   6.859 +
   6.860 +	return sock;
   6.861 +}
   6.862 +
   6.863 +static struct domain *
   6.864 +find_dom0(void)
   6.865 +{
   6.866 +	int r;
   6.867 +	xc_dominfo_t info;
   6.868 +	struct domain *work;
   6.869 +
   6.870 +	r = xc_domain_getinfo(xc_handle, 0, 1, &info);
   6.871 +	if (r < 0)
   6.872 +		err(1, "getting domain 0 information");
   6.873 +	work = xmalloc(sizeof(*work));
   6.874 +	work->control_evtchn = 2;
   6.875 +	if (ioctl(evtchn_fd, EVTCHN_BIND, 2) < 0)
   6.876 +		err(1, "binding to domain 0 control event channel");
   6.877 +
   6.878 +	work->domid = 0;
   6.879 +	work->name = strdup("dom0");
   6.880 +	work->mem_kb = info.max_memkb;
   6.881 +	work->state = DOM_STATE_RUNNING;
   6.882 +	work->shared_info_mfn = info.shared_info_frame;
   6.883 +
   6.884 +	work->shared_info = map_domain_mem(work, info.shared_info_frame);
   6.885 +	work->ctrl_if = (control_if_t *)((unsigned)work->shared_info + 2048);
   6.886 +	work->tx_req_cons = work->ctrl_if->tx_req_prod;
   6.887 +	work->rx_resp_cons = work->ctrl_if->rx_resp_prod;
   6.888 +
   6.889 +	pthread_mutex_init(&work->mux, NULL);
   6.890 +	pthread_cond_init(&work->cond, NULL);
   6.891 +
   6.892 +	list_insert_after(&work->domain_list, &head_domain);
   6.893 +
   6.894 +	return work;
   6.895 +}
   6.896 +
   6.897 +int
   6.898 +main(int argc, char *argv[])
   6.899 +{
   6.900 +	int r;
   6.901 +
   6.902 +	r = our_system(NETWORK_SCRIPT " start antispoof=no");
   6.903 +	if (r < 0)
   6.904 +		err(1, "running " NETWORK_SCRIPT);
   6.905 +	if (!WIFEXITED(r)) {
   6.906 +		if (WIFSIGNALED(r)) {
   6.907 +			errx(1, NETWORK_SCRIPT " killed by signal %d",
   6.908 +			     WTERMSIG(r));
   6.909 +		}
   6.910 +		errx(1, NETWORK_SCRIPT " terminated abnormally");
   6.911 +	}
   6.912 +	if (WEXITSTATUS(r) != 0)
   6.913 +		errx(1, NETWORK_SCRIPT " returned error status %d",
   6.914 +		     WEXITSTATUS(r));
   6.915 +
   6.916 +	xc_handle = xc_interface_open();
   6.917 +
   6.918 +	listen_fd = start_listening();
   6.919 +
   6.920 +	evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
   6.921 +	if (evtchn_fd < 0)
   6.922 +		err(1, "openning /dev/xen/evtchn");
   6.923 +
   6.924 +	dom0 = find_dom0();
   6.925 +
   6.926 +	while (1) {
   6.927 +		get_and_process_event();
   6.928 +
   6.929 +		PRINTF(5, "Dom0 ring state:\n");
   6.930 +		PRINTF(5, "RX: req_prod %ld, resp_prod %ld, resp_cons %ld\n",
   6.931 +		       dom0->ctrl_if->rx_req_prod,
   6.932 +		       dom0->ctrl_if->rx_resp_prod,
   6.933 +		       dom0->rx_resp_cons);
   6.934 +		PRINTF(5, "TX: req_prod %ld, resp_prod %ld, req_cons %ld\n",
   6.935 +		       dom0->ctrl_if->tx_req_prod,
   6.936 +		       dom0->ctrl_if->tx_resp_prod,
   6.937 +		       dom0->tx_req_cons);
   6.938 +	}
   6.939 +
   6.940 +	return 0;
   6.941 +}
   6.942 +
     7.1 --- a/tools/x2d2/minixend.h	Thu Nov 18 13:13:56 2004 +0000
     7.2 +++ b/tools/x2d2/minixend.h	Thu Nov 18 14:58:31 2004 +0000
     7.3 @@ -3,70 +3,6 @@
     7.4  
     7.5  #include <sys/types.h>
     7.6  #include <xc.h>
     7.7 -#include "domain_controller.h"
     7.8 -
     7.9 -/* Yet again, persuading Xen headers to include successfully in a
    7.10 -   userspace process proves to be beyond me.  Sigh. */
    7.11 -#define MAX_VIRT_CPUS 1
    7.12 -
    7.13 -typedef struct {
    7.14 -    u32  tsc_bits;      /* 0: 32 bits read from the CPU's TSC. */
    7.15 -    u32  tsc_bitshift;  /* 4: 'tsc_bits' uses N:N+31 of TSC.   */
    7.16 -} PACKED tsc_timestamp_t; /* 8 bytes */
    7.17 -
    7.18 -typedef struct {
    7.19 -    u64 mfn_to_pfn_start;      /* MFN of start of m2p table */
    7.20 -    u64 pfn_to_mfn_frame_list; /* MFN of a table of MFNs that 
    7.21 -				  make up p2m table */
    7.22 -} PACKED arch_shared_info_t;
    7.23 -
    7.24 -typedef struct
    7.25 -{
    7.26 -    unsigned long ebx;
    7.27 -    unsigned long ecx;
    7.28 -    unsigned long edx;
    7.29 -    unsigned long esi;
    7.30 -    unsigned long edi;
    7.31 -    unsigned long ebp;
    7.32 -    unsigned long eax;
    7.33 -    unsigned long ds;
    7.34 -    unsigned long es;
    7.35 -    unsigned long fs;
    7.36 -    unsigned long gs;
    7.37 -    unsigned long _unused;
    7.38 -    unsigned long eip;
    7.39 -    unsigned long cs;
    7.40 -    unsigned long eflags;
    7.41 -    unsigned long esp;
    7.42 -    unsigned long ss;
    7.43 -} PACKED execution_context_t;
    7.44 -
    7.45 -typedef struct shared_info_st
    7.46 -{
    7.47 -    struct {
    7.48 -        u8 evtchn_upcall_pending;
    7.49 -        u8 evtchn_upcall_mask;
    7.50 -        u8 pad0, pad1;
    7.51 -    } PACKED vcpu_data[MAX_VIRT_CPUS];  /*   0 */
    7.52 -    u32 evtchn_pending[32];             /*   4 */
    7.53 -    u32 evtchn_pending_sel;             /* 132 */
    7.54 -    u32 evtchn_mask[32];                /* 136 */
    7.55 -    u64                cpu_freq;        /* 264: CPU frequency (Hz).          */
    7.56 -    u32                time_version1;   /* 272 */
    7.57 -    u32                time_version2;   /* 276 */
    7.58 -    tsc_timestamp_t    tsc_timestamp;   /* TSC at last update of time vals.  */
    7.59 -    u64                system_time;     /* Time, in nanosecs, since boot.    */
    7.60 -    u32                wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
    7.61 -    u32                wc_usec;         /* Usecs 00:00:00 UTC, Jan 1, 1970.  */
    7.62 -    u64                domain_time;     /* Domain virtual time, in nanosecs. */
    7.63 -    u64                wall_timeout;    /* 312 */
    7.64 -    u64                domain_timeout;  /* 320 */
    7.65 -    execution_context_t execution_context; /* 328 */
    7.66 -    arch_shared_info_t arch;
    7.67 -} PACKED shared_info_t;
    7.68 -
    7.69 -/* End of stuff which belongs in a Xen header */
    7.70 -
    7.71  
    7.72  struct list_head {
    7.73  	struct list_head *next, **pprev;