direct-io.hg

changeset 2520:1c1f4aac700c

bitkeeper revision 1.1159.82.1 (4152d2abNRTmjgcJM5fkbYQyAoi9pA)

Change device messaging to support adding netifs at runtime,
and to support front-end polling.
author mjw@wray-m-3.hpl.hp.com
date Thu Sep 23 13:42:03 2004 +0000 (2004-09-23)
parents f7b2e90dac20
children acee0d04bc60
files linux-2.6.8.1-xen-sparse/drivers/xen/blkback/control.c linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6.8.1-xen-sparse/drivers/xen/netback/control.c linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py xen/include/hypervisor-ifs/io/domain_controller.h
line diff
     1.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/blkback/control.c	Wed Sep 22 11:02:20 2004 +0000
     1.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/blkback/control.c	Thu Sep 23 13:42:03 2004 +0000
     1.3 @@ -71,16 +71,16 @@ static void blkif_ctrlif_rx(ctrl_msg_t *
     1.4  
     1.5  void blkif_ctrlif_init(void)
     1.6  {
     1.7 -    ctrl_msg_t                       cmsg;
     1.8 -    blkif_be_driver_status_changed_t st;
     1.9 +    ctrl_msg_t cmsg;
    1.10 +    blkif_be_driver_status_t st;
    1.11  
    1.12      (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
    1.13                                      CALLBACK_IN_BLOCKING_CONTEXT);
    1.14  
    1.15      /* Send a driver-UP notification to the domain controller. */
    1.16      cmsg.type      = CMSG_BLKIF_BE;
    1.17 -    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED;
    1.18 -    cmsg.length    = sizeof(blkif_be_driver_status_changed_t);
    1.19 +    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS;
    1.20 +    cmsg.length    = sizeof(blkif_be_driver_status_t);
    1.21      st.status      = BLKIF_DRIVER_STATUS_UP;
    1.22      memcpy(cmsg.msg, &st, sizeof(st));
    1.23      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
     2.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Sep 22 11:02:20 2004 +0000
     2.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c	Thu Sep 23 13:42:03 2004 +0000
     2.3 @@ -1010,23 +1010,23 @@ void blkif_control_send(blkif_request_t 
     2.4  }
     2.5  
     2.6  
     2.7 -static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
     2.8 +static void blkif_status_change(blkif_fe_interface_status_t *status)
     2.9  {
    2.10      ctrl_msg_t                   cmsg;
    2.11      blkif_fe_interface_connect_t up;
    2.12      long rc;
    2.13  
    2.14 -    if ( status->handle != 0 )
    2.15 -    {
    2.16 -        printk(KERN_WARNING "Status change on unsupported blkif %d\n",
    2.17 -               status->handle);
    2.18 -        return;
    2.19 -    }
    2.20 +/*     if ( status->handle != 0 ) */
    2.21 +/*     { */
    2.22 +/*         printk(KERN_WARNING "Status change on unsupported blkif %d\n", */
    2.23 +/*                status->handle); */
    2.24 +/*         return; */
    2.25 +/*     } */
    2.26  
    2.27      switch ( status->status )
    2.28      {
    2.29 -    case BLKIF_INTERFACE_STATUS_DESTROYED:
    2.30 -        printk(KERN_WARNING "Unexpected blkif-DESTROYED message in state %d\n",
    2.31 +    case BLKIF_INTERFACE_STATUS_CLOSED:
    2.32 +        printk(KERN_WARNING "Unexpected blkif-CLOSED message in state %d\n",
    2.33                 blkif_state);
    2.34          break;
    2.35  
    2.36 @@ -1148,11 +1148,11 @@ static void blkif_status_change(blkif_fe
    2.37  
    2.38          break;
    2.39  
    2.40 -    case BLKIF_INTERFACE_STATUS_CHANGED:
    2.41 -        /* The domain controller is notifying us that a device has been
    2.42 -        * added or removed.
    2.43 -        */
    2.44 -        break;
    2.45 +//    case BLKIF_INTERFACE_STATUS_CHANGED:
    2.46 +//        /* The domain controller is notifying us that a device has been
    2.47 +//        * added or removed.
    2.48 +//        */
    2.49 +//        break;
    2.50  
    2.51      default:
    2.52          printk(KERN_WARNING "Status change to unknown value %d\n", 
    2.53 @@ -1166,14 +1166,14 @@ static void blkif_ctrlif_rx(ctrl_msg_t *
    2.54  {
    2.55      switch ( msg->subtype )
    2.56      {
    2.57 -    case CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
    2.58 -        if ( msg->length != sizeof(blkif_fe_interface_status_changed_t) )
    2.59 +    case CMSG_BLKIF_FE_INTERFACE_STATUS:
    2.60 +        if ( msg->length != sizeof(blkif_fe_interface_status_t) )
    2.61              goto parse_error;
    2.62 -        blkif_status_change((blkif_fe_interface_status_changed_t *)
    2.63 +        blkif_status_change((blkif_fe_interface_status_t *)
    2.64                              &msg->msg[0]);
    2.65          break;        
    2.66  #if 0
    2.67 -    case CMSG_BLKIF_FE_VBD_STATUS_CHANGED:
    2.68 +    case CMSG_BLKIF_FE_VBD_STATUS:
    2.69          update_tq.routine = update_vbds_task;
    2.70          schedule_task(&update_tq);
    2.71          break;
    2.72 @@ -1194,7 +1194,7 @@ static void blkif_ctrlif_rx(ctrl_msg_t *
    2.73  int __init xlblk_init(void)
    2.74  {
    2.75      ctrl_msg_t                       cmsg;
    2.76 -    blkif_fe_driver_status_changed_t st;
    2.77 +    blkif_fe_driver_status_t st;
    2.78      int i;
    2.79      
    2.80      if ( (start_info.flags & SIF_INITDOMAIN) 
    2.81 @@ -1215,8 +1215,8 @@ int __init xlblk_init(void)
    2.82  
    2.83      /* Send a driver-UP notification to the domain controller. */
    2.84      cmsg.type      = CMSG_BLKIF_FE;
    2.85 -    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
    2.86 -    cmsg.length    = sizeof(blkif_fe_driver_status_changed_t);
    2.87 +    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS;
    2.88 +    cmsg.length    = sizeof(blkif_fe_driver_status_t);
    2.89      st.status      = BLKIF_DRIVER_STATUS_UP;
    2.90      memcpy(cmsg.msg, &st, sizeof(st));
    2.91      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    2.92 @@ -1245,12 +1245,12 @@ void blkdev_suspend(void)
    2.93  void blkdev_resume(void)
    2.94  {
    2.95      ctrl_msg_t                       cmsg;
    2.96 -    blkif_fe_driver_status_changed_t st;    
    2.97 +    blkif_fe_driver_status_t st;    
    2.98  
    2.99      /* Send a driver-UP notification to the domain controller. */
   2.100      cmsg.type      = CMSG_BLKIF_FE;
   2.101 -    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
   2.102 -    cmsg.length    = sizeof(blkif_fe_driver_status_changed_t);
   2.103 +    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS;
   2.104 +    cmsg.length    = sizeof(blkif_fe_driver_status_t);
   2.105      st.status      = BLKIF_DRIVER_STATUS_UP;
   2.106      memcpy(cmsg.msg, &st, sizeof(st));
   2.107      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
     3.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netback/control.c	Wed Sep 22 11:02:20 2004 +0000
     3.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netback/control.c	Thu Sep 23 13:42:03 2004 +0000
     3.3 @@ -49,16 +49,16 @@ static void netif_ctrlif_rx(ctrl_msg_t *
     3.4  
     3.5  void netif_ctrlif_init(void)
     3.6  {
     3.7 -    ctrl_msg_t                       cmsg;
     3.8 -    netif_be_driver_status_changed_t st;
     3.9 +    ctrl_msg_t cmsg;
    3.10 +    netif_be_driver_status_t st;
    3.11  
    3.12      (void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx,
    3.13                                      CALLBACK_IN_BLOCKING_CONTEXT);
    3.14  
    3.15      /* Send a driver-UP notification to the domain controller. */
    3.16      cmsg.type      = CMSG_NETIF_BE;
    3.17 -    cmsg.subtype   = CMSG_NETIF_BE_DRIVER_STATUS_CHANGED;
    3.18 -    cmsg.length    = sizeof(netif_be_driver_status_changed_t);
    3.19 +    cmsg.subtype   = CMSG_NETIF_BE_DRIVER_STATUS;
    3.20 +    cmsg.length    = sizeof(netif_be_driver_status_t);
    3.21      st.status      = NETIF_DRIVER_STATUS_UP;
    3.22      memcpy(cmsg.msg, &st, sizeof(st));
    3.23      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
     4.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c	Wed Sep 22 11:02:20 2004 +0000
     4.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c	Thu Sep 23 13:42:03 2004 +0000
     4.3 @@ -29,13 +29,30 @@
     4.4  #include <net/arp.h>
     4.5  #include <net/route.h>
     4.6  
     4.7 -#if 0
     4.8 +#define DEBUG 0
     4.9 +
    4.10 +#if DEBUG
    4.11 +
    4.12  #define DPRINTK(fmt, args...) \
    4.13      printk(KERN_INFO "[XEN] %s" fmt, __FUNCTION__, ##args)
    4.14 +
    4.15  #else
    4.16 +
    4.17  #define DPRINTK(fmt, args...) ((void)0)
    4.18 +
    4.19  #endif
    4.20  
    4.21 +#define IPRINTK(fmt, args...) \
    4.22 +    printk(KERN_INFO "[XEN]" fmt, ##args)
    4.23 +
    4.24 +#define WPRINTK(fmt, args...) \
    4.25 +    printk(KERN_WARNING "[XEN]" fmt, ##args)
    4.26 +
    4.27 +#define EPRINTK(fmt, args...) \
    4.28 +    printk(KERN_ERROR "[XEN]" fmt, ##args)
    4.29 +
    4.30 +
    4.31 +
    4.32  #ifndef __GFP_NOWARN
    4.33  #define __GFP_NOWARN 0
    4.34  #endif
    4.35 @@ -101,6 +118,24 @@ struct net_private
    4.36      struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
    4.37  };
    4.38  
    4.39 +static char * status_name[] = {
    4.40 +    [NETIF_INTERFACE_STATUS_CLOSED]       = "closed",
    4.41 +    [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
    4.42 +    [NETIF_INTERFACE_STATUS_CONNECTED]    = "connected",
    4.43 +    [NETIF_INTERFACE_STATUS_CHANGED]      = "changed",
    4.44 +};
    4.45 +
    4.46 +static char * be_state_name[] = {
    4.47 +    [BEST_CLOSED]       = "closed",
    4.48 +    [BEST_DISCONNECTED] = "disconnected",
    4.49 +    [BEST_CONNECTED]    = "connected",
    4.50 +};
    4.51 +
    4.52 +static char * user_state_name[] = {
    4.53 +    [UST_CLOSED] = "closed",
    4.54 +    [UST_OPEN]   = "open",
    4.55 +};
    4.56 +
    4.57  /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
    4.58  #define ADD_ID_TO_FREELIST(_list, _id)             \
    4.59      (_list)[(_id)] = (_list)[0];                   \
    4.60 @@ -131,6 +166,7 @@ struct netif_ctrl {
    4.61      int connected_n;
    4.62      /** Error code. */
    4.63      int err;
    4.64 +    int up;
    4.65  };
    4.66  
    4.67  static struct netif_ctrl netctrl;
    4.68 @@ -138,15 +174,16 @@ static struct netif_ctrl netctrl;
    4.69  static void netctrl_init(void)
    4.70  {
    4.71      memset(&netctrl, 0, sizeof(netctrl));
    4.72 -    netctrl.interface_n = -1;
    4.73 +    netctrl.up = NETIF_DRIVER_STATUS_DOWN;
    4.74  }
    4.75  
    4.76  /** Get or set a network interface error.
    4.77   */
    4.78  static int netctrl_err(int err)
    4.79  {
    4.80 -    if ( (err < 0) && !netctrl.err )
    4.81 +    if ( (err < 0) && !netctrl.err ){
    4.82          netctrl.err = err;
    4.83 +    }
    4.84      return netctrl.err;
    4.85  }
    4.86  
    4.87 @@ -157,8 +194,12 @@ static int netctrl_err(int err)
    4.88  static int netctrl_connected(void)
    4.89  {
    4.90      int ok = 0;
    4.91 -    ok = (netctrl.err ? netctrl.err :
    4.92 -          (netctrl.connected_n == netctrl.interface_n));
    4.93 +
    4.94 +    if(netctrl.err){
    4.95 +        ok = netctrl.err;
    4.96 +    } else if(netctrl.up == NETIF_DRIVER_STATUS_UP){
    4.97 +        ok = (netctrl.connected_n == netctrl.interface_n);
    4.98 +    }
    4.99      return ok;
   4.100  }
   4.101  
   4.102 @@ -175,11 +216,11 @@ static int netctrl_connected_count(void)
   4.103  
   4.104      connected = 0;
   4.105      
   4.106 -    list_for_each(ent, &dev_list)
   4.107 -    {
   4.108 +    list_for_each(ent, &dev_list) {
   4.109          np = list_entry(ent, struct net_private, list);
   4.110 -        if ( np->backend_state == BEST_CONNECTED )
   4.111 +        if (np->backend_state == BEST_CONNECTED){
   4.112              connected++;
   4.113 +        }
   4.114      }
   4.115  
   4.116      netctrl.connected_n = connected;
   4.117 @@ -589,7 +630,7 @@ static struct net_device_stats *network_
   4.118  
   4.119  
   4.120  static void network_connect(struct net_device *dev,
   4.121 -                            netif_fe_interface_status_changed_t *status)
   4.122 +                            netif_fe_interface_status_t *status)
   4.123  {
   4.124      struct net_private *np;
   4.125      int i, requeue_idx;
   4.126 @@ -647,8 +688,8 @@ static void network_connect(struct net_d
   4.127      wmb();                
   4.128      np->rx->req_prod = requeue_idx;
   4.129  
   4.130 -printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
   4.131 -       np->tx->req_prod,np->rx->req_prod);
   4.132 +    printk(KERN_ALERT "[XEN] Netfront recovered tx=%d rxfree=%d\n",
   4.133 +           np->tx->req_prod,np->rx->req_prod);
   4.134  
   4.135  
   4.136      /* Step 3: All public and private state should now be sane.  Get
   4.137 @@ -668,129 +709,154 @@ printk(KERN_ALERT"Netfront recovered tx=
   4.138      spin_unlock_irq(&np->rx_lock);
   4.139  }
   4.140  
   4.141 -static void netif_status_change(netif_fe_interface_status_changed_t *status)
   4.142 +static void vif_show(struct net_private *np){
   4.143 +#if DEBUG
   4.144 +    if(np){
   4.145 +        IPRINTK(" <vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n",
   4.146 +               np->handle,
   4.147 +               be_state_name[np->backend_state],
   4.148 +               user_state_name[np->user_state],
   4.149 +               np->evtchn,
   4.150 +               np->irq,
   4.151 +               np->tx,
   4.152 +               np->rx);
   4.153 +    } else {
   4.154 +        IPRINTK("<vif NULL>\n");
   4.155 +    }
   4.156 +#endif
   4.157 +}
   4.158 +
   4.159 +/* Send a connect message to xend to tell it to bring up the interface.
   4.160 + */
   4.161 +static void send_interface_connect(struct net_private *np){
   4.162 +    ctrl_msg_t cmsg = {
   4.163 +        .type    = CMSG_NETIF_FE,
   4.164 +        .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT,
   4.165 +        .length  = sizeof(netif_fe_interface_connect_t),
   4.166 +    };
   4.167 +    netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   4.168 +
   4.169 +    DPRINTK(">\n"); vif_show(np); 
   4.170 +    msg->handle = np->handle;
   4.171 +    msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
   4.172 +    msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
   4.173 +        
   4.174 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.175 +    DPRINTK("<\n");
   4.176 +}
   4.177 +
   4.178 +/* Send a driver status notification to the domain controller. */
   4.179 +static int send_driver_status(int ok)
   4.180  {
   4.181 -    ctrl_msg_t                   cmsg;
   4.182 -    netif_fe_interface_connect_t up;
   4.183 -    struct net_device *dev;
   4.184 -    struct net_private *np;
   4.185 +    int err = 0;
   4.186 +    ctrl_msg_t cmsg = {
   4.187 +        .type    = CMSG_NETIF_FE,
   4.188 +        .subtype = CMSG_NETIF_FE_DRIVER_STATUS,
   4.189 +        .length  = sizeof(netif_fe_driver_status_t),
   4.190 +    };
   4.191 +    netif_fe_driver_status_t *msg = (void*)cmsg.msg;
   4.192 +
   4.193 +    msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN);
   4.194 +    err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.195 +    return err;
   4.196 +}
   4.197 +
   4.198 +/* Stop network device and free tx/rx queues and irq.
   4.199 + */
   4.200 +static void vif_release(struct net_private *np){
   4.201 +
   4.202 +    /* Stop old i/f to prevent errors whilst we rebuild the state. */
   4.203 +    spin_lock_irq(&np->tx_lock);
   4.204 +    spin_lock(&np->rx_lock);
   4.205 +    netif_stop_queue(np->dev);
   4.206 +    //np->backend_state = BEST_DISCONNECTED;
   4.207 +    spin_unlock(&np->rx_lock);
   4.208 +    spin_unlock_irq(&np->tx_lock);
   4.209      
   4.210 -    DPRINTK(">\n");
   4.211 -    DPRINTK("> status=%d handle=%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
   4.212 -           status->status,
   4.213 -           status->handle,
   4.214 -           status->mac[0], status->mac[1], status->mac[2],
   4.215 -           status->mac[3], status->mac[4], status->mac[5]);
   4.216 -
   4.217 -    if ( netctrl.interface_n <= 0 )
   4.218 -    {
   4.219 -        printk(KERN_WARNING "Status change: no interfaces\n");
   4.220 -        return;
   4.221 +    /* Free resources. */
   4.222 +    if(np->tx != NULL){
   4.223 +        free_irq(np->irq, np->dev);
   4.224 +        unbind_evtchn_from_irq(np->evtchn);
   4.225 +        free_page((unsigned long)np->tx);
   4.226 +        free_page((unsigned long)np->rx);
   4.227 +        np->irq = 0;
   4.228 +        np->evtchn = 0;
   4.229 +        np->tx = NULL;
   4.230 +        np->rx = NULL;
   4.231      }
   4.232  
   4.233 -    dev = find_dev_by_handle(status->handle);
   4.234 -    if(!dev){
   4.235 -        printk(KERN_WARNING "Status change: invalid netif handle %u\n",
   4.236 -               status->handle);
   4.237 -         return;
   4.238 -    }
   4.239 -    np  = dev->priv;
   4.240 -    
   4.241 -    switch ( status->status )
   4.242 -    {
   4.243 -    case NETIF_INTERFACE_STATUS_DESTROYED:
   4.244 -        printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n",
   4.245 -               np->backend_state);
   4.246 -        break;
   4.247 +}
   4.248  
   4.249 -    case NETIF_INTERFACE_STATUS_DISCONNECTED:
   4.250 -        if ( np->backend_state != BEST_CLOSED )
   4.251 -        {
   4.252 -            printk(KERN_WARNING "Unexpected netif-DISCONNECTED message"
   4.253 -                   " in state %d\n", np->backend_state);
   4.254 -	    printk(KERN_INFO "Attempting to reconnect network interface\n");
   4.255 +/* Release vif resources and close it down completely.
   4.256 + */
   4.257 +static void vif_close(struct net_private *np){
   4.258 +    DPRINTK(">\n"); vif_show(np);
   4.259 +    WPRINTK(" Unexpected netif-CLOSED message in state %s\n",
   4.260 +            be_state_name[np->backend_state]);
   4.261 +    vif_release(np);
   4.262 +    np->backend_state = BEST_CLOSED;
   4.263 +    //todo: take dev down and free.
   4.264 +    vif_show(np); DPRINTK("<\n");
   4.265 +}
   4.266  
   4.267 -            /* Begin interface recovery.
   4.268 -	     *
   4.269 -	     * NB. Whilst we're recovering, we turn the carrier state off.  We
   4.270 -	     * take measures to ensure that this device isn't used for
   4.271 -	     * anything.  We also stop the queue for this device.  Various
   4.272 -	     * different approaches (e.g. continuing to buffer packets) have
   4.273 -	     * been tested but don't appear to improve the overall impact on
   4.274 -             * TCP connections.
   4.275 -	     *
   4.276 -             * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
   4.277 -             * is initiated by a special "RESET" message - disconnect could
   4.278 -             * just mean we're not allowed to use this interface any more.
   4.279 -             */
   4.280 -
   4.281 -            /* Stop old i/f to prevent errors whilst we rebuild the state. */
   4.282 -            spin_lock_irq(&np->tx_lock);
   4.283 -            spin_lock(&np->rx_lock);
   4.284 -            netif_stop_queue(dev);
   4.285 -            np->backend_state = BEST_DISCONNECTED;
   4.286 -            spin_unlock(&np->rx_lock);
   4.287 -            spin_unlock_irq(&np->tx_lock);
   4.288 -
   4.289 -            /* Free resources. */
   4.290 -            free_irq(np->irq, dev);
   4.291 -            unbind_evtchn_from_irq(np->evtchn);
   4.292 -	    free_page((unsigned long)np->tx);
   4.293 -            free_page((unsigned long)np->rx);
   4.294 -        }
   4.295 +/* Move the vif into disconnected state.
   4.296 + * Allocates tx/rx pages.
   4.297 + * Sends connect message to xend.
   4.298 + */
   4.299 +static void vif_disconnect(struct net_private *np){
   4.300 +    DPRINTK(">\n");
   4.301 +    if(np->tx) free_page((unsigned long)np->tx);
   4.302 +    if(np->rx) free_page((unsigned long)np->rx);
   4.303 +    // Before this np->tx and np->rx had better be null.
   4.304 +    np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
   4.305 +    np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
   4.306 +    memset(np->tx, 0, PAGE_SIZE);
   4.307 +    memset(np->rx, 0, PAGE_SIZE);
   4.308 +    np->backend_state = BEST_DISCONNECTED;
   4.309 +    send_interface_connect(np);
   4.310 +    vif_show(np); DPRINTK("<\n");
   4.311 +}
   4.312  
   4.313 -        /* Move from CLOSED to DISCONNECTED state. */
   4.314 -        np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
   4.315 -        np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
   4.316 -        memset(np->tx, 0, PAGE_SIZE);
   4.317 -        memset(np->rx, 0, PAGE_SIZE);
   4.318 -        np->backend_state = BEST_DISCONNECTED;
   4.319 -
   4.320 -        /* Construct an interface-CONNECT message for the domain controller. */
   4.321 -        cmsg.type      = CMSG_NETIF_FE;
   4.322 -        cmsg.subtype   = CMSG_NETIF_FE_INTERFACE_CONNECT;
   4.323 -        cmsg.length    = sizeof(netif_fe_interface_connect_t);
   4.324 -        up.handle      = status->handle;
   4.325 -        up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
   4.326 -        up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
   4.327 -        memcpy(cmsg.msg, &up, sizeof(up));
   4.328 -        
   4.329 -        /* Tell the controller to bring up the interface. */
   4.330 -        ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.331 -        break;
   4.332 +/* Begin interface recovery.
   4.333 + *
   4.334 + * NB. Whilst we're recovering, we turn the carrier state off.  We
   4.335 + * take measures to ensure that this device isn't used for
   4.336 + * anything.  We also stop the queue for this device.  Various
   4.337 + * different approaches (e.g. continuing to buffer packets) have
   4.338 + * been tested but don't appear to improve the overall impact on
   4.339 + * TCP connections.
   4.340 + *
   4.341 + * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
   4.342 + * is initiated by a special "RESET" message - disconnect could
   4.343 + * just mean we're not allowed to use this interface any more.
   4.344 + */
   4.345 +static void vif_reset(struct net_private *np){
   4.346 +    DPRINTK(">\n");
   4.347 +    IPRINTK(" Attempting to reconnect network interface: handle=%u\n",
   4.348 +            np->handle);
   4.349 +    
   4.350 +    vif_release(np);
   4.351 +    vif_disconnect(np);
   4.352 +    vif_show(np); DPRINTK("<\n");
   4.353 +}
   4.354  
   4.355 -    case NETIF_INTERFACE_STATUS_CONNECTED:
   4.356 -        if ( np->backend_state == BEST_CLOSED )
   4.357 -        {
   4.358 -            printk(KERN_WARNING "Unexpected netif-CONNECTED message"
   4.359 -                   " in state %d\n", np->backend_state);
   4.360 -            break;
   4.361 -        }
   4.362 -
   4.363 -        memcpy(dev->dev_addr, status->mac, ETH_ALEN);
   4.364 -
   4.365 -        network_connect(dev, status);
   4.366 +/* Move the vif into connected state.
   4.367 + * Sets the mac and event channel from the message.
   4.368 + * Binds the irq to the event channel.
   4.369 + */
   4.370 +static void vif_connect(struct net_private *np, netif_fe_interface_status_t *status){
   4.371 +    struct net_device *dev = np->dev;
   4.372 +    DPRINTK(">\n");
   4.373 +    memcpy(dev->dev_addr, status->mac, ETH_ALEN);
   4.374 +    network_connect(dev, status);
   4.375 +    np->evtchn = status->evtchn;
   4.376 +    np->irq = bind_evtchn_to_irq(np->evtchn);
   4.377 +    (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
   4.378 +    netctrl_connected_count();
   4.379 +    vif_wake(dev);
   4.380 +    vif_show(np); DPRINTK("<\n");
   4.381 +}
   4.382  
   4.383 -        np->evtchn = status->evtchn;
   4.384 -        np->irq = bind_evtchn_to_irq(np->evtchn);
   4.385 -        (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 
   4.386 -                          dev->name, dev);
   4.387 -        netctrl_connected_count();
   4.388 -        vif_wake(dev);
   4.389 -        break;
   4.390 -
   4.391 -    case NETIF_INTERFACE_STATUS_CHANGED:
   4.392 -        /* The domain controller is notifying us that a device has been
   4.393 -        * added or removed.
   4.394 -        */
   4.395 -        break;
   4.396 -
   4.397 -    default:
   4.398 -        printk(KERN_WARNING "Status change to unknown value %d\n", 
   4.399 -               status->status);
   4.400 -        break;
   4.401 -    }
   4.402 -}
   4.403  
   4.404  /** Create a network device.
   4.405   * @param handle device handle
   4.406 @@ -819,10 +885,12 @@ static int create_netdev(int handle, str
   4.407      spin_lock_init(&np->rx_lock);
   4.408  
   4.409      /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
   4.410 -    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
   4.411 +    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ){
   4.412          np->tx_skbs[i] = (void *)(i+1);
   4.413 -    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
   4.414 +    }
   4.415 +    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ){
   4.416          np->rx_skbs[i] = (void *)(i+1);
   4.417 +    }
   4.418  
   4.419      dev->open            = network_open;
   4.420      dev->hard_start_xmit = network_start_xmit;
   4.421 @@ -840,58 +908,172 @@ static int create_netdev(int handle, str
   4.422      list_add(&np->list, &dev_list);
   4.423  
   4.424    exit:
   4.425 -    if ( (err != 0) && (dev != NULL ) )
   4.426 +    if ( (err != 0) && (dev != NULL ) ){
   4.427          kfree(dev);
   4.428 -    else if ( val != NULL )
   4.429 +    } else if ( val != NULL ) {
   4.430          *val = dev;
   4.431 +    }
   4.432      return err;
   4.433  }
   4.434  
   4.435 +/* Get the target interface for a status message.
   4.436 + * Creates the interface when it makes sense.
   4.437 + * The returned interface may be null when there is no error.
   4.438 + *
   4.439 + * @param status status message
   4.440 + * @param np return parameter for interface state
   4.441 + * @return 0 on success, error code otherwise
   4.442 + */
   4.443 +static int target_vif(netif_fe_interface_status_t *status, struct net_private **np)
   4.444 +{
   4.445 +    int err = 0;
   4.446 +    struct net_device *dev;
   4.447 +
   4.448 +    DPRINTK("> handle=%d\n", status->handle);
   4.449 +    if(status->handle < 0) {
   4.450 +        err = -EINVAL;
   4.451 +        goto exit;
   4.452 +    }
   4.453 +    dev = find_dev_by_handle(status->handle);
   4.454 +    DPRINTK("> dev=%p\n", dev);
   4.455 +    if(dev) goto exit;
   4.456 +    // No good - give up.
   4.457 +    if(status->status == NETIF_INTERFACE_STATUS_CLOSED) goto exit;
   4.458 +    if(status->status == NETIF_INTERFACE_STATUS_CHANGED) goto exit;
   4.459 +    // It's a new interface in a good state - create it.
   4.460 +    DPRINTK("> create device...\n");
   4.461 +    err = create_netdev(status->handle, &dev);
   4.462 +    if(err) goto exit;
   4.463 +    netctrl.interface_n++;
   4.464 +  exit:
   4.465 +    if(np){
   4.466 +        *np = ((dev && !err) ? dev->priv : NULL);
   4.467 +    }
   4.468 +    DPRINTK("< err=%d\n", err);
   4.469 +    return err;
   4.470 +}
   4.471 +
   4.472 +/* Warn about an unexpected status. */
   4.473 +static void unexpected(struct net_private *np,
   4.474 +                       netif_fe_interface_status_t *status)
   4.475 +{
   4.476 +    WPRINTK(" Unexpected netif status %s in state %s\n",
   4.477 +            status_name[status->status],
   4.478 +            be_state_name[np->backend_state]);
   4.479 +}
   4.480 +
   4.481 +/* Handle an interface status message. */
   4.482 +static void netif_interface_status(netif_fe_interface_status_t *status)
   4.483 +{
   4.484 +    int err = 0;
   4.485 +    struct net_private *np = NULL;
   4.486 +    
   4.487 +    DPRINTK(">\n");
   4.488 +    DPRINTK("> status=%s handle=%d\n", status_name[status->status], status->handle);
   4.489 +
   4.490 +    err = target_vif(status, &np);
   4.491 +    if(err){
   4.492 +        WPRINTK(" Invalid netif: handle=%u\n", status->handle);
   4.493 +        return;
   4.494 +    }
   4.495 +    if(np == NULL){
   4.496 +        DPRINTK("> no vif\n");
   4.497 +        return;
   4.498 +    }
   4.499 +
   4.500 +    DPRINTK(">\n"); vif_show(np);
   4.501 +
   4.502 +    switch (status->status) {
   4.503 +
   4.504 +    case NETIF_INTERFACE_STATUS_CLOSED:
   4.505 +        switch(np->backend_state){
   4.506 +
   4.507 +        case BEST_CLOSED:
   4.508 +        case BEST_DISCONNECTED:
   4.509 +        case BEST_CONNECTED:
   4.510 +            vif_close(np);
   4.511 +            break;
   4.512 +        }
   4.513 +        break;
   4.514 +
   4.515 +    case NETIF_INTERFACE_STATUS_DISCONNECTED:
   4.516 +        switch(np->backend_state){
   4.517 +
   4.518 +        case BEST_CLOSED:
   4.519 +            vif_disconnect(np);
   4.520 +            break;
   4.521 +
   4.522 +        case BEST_DISCONNECTED:
   4.523 +        case BEST_CONNECTED:
   4.524 +            vif_reset(np);
   4.525 +            break;
   4.526 +        }
   4.527 +        break;
   4.528 +
   4.529 +    case NETIF_INTERFACE_STATUS_CONNECTED:
   4.530 +        switch(np->backend_state){
   4.531 +
   4.532 +        case BEST_CLOSED:
   4.533 +            unexpected(np, status);
   4.534 +            vif_disconnect(np);
   4.535 +            vif_connect(np, status);
   4.536 +            break;
   4.537 +
   4.538 +        case BEST_DISCONNECTED:
   4.539 +            vif_connect(np, status);
   4.540 +            break;
   4.541 +
   4.542 +        case BEST_CONNECTED:
   4.543 +            //todo Do what?
   4.544 +            unexpected(np, status);
   4.545 +            break;
   4.546 +        }
   4.547 +        break;
   4.548 +
   4.549 +    case NETIF_INTERFACE_STATUS_CHANGED:
   4.550 +        /* The domain controller is notifying us that a device has been
   4.551 +        * added or removed.
   4.552 +        */
   4.553 +        break;
   4.554 +
   4.555 +    default:
   4.556 +        WPRINTK(" Invalid netif status code %d\n", status->status);
   4.557 +        break;
   4.558 +    }
   4.559 +    vif_show(np);
   4.560 +    DPRINTK("<\n");
   4.561 +}
   4.562 +
   4.563  /*
   4.564 - * Initialize the network control interface. Set the number of network devices
   4.565 - * and create them.
   4.566 + * Initialize the network control interface. 
   4.567   */
   4.568 -
   4.569 -static void netif_driver_status_change(
   4.570 -    netif_fe_driver_status_changed_t *status)
   4.571 +static void netif_driver_status(netif_fe_driver_status_t *status)
   4.572  {
   4.573 -    int err = 0;
   4.574 -    int i;
   4.575 -
   4.576 -    DPRINTK("> max_handle=%d\n", status->max_handle);
   4.577 -
   4.578 -    /* XXX FIXME: Abuse of 'max_handle' as interface count. */
   4.579 -    netctrl.interface_n = status->max_handle;
   4.580 -    netctrl.connected_n = 0;
   4.581 -
   4.582 -    for ( i = 0; i < netctrl.interface_n; i++ )
   4.583 -    {
   4.584 -        if ( (err = create_netdev(i, NULL)) != 0 )
   4.585 -        {
   4.586 -            netctrl_err(err);
   4.587 -            break;
   4.588 -        }
   4.589 -    }
   4.590 +    DPRINTK("> status=%d\n", status->status);
   4.591 +    netctrl.up = status->status;
   4.592 +    //netctrl.interface_n = status->max_handle;
   4.593 +    //netctrl.connected_n = 0;
   4.594 +    netctrl_connected_count();
   4.595  }
   4.596  
   4.597 +/* Receive handler for control messages. */
   4.598  static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
   4.599  {
   4.600 -    int respond = 1;
   4.601  
   4.602      switch ( msg->subtype )
   4.603      {
   4.604 -    case CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
   4.605 -        if ( msg->length != sizeof(netif_fe_interface_status_changed_t) )
   4.606 +    case CMSG_NETIF_FE_INTERFACE_STATUS:
   4.607 +        if ( msg->length != sizeof(netif_fe_interface_status_t) )
   4.608              goto error;
   4.609 -        netif_status_change((netif_fe_interface_status_changed_t *)
   4.610 -                            &msg->msg[0]);
   4.611 +        netif_interface_status((netif_fe_interface_status_t *)
   4.612 +                               &msg->msg[0]);
   4.613          break;
   4.614  
   4.615 -    case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   4.616 -        if ( msg->length != sizeof(netif_fe_driver_status_changed_t) )
   4.617 +    case CMSG_NETIF_FE_DRIVER_STATUS:
   4.618 +        if ( msg->length != sizeof(netif_fe_driver_status_t) )
   4.619              goto error;
   4.620 -        netif_driver_status_change((netif_fe_driver_status_changed_t *)
   4.621 -                                   &msg->msg[0]);
   4.622 +        netif_driver_status((netif_fe_driver_status_t *)
   4.623 +                            &msg->msg[0]);
   4.624          break;
   4.625  
   4.626      error:
   4.627 @@ -900,156 +1082,170 @@ static void netif_ctrlif_rx(ctrl_msg_t *
   4.628          break;
   4.629      }
   4.630  
   4.631 -    if ( respond )
   4.632 -        ctrl_if_send_response(msg);
   4.633 +    ctrl_if_send_response(msg);
   4.634  }
   4.635  
   4.636  
   4.637 -/* Wait for all interfaces to be connected. */
   4.638 -static int wait_for_interfaces(void)
   4.639 +#if 1
   4.640 +/* Wait for all interfaces to be connected.
   4.641 + *
   4.642 + * This works OK, but we'd like to use the probing mode (see below).
   4.643 + */
   4.644 +static int probe_interfaces(void)
   4.645  {
   4.646      int err = 0, conn = 0;
   4.647      int wait_i, wait_n = 100;
   4.648  
   4.649      DPRINTK(">\n");
   4.650  
   4.651 -    for ( wait_i = 0; wait_i < wait_n; wait_i++)
   4.652 -    { 
   4.653 +    for ( wait_i = 0; wait_i < wait_n; wait_i++) { 
   4.654          DPRINTK("> wait_i=%d\n", wait_i);
   4.655          conn = netctrl_connected();
   4.656          if(conn) break;
   4.657 +        DPRINTK("> schedule_timeout...\n");
   4.658          set_current_state(TASK_INTERRUPTIBLE);
   4.659          schedule_timeout(10);
   4.660      }
   4.661  
   4.662 -    if ( conn <= 0 )
   4.663 -    {
   4.664 +    DPRINTK("> wait finished...\n");
   4.665 +    if ( conn <= 0 ) {
   4.666          err = netctrl_err(-ENETDOWN);
   4.667 -        printk(KERN_WARNING "[XEN] Failed to connect all virtual interfaces: "
   4.668 -               "err=%d\n", err);
   4.669 +        WPRINTK(" Failed to connect all virtual interfaces: err=%d\n", err);
   4.670      }
   4.671  
   4.672      DPRINTK("< err=%d\n", err);
   4.673  
   4.674      return err;
   4.675  }
   4.676 +#else
   4.677 +/* Probe for interfaces until no more are found.
   4.678 + *
   4.679 + * This is the mode we'd like to use, but at the moment it panics the kernel.
   4.680 +*/
   4.681 +static int probe_interfaces(void)
   4.682 +{
   4.683 +    int err = 0;
   4.684 +    int wait_i, wait_n = 100;
   4.685 +    ctrl_msg_t cmsg = {
   4.686 +        .type    = CMSG_NETIF_FE,
   4.687 +        .subtype = CMSG_NETIF_FE_INTERFACE_STATUS,
   4.688 +        .length  = sizeof(netif_fe_interface_status_t),
   4.689 +    };
   4.690 +    netif_fe_interface_status_t msg = {};
   4.691 +    ctrl_msg_t rmsg = {};
   4.692 +    netif_fe_interface_status_t *reply = (void*)rmsg.msg;
   4.693 +    int state = TASK_UNINTERRUPTIBLE;
   4.694 +    u32 query = -1;
   4.695 +
   4.696 +    DPRINTK(">\n");
   4.697 +
   4.698 +    netctrl.interface_n = 0;
   4.699 +    for (wait_i = 0; wait_i < wait_n; wait_i++) { 
   4.700 +        DPRINTK("> wait_i=%d query=%d\n", wait_i, query);
   4.701 +        msg.handle = query;
   4.702 +        memcpy(cmsg.msg, &msg, sizeof(msg));
   4.703 +        DPRINTK("> set_current_state...\n");
   4.704 +        set_current_state(state);
   4.705 +        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
   4.706 +        DPRINTK("> sending...\n");
   4.707 +        err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state);
   4.708 +        DPRINTK("> err=%d\n", err);
   4.709 +        if(err) goto exit;
   4.710 +        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
   4.711 +        if((int)reply->handle < 0){
   4.712 +            // No more interfaces.
   4.713 +            break;
   4.714 +        }
   4.715 +        query = -reply->handle - 2;
   4.716 +        DPRINTK(">netif_interface_status ...\n");
   4.717 +        netif_interface_status(reply);
   4.718 +    }
   4.719 +
   4.720 +  exit:
   4.721 +    if (err) {
   4.722 +        err = netctrl_err(-ENETDOWN);
   4.723 +        WPRINTK(" Connecting virtual network interfaces failed: err=%d\n", err);
   4.724 +    }
   4.725 +
   4.726 +    DPRINTK("< err=%d\n", err);
   4.727 +    return err;
   4.728 +}
   4.729 +
   4.730 +#endif
   4.731  
   4.732  static int __init netif_init(void)
   4.733  {
   4.734 -    ctrl_msg_t                       cmsg;
   4.735 -    netif_fe_driver_status_changed_t st;
   4.736      int err = 0;
   4.737  
   4.738      if ( (start_info.flags & SIF_INITDOMAIN) ||
   4.739           (start_info.flags & SIF_NET_BE_DOMAIN) )
   4.740          return 0;
   4.741  
   4.742 -    printk(KERN_INFO "Initialising Xen virtual ethernet frontend driver.\n");
   4.743 -
   4.744 +    IPRINTK(" Initialising virtual ethernet driver.\n");
   4.745      INIT_LIST_HEAD(&dev_list);
   4.746 -
   4.747      netctrl_init();
   4.748 -
   4.749      (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
   4.750                                      CALLBACK_IN_BLOCKING_CONTEXT);
   4.751 -
   4.752 -    /* Send a driver-UP notification to the domain controller. */
   4.753 -    cmsg.type      = CMSG_NETIF_FE;
   4.754 -    cmsg.subtype   = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
   4.755 -    cmsg.length    = sizeof(netif_fe_driver_status_changed_t);
   4.756 -    st.status      = NETIF_DRIVER_STATUS_UP;
   4.757 -    st.max_handle  = 0;
   4.758 -    memcpy(cmsg.msg, &st, sizeof(st));
   4.759 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.760 -
   4.761 -    err = wait_for_interfaces();
   4.762 +    send_driver_status(1);
   4.763 +    err = probe_interfaces();
   4.764      if ( err )
   4.765          ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
   4.766  
   4.767 +    DPRINTK("< err=%d\n", err);
   4.768      return err;
   4.769  }
   4.770  
   4.771 +static void vif_suspend(struct net_private *np)
   4.772 +{
   4.773 +    // Avoid having tx/rx stuff happen until we're ready.
   4.774 +    DPRINTK(">\n");
   4.775 +    free_irq(np->irq, np->dev);
   4.776 +    unbind_evtchn_from_irq(np->evtchn);
   4.777 +    DPRINTK("<\n");
   4.778 +}
   4.779 +
   4.780 +static void vif_resume(struct net_private *np)
   4.781 +{
   4.782 +    // Connect regardless of whether IFF_UP flag set.
   4.783 +    // Stop bad things from happening until we're back up.
   4.784 +    DPRINTK(">\n");
   4.785 +    np->backend_state = BEST_DISCONNECTED;
   4.786 +    memset(np->tx, 0, PAGE_SIZE);
   4.787 +    memset(np->rx, 0, PAGE_SIZE);
   4.788 +    
   4.789 +    send_interface_connect(np);
   4.790 +    DPRINTK("<\n");
   4.791 +}
   4.792 +
   4.793  void netif_suspend(void)
   4.794  {
   4.795  #if 1 /* XXX THIS IS TEMPORARY */
   4.796 -    struct net_device *dev = NULL;
   4.797 -    struct net_private *np = NULL;
   4.798 -    int i;
   4.799 -
   4.800 -/* avoid having tx/rx stuff happen until we're ready */
   4.801 -
   4.802 -    for(i=0;i<netctrl.interface_n;i++)
   4.803 -    {
   4.804 -	char name[32];
   4.805 -
   4.806 -	sprintf(name,"eth%d",i);
   4.807 -	dev = __dev_get_by_name(name);
   4.808 -
   4.809 -	if ( dev )
   4.810 -	{
   4.811 -	    np  = dev->priv;
   4.812 -	    free_irq(np->irq, dev);
   4.813 -            unbind_evtchn_from_irq(np->evtchn);
   4.814 -	}    
   4.815 +    struct list_head *ent;
   4.816 +    struct net_private *np;
   4.817 +    
   4.818 +    DPRINTK(">\n");
   4.819 +    list_for_each(ent, &dev_list){
   4.820 +        np = list_entry(ent, struct net_private, list);
   4.821 +        vif_suspend(np);
   4.822      }
   4.823 +    DPRINTK("<\n");
   4.824  #endif
   4.825  }
   4.826  
   4.827  void netif_resume(void)
   4.828  {
   4.829 -    ctrl_msg_t                   cmsg;
   4.830 -    netif_fe_interface_connect_t up;
   4.831 -    struct net_device *dev = NULL;
   4.832 -    struct net_private *np = NULL;
   4.833 -    int i;
   4.834 -
   4.835  #if 1
   4.836      /* XXX THIS IS TEMPORARY */
   4.837 -
   4.838 -    for(i=0;i<netctrl.interface_n;i++)    
   4.839 -    {
   4.840 -	char name[32];
   4.841 -
   4.842 -	sprintf(name,"eth%d",i);
   4.843 -	dev = __dev_get_by_name(name);
   4.844 -
   4.845 -	if ( dev ) // connect regardless of whether IFF_UP flag set
   4.846 -	{
   4.847 -	    np  = dev->priv;
   4.848 -
   4.849 -	    // stop bad things from happening until we're back up
   4.850 -	    np->backend_state = BEST_DISCONNECTED;
   4.851 -	    
   4.852 -	    memset(np->tx,0,PAGE_SIZE);
   4.853 -	    memset(np->rx,0,PAGE_SIZE);
   4.854 +    struct list_head *ent;
   4.855 +    struct net_private *np;
   4.856  
   4.857 -	    cmsg.type      = CMSG_NETIF_FE;
   4.858 -	    cmsg.subtype   = CMSG_NETIF_FE_INTERFACE_CONNECT;
   4.859 -	    cmsg.length    = sizeof(netif_fe_interface_connect_t);
   4.860 -	    up.handle      = np->handle;
   4.861 -	    up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
   4.862 -	    up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
   4.863 -	    memcpy(cmsg.msg, &up, sizeof(up));
   4.864 -
   4.865 -	    /* Tell the controller to bring up the interface. */
   4.866 -	    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.867 -	}
   4.868 +    DPRINTK(">\n");
   4.869 +    list_for_each(ent, &dev_list){
   4.870 +        np = list_entry(ent, struct net_private, list);
   4.871 +        vif_resume(np);
   4.872      }
   4.873 +    DPRINTK("<\n");
   4.874  #endif	    
   4.875 -
   4.876 -
   4.877 -#if 0
   4.878 -    /* Send a driver-UP notification to the domain controller. */
   4.879 -    cmsg.type      = CMSG_NETIF_FE;
   4.880 -    cmsg.subtype   = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
   4.881 -    cmsg.length    = sizeof(netif_fe_driver_status_changed_t);
   4.882 -    st.status      = NETIF_DRIVER_STATUS_UP;
   4.883 -    st.max_handle  = 0;
   4.884 -    memcpy(cmsg.msg, &st, sizeof(st));
   4.885 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.886 -#endif
   4.887 -
   4.888 -
   4.889  }
   4.890  
   4.891  
     5.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Wed Sep 22 11:02:20 2004 +0000
     5.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Thu Sep 23 13:42:03 2004 +0000
     5.3 @@ -324,11 +324,11 @@ static PyObject *xu_message_set_response
     5.4  
     5.5      switch ( TYPE(xum->msg.type, xum->msg.subtype) )
     5.6      {
     5.7 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
     5.8 -        P2C(blkif_fe_driver_status_changed_t, max_handle, u32);
     5.9 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
    5.10 +        P2C(blkif_fe_driver_status_t, max_handle, u32);
    5.11          break;
    5.12 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
    5.13 -        P2C(netif_fe_driver_status_changed_t, max_handle, u32);
    5.14 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
    5.15 +        P2C(netif_fe_driver_status_t, max_handle, u32);
    5.16          break;
    5.17      }
    5.18  
    5.19 @@ -352,13 +352,13 @@ static PyObject *xu_message_get_payload(
    5.20  
    5.21      switch ( TYPE(xum->msg.type, xum->msg.subtype) )
    5.22      {
    5.23 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
    5.24 -        C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
    5.25 -        C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
    5.26 -        C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
    5.27 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
    5.28 +        C2P(blkif_fe_interface_status_t, handle, Int, Long);
    5.29 +        C2P(blkif_fe_interface_status_t, status, Int, Long);
    5.30 +        C2P(blkif_fe_interface_status_t, evtchn, Int, Long);
    5.31          return dict;
    5.32 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
    5.33 -        C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
    5.34 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
    5.35 +        C2P(blkif_fe_driver_status_t, status, Int, Long);
    5.36          return dict;
    5.37      case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
    5.38          C2P(blkif_fe_interface_connect_t, handle,      Int, Long);
    5.39 @@ -419,23 +419,23 @@ static PyObject *xu_message_get_payload(
    5.40          C2P(blkif_be_vbd_shrink_t, vdevice,      Int, Long);
    5.41          C2P(blkif_be_vbd_shrink_t, status,       Int, Long);
    5.42          return dict;
    5.43 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
    5.44 -        C2P(blkif_be_driver_status_changed_t, status, Int, Long);
    5.45 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS):
    5.46 +        C2P(blkif_be_driver_status_t, status, Int, Long);
    5.47          return dict;
    5.48 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
    5.49 -        C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
    5.50 -        C2P(netif_fe_interface_status_changed_t, status, Int, Long);
    5.51 -        C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
    5.52 -        C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
    5.53 -        C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
    5.54 -        C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
    5.55 -        C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
    5.56 -        C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
    5.57 -        C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
    5.58 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
    5.59 +        C2P(netif_fe_interface_status_t, handle, Int, Long);
    5.60 +        C2P(netif_fe_interface_status_t, status, Int, Long);
    5.61 +        C2P(netif_fe_interface_status_t, evtchn, Int, Long);
    5.62 +        C2P(netif_fe_interface_status_t, mac[0], Int, Long);
    5.63 +        C2P(netif_fe_interface_status_t, mac[1], Int, Long);
    5.64 +        C2P(netif_fe_interface_status_t, mac[2], Int, Long);
    5.65 +        C2P(netif_fe_interface_status_t, mac[3], Int, Long);
    5.66 +        C2P(netif_fe_interface_status_t, mac[4], Int, Long);
    5.67 +        C2P(netif_fe_interface_status_t, mac[5], Int, Long);
    5.68          return dict;
    5.69 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
    5.70 -        C2P(netif_fe_driver_status_changed_t, status,        Int, Long);
    5.71 -        C2P(netif_fe_driver_status_changed_t, max_handle,    Int, Long);
    5.72 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
    5.73 +        C2P(netif_fe_driver_status_t, status,        Int, Long);
    5.74 +        C2P(netif_fe_driver_status_t, max_handle,    Int, Long);
    5.75          return dict;
    5.76      case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
    5.77          C2P(netif_fe_interface_connect_t, handle,         Int, Long);
    5.78 @@ -468,8 +468,8 @@ static PyObject *xu_message_get_payload(
    5.79          C2P(netif_be_disconnect_t, netif_handle, Int, Long);
    5.80          C2P(netif_be_disconnect_t, status,       Int, Long);
    5.81          return dict;
    5.82 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
    5.83 -        C2P(netif_be_driver_status_changed_t, status, Int, Long);
    5.84 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS):
    5.85 +        C2P(netif_be_driver_status_t, status, Int, Long);
    5.86          return dict;
    5.87      }
    5.88  
    5.89 @@ -543,11 +543,11 @@ static PyObject *xu_message_new(PyObject
    5.90  
    5.91      switch ( TYPE(type, subtype) )
    5.92      {
    5.93 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
    5.94 -        P2C(blkif_fe_interface_status_changed_t, handle, u32);
    5.95 -        P2C(blkif_fe_interface_status_changed_t, status, u32);
    5.96 -        P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
    5.97 -        P2C(blkif_fe_interface_status_changed_t, domid,  u16);
    5.98 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
    5.99 +        P2C(blkif_fe_interface_status_t, handle, u32);
   5.100 +        P2C(blkif_fe_interface_status_t, status, u32);
   5.101 +        P2C(blkif_fe_interface_status_t, evtchn, u16);
   5.102 +        P2C(blkif_fe_interface_status_t, domid,  u16);
   5.103          break;
   5.104      case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
   5.105          P2C(blkif_be_create_t, domid,        u32);
   5.106 @@ -591,17 +591,17 @@ static PyObject *xu_message_new(PyObject
   5.107          P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
   5.108          P2C(blkif_be_vbd_shrink_t, vdevice,      blkif_vdev_t);
   5.109          break;
   5.110 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
   5.111 -        P2C(netif_fe_interface_status_changed_t, handle, u32);
   5.112 -        P2C(netif_fe_interface_status_changed_t, status, u32);
   5.113 -        P2C(netif_fe_interface_status_changed_t, evtchn, u16);
   5.114 -        P2C(netif_fe_interface_status_changed_t, domid,  u16);
   5.115 -        P2C(netif_fe_interface_status_changed_t, mac[0], u8);
   5.116 -        P2C(netif_fe_interface_status_changed_t, mac[1], u8);
   5.117 -        P2C(netif_fe_interface_status_changed_t, mac[2], u8);
   5.118 -        P2C(netif_fe_interface_status_changed_t, mac[3], u8);
   5.119 -        P2C(netif_fe_interface_status_changed_t, mac[4], u8);
   5.120 -        P2C(netif_fe_interface_status_changed_t, mac[5], u8);
   5.121 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
   5.122 +        P2C(netif_fe_interface_status_t, handle, u32);
   5.123 +        P2C(netif_fe_interface_status_t, status, u32);
   5.124 +        P2C(netif_fe_interface_status_t, evtchn, u16);
   5.125 +        P2C(netif_fe_interface_status_t, domid,  u16);
   5.126 +        P2C(netif_fe_interface_status_t, mac[0], u8);
   5.127 +        P2C(netif_fe_interface_status_t, mac[1], u8);
   5.128 +        P2C(netif_fe_interface_status_t, mac[2], u8);
   5.129 +        P2C(netif_fe_interface_status_t, mac[3], u8);
   5.130 +        P2C(netif_fe_interface_status_t, mac[4], u8);
   5.131 +        P2C(netif_fe_interface_status_t, mac[5], u8);
   5.132          break;
   5.133      case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
   5.134          P2C(netif_be_create_t, domid,        u32);
   5.135 @@ -628,9 +628,9 @@ static PyObject *xu_message_new(PyObject
   5.136          P2C(netif_be_disconnect_t, domid,        u32);
   5.137          P2C(netif_be_disconnect_t, netif_handle, u32);
   5.138          break;
   5.139 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
   5.140 -        P2C(netif_fe_driver_status_changed_t, status,        u32);
   5.141 -        P2C(netif_fe_driver_status_changed_t, max_handle,    u32);
   5.142 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
   5.143 +        P2C(netif_fe_driver_status_t, status,        u32);
   5.144 +        P2C(netif_fe_driver_status_t, max_handle,    u32);
   5.145          break;
   5.146      }
   5.147  
     6.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Sep 22 11:02:20 2004 +0000
     6.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Sep 23 13:42:03 2004 +0000
     6.3 @@ -239,14 +239,14 @@ class XendDomain:
     6.4          destroyed = 0
     6.5          for d in casualties:
     6.6              id = str(d['dom'])
     6.7 -            log.debug('XendDomain>reap> domain died id=%s', id)
     6.8 +            dominfo = self.domain_by_id.get(id)
     6.9 +            name = (dominfo and dominfo.name) or '??'
    6.10 +            log.debug('XendDomain>reap> domain died name=%s id=%s', name, id)
    6.11              if d['shutdown']:
    6.12                  reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
    6.13                  log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
    6.14 -                dominfo = self.domain_by_id.get(id)
    6.15 -                name = (dominfo and dominfo.name) or '??'
    6.16                  if reason in ['suspend']:
    6.17 -                    if dominfo.is_terminated():
    6.18 +                    if dominfo and dominfo.is_terminated():
    6.19                          log.debug('XendDomain>reap> Suspended domain died id=%s', id)
    6.20                      else:
    6.21                          eserver.inject('xend.domain.suspended', [name, id])
     7.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Sep 22 11:02:20 2004 +0000
     7.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 23 13:42:03 2004 +0000
     7.3 @@ -155,6 +155,7 @@ def make_disk(vm, config, uname, dev, mo
     7.4      @param recreate: recreate flag (after xend restart)
     7.5      @return: deferred
     7.6      """
     7.7 +    idx = vm.next_device_index('vbd')
     7.8      segments = lookup_disk_uname(uname)
     7.9      if not segments:
    7.10          raise VmError("vbd: Segments not found: uname=%s" % uname)
    7.11 @@ -166,7 +167,7 @@ def make_disk(vm, config, uname, dev, mo
    7.12      if not vdev:
    7.13          raise VmError("vbd: Device not found: uname=%s dev=%s" % (uname, dev))
    7.14      ctrl = xend.blkif_create(vm.dom, recreate=recreate)
    7.15 -    return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
    7.16 +    return ctrl.attachDevice(idx, config, vdev, mode, segment, recreate=recreate)
    7.17          
    7.18  def vif_up(iplist):
    7.19      """send an unsolicited ARP reply for all non link-local IP addresses.
     8.1 --- a/tools/python/xen/xend/server/blkif.py	Wed Sep 22 11:02:20 2004 +0000
     8.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Sep 23 13:42:03 2004 +0000
     8.3 @@ -19,19 +19,19 @@ class BlkifBackendController(controller.
     8.4      def __init__(self, factory, dom):
     8.5          controller.BackendController.__init__(self, factory, dom)
     8.6          self.addMethod(CMSG_BLKIF_BE,
     8.7 -                       CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
     8.8 -                       self.recv_be_driver_status_changed)
     8.9 +                       CMSG_BLKIF_BE_DRIVER_STATUS,
    8.10 +                       self.recv_be_driver_status)
    8.11          self.registerChannel()
    8.12  
    8.13 -    def recv_be_driver_status_changed(self, msg, req):
    8.14 -        """Request handler for be_driver_status_changed messages.
    8.15 +    def recv_be_driver_status(self, msg, req):
    8.16 +        """Request handler for be_driver_status messages.
    8.17          
    8.18          @param msg: message
    8.19          @type  msg: xu message
    8.20          @param req: request flag (true if the msg is a request)
    8.21          @type  req: bool
    8.22          """
    8.23 -        val = unpackMsg('blkif_be_driver_status_changed_t', msg)
    8.24 +        val = unpackMsg('blkif_be_driver_status_t', msg)
    8.25          status = val['status']
    8.26  
    8.27  class BlkifBackendInterface(controller.BackendInterface):
    8.28 @@ -45,10 +45,23 @@ class BlkifBackendInterface(controller.B
    8.29          controller.BackendInterface.__init__(self, ctrl, dom, handle)
    8.30          self.connected = 0
    8.31          self.evtchn = None
    8.32 +        self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
    8.33  
    8.34      def __str__(self):
    8.35          return '<BlkifBackendInterface %d %d>' % (self.controller.dom, self.dom)
    8.36  
    8.37 +    def getEventChannelBackend(self):
    8.38 +        val = 0
    8.39 +        if self.evtchn:
    8.40 +            val = self.evtchn['port1']
    8.41 +        return val
    8.42 +
    8.43 +    def getEventChannelFrontend(self):
    8.44 +        val = 0
    8.45 +        if self.evtchn:
    8.46 +            val = self.evtchn['port2']
    8.47 +        return val
    8.48 +
    8.49      def connect(self, recreate=0):
    8.50          """Connect to the blkif control interface.
    8.51  
    8.52 @@ -105,7 +118,7 @@ class BlkifBackendInterface(controller.B
    8.53          msg = packMsg('blkif_be_connect_t',
    8.54                        { 'domid'        : self.controller.dom,
    8.55                          'blkif_handle' : self.handle,
    8.56 -                        'evtchn'       : self.evtchn['port1'],
    8.57 +                        'evtchn'       : self.getEventChannelBackend(),
    8.58                          'shmem_frame'  : val['shmem_frame'] })
    8.59          d = defer.Deferred()
    8.60          d.addCallback(self.respond_be_connect)
    8.61 @@ -118,31 +131,29 @@ class BlkifBackendInterface(controller.B
    8.62          @type  msg: xu message
    8.63          """
    8.64          val = unpackMsg('blkif_be_connect_t', msg)
    8.65 -        self.send_fe_interface_status_changed()
    8.66 +        self.status = BLKIF_INTERFACE_STATUS_CONNECTED
    8.67 +        self.send_fe_interface_status()
    8.68              
    8.69 -    def send_fe_interface_status_changed(self, response=None):
    8.70 -        msg = packMsg('blkif_fe_interface_status_changed_t',
    8.71 +    def send_fe_interface_status(self, response=None):
    8.72 +        msg = packMsg('blkif_fe_interface_status_t',
    8.73                        { 'handle' : self.handle,
    8.74 -                        'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
    8.75 +                        'status' : self.status,
    8.76                          'domid'  : self.dom,
    8.77 -                        'evtchn' : self.evtchn['port2'] })
    8.78 +                        'evtchn' : self.getEventChannelFrontend() })
    8.79          self.controller.writeRequest(msg, response=response)
    8.80  
    8.81      def interfaceDisconnected(self):
    8.82 -        msg = packMsg('blkif_fe_interface_status_changed_t',
    8.83 -                      { 'handle' : self.handle,
    8.84 -                        'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
    8.85 -                        'domid'  : self.dom,
    8.86 -                        'evtchn' : 0 })
    8.87 -        self.controller.writeRequest(msg)
    8.88 +        self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
    8.89 +        #todo?: Do this: self.evtchn = None
    8.90 +        self.send_fe_interface_status()
    8.91          
    8.92      def interfaceChanged(self):
    8.93          """Notify the front-end that devices have been added or removed.
    8.94          The front-end should then probe for devices.
    8.95          """
    8.96 -        msg = packMsg('blkif_fe_interface_status_changed_t',
    8.97 +        msg = packMsg('blkif_fe_interface_status_t',
    8.98                        { 'handle' : self.handle,
    8.99 -                        'status' : BLKIF_INTERFACE_STATUS_CHANGED,
   8.100 +                        'status' : BLKIF_INTERFACE_STATUS,
   8.101                          'domid'  : self.dom,
   8.102                          'evtchn' : 0 })
   8.103          self.controller.writeRequest(msg)
   8.104 @@ -199,25 +210,25 @@ class BlkifControllerFactory(controller.
   8.105          blkif = self.getControllerByDom(dom)
   8.106          return (blkif and blkif.getDevices()) or []
   8.107  
   8.108 -    def getDomainDevice(self, dom, vdev):
   8.109 +    def getDomainDevice(self, dom, idx):
   8.110          """Get a block device from a domain.
   8.111  
   8.112          @param dom: domain
   8.113          @type  dom: int
   8.114 -        @param vdev: device index
   8.115 -        @type  vdev: int
   8.116 +        @param idx: device index
   8.117 +        @type  idx: int
   8.118          @return: device
   8.119          @rtype:  device
   8.120          """
   8.121          blkif = self.getControllerByDom(dom)
   8.122 -        return (blkif and blkif.getDevice(vdev)) or None
   8.123 +        return (blkif and blkif.getDevice(idx)) or None
   8.124  
   8.125  class BlkDev(controller.SplitDev):
   8.126      """Info record for a block device.
   8.127      """
   8.128  
   8.129 -    def __init__(self, ctrl, config, vdev, mode, segment):
   8.130 -        controller.SplitDev.__init__(self,  segment['device'], ctrl)
   8.131 +    def __init__(self, idx, ctrl, config, vdev, mode, segment):
   8.132 +        controller.SplitDev.__init__(self, idx, ctrl)
   8.133          self.config = config
   8.134          self.dev = None
   8.135          self.uname = None
   8.136 @@ -251,7 +262,7 @@ class BlkDev(controller.SplitDev):
   8.137  
   8.138          @param change: change flag
   8.139          """
   8.140 -        log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
   8.141 +        log.debug("Destroying vbd domain=%d idx=%s", self.controller.dom, self.idx)
   8.142          d = self.send_be_vbd_destroy()
   8.143          if change:
   8.144              d.addCallback(lambda val: self.interfaceChanged())
   8.145 @@ -345,10 +356,9 @@ class BlkifController(controller.SplitCo
   8.146          Do not call directly - use createController() on the factory instead.
   8.147          """
   8.148          controller.SplitController.__init__(self, factory, dom)
   8.149 -        self.devices = {}
   8.150          self.addMethod(CMSG_BLKIF_FE,
   8.151 -                       CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
   8.152 -                       self.recv_fe_driver_status_changed)
   8.153 +                       CMSG_BLKIF_FE_DRIVER_STATUS,
   8.154 +                       self.recv_fe_driver_status)
   8.155          self.addMethod(CMSG_BLKIF_FE,
   8.156                         CMSG_BLKIF_FE_INTERFACE_CONNECT,
   8.157                         self.recv_fe_interface_connect)
   8.158 @@ -358,13 +368,7 @@ class BlkifController(controller.SplitCo
   8.159          val = ['blkif', ['dom', self.dom]]
   8.160          return val
   8.161  
   8.162 -    def getDevices(self):
   8.163 -        return self.devices.values()
   8.164 -
   8.165 -    def getDevice(self, vdev):
   8.166 -        return self.devices.get(vdev)
   8.167 -
   8.168 -    def addDevice(self, config, vdev, mode, segment):
   8.169 +    def addDevice(self, idx, config, vdev, mode, segment):
   8.170          """Add a device to the device table.
   8.171  
   8.172          @param vdev:     device index
   8.173 @@ -376,20 +380,18 @@ class BlkifController(controller.SplitCo
   8.174          @return: device
   8.175          @rtype:  BlkDev
   8.176          """
   8.177 -        if vdev in self.devices:
   8.178 -            raise XendError('device exists: ' + str(vdev))
   8.179 -        dev = BlkDev(self, config, vdev, mode, segment)
   8.180 -        self.devices[vdev] = dev
   8.181 +        if idx in self.devices:
   8.182 +            raise XendError('device exists: ' + str(idx))
   8.183 +        dev = BlkDev(idx, self, config, vdev, mode, segment)
   8.184 +        self.devices[idx] = dev
   8.185          return dev
   8.186  
   8.187 -    def delDevice(self, vdev):
   8.188 -        if vdev in self.devices:
   8.189 -            del self.devices[vdev]
   8.190 -
   8.191 -    def attachDevice(self, config, vdev, mode, segment, recreate=0):
   8.192 +    def attachDevice(self, idx, config, vdev, mode, segment, recreate=0):
   8.193          """Attach a device to the specified interface.
   8.194          On success the returned deferred will be called with the device.
   8.195  
   8.196 +        @param idx:      device id
   8.197 +        @param config:   device configuration
   8.198          @param vdev:     device index
   8.199          @type  vdev:     int
   8.200          @param mode:     read/write mode
   8.201 @@ -401,7 +403,7 @@ class BlkifController(controller.SplitCo
   8.202          @return: deferred
   8.203          @rtype:  Deferred
   8.204          """
   8.205 -        dev = self.addDevice(config, vdev, mode, segment)
   8.206 +        dev = self.addDevice(idx, config, vdev, mode, segment)
   8.207          if recreate:
   8.208              d = defer.succeed(dev)
   8.209          else:
   8.210 @@ -425,8 +427,9 @@ class BlkifController(controller.SplitCo
   8.211          for backend in self.getBackendInterfaces():
   8.212              backend.destroy()
   8.213  
   8.214 -    def recv_fe_driver_status_changed(self, msg, req):
   8.215 -        val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
   8.216 +    def recv_fe_driver_status(self, msg, req):
   8.217 +        val = unpackMsg('blkif_fe_driver_status_t', msg)
   8.218 +        print 'recv_fe_driver_status>', val
   8.219          for backend in self.getBackendInterfaces():
   8.220              backend.interfaceDisconnected()
   8.221  
   8.222 @@ -439,5 +442,6 @@ class BlkifController(controller.SplitCo
   8.223          else:
   8.224              log.error('interface connect on unknown interface: handle=%d', handle)
   8.225  
   8.226 +
   8.227      
   8.228  
     9.1 --- a/tools/python/xen/xend/server/controller.py	Wed Sep 22 11:02:20 2004 +0000
     9.2 +++ b/tools/python/xen/xend/server/controller.py	Thu Sep 23 13:42:03 2004 +0000
     9.3 @@ -522,6 +522,9 @@ class BackendInterface:
     9.4      def writeRequest(self, msg, response=None):
     9.5          return self.backend.writeRequest(msg, response=response)
     9.6  
     9.7 +    def writeResponse(self, msg):
     9.8 +        return self.backend.writeResponse(msg)
     9.9 +    
    9.10      def close(self):
    9.11          self.backend.deregisterInterface(self)
    9.12          self.controller.backendInterfaceClosed(self)
    9.13 @@ -536,6 +539,60 @@ class SplitController(Controller):
    9.14          Controller.__init__(self, factory, dom)
    9.15          self.backendInterfaces = {}
    9.16          self.backendHandle = 0
    9.17 +        self.devices = {}
    9.18 +
    9.19 +    def getDevices(self):
    9.20 +        """Get a list of the devices..
    9.21 +        """
    9.22 +        return self.devices.values()
    9.23 +
    9.24 +    def delDevice(self, idx):
    9.25 +        """Remove the device with the given index from the device table.
    9.26 +
    9.27 +        @param idx device index
    9.28 +        """
    9.29 +        if idx in self.devices:
    9.30 +            del self.devices[idx]
    9.31 +
    9.32 +    def getDevice(self, idx):
    9.33 +        """Get the device with a given index.
    9.34 +
    9.35 +        @param idx device index
    9.36 +        @return device (or None)
    9.37 +        """
    9.38 +        return self.devices.get(idx)
    9.39 +
    9.40 +    def findDevice(self, idx):
    9.41 +        """Find a device. If idx is non-negative,
    9.42 +        get the device with the given index. If idx is negative,
    9.43 +        look for the device with least index greater than -idx - 2.
    9.44 +        For example, if idx is -2, look for devices with index
    9.45 +        greater than 0, i.e. 1 or above.
    9.46 +
    9.47 +        @param idx device index
    9.48 +        @return device (or None)
    9.49 +        """
    9.50 +        if idx < 0:
    9.51 +            idx = -idx - 2
    9.52 +            val = None
    9.53 +            for dev in self.devices.values():
    9.54 +                if dev.idx <= idx: continue
    9.55 +                if (val is None) or (dev.idx < val.idx):
    9.56 +                    val = dev
    9.57 +        else:
    9.58 +            val = getDevice(idx)
    9.59 +        return val
    9.60 +
    9.61 +    def getMaxDeviceIdx(self):
    9.62 +        """Get the maximum id used by devices.
    9.63 +
    9.64 +        @return maximum idx
    9.65 +        """
    9.66 +        maxIdx = 0
    9.67 +        for dev in self.devices:
    9.68 +            if dev.idx > maxIdx:
    9.69 +                maxIdx = dev.idx
    9.70 +        return maxIdx
    9.71          
    9.72      def getBackendInterfaces(self):
    9.73          return self.backendInterfaces.values()
    10.1 --- a/tools/python/xen/xend/server/messages.py	Wed Sep 22 11:02:20 2004 +0000
    10.2 +++ b/tools/python/xen/xend/server/messages.py	Thu Sep 23 13:42:03 2004 +0000
    10.3 @@ -29,70 +29,106 @@ msg_formats.update(console_formats)
    10.4  CMSG_BLKIF_BE = 1
    10.5  CMSG_BLKIF_FE = 2
    10.6  
    10.7 -CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED =  0
    10.8 -CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED    = 32
    10.9 -CMSG_BLKIF_FE_INTERFACE_CONNECT        = 33
   10.10 -CMSG_BLKIF_FE_INTERFACE_DISCONNECT     = 34
   10.11 +CMSG_BLKIF_FE_INTERFACE_STATUS      =  0
   10.12 +CMSG_BLKIF_FE_DRIVER_STATUS         = 32
   10.13 +CMSG_BLKIF_FE_INTERFACE_CONNECT     = 33
   10.14 +CMSG_BLKIF_FE_INTERFACE_DISCONNECT  = 34
   10.15 +CMSG_BLKIF_FE_INTERFACE_QUERY       = 35
   10.16  
   10.17 -CMSG_BLKIF_BE_CREATE      = 0
   10.18 -CMSG_BLKIF_BE_DESTROY     = 1
   10.19 -CMSG_BLKIF_BE_CONNECT     = 2
   10.20 -CMSG_BLKIF_BE_DISCONNECT  = 3
   10.21 -CMSG_BLKIF_BE_VBD_CREATE  = 4
   10.22 -CMSG_BLKIF_BE_VBD_DESTROY = 5
   10.23 -CMSG_BLKIF_BE_VBD_GROW    = 6
   10.24 -CMSG_BLKIF_BE_VBD_SHRINK  = 7
   10.25 -CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED    = 32
   10.26 +CMSG_BLKIF_BE_CREATE                =  0
   10.27 +CMSG_BLKIF_BE_DESTROY               =  1
   10.28 +CMSG_BLKIF_BE_CONNECT               =  2
   10.29 +CMSG_BLKIF_BE_DISCONNECT            =  3
   10.30 +CMSG_BLKIF_BE_VBD_CREATE            =  4
   10.31 +CMSG_BLKIF_BE_VBD_DESTROY           =  5
   10.32 +CMSG_BLKIF_BE_VBD_GROW              =  6
   10.33 +CMSG_BLKIF_BE_VBD_SHRINK            =  7
   10.34 +CMSG_BLKIF_BE_DRIVER_STATUS         = 32
   10.35  
   10.36 -BLKIF_DRIVER_STATUS_DOWN  = 0
   10.37 -BLKIF_DRIVER_STATUS_UP    = 1
   10.38 +BLKIF_DRIVER_STATUS_DOWN            =  0
   10.39 +BLKIF_DRIVER_STATUS_UP              =  1
   10.40  
   10.41 -BLKIF_INTERFACE_STATUS_DESTROYED    = 0 #/* Interface doesn't exist.    */
   10.42 -BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
   10.43 -BLKIF_INTERFACE_STATUS_CONNECTED    = 2 #/* Exists and is connected.    */
   10.44 -BLKIF_INTERFACE_STATUS_CHANGED      = 3 #/* A device has been added or removed. */
   10.45 +BLKIF_INTERFACE_STATUS_CLOSED       =  0 #/* Interface doesn't exist.    */
   10.46 +BLKIF_INTERFACE_STATUS_DISCONNECTED =  1 #/* Exists but is disconnected. */
   10.47 +BLKIF_INTERFACE_STATUS_CONNECTED    =  2 #/* Exists and is connected.    */
   10.48 +BLKIF_INTERFACE_STATUS_CHANGED      =  3 #/* A device has been added or removed. */
   10.49  
   10.50 -BLKIF_BE_STATUS_OKAY                = 0
   10.51 -BLKIF_BE_STATUS_ERROR               = 1
   10.52 -BLKIF_BE_STATUS_INTERFACE_EXISTS    = 2
   10.53 -BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
   10.54 -BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
   10.55 -BLKIF_BE_STATUS_VBD_EXISTS          = 5
   10.56 -BLKIF_BE_STATUS_VBD_NOT_FOUND       = 6
   10.57 -BLKIF_BE_STATUS_OUT_OF_MEMORY       = 7
   10.58 -BLKIF_BE_STATUS_EXTENT_NOT_FOUND    = 8
   10.59 -BLKIF_BE_STATUS_MAPPING_ERROR       = 9
   10.60 +BLKIF_BE_STATUS_OKAY                =  0
   10.61 +BLKIF_BE_STATUS_ERROR               =  1
   10.62 +BLKIF_BE_STATUS_INTERFACE_EXISTS    =  2
   10.63 +BLKIF_BE_STATUS_INTERFACE_NOT_FOUND =  3
   10.64 +BLKIF_BE_STATUS_INTERFACE_CONNECTED =  4
   10.65 +BLKIF_BE_STATUS_VBD_EXISTS          =  5
   10.66 +BLKIF_BE_STATUS_VBD_NOT_FOUND       =  6
   10.67 +BLKIF_BE_STATUS_OUT_OF_MEMORY       =  7
   10.68 +BLKIF_BE_STATUS_EXTENT_NOT_FOUND    =  8
   10.69 +BLKIF_BE_STATUS_MAPPING_ERROR       =  9
   10.70  
   10.71  blkif_formats = {
   10.72      'blkif_be_connect_t':
   10.73      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT),
   10.74 +    # Connect be to fe (in response to blkif_fe_interface_connect_t).
   10.75  
   10.76      'blkif_be_create_t':
   10.77      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE),
   10.78 +    # Create be.
   10.79  
   10.80      'blkif_be_disconnect_t':
   10.81      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT),
   10.82 +    # Disconnect be from fe.
   10.83  
   10.84      'blkif_be_destroy_t':
   10.85      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY),
   10.86 +    # Destroy be (after disconnect).
   10.87 +    # Make be do this even if no disconnect (and destroy all vbd too).
   10.88  
   10.89      'blkif_be_vbd_create_t':
   10.90      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
   10.91 +    # Create a vbd device.
   10.92  
   10.93      'blkif_be_vbd_grow_t':
   10.94      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW),
   10.95 +    # Change the size of a vbd device. Remove?
   10.96 +    # Do in one go in blkif_be_vbd_create_t.
   10.97  
   10.98      'blkif_be_vbd_destroy_t':
   10.99      (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY),
  10.100 +    # Destroy a vbd.
  10.101  
  10.102 -    'blkif_fe_interface_status_changed_t':
  10.103 -    (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED),
  10.104 +    # Add message to query be for state and vbds.
  10.105 +
  10.106 +    'blkif_fe_interface_status_t':
  10.107 +    (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS),
  10.108 +    # Notify device status to fe.
  10.109 +    # Also used to notify 'any' device change with status BLKIF_INTERFACE_STATUS_CHANGED.
  10.110 +    # Rename to blkif_fe_interface_status.
  10.111  
  10.112 -    'blkif_fe_driver_status_changed_t':
  10.113 -    (CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED),
  10.114 +    'blkif_fe_driver_status_t':
  10.115 +    (CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS),
  10.116 +    # Comes from fe, treated as notifying that fe has come up/changed.
  10.117 +    # Xend sets be(s) to BLKIF_INTERFACE_STATUS_DISCONNECTED,
  10.118 +    # sends blkif_fe_interface_status_t to fe (from each be).
  10.119 +    #
  10.120 +    # Rename to blkif_fe_driver_status.
  10.121 +    # Reply with i/f count.
  10.122 +    # The i/f sends probes (using -ve trick), we reply with the info.
  10.123  
  10.124      'blkif_fe_interface_connect_t':
  10.125      (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT),
  10.126 +    # Comes from fe, passing shmem frame to use for be.
  10.127 +    # fe sends when gets blkif_fe_interface_status_t with state NETIF_INTERFACE_STATUS_DISCONNECTED.
  10.128 +    # Xend creates event channel and notifies be.
  10.129 +    # Then notifies fe of event channel with blkif_fe_interface_status_t.
  10.130 +
  10.131 +    # Add message to kick fe to probe for devices.
  10.132 +    # Just report new devices to fe?
  10.133 +
  10.134 +    # 
  10.135 +    # Add message for fe to probe a device.
  10.136 +    # And probing with id -1 should return first.
  10.137 +    # And probing with id -n should return first device with id > n.
  10.138 +    
  10.139 +    # Add message to query fe for state and vbds.
  10.140  }
  10.141  
  10.142  msg_formats.update(blkif_formats)
  10.143 @@ -104,24 +140,25 @@ msg_formats.update(blkif_formats)
  10.144  CMSG_NETIF_BE = 3
  10.145  CMSG_NETIF_FE = 4
  10.146  
  10.147 -CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED =  0
  10.148 -CMSG_NETIF_FE_DRIVER_STATUS_CHANGED    = 32
  10.149 -CMSG_NETIF_FE_INTERFACE_CONNECT        = 33
  10.150 -CMSG_NETIF_FE_INTERFACE_DISCONNECT     = 34
  10.151 +CMSG_NETIF_FE_INTERFACE_STATUS      =  0
  10.152 +CMSG_NETIF_FE_DRIVER_STATUS         = 32
  10.153 +CMSG_NETIF_FE_INTERFACE_CONNECT     = 33
  10.154 +CMSG_NETIF_FE_INTERFACE_DISCONNECT  = 34
  10.155 +CMSG_NETIF_FE_INTERFACE_QUERY       = 35
  10.156  
  10.157 -CMSG_NETIF_BE_CREATE      = 0
  10.158 -CMSG_NETIF_BE_DESTROY     = 1
  10.159 -CMSG_NETIF_BE_CONNECT     = 2
  10.160 -CMSG_NETIF_BE_DISCONNECT  = 3
  10.161 -CMSG_NETIF_BE_DRIVER_STATUS_CHANGED    = 32
  10.162 +CMSG_NETIF_BE_CREATE                =  0
  10.163 +CMSG_NETIF_BE_DESTROY               =  1
  10.164 +CMSG_NETIF_BE_CONNECT               =  2
  10.165 +CMSG_NETIF_BE_DISCONNECT            =  3
  10.166 +CMSG_NETIF_BE_DRIVER_STATUS         = 32
  10.167  
  10.168 -NETIF_INTERFACE_STATUS_DESTROYED    = 0 #/* Interface doesn't exist.    */
  10.169 -NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
  10.170 -NETIF_INTERFACE_STATUS_CONNECTED    = 2 #/* Exists and is connected.    */
  10.171 -NETIF_INTERFACE_STATUS_CHANGED      = 3 #/* A device has been added or removed. */
  10.172 +NETIF_INTERFACE_STATUS_CLOSED       =  0 #/* Interface doesn't exist.    */
  10.173 +NETIF_INTERFACE_STATUS_DISCONNECTED =  1 #/* Exists but is disconnected. */
  10.174 +NETIF_INTERFACE_STATUS_CONNECTED    =  2 #/* Exists and is connected.    */
  10.175 +NETIF_INTERFACE_STATUS_CHANGED      =  3 #/* A device has been added or removed. */
  10.176  
  10.177 -NETIF_DRIVER_STATUS_DOWN   = 0
  10.178 -NETIF_DRIVER_STATUS_UP     = 1
  10.179 +NETIF_DRIVER_STATUS_DOWN            =  0
  10.180 +NETIF_DRIVER_STATUS_UP              =  1
  10.181  
  10.182  netif_formats = {
  10.183      'netif_be_connect_t':
  10.184 @@ -136,17 +173,17 @@ netif_formats = {
  10.185      'netif_be_destroy_t':
  10.186      (CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY),
  10.187  
  10.188 -    'netif_be_driver_status_changed_t':
  10.189 -    (CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED),
  10.190 +    'netif_be_driver_status_t':
  10.191 +    (CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS),
  10.192  
  10.193 -    'netif_fe_driver_status_changed_t':
  10.194 -    (CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED),
  10.195 +    'netif_fe_driver_status_t':
  10.196 +    (CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS),
  10.197  
  10.198      'netif_fe_interface_connect_t':
  10.199      (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT),
  10.200  
  10.201 -    'netif_fe_interface_status_changed_t':
  10.202 -    (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED),
  10.203 +    'netif_fe_interface_status_t':
  10.204 +    (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS),
  10.205      }
  10.206  
  10.207  msg_formats.update(netif_formats)
  10.208 @@ -241,13 +278,15 @@ def unpackMsg(ty, msg):
  10.209          macs = []
  10.210          for (k, v) in args.items():
  10.211              if k.startswith('mac['):
  10.212 -                macs += k
  10.213 +                macs.append(k)
  10.214                  i = int(k[4:5])
  10.215                  mac[i] = v
  10.216              else:
  10.217                  pass
  10.218          if macs:
  10.219              args['mac'] = mac
  10.220 +            print 'macs=', macs
  10.221 +            print 'args=', args
  10.222              for k in macs:
  10.223                  del args[k]
  10.224      if DEBUG:
    11.1 --- a/tools/python/xen/xend/server/netif.py	Wed Sep 22 11:02:20 2004 +0000
    11.2 +++ b/tools/python/xen/xend/server/netif.py	Thu Sep 23 13:42:03 2004 +0000
    11.3 @@ -24,12 +24,12 @@ class NetifBackendController(controller.
    11.4      def __init__(self, ctrl, dom):
    11.5          controller.BackendController.__init__(self, ctrl, dom)
    11.6          self.addMethod(CMSG_NETIF_BE,
    11.7 -                       CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
    11.8 -                       self.recv_be_driver_status_changed)
    11.9 +                       CMSG_NETIF_BE_DRIVER_STATUS,
   11.10 +                       self.recv_be_driver_status)
   11.11          self.registerChannel()
   11.12  
   11.13 -    def recv_be_driver_status_changed(self, msg, req):
   11.14 -        val = unpackMsg('netif_be_driver_status_changed_t', msg)
   11.15 +    def recv_be_driver_status(self, msg, req):
   11.16 +        val = unpackMsg('netif_be_driver_status_t', msg)
   11.17          status = val['status']
   11.18  
   11.19  class NetifBackendInterface(controller.BackendInterface):
   11.20 @@ -98,11 +98,12 @@ class NetDev(controller.SplitDev):
   11.21      """Info record for a network device.
   11.22      """
   11.23  
   11.24 -    def __init__(self, ctrl, vif, config):
   11.25 +    def __init__(self, vif, ctrl, config):
   11.26          controller.SplitDev.__init__(self, vif, ctrl)
   11.27          self.vif = vif
   11.28          self.evtchn = None
   11.29          self.configure(config)
   11.30 +        self.status = NETIF_INTERFACE_STATUS_DISCONNECTED
   11.31  
   11.32      def _get_config_mac(self, config):
   11.33          vmac = sxp.child_value(config, 'mac')
   11.34 @@ -245,6 +246,18 @@ class NetDev(controller.SplitDev):
   11.35          d.addCallback(self.respond_be_create)
   11.36          return d
   11.37  
   11.38 +    def getEventChannelBackend(self):
   11.39 +        val = 0
   11.40 +        if self.evtchn:
   11.41 +            val = self.evtchn['port1']
   11.42 +        return val
   11.43 +
   11.44 +    def getEventChannelFrontend(self):
   11.45 +        val = 0
   11.46 +        if self.evtchn:
   11.47 +            val = self.evtchn['port2']
   11.48 +        return val
   11.49 +
   11.50      def send_be_create(self):
   11.51          d = defer.Deferred()
   11.52          msg = packMsg('netif_be_create_t',
   11.53 @@ -264,11 +277,12 @@ class NetDev(controller.SplitDev):
   11.54  
   11.55          @param change: change flag
   11.56          """
   11.57 +        self.status = NETIF_INTERFACE_STATUS_CLOSED
   11.58          def cb_destroy(val):
   11.59              self.send_be_destroy()
   11.60              self.getBackendInterface().close()
   11.61              if change:
   11.62 -                self.interfaceChanged()
   11.63 +                self.reportStatus()
   11.64          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
   11.65          self.vifctl('down')
   11.66          d = self.send_be_disconnect()
   11.67 @@ -295,7 +309,7 @@ class NetDev(controller.SplitDev):
   11.68          msg = packMsg('netif_be_connect_t',
   11.69                        { 'domid'          : self.controller.dom,
   11.70                          'netif_handle'   : self.vif,
   11.71 -                        'evtchn'         : self.evtchn['port1'],
   11.72 +                        'evtchn'         : self.getEventChannelBackend(),
   11.73                          'tx_shmem_frame' : val['tx_shmem_frame'],
   11.74                          'rx_shmem_frame' : val['rx_shmem_frame'] })
   11.75          d = defer.Deferred()
   11.76 @@ -306,34 +320,25 @@ class NetDev(controller.SplitDev):
   11.77          val = unpackMsg('netif_be_connect_t', msg)
   11.78          dom = val['domid']
   11.79          vif = val['netif_handle']
   11.80 -        msg = packMsg('netif_fe_interface_status_changed_t',
   11.81 +        self.status = NETIF_INTERFACE_STATUS_CONNECTED
   11.82 +        self.reportStatus()
   11.83 +
   11.84 +    def reportStatus(self, resp=0):
   11.85 +        msg = packMsg('netif_fe_interface_status_t',
   11.86                        { 'handle' : self.vif,
   11.87 -                        'status' : NETIF_INTERFACE_STATUS_CONNECTED,
   11.88 -                        'evtchn' : self.evtchn['port2'],
   11.89 +                        'status' : self.status,
   11.90 +                        'evtchn' : self.getEventChannelFrontend(),
   11.91                          'domid'  : self.backendDomain,
   11.92                          'mac'    : self.mac })
   11.93 -        self.controller.writeRequest(msg)
   11.94 -
   11.95 -    def attach_fe_device(self):
   11.96 -        msg = packMsg('netif_fe_interface_status_changed_t',
   11.97 -                      { 'handle' : self.vif,
   11.98 -                        'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
   11.99 -                        'evtchn' : 0,
  11.100 -                        'domid'  : self.backendDomain,
  11.101 -                        'mac'    : self.mac })
  11.102 -        self.controller.writeRequest(msg)
  11.103 +        if resp:
  11.104 +            self.controller.writeResponse(msg)
  11.105 +        else:
  11.106 +            self.controller.writeRequest(msg)
  11.107  
  11.108      def interfaceChanged(self):
  11.109          """Notify the font-end that a device has been added or removed.
  11.110 -        The front-end should then probe the devices.
  11.111          """
  11.112 -        msg = packMsg('netif_fe_interface_status_changed_t',
  11.113 -                      { 'handle' : self.vif,
  11.114 -                        'status' : NETIF_INTERFACE_STATUS_CHANGED,
  11.115 -                        'evtchn' : 0,
  11.116 -                        'domid'  : self.backendDomain,
  11.117 -                        'mac'    : self.mac })
  11.118 -        self.controller.writeRequest(msg)
  11.119 +        self.reportStatus()
  11.120          
  11.121  class NetifController(controller.SplitController):
  11.122      """Network interface controller. Handles all network devices for a domain.
  11.123 @@ -343,8 +348,11 @@ class NetifController(controller.SplitCo
  11.124          controller.SplitController.__init__(self, factory, dom)
  11.125          self.devices = {}
  11.126          self.addMethod(CMSG_NETIF_FE,
  11.127 -                       CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
  11.128 -                       self.recv_fe_driver_status_changed)
  11.129 +                       CMSG_NETIF_FE_DRIVER_STATUS,
  11.130 +                       self.recv_fe_driver_status)
  11.131 +        self.addMethod(CMSG_NETIF_FE,
  11.132 +                       CMSG_NETIF_FE_INTERFACE_STATUS,
  11.133 +                       self.recv_fe_interface_status)
  11.134          self.addMethod(CMSG_NETIF_FE,
  11.135                         CMSG_NETIF_FE_INTERFACE_CONNECT,
  11.136                         self.recv_fe_interface_connect)
  11.137 @@ -359,19 +367,6 @@ class NetifController(controller.SplitCo
  11.138          """
  11.139          controller.Controller.lostChannel(self)
  11.140  
  11.141 -    def getDevices(self):
  11.142 -        """Get a list of the devices.
  11.143 -        """
  11.144 -        return self.devices.values()
  11.145 -
  11.146 -    def getDevice(self, vif):
  11.147 -        """Get a device.
  11.148 -
  11.149 -        @param vif: device index
  11.150 -        @return: device (or None)
  11.151 -        """
  11.152 -        return self.devices.get(vif)
  11.153 -
  11.154      def addDevice(self, vif, config):
  11.155          """Add a network interface.
  11.156  
  11.157 @@ -381,14 +376,10 @@ class NetifController(controller.SplitCo
  11.158          """
  11.159          if vif in self.devices:
  11.160              raise XendError('device exists:' + str(vif))
  11.161 -        dev = NetDev(self, vif, config)
  11.162 +        dev = NetDev(vif, self, config)
  11.163          self.devices[vif] = dev
  11.164          return dev
  11.165  
  11.166 -    def delDevice(self, vif):
  11.167 -        if vif in self.devices:
  11.168 -            del self.devices[vif]
  11.169 -
  11.170      def destroy(self):
  11.171          """Destroy the controller and all devices.
  11.172          """
  11.173 @@ -415,23 +406,64 @@ class NetifController(controller.SplitCo
  11.174              d = dev.attach()
  11.175          return d
  11.176  
  11.177 -    def recv_fe_driver_status_changed(self, msg, req):
  11.178 +    def recv_fe_driver_status(self, msg, req):
  11.179          if not req: return
  11.180 -        msg = packMsg('netif_fe_driver_status_changed_t',
  11.181 +        print
  11.182 +        print 'recv_fe_driver_status>'
  11.183 +        msg = packMsg('netif_fe_driver_status_t',
  11.184                        { 'status'     : NETIF_DRIVER_STATUS_UP,
  11.185                          ## FIXME: max_handle should be max active interface id
  11.186 -                        'max_handle' : len(self.devices) })
  11.187 -        self.writeRequest(msg)
  11.188 -        for dev in self.devices.values():
  11.189 -            dev.attach_fe_device()
  11.190 +                        'max_handle' : len(self.devices)
  11.191 +                        #'max_handle' : self.getMaxDeviceIdx()
  11.192 +                        })
  11.193 +        # Two ways of doing it:
  11.194 +        # 1) front-end requests driver status, we reply with the interface count,
  11.195 +        #    front-end polls the interfaces,
  11.196 +        #    front-end checks they are all up
  11.197 +        # 2) front-end requests driver status, we reply (with anything),
  11.198 +        #    we notify the interfaces,
  11.199 +        #    we notify driver status up with the count
  11.200 +        #    front-end checks they are all up
  11.201 +        #
  11.202 +        # We really want to use 1), but at the moment the xenU kernel panics
  11.203 +        # in that mode, so we're sticking to 2) for now.
  11.204 +        resp = 0
  11.205 +        if resp:
  11.206 +            self.writeResponse(msg)
  11.207 +        else:
  11.208 +            for dev in self.devices.values():
  11.209 +                dev.reportStatus()
  11.210 +            self.writeRequest(msg)
  11.211 +        return resp
  11.212 +
  11.213 +    def recv_fe_interface_status(self, msg, req):
  11.214 +        if not req: return
  11.215 +        print
  11.216 +        val = unpackMsg('netif_fe_interface_status_t', msg)
  11.217 +        print "recv_fe_interface_status>", val
  11.218 +        vif = val['handle']
  11.219 +        dev = self.findDevice(vif)
  11.220 +        if dev:
  11.221 +            print 'recv_fe_interface_status>', 'dev=', dev
  11.222 +            dev.reportStatus(resp=1)
  11.223 +        else:
  11.224 +            msg = packMsg('netif_fe_interface_status_t',
  11.225 +                          { 'handle' : -1,
  11.226 +                            'status' : NETIF_INTERFACE_STATUS_CLOSED,
  11.227 +                            });
  11.228 +            print 'recv_fe_interface_status>', 'no dev, returning -1'
  11.229 +            self.writeResponse(msg)
  11.230 +        return 1
  11.231 +            
  11.232      
  11.233      def recv_fe_interface_connect(self, msg, req):
  11.234          val = unpackMsg('netif_fe_interface_connect_t', msg)
  11.235          vif = val['handle']
  11.236 -        dev = self.devices.get(vif)
  11.237 +        print
  11.238 +        print "recv_fe_interface_connect", val
  11.239 +        dev = self.getDevice(vif)
  11.240          if dev:
  11.241              dev.recv_fe_interface_connect(val, req)
  11.242          else:
  11.243              log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
  11.244                        self.dom, vif)
  11.245 -
    12.1 --- a/xen/include/hypervisor-ifs/io/domain_controller.h	Wed Sep 22 11:02:20 2004 +0000
    12.2 +++ b/xen/include/hypervisor-ifs/io/domain_controller.h	Thu Sep 23 13:42:03 2004 +0000
    12.3 @@ -70,10 +70,10 @@ typedef struct {
    12.4   */
    12.5  
    12.6  /* Messages from domain controller to guest. */
    12.7 -#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED   0
    12.8 +#define CMSG_BLKIF_FE_INTERFACE_STATUS           0
    12.9  
   12.10  /* Messages from guest to domain controller. */
   12.11 -#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED     32
   12.12 +#define CMSG_BLKIF_FE_DRIVER_STATUS             32
   12.13  #define CMSG_BLKIF_FE_INTERFACE_CONNECT         33
   12.14  #define CMSG_BLKIF_FE_INTERFACE_DISCONNECT      34
   12.15  #define CMSG_BLKIF_FE_INTERFACE_QUERY           35
   12.16 @@ -84,25 +84,25 @@ typedef struct {
   12.17  #define blkif_sector_t u64
   12.18  
   12.19  /*
   12.20 - * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
   12.21 + * CMSG_BLKIF_FE_INTERFACE_STATUS:
   12.22   *  Notify a guest about a status change on one of its block interfaces.
   12.23   *  If the interface is DESTROYED or DOWN then the interface is disconnected:
   12.24   *   1. The shared-memory frame is available for reuse.
   12.25   *   2. Any unacknowledged messages pending on the interface were dropped.
   12.26   */
   12.27 -#define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   12.28 +#define BLKIF_INTERFACE_STATUS_CLOSED       0 /* Interface doesn't exist.    */
   12.29  #define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   12.30  #define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   12.31 -#define BLKIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
   12.32 +//#define BLKIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
   12.33  typedef struct {
   12.34      u32 handle; /*  0 */
   12.35      u32 status; /*  4 */
   12.36      u16 evtchn; /*  8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
   12.37      domid_t domid; /* 10: status != BLKIF_INTERFACE_STATUS_DESTROYED */
   12.38 -} PACKED blkif_fe_interface_status_changed_t; /* 12 bytes */
   12.39 +} PACKED blkif_fe_interface_status_t; /* 12 bytes */
   12.40  
   12.41  /*
   12.42 - * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
   12.43 + * CMSG_BLKIF_FE_DRIVER_STATUS:
   12.44   *  Notify the domain controller that the front-end driver is DOWN or UP.
   12.45   *  When the driver goes DOWN then the controller will send no more
   12.46   *  status-change notifications.
   12.47 @@ -121,7 +121,7 @@ typedef struct {
   12.48      /* OUT */
   12.49      /* Driver should query interfaces [0..max_handle]. */
   12.50      u32 max_handle;    /*  4 */
   12.51 -} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
   12.52 +} PACKED blkif_fe_driver_status_t; /* 8 bytes */
   12.53  
   12.54  /*
   12.55   * CMSG_BLKIF_FE_INTERFACE_CONNECT:
   12.56 @@ -172,7 +172,7 @@ typedef struct {
   12.57  #define CMSG_BLKIF_BE_VBD_SHRINK  7  /* Remove last extent from a given VBD. */
   12.58  
   12.59  /* Messages to domain controller. */
   12.60 -#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
   12.61 +#define CMSG_BLKIF_BE_DRIVER_STATUS 32
   12.62  
   12.63  /*
   12.64   * Message request/response definitions for block-device messages.
   12.65 @@ -325,14 +325,14 @@ typedef struct {
   12.66  } PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
   12.67  
   12.68  /*
   12.69 - * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
   12.70 + * CMSG_BLKIF_BE_DRIVER_STATUS:
   12.71   *  Notify the domain controller that the back-end driver is DOWN or UP.
   12.72   *  If the driver goes DOWN while interfaces are still UP, the controller
   12.73   *  will automatically send DOWN notifications.
   12.74   */
   12.75  typedef struct {
   12.76      u32        status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   12.77 -} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
   12.78 +} PACKED blkif_be_driver_status_t; /* 4 bytes */
   12.79  
   12.80  
   12.81  /******************************************************************************
   12.82 @@ -340,22 +340,22 @@ typedef struct {
   12.83   */
   12.84  
   12.85  /* Messages from domain controller to guest. */
   12.86 -#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED   0
   12.87 +#define CMSG_NETIF_FE_INTERFACE_STATUS   0
   12.88  
   12.89  /* Messages from guest to domain controller. */
   12.90 -#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED     32
   12.91 +#define CMSG_NETIF_FE_DRIVER_STATUS             32
   12.92  #define CMSG_NETIF_FE_INTERFACE_CONNECT         33
   12.93  #define CMSG_NETIF_FE_INTERFACE_DISCONNECT      34
   12.94  #define CMSG_NETIF_FE_INTERFACE_QUERY           35
   12.95  
   12.96  /*
   12.97 - * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
   12.98 + * CMSG_NETIF_FE_INTERFACE_STATUS:
   12.99   *  Notify a guest about a status change on one of its network interfaces.
  12.100 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
  12.101 + *  If the interface is CLOSED or DOWN then the interface is disconnected:
  12.102   *   1. The shared-memory frame is available for reuse.
  12.103   *   2. Any unacknowledged messgaes pending on the interface were dropped.
  12.104   */
  12.105 -#define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
  12.106 +#define NETIF_INTERFACE_STATUS_CLOSED       0 /* Interface doesn't exist.    */
  12.107  #define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
  12.108  #define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
  12.109  #define NETIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
  12.110 @@ -365,17 +365,17 @@ typedef struct {
  12.111      u16        evtchn; /*  8: status == NETIF_INTERFACE_STATUS_CONNECTED */
  12.112      u8         mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
  12.113      domid_t    domid;  /* 16: status != NETIF_INTERFACE_STATUS_DESTROYED */
  12.114 -} PACKED netif_fe_interface_status_changed_t; /* 18 bytes */
  12.115 +} PACKED netif_fe_interface_status_t; /* 18 bytes */
  12.116  
  12.117  /*
  12.118 - * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
  12.119 + * CMSG_NETIF_FE_DRIVER_STATUS:
  12.120   *  Notify the domain controller that the front-end driver is DOWN or UP.
  12.121   *  When the driver goes DOWN then the controller will send no more
  12.122   *  status-change notifications.
  12.123   *  If the driver goes DOWN while interfaces are still UP, the domain
  12.124   *  will automatically take the interfaces DOWN.
  12.125   * 
  12.126 - *  NB. The controller should not send an INTERFACE_STATUS_CHANGED message
  12.127 + *  NB. The controller should not send an INTERFACE_STATUS message
  12.128   *  for interfaces that are active when it receives an UP notification. We
  12.129   *  expect that the frontend driver will query those interfaces itself.
  12.130   */
  12.131 @@ -387,7 +387,7 @@ typedef struct {
  12.132      /* OUT */
  12.133      /* Driver should query interfaces [0..max_handle]. */
  12.134      u32        max_handle;    /*  4 */
  12.135 -} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
  12.136 +} PACKED netif_fe_driver_status_t; /* 8 bytes */
  12.137  
  12.138  /*
  12.139   * CMSG_NETIF_FE_INTERFACE_CONNECT:
  12.140 @@ -437,7 +437,7 @@ typedef struct {
  12.141  #define CMSG_NETIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
  12.142  
  12.143  /* Messages to domain controller. */
  12.144 -#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
  12.145 +#define CMSG_NETIF_BE_DRIVER_STATUS 32
  12.146  
  12.147  /*
  12.148   * Message request/response definitions for net-device messages.
  12.149 @@ -533,14 +533,14 @@ typedef struct {
  12.150  } PACKED netif_be_disconnect_t; /* 12 bytes */
  12.151  
  12.152  /*
  12.153 - * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
  12.154 + * CMSG_NETIF_BE_DRIVER_STATUS:
  12.155   *  Notify the domain controller that the back-end driver is DOWN or UP.
  12.156   *  If the driver goes DOWN while interfaces are still UP, the domain
  12.157   *  will automatically send DOWN notifications.
  12.158   */
  12.159  typedef struct {
  12.160      u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
  12.161 -} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
  12.162 +} PACKED netif_be_driver_status_t; /* 4 bytes */
  12.163  
  12.164  
  12.165  /******************************************************************************