ia64/xen-unstable

changeset 2538:5ba3470963d4

bitkeeper revision 1.1159.1.170 (415423c9mNXXcoxG0hSTar31OX4ATQ)

Enable addings vbds to a running domain. Not completely working yet.
author mjw@wray-m-3.hpl.hp.com
date Fri Sep 24 13:40:25 2004 +0000 (2004-09-24)
parents 5e9765a83755
children ea88ad0fa2df
files linux-2.6.8.1-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/blkif.py xen/include/hypervisor-ifs/io/domain_controller.h
line diff
     1.1 --- a/linux-2.6.8.1-xen-sparse/arch/xen/kernel/reboot.c	Fri Sep 24 13:36:44 2004 +0000
     1.2 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/kernel/reboot.c	Fri Sep 24 13:40:25 2004 +0000
     1.3 @@ -64,11 +64,19 @@ static void __do_suspend(void)
     1.4  #ifdef CONFIG_XEN_BLKDEV_FRONTEND
     1.5      extern void blkdev_suspend(void);
     1.6      extern void blkdev_resume(void);
     1.7 +#else
     1.8 +#define blkdev_suspend() do{}while(0)
     1.9 +#define blkdev_resume()  do{}while(0)
    1.10  #endif
    1.11 +
    1.12  #ifdef CONFIG_XEN_NETDEV_FRONTEND
    1.13      extern void netif_suspend(void);
    1.14 -    extern void netif_resume(void);    
    1.15 +    extern void netif_resume(void);  
    1.16 +#else
    1.17 +#define netif_suspend() do{}while(0)
    1.18 +#define netif_resume()  do{}while(0)
    1.19  #endif
    1.20 +
    1.21      extern void time_suspend(void);
    1.22      extern void time_resume(void);
    1.23      extern unsigned long max_pfn;
    1.24 @@ -82,13 +90,9 @@ static void __do_suspend(void)
    1.25  
    1.26      __cli();
    1.27  
    1.28 -#ifdef CONFIG_XEN_NETDEV_FRONTEND
    1.29      netif_suspend();
    1.30 -#endif
    1.31  
    1.32 -#ifdef CONFIG_XEN_BLKDEV_FRONTEND
    1.33      blkdev_suspend();
    1.34 -#endif
    1.35  
    1.36      time_suspend();
    1.37  
    1.38 @@ -139,13 +143,9 @@ static void __do_suspend(void)
    1.39  
    1.40      time_resume();
    1.41  
    1.42 -#ifdef CONFIG_XEN_BLKDEV_FRONTEND
    1.43      blkdev_resume();
    1.44 -#endif
    1.45  
    1.46 -#ifdef CONFIG_XEN_NETDEV_FRONTEND
    1.47      netif_resume();
    1.48 -#endif
    1.49  
    1.50      __sti();
    1.51  
     2.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 24 13:36:44 2004 +0000
     2.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 24 13:40:25 2004 +0000
     2.3 @@ -26,16 +26,48 @@
     2.4  
     2.5  typedef unsigned char byte; /* from linux/ide.h */
     2.6  
     2.7 +/* Control whether runtime update of vbds is enabled. */
     2.8 +#define ENABLE_VBD_UPDATE 1
     2.9 +
    2.10 +#if ENABLE_VBD_UPDATE
    2.11 +static void vbd_update(void);
    2.12 +#else
    2.13 +static void vbd_update(void){};
    2.14 +#endif
    2.15 +
    2.16  #define BLKIF_STATE_CLOSED       0
    2.17  #define BLKIF_STATE_DISCONNECTED 1
    2.18  #define BLKIF_STATE_CONNECTED    2
    2.19 +
    2.20 +static char *blkif_state_name[] = {
    2.21 +    [BLKIF_STATE_CLOSED]       = "closed",
    2.22 +    [BLKIF_STATE_DISCONNECTED] = "disconnected",
    2.23 +    [BLKIF_STATE_CONNECTED]    = "connected",
    2.24 +};
    2.25 +
    2.26 +static char * blkif_status_name[] = {
    2.27 +    [BLKIF_INTERFACE_STATUS_CLOSED]       = "closed",
    2.28 +    [BLKIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
    2.29 +    [BLKIF_INTERFACE_STATUS_CONNECTED]    = "connected",
    2.30 +    [BLKIF_INTERFACE_STATUS_CHANGED]      = "changed",
    2.31 +};
    2.32 +
    2.33 +#if 1
    2.34 +#define dprintf(fmt, args...) \
    2.35 +printk(KERN_ALERT "[XEN:%s:%s:%d] " fmt, __FUNCTION__, __FILE__, __LINE__, ##args)
    2.36 +#endif
    2.37 +
    2.38 +#define WPRINTK(fmt, args...) printk(KERN_WARNING "[XEN] " fmt, ##args)
    2.39 +
    2.40 +static int blkif_handle = 0;
    2.41  static unsigned int blkif_state = BLKIF_STATE_CLOSED;
    2.42 -static unsigned int blkif_evtchn, blkif_irq;
    2.43 +static unsigned int blkif_evtchn = 0;
    2.44 +static unsigned int blkif_irq = 0;
    2.45  
    2.46  static int blkif_control_rsp_valid;
    2.47  static blkif_response_t blkif_control_rsp;
    2.48  
    2.49 -static blkif_ring_t *blk_ring;
    2.50 +static blkif_ring_t *blk_ring = NULL;
    2.51  static BLKIF_RING_IDX resp_cons; /* Response consumer for comms ring. */
    2.52  static BLKIF_RING_IDX req_prod;  /* Private request producer.         */
    2.53  
    2.54 @@ -92,6 +124,13 @@ static inline void ADD_ID_TO_FREELIST( u
    2.55  
    2.56  __initcall(xlblk_init);
    2.57  
    2.58 +#if ENABLE_VBD_UPDATE
    2.59 +static void vbd_update()
    2.60 +{
    2.61 +    dprintf(">\n");
    2.62 +    dprintf("<\n");
    2.63 +}
    2.64 +#endif /* ENABLE_VBD_UPDATE */
    2.65  
    2.66  static void kick_pending_request_queues(void)
    2.67  {
    2.68 @@ -131,10 +170,7 @@ int blkif_release(struct inode *inode, s
    2.69       * Update of usage count is protected by a per-device semaphore.
    2.70       */
    2.71      if (--di->mi->usage == 0) {
    2.72 -#if 0
    2.73 -        update_tq.routine = update_vbds_task;
    2.74 -        schedule_task(&update_tq);
    2.75 -#endif
    2.76 +        vbd_update();
    2.77      }
    2.78  
    2.79      return 0;
    2.80 @@ -415,19 +451,31 @@ static int nr_pending;
    2.81  
    2.82  #define blkif_io_lock io_request_lock
    2.83  
    2.84 +/*============================================================================*/
    2.85 +#if ENABLE_VBD_UPDATE
    2.86 +
    2.87  /*
    2.88   * blkif_update_int/update-vbds_task - handle VBD update events.
    2.89   *  Schedule a task for keventd to run, which will update the VBDs and perform 
    2.90   *  the corresponding updates to our view of VBD state.
    2.91   */
    2.92 -
    2.93 -#if 0
    2.94 -static struct tq_struct update_tq;
    2.95  static void update_vbds_task(void *unused)
    2.96  { 
    2.97      xlvbd_update_vbds();
    2.98  }
    2.99 -#endif
   2.100 +
   2.101 +static void vbd_update(void)
   2.102 +{
   2.103 +    static struct tq_struct update_tq;
   2.104 +    dprintf(">\n");
   2.105 +    update_tq.routine = update_vbds_task;
   2.106 +    schedule_task(&update_tq);
   2.107 +    dprintf("<\n");
   2.108 +}
   2.109 +
   2.110 +#endif /* ENABLE_VBD_UPDATE */
   2.111 +/*============================================================================*/
   2.112 +
   2.113  
   2.114  static void kick_pending_request_queues(void)
   2.115  {
   2.116 @@ -490,12 +538,8 @@ int blkif_release(struct inode *inode, s
   2.117       * When usage drops to zero it may allow more VBD updates to occur.
   2.118       * Update of usage count is protected by a per-device semaphore.
   2.119       */
   2.120 -    if ( --disk->usage == 0 )
   2.121 -    {
   2.122 -#if 0
   2.123 -        update_tq.routine = update_vbds_task;
   2.124 -        schedule_task(&update_tq);
   2.125 -#endif
   2.126 +    if ( --disk->usage == 0 ) {
   2.127 +        vbd_update();
   2.128      }
   2.129  
   2.130      return 0;
   2.131 @@ -937,8 +981,9 @@ static inline void translate_req_to_pfn(
   2.132      /* preserve id */
   2.133      xreq->sector_number = req->sector_number;
   2.134  
   2.135 -    for ( i = 0; i < req->nr_segments; i++ )
   2.136 +    for ( i = 0; i < req->nr_segments; i++ ){
   2.137          xreq->frame_and_sects[i] = machine_to_phys(req->frame_and_sects[i]);
   2.138 +    }
   2.139  }
   2.140  
   2.141  static inline void translate_req_to_mfn(blkif_request_t *xreq,
   2.142 @@ -952,8 +997,9 @@ static inline void translate_req_to_mfn(
   2.143      xreq->id            = req->id;   /* copy id (unlike above) */
   2.144      xreq->sector_number = req->sector_number;
   2.145  
   2.146 -    for ( i = 0; i < req->nr_segments; i++ )
   2.147 +    for ( i = 0; i < req->nr_segments; i++ ){
   2.148          xreq->frame_and_sects[i] = phys_to_machine(req->frame_and_sects[i]);
   2.149 +    }
   2.150  }
   2.151  
   2.152  
   2.153 @@ -1010,153 +1056,230 @@ void blkif_control_send(blkif_request_t 
   2.154  }
   2.155  
   2.156  
   2.157 -static void blkif_status_change(blkif_fe_interface_status_t *status)
   2.158 +/* Send a driver status notification to the domain controller. */
   2.159 +static void send_driver_status(int ok){
   2.160 +    ctrl_msg_t cmsg = {
   2.161 +        .type    = CMSG_BLKIF_FE,
   2.162 +        .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
   2.163 +        .length  = sizeof(blkif_fe_driver_status_t),
   2.164 +    };
   2.165 +    blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
   2.166 +    
   2.167 +    msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
   2.168 +
   2.169 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   2.170 +}
   2.171 +
   2.172 +/* Tell the controller to bring up the interface. */
   2.173 +static void blkif_send_interface_connect(void){
   2.174 +    ctrl_msg_t cmsg = {
   2.175 +        .type    = CMSG_BLKIF_FE,
   2.176 +        .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
   2.177 +        .length  = sizeof(blkif_fe_interface_connect_t),
   2.178 +    };
   2.179 +    blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   2.180 +    
   2.181 +    msg->handle      = 0;
   2.182 +    msg->shmem_frame = (virt_to_machine(blk_ring) >> PAGE_SHIFT);
   2.183 +    
   2.184 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   2.185 +}
   2.186 +
   2.187 +static void blkif_free(void)
   2.188  {
   2.189 -    ctrl_msg_t                   cmsg;
   2.190 -    blkif_fe_interface_connect_t up;
   2.191 -    long rc;
   2.192 +
   2.193 +    printk(KERN_INFO "[XEN] Recovering virtual block device driver\n");
   2.194 +            
   2.195 +    /* Prevent new requests being issued until we fix things up. */
   2.196 +    spin_lock_irq(&blkif_io_lock);
   2.197 +    recovery = 1;
   2.198 +    blkif_state = BLKIF_STATE_DISCONNECTED;
   2.199 +    spin_unlock_irq(&blkif_io_lock);
   2.200 +
   2.201 +    /* Free resources associated with old device channel. */
   2.202 +    if(blk_ring){
   2.203 +        free_page((unsigned long)blk_ring);
   2.204 +        blk_ring = 0;
   2.205 +    }
   2.206 +    free_irq(blkif_irq, NULL);
   2.207 +    blkif_irq = 0;
   2.208 +    
   2.209 +    unbind_evtchn_from_irq(blkif_evtchn);
   2.210 +    blkif_evtchn = 0;
   2.211 +}
   2.212 +
   2.213 +static void blkif_close(void){
   2.214 +}
   2.215 +
   2.216 +/* Move from CLOSED to DISCONNECTED state. */
   2.217 +static void blkif_disconnect(void)
   2.218 +{
   2.219 +    if(blk_ring) free_page((unsigned long)blk_ring);
   2.220 +    blk_ring = (blkif_ring_t *)__get_free_page(GFP_KERNEL);
   2.221 +    blk_ring->req_prod = blk_ring->resp_prod = resp_cons = req_prod = 0;
   2.222 +    blkif_state  = BLKIF_STATE_DISCONNECTED;
   2.223 +    blkif_send_interface_connect();
   2.224 +}
   2.225 +
   2.226 +static void blkif_reset(void)
   2.227 +{
   2.228 +    printk(KERN_INFO "[XEN] Recovering virtual block device driver\n");
   2.229 +    blkif_free();
   2.230 +    blkif_disconnect();
   2.231 +}
   2.232 +
   2.233 +static void blkif_recover(void)
   2.234 +{
   2.235 +
   2.236 +    int i;
   2.237 +
   2.238 +    /* Hmm, requests might be re-ordered when we re-issue them.
   2.239 +     * This will need to be fixed once we have barriers */
   2.240 +
   2.241 +    /* Stage 1 : Find active and move to safety. */
   2.242 +    for ( i = 0; i < BLKIF_RING_SIZE; i++ ) {
   2.243 +        if ( rec_ring[i].id >= PAGE_OFFSET ) {
   2.244 +            translate_req_to_mfn(
   2.245 +                &blk_ring->ring[req_prod].req, &rec_ring[i]);
   2.246 +            req_prod++;
   2.247 +        }
   2.248 +    }
   2.249  
   2.250 -/*     if ( status->handle != 0 ) */
   2.251 -/*     { */
   2.252 -/*         printk(KERN_WARNING "Status change on unsupported blkif %d\n", */
   2.253 -/*                status->handle); */
   2.254 -/*         return; */
   2.255 -/*     } */
   2.256 +    printk(KERN_ALERT"blkfront: recovered %d descriptors\n",req_prod);
   2.257 +	    
   2.258 +    /* Stage 2 : Set up shadow list. */
   2.259 +    for ( i = 0; i < req_prod; i++ ) {
   2.260 +        rec_ring[i].id = blk_ring->ring[i].req.id;		
   2.261 +        blk_ring->ring[i].req.id = i;
   2.262 +        translate_req_to_pfn(&rec_ring[i], &blk_ring->ring[i].req);
   2.263 +    }
   2.264 +
   2.265 +    /* Stage 3 : Set up free list. */
   2.266 +    for ( ; i < BLKIF_RING_SIZE; i++ ){
   2.267 +        rec_ring[i].id = i+1;
   2.268 +    }
   2.269 +    rec_ring_free = req_prod;
   2.270 +    rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff;
   2.271 +
   2.272 +    /* blk_ring->req_prod will be set when we flush_requests().*/
   2.273 +    wmb();
   2.274 +
   2.275 +    /* Switch off recovery mode, using a memory barrier to ensure that
   2.276 +     * it's seen before we flush requests - we don't want to miss any
   2.277 +     * interrupts. */
   2.278 +    recovery = 0;
   2.279 +    wmb();
   2.280 +
   2.281 +    /* Kicks things back into life. */
   2.282 +    flush_requests();
   2.283 +
   2.284 +    /* Now safe to left other peope use interface. */
   2.285 +    blkif_state = BLKIF_STATE_CONNECTED;
   2.286 +}
   2.287 +
   2.288 +static void blkif_connect(blkif_fe_interface_status_t *status)
   2.289 +{
   2.290 +    int err = 0;
   2.291 +
   2.292 +    blkif_evtchn = status->evtchn;
   2.293 +    blkif_irq    = bind_evtchn_to_irq(blkif_evtchn);
   2.294 +
   2.295 +    err = request_irq(blkif_irq, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
   2.296 +    if(err){
   2.297 +        printk(KERN_ALERT "[XEN] blkfront request_irq failed (err=%d)\n", err);
   2.298 +        return;
   2.299 +    }
   2.300  
   2.301 -    switch ( status->status )
   2.302 -    {
   2.303 +    if ( recovery ) {
   2.304 +        blkif_recover();
   2.305 +    } else {
   2.306 +        /* Transition to connected in case we need to do 
   2.307 +         *  a partition probe on a whole disk. */
   2.308 +        blkif_state = BLKIF_STATE_CONNECTED;
   2.309 +        
   2.310 +        /* Probe for discs attached to the interface. */
   2.311 +        xlvbd_init();
   2.312 +    }
   2.313 +    
   2.314 +    /* Kick pending requests. */
   2.315 +    spin_lock_irq(&blkif_io_lock);
   2.316 +    kick_pending_request_queues();
   2.317 +    spin_unlock_irq(&blkif_io_lock);
   2.318 +}
   2.319 +
   2.320 +static void unexpected(blkif_fe_interface_status_t *status)
   2.321 +{
   2.322 +    WPRINTK(" Unexpected blkif status %s in state %s\n", 
   2.323 +           blkif_status_name[status->status],
   2.324 +           blkif_state_name[blkif_state]);
   2.325 +}
   2.326 +
   2.327 +static void blkif_status(blkif_fe_interface_status_t *status)
   2.328 +{
   2.329 +    if (status->handle != blkif_handle) {
   2.330 +        WPRINTK(" Invalid blkif: handle=%u", status->handle);
   2.331 +        return;
   2.332 +    }
   2.333 +
   2.334 +    switch (status->status) {
   2.335 +
   2.336      case BLKIF_INTERFACE_STATUS_CLOSED:
   2.337 -        printk(KERN_WARNING "Unexpected blkif-CLOSED message in state %d\n",
   2.338 -               blkif_state);
   2.339 +        switch(blkif_state){
   2.340 +        case BLKIF_STATE_CLOSED:
   2.341 +            unexpected(status);
   2.342 +            break;
   2.343 +        case BLKIF_STATE_DISCONNECTED:
   2.344 +        case BLKIF_STATE_CONNECTED:
   2.345 +            unexpected(status);
   2.346 +            blkif_close();
   2.347 +            break;
   2.348 +        }
   2.349          break;
   2.350  
   2.351      case BLKIF_INTERFACE_STATUS_DISCONNECTED:
   2.352 -        if ( blkif_state != BLKIF_STATE_CLOSED )
   2.353 -        {
   2.354 -            printk(KERN_WARNING "Unexpected blkif-DISCONNECTED message"
   2.355 -                   " in state %d\n", blkif_state);
   2.356 -
   2.357 -            printk(KERN_INFO "VBD driver recovery in progress\n");
   2.358 -            
   2.359 -            /* Prevent new requests being issued until we fix things up. */
   2.360 -            spin_lock_irq(&blkif_io_lock);
   2.361 -            recovery = 1;
   2.362 -            blkif_state = BLKIF_STATE_DISCONNECTED;
   2.363 -            spin_unlock_irq(&blkif_io_lock);
   2.364 -
   2.365 -            /* Free resources associated with old device channel. */
   2.366 -            free_page((unsigned long)blk_ring);
   2.367 -            free_irq(blkif_irq, NULL);
   2.368 -            unbind_evtchn_from_irq(blkif_evtchn);
   2.369 +        switch(blkif_state){
   2.370 +        case BLKIF_STATE_CLOSED:
   2.371 +            blkif_disconnect();
   2.372 +            break;
   2.373 +        case BLKIF_STATE_DISCONNECTED:
   2.374 +        case BLKIF_STATE_CONNECTED:
   2.375 +            unexpected(status);
   2.376 +            blkif_reset();
   2.377 +            break;
   2.378          }
   2.379 -
   2.380 -        /* Move from CLOSED to DISCONNECTED state. */
   2.381 -        blk_ring = (blkif_ring_t *)__get_free_page(GFP_KERNEL);
   2.382 -        blk_ring->req_prod = blk_ring->resp_prod = resp_cons = req_prod = 0;
   2.383 -        blkif_state  = BLKIF_STATE_DISCONNECTED;
   2.384 -
   2.385 -        /* Construct an interface-CONNECT message for the domain controller. */
   2.386 -        cmsg.type      = CMSG_BLKIF_FE;
   2.387 -        cmsg.subtype   = CMSG_BLKIF_FE_INTERFACE_CONNECT;
   2.388 -        cmsg.length    = sizeof(blkif_fe_interface_connect_t);
   2.389 -        up.handle      = 0;
   2.390 -        up.shmem_frame = virt_to_machine(blk_ring) >> PAGE_SHIFT;
   2.391 -        memcpy(cmsg.msg, &up, sizeof(up));
   2.392 -        
   2.393 -        /* Tell the controller to bring up the interface. */
   2.394 -        ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   2.395          break;
   2.396  
   2.397      case BLKIF_INTERFACE_STATUS_CONNECTED:
   2.398 -        if ( blkif_state == BLKIF_STATE_CLOSED )
   2.399 -        {
   2.400 -            printk(KERN_WARNING "Unexpected blkif-CONNECTED message"
   2.401 -                   " in state %d\n", blkif_state);
   2.402 +        switch(blkif_state){
   2.403 +        case BLKIF_STATE_CLOSED:
   2.404 +            unexpected(status);
   2.405 +            blkif_disconnect();
   2.406 +            blkif_connect(status);
   2.407 +            break;
   2.408 +        case BLKIF_STATE_DISCONNECTED:
   2.409 +            blkif_connect(status);
   2.410 +            break;
   2.411 +        case BLKIF_STATE_CONNECTED:
   2.412 +            unexpected(status);
   2.413 +            blkif_connect(status);
   2.414              break;
   2.415          }
   2.416 -
   2.417 -        blkif_evtchn = status->evtchn;
   2.418 -        blkif_irq    = bind_evtchn_to_irq(blkif_evtchn);
   2.419 -
   2.420 -        if ( (rc = request_irq(blkif_irq, blkif_int, 
   2.421 -                               SA_SAMPLE_RANDOM, "blkif", NULL)) )
   2.422 -	    printk(KERN_ALERT"blkfront request_irq failed (%ld)\n",rc);
   2.423 -
   2.424 -        if ( recovery )
   2.425 -        {
   2.426 -	    int i;
   2.427 -
   2.428 -	    /* Hmm, requests might be re-ordered when we re-issue them.
   2.429 -	       This will need to be fixed once we have barriers */
   2.430 -
   2.431 -	    /* Stage 1 : Find active and move to safety. */
   2.432 -	    for ( i = 0; i < BLKIF_RING_SIZE; i++ )
   2.433 -	    {
   2.434 -		if ( rec_ring[i].id >= PAGE_OFFSET )
   2.435 -		{
   2.436 -		    translate_req_to_mfn(
   2.437 -			&blk_ring->ring[req_prod].req, &rec_ring[i]);
   2.438 -		    req_prod++;
   2.439 -		}
   2.440 -	    }
   2.441 -
   2.442 -            printk(KERN_ALERT"blkfront: recovered %d descriptors\n",req_prod);
   2.443 -	    
   2.444 -            /* Stage 2 : Set up shadow list. */
   2.445 -	    for ( i = 0; i < req_prod; i++ )
   2.446 -	    {
   2.447 -		rec_ring[i].id = blk_ring->ring[i].req.id;		
   2.448 -		blk_ring->ring[i].req.id = i;
   2.449 -		translate_req_to_pfn(&rec_ring[i], &blk_ring->ring[i].req);
   2.450 -	    }
   2.451 -
   2.452 -	    /* Stage 3 : Set up free list. */
   2.453 -	    for ( ; i < BLKIF_RING_SIZE; i++ )
   2.454 -		rec_ring[i].id = i+1;
   2.455 -	    rec_ring_free = req_prod;
   2.456 -	    rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff;
   2.457 -
   2.458 -            /* blk_ring->req_prod will be set when we flush_requests().*/
   2.459 -            wmb();
   2.460 -
   2.461 -            /* Switch off recovery mode, using a memory barrier to ensure that
   2.462 -             * it's seen before we flush requests - we don't want to miss any
   2.463 -             * interrupts. */
   2.464 -            recovery = 0;
   2.465 -            wmb();
   2.466 -
   2.467 -            /* Kicks things back into life. */
   2.468 -            flush_requests();
   2.469 -
   2.470 -	    /* Now safe to left other peope use interface */
   2.471 -	    blkif_state = BLKIF_STATE_CONNECTED;
   2.472 -        }
   2.473 -        else
   2.474 -        {
   2.475 -	    /* transtion to connected in case we need to do a 
   2.476 -	       a partion probe on a whole disk */
   2.477 -	    blkif_state = BLKIF_STATE_CONNECTED;
   2.478 -
   2.479 -            /* Probe for discs that are attached to the interface. */
   2.480 -            xlvbd_init();
   2.481 -        }
   2.482 -        
   2.483 -        /* Kick pending requests. */
   2.484 -        spin_lock_irq(&blkif_io_lock);
   2.485 -        kick_pending_request_queues();
   2.486 -        spin_unlock_irq(&blkif_io_lock);
   2.487 -
   2.488          break;
   2.489  
   2.490 -//    case BLKIF_INTERFACE_STATUS_CHANGED:
   2.491 -//        /* The domain controller is notifying us that a device has been
   2.492 -//        * added or removed.
   2.493 -//        */
   2.494 -//        break;
   2.495 +   case BLKIF_INTERFACE_STATUS_CHANGED:
   2.496 +        switch(blkif_state){
   2.497 +        case BLKIF_STATE_CLOSED:
   2.498 +        case BLKIF_STATE_DISCONNECTED:
   2.499 +            unexpected(status);
   2.500 +            break;
   2.501 +        case BLKIF_STATE_CONNECTED:
   2.502 +            vbd_update();
   2.503 +            break;
   2.504 +        }
   2.505 +       break;
   2.506  
   2.507      default:
   2.508 -        printk(KERN_WARNING "Status change to unknown value %d\n", 
   2.509 -               status->status);
   2.510 +        WPRINTK(" Invalid blkif status: %d\n", status->status);
   2.511          break;
   2.512      }
   2.513  }
   2.514 @@ -1169,15 +1292,9 @@ static void blkif_ctrlif_rx(ctrl_msg_t *
   2.515      case CMSG_BLKIF_FE_INTERFACE_STATUS:
   2.516          if ( msg->length != sizeof(blkif_fe_interface_status_t) )
   2.517              goto parse_error;
   2.518 -        blkif_status_change((blkif_fe_interface_status_t *)
   2.519 -                            &msg->msg[0]);
   2.520 +        blkif_status((blkif_fe_interface_status_t *)
   2.521 +                     &msg->msg[0]);
   2.522          break;        
   2.523 -#if 0
   2.524 -    case CMSG_BLKIF_FE_VBD_STATUS:
   2.525 -        update_tq.routine = update_vbds_task;
   2.526 -        schedule_task(&update_tq);
   2.527 -        break;
   2.528 -#endif
   2.529      default:
   2.530          goto parse_error;
   2.531      }
   2.532 @@ -1190,36 +1307,10 @@ static void blkif_ctrlif_rx(ctrl_msg_t *
   2.533      ctrl_if_send_response(msg);
   2.534  }
   2.535  
   2.536 -
   2.537 -int __init xlblk_init(void)
   2.538 -{
   2.539 -    ctrl_msg_t                       cmsg;
   2.540 -    blkif_fe_driver_status_t st;
   2.541 +int wait_for_blkif(void){
   2.542 +    int err = 0;
   2.543      int i;
   2.544 -    
   2.545 -    if ( (start_info.flags & SIF_INITDOMAIN) 
   2.546 -         || (start_info.flags & SIF_BLK_BE_DOMAIN) )
   2.547 -        return 0;
   2.548 -
   2.549 -    printk(KERN_INFO "Initialising Xen virtual block device\n");
   2.550 -
   2.551 -    rec_ring_free = 0;
   2.552 -    for (i=0; i<BLKIF_RING_SIZE; i++)
   2.553 -    {
   2.554 -	rec_ring[i].id = i+1;
   2.555 -    }
   2.556 -    rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff;
   2.557 -
   2.558 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
   2.559 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
   2.560 -
   2.561 -    /* Send a driver-UP notification to the domain controller. */
   2.562 -    cmsg.type      = CMSG_BLKIF_FE;
   2.563 -    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS;
   2.564 -    cmsg.length    = sizeof(blkif_fe_driver_status_t);
   2.565 -    st.status      = BLKIF_DRIVER_STATUS_UP;
   2.566 -    memcpy(cmsg.msg, &st, sizeof(st));
   2.567 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   2.568 +    send_driver_status(1);
   2.569  
   2.570      /*
   2.571       * We should read 'nr_interfaces' from response message and wait
   2.572 @@ -1232,8 +1323,34 @@ int __init xlblk_init(void)
   2.573          schedule_timeout(1);
   2.574      }
   2.575  
   2.576 -    if (blkif_state != BLKIF_STATE_CONNECTED)
   2.577 -        printk(KERN_INFO "Timeout connecting block device driver!\n");
   2.578 +    if (blkif_state != BLKIF_STATE_CONNECTED){
   2.579 +        printk(KERN_INFO "[XEN] Timeout connecting block device driver!\n");
   2.580 +        err = -ENOSYS;
   2.581 +    }
   2.582 +    return err;
   2.583 +}
   2.584 +
   2.585 +int __init xlblk_init(void)
   2.586 +{
   2.587 +    int i;
   2.588 +    
   2.589 +    if ( (start_info.flags & SIF_INITDOMAIN) 
   2.590 +         || (start_info.flags & SIF_BLK_BE_DOMAIN) )
   2.591 +        return 0;
   2.592 +
   2.593 +    printk(KERN_INFO "[XEN] Initialising virtual block device driver\n");
   2.594 +
   2.595 +    rec_ring_free = 0;
   2.596 +    for (i=0; i<BLKIF_RING_SIZE; i++)
   2.597 +    {
   2.598 +	rec_ring[i].id = i+1;
   2.599 +    }
   2.600 +    rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff;
   2.601 +
   2.602 +    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
   2.603 +                                    CALLBACK_IN_BLOCKING_CONTEXT);
   2.604 +
   2.605 +    wait_for_blkif();
   2.606  
   2.607      return 0;
   2.608  }
   2.609 @@ -1244,16 +1361,7 @@ void blkdev_suspend(void)
   2.610  
   2.611  void blkdev_resume(void)
   2.612  {
   2.613 -    ctrl_msg_t                       cmsg;
   2.614 -    blkif_fe_driver_status_t st;    
   2.615 -
   2.616 -    /* Send a driver-UP notification to the domain controller. */
   2.617 -    cmsg.type      = CMSG_BLKIF_FE;
   2.618 -    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS;
   2.619 -    cmsg.length    = sizeof(blkif_fe_driver_status_t);
   2.620 -    st.status      = BLKIF_DRIVER_STATUS_UP;
   2.621 -    memcpy(cmsg.msg, &st, sizeof(st));
   2.622 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   2.623 +    send_driver_status(1);
   2.624  }
   2.625  
   2.626  /* XXXXX THIS IS A TEMPORARY FUNCTION UNTIL WE GET GRANT TABLES */
   2.627 @@ -1275,5 +1383,3 @@ void blkif_completion(blkif_request_t *r
   2.628      }
   2.629      
   2.630  }
   2.631 -
   2.632 -
     3.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 24 13:36:44 2004 +0000
     3.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 24 13:40:25 2004 +0000
     3.3 @@ -128,20 +128,20 @@ struct net_private
     3.4      struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
     3.5  };
     3.6  
     3.7 -static char * status_name[] = {
     3.8 +char * status_name[] = {
     3.9      [NETIF_INTERFACE_STATUS_CLOSED]       = "closed",
    3.10      [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
    3.11      [NETIF_INTERFACE_STATUS_CONNECTED]    = "connected",
    3.12      [NETIF_INTERFACE_STATUS_CHANGED]      = "changed",
    3.13  };
    3.14  
    3.15 -static char * be_state_name[] = {
    3.16 +char * be_state_name[] = {
    3.17      [BEST_CLOSED]       = "closed",
    3.18      [BEST_DISCONNECTED] = "disconnected",
    3.19      [BEST_CONNECTED]    = "connected",
    3.20  };
    3.21  
    3.22 -static char * user_state_name[] = {
    3.23 +char * user_state_name[] = {
    3.24      [UST_CLOSED] = "closed",
    3.25      [UST_OPEN]   = "open",
    3.26  };
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Sep 24 13:36:44 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Sep 24 13:40:25 2004 +0000
     4.3 @@ -824,6 +824,9 @@ class XendDomainInfo:
     4.4          dev_index = len(devs)
     4.5          self.config.append(['device', dev_config])
     4.6          d = dev_handler(self, dev_config, dev_index, change=1)
     4.7 +        def cbok(dev):
     4.8 +            return dev.sxpr()
     4.9 +        d.addCallback(cbok)
    4.10          return d
    4.11  
    4.12      def device_configure(self, dev_config, idx):
     5.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Sep 24 13:36:44 2004 +0000
     5.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Sep 24 13:40:25 2004 +0000
     5.3 @@ -153,7 +153,7 @@ class BlkifBackendInterface(controller.B
     5.4          """
     5.5          msg = packMsg('blkif_fe_interface_status_t',
     5.6                        { 'handle' : self.handle,
     5.7 -                        'status' : BLKIF_INTERFACE_STATUS,
     5.8 +                        'status' : BLKIF_INTERFACE_STATUS_CHANGED,
     5.9                          'domid'  : self.dom,
    5.10                          'evtchn' : 0 })
    5.11          self.controller.writeRequest(msg)
     6.1 --- a/xen/include/hypervisor-ifs/io/domain_controller.h	Fri Sep 24 13:36:44 2004 +0000
     6.2 +++ b/xen/include/hypervisor-ifs/io/domain_controller.h	Fri Sep 24 13:40:25 2004 +0000
     6.3 @@ -93,7 +93,7 @@ typedef struct {
     6.4  #define BLKIF_INTERFACE_STATUS_CLOSED       0 /* Interface doesn't exist.    */
     6.5  #define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
     6.6  #define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
     6.7 -//#define BLKIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
     6.8 +#define BLKIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
     6.9  typedef struct {
    6.10      u32 handle; /*  0 */
    6.11      u32 status; /*  4 */