mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
bitkeeper revision 1.1159.1.168 (4152d33dmJ9oXFP7VWvfCRpxNf8e6g)
Merge xenbk@gandalf:/var/bk/xeno-unstable.bk into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
This commit is contained in:
commit
55bd4a36aa
13 files changed
+852
-550
No files matched your search
@@ -71,16 +71,16 @@ static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
|
||||
void blkif_ctrlif_init(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
blkif_be_driver_status_changed_t st;
|
||||
ctrl_msg_t cmsg;
|
||||
blkif_be_driver_status_t st;
|
||||
|
||||
(void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx,
|
||||
CALLBACK_IN_BLOCKING_CONTEXT);
|
||||
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_BLKIF_BE;
|
||||
cmsg.subtype = CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(blkif_be_driver_status_changed_t);
|
||||
cmsg.subtype = CMSG_BLKIF_BE_DRIVER_STATUS;
|
||||
cmsg.length = sizeof(blkif_be_driver_status_t);
|
||||
st.status = BLKIF_DRIVER_STATUS_UP;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
|
||||
@@ -1010,23 +1010,23 @@ void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
|
||||
}
|
||||
|
||||
|
||||
static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
|
||||
static void blkif_status_change(blkif_fe_interface_status_t *status)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
blkif_fe_interface_connect_t up;
|
||||
long rc;
|
||||
|
||||
if ( status->handle != 0 )
|
||||
{
|
||||
printk(KERN_WARNING "Status change on unsupported blkif %d\n",
|
||||
status->handle);
|
||||
return;
|
||||
}
|
||||
/* if ( status->handle != 0 ) */
|
||||
/* { */
|
||||
/* printk(KERN_WARNING "Status change on unsupported blkif %d\n", */
|
||||
/* status->handle); */
|
||||
/* return; */
|
||||
/* } */
|
||||
|
||||
switch ( status->status )
|
||||
{
|
||||
case BLKIF_INTERFACE_STATUS_DESTROYED:
|
||||
printk(KERN_WARNING "Unexpected blkif-DESTROYED message in state %d\n",
|
||||
case BLKIF_INTERFACE_STATUS_CLOSED:
|
||||
printk(KERN_WARNING "Unexpected blkif-CLOSED message in state %d\n",
|
||||
blkif_state);
|
||||
break;
|
||||
|
||||
@@ -1148,11 +1148,11 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
|
||||
|
||||
break;
|
||||
|
||||
case BLKIF_INTERFACE_STATUS_CHANGED:
|
||||
/* The domain controller is notifying us that a device has been
|
||||
* added or removed.
|
||||
*/
|
||||
break;
|
||||
// case BLKIF_INTERFACE_STATUS_CHANGED:
|
||||
// /* The domain controller is notifying us that a device has been
|
||||
// * added or removed.
|
||||
// */
|
||||
// break;
|
||||
|
||||
default:
|
||||
printk(KERN_WARNING "Status change to unknown value %d\n",
|
||||
@@ -1166,14 +1166,14 @@ static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
{
|
||||
switch ( msg->subtype )
|
||||
{
|
||||
case CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
|
||||
if ( msg->length != sizeof(blkif_fe_interface_status_changed_t) )
|
||||
case CMSG_BLKIF_FE_INTERFACE_STATUS:
|
||||
if ( msg->length != sizeof(blkif_fe_interface_status_t) )
|
||||
goto parse_error;
|
||||
blkif_status_change((blkif_fe_interface_status_changed_t *)
|
||||
blkif_status_change((blkif_fe_interface_status_t *)
|
||||
&msg->msg[0]);
|
||||
break;
|
||||
#if 0
|
||||
case CMSG_BLKIF_FE_VBD_STATUS_CHANGED:
|
||||
case CMSG_BLKIF_FE_VBD_STATUS:
|
||||
update_tq.routine = update_vbds_task;
|
||||
schedule_task(&update_tq);
|
||||
break;
|
||||
@@ -1194,7 +1194,7 @@ static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
int __init xlblk_init(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
blkif_fe_driver_status_changed_t st;
|
||||
blkif_fe_driver_status_t st;
|
||||
int i;
|
||||
|
||||
if ( (start_info.flags & SIF_INITDOMAIN)
|
||||
@@ -1215,8 +1215,8 @@ int __init xlblk_init(void)
|
||||
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_BLKIF_FE;
|
||||
cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(blkif_fe_driver_status_changed_t);
|
||||
cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS;
|
||||
cmsg.length = sizeof(blkif_fe_driver_status_t);
|
||||
st.status = BLKIF_DRIVER_STATUS_UP;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
@@ -1245,12 +1245,12 @@ void blkdev_suspend(void)
|
||||
void blkdev_resume(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
blkif_fe_driver_status_changed_t st;
|
||||
blkif_fe_driver_status_t st;
|
||||
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_BLKIF_FE;
|
||||
cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(blkif_fe_driver_status_changed_t);
|
||||
cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS;
|
||||
cmsg.length = sizeof(blkif_fe_driver_status_t);
|
||||
st.status = BLKIF_DRIVER_STATUS_UP;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
|
||||
@@ -49,16 +49,16 @@ static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
|
||||
void netif_ctrlif_init(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
netif_be_driver_status_changed_t st;
|
||||
ctrl_msg_t cmsg;
|
||||
netif_be_driver_status_t st;
|
||||
|
||||
(void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx,
|
||||
CALLBACK_IN_BLOCKING_CONTEXT);
|
||||
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_NETIF_BE;
|
||||
cmsg.subtype = CMSG_NETIF_BE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(netif_be_driver_status_changed_t);
|
||||
cmsg.subtype = CMSG_NETIF_BE_DRIVER_STATUS;
|
||||
cmsg.length = sizeof(netif_be_driver_status_t);
|
||||
st.status = NETIF_DRIVER_STATUS_UP;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
|
||||
@@ -29,13 +29,30 @@
|
||||
#include <net/arp.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#if 0
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#define DPRINTK(fmt, args...) \
|
||||
printk(KERN_INFO "[XEN] %s" fmt, __FUNCTION__, ##args)
|
||||
|
||||
#else
|
||||
|
||||
#define DPRINTK(fmt, args...) ((void)0)
|
||||
|
||||
#endif
|
||||
|
||||
#define IPRINTK(fmt, args...) \
|
||||
printk(KERN_INFO "[XEN]" fmt, ##args)
|
||||
|
||||
#define WPRINTK(fmt, args...) \
|
||||
printk(KERN_WARNING "[XEN]" fmt, ##args)
|
||||
|
||||
#define EPRINTK(fmt, args...) \
|
||||
printk(KERN_ERROR "[XEN]" fmt, ##args)
|
||||
|
||||
|
||||
|
||||
#ifndef __GFP_NOWARN
|
||||
#define __GFP_NOWARN 0
|
||||
#endif
|
||||
@@ -111,6 +128,24 @@ struct net_private
|
||||
struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
|
||||
};
|
||||
|
||||
static char * status_name[] = {
|
||||
[NETIF_INTERFACE_STATUS_CLOSED] = "closed",
|
||||
[NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
|
||||
[NETIF_INTERFACE_STATUS_CONNECTED] = "connected",
|
||||
[NETIF_INTERFACE_STATUS_CHANGED] = "changed",
|
||||
};
|
||||
|
||||
static char * be_state_name[] = {
|
||||
[BEST_CLOSED] = "closed",
|
||||
[BEST_DISCONNECTED] = "disconnected",
|
||||
[BEST_CONNECTED] = "connected",
|
||||
};
|
||||
|
||||
static char * user_state_name[] = {
|
||||
[UST_CLOSED] = "closed",
|
||||
[UST_OPEN] = "open",
|
||||
};
|
||||
|
||||
/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
|
||||
#define ADD_ID_TO_FREELIST(_list, _id) \
|
||||
(_list)[(_id)] = (_list)[0]; \
|
||||
@@ -141,6 +176,7 @@ struct netif_ctrl {
|
||||
int connected_n;
|
||||
/** Error code. */
|
||||
int err;
|
||||
int up;
|
||||
};
|
||||
|
||||
static struct netif_ctrl netctrl;
|
||||
@@ -148,15 +184,16 @@ static struct netif_ctrl netctrl;
|
||||
static void netctrl_init(void)
|
||||
{
|
||||
memset(&netctrl, 0, sizeof(netctrl));
|
||||
netctrl.interface_n = -1;
|
||||
netctrl.up = NETIF_DRIVER_STATUS_DOWN;
|
||||
}
|
||||
|
||||
/** Get or set a network interface error.
|
||||
*/
|
||||
static int netctrl_err(int err)
|
||||
{
|
||||
if ( (err < 0) && !netctrl.err )
|
||||
if ( (err < 0) && !netctrl.err ){
|
||||
netctrl.err = err;
|
||||
}
|
||||
return netctrl.err;
|
||||
}
|
||||
|
||||
@@ -167,8 +204,12 @@ static int netctrl_err(int err)
|
||||
static int netctrl_connected(void)
|
||||
{
|
||||
int ok = 0;
|
||||
ok = (netctrl.err ? netctrl.err :
|
||||
(netctrl.connected_n == netctrl.interface_n));
|
||||
|
||||
if(netctrl.err){
|
||||
ok = netctrl.err;
|
||||
} else if(netctrl.up == NETIF_DRIVER_STATUS_UP){
|
||||
ok = (netctrl.connected_n == netctrl.interface_n);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -185,11 +226,11 @@ static int netctrl_connected_count(void)
|
||||
|
||||
connected = 0;
|
||||
|
||||
list_for_each(ent, &dev_list)
|
||||
{
|
||||
list_for_each(ent, &dev_list) {
|
||||
np = list_entry(ent, struct net_private, list);
|
||||
if ( np->backend_state == BEST_CONNECTED )
|
||||
if (np->backend_state == BEST_CONNECTED){
|
||||
connected++;
|
||||
}
|
||||
}
|
||||
|
||||
netctrl.connected_n = connected;
|
||||
@@ -639,7 +680,7 @@ static struct net_device_stats *network_get_stats(struct net_device *dev)
|
||||
|
||||
|
||||
static void network_connect(struct net_device *dev,
|
||||
netif_fe_interface_status_changed_t *status)
|
||||
netif_fe_interface_status_t *status)
|
||||
{
|
||||
struct net_private *np;
|
||||
int i, requeue_idx;
|
||||
@@ -697,8 +738,8 @@ static void network_connect(struct net_device *dev,
|
||||
wmb();
|
||||
np->rx->req_prod = requeue_idx;
|
||||
|
||||
printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
|
||||
np->tx->req_prod,np->rx->req_prod);
|
||||
printk(KERN_ALERT "[XEN] Netfront recovered tx=%d rxfree=%d\n",
|
||||
np->tx->req_prod,np->rx->req_prod);
|
||||
|
||||
|
||||
/* Step 3: All public and private state should now be sane. Get
|
||||
@@ -718,130 +759,155 @@ printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
|
||||
spin_unlock_irq(&np->tx_lock);
|
||||
}
|
||||
|
||||
static void netif_status_change(netif_fe_interface_status_changed_t *status)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
netif_fe_interface_connect_t up;
|
||||
struct net_device *dev;
|
||||
struct net_private *np;
|
||||
|
||||
DPRINTK(">\n");
|
||||
DPRINTK("> status=%d handle=%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
status->status,
|
||||
status->handle,
|
||||
status->mac[0], status->mac[1], status->mac[2],
|
||||
status->mac[3], status->mac[4], status->mac[5]);
|
||||
|
||||
if ( netctrl.interface_n <= 0 )
|
||||
{
|
||||
printk(KERN_WARNING "Status change: no interfaces\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dev = find_dev_by_handle(status->handle);
|
||||
if(!dev){
|
||||
printk(KERN_WARNING "Status change: invalid netif handle %u\n",
|
||||
status->handle);
|
||||
return;
|
||||
}
|
||||
np = dev->priv;
|
||||
|
||||
switch ( status->status )
|
||||
{
|
||||
case NETIF_INTERFACE_STATUS_DESTROYED:
|
||||
printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n",
|
||||
np->backend_state);
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_DISCONNECTED:
|
||||
if ( np->backend_state != BEST_CLOSED )
|
||||
{
|
||||
printk(KERN_WARNING "Unexpected netif-DISCONNECTED message"
|
||||
" in state %d\n", np->backend_state);
|
||||
printk(KERN_INFO "Attempting to reconnect network interface\n");
|
||||
|
||||
/* Begin interface recovery.
|
||||
*
|
||||
* NB. Whilst we're recovering, we turn the carrier state off. We
|
||||
* take measures to ensure that this device isn't used for
|
||||
* anything. We also stop the queue for this device. Various
|
||||
* different approaches (e.g. continuing to buffer packets) have
|
||||
* been tested but don't appear to improve the overall impact on
|
||||
* TCP connections.
|
||||
*
|
||||
* TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
|
||||
* is initiated by a special "RESET" message - disconnect could
|
||||
* just mean we're not allowed to use this interface any more.
|
||||
*/
|
||||
|
||||
/* Stop old i/f to prevent errors whilst we rebuild the state. */
|
||||
spin_lock_irq(&np->tx_lock);
|
||||
spin_lock(&np->rx_lock);
|
||||
netif_stop_queue(dev);
|
||||
np->backend_state = BEST_DISCONNECTED;
|
||||
spin_unlock(&np->rx_lock);
|
||||
spin_unlock_irq(&np->tx_lock);
|
||||
|
||||
/* Free resources. */
|
||||
free_irq(np->irq, dev);
|
||||
unbind_evtchn_from_irq(np->evtchn);
|
||||
free_page((unsigned long)np->tx);
|
||||
free_page((unsigned long)np->rx);
|
||||
}
|
||||
|
||||
/* Move from CLOSED to DISCONNECTED state. */
|
||||
np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
|
||||
np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
|
||||
memset(np->tx, 0, PAGE_SIZE);
|
||||
memset(np->rx, 0, PAGE_SIZE);
|
||||
np->backend_state = BEST_DISCONNECTED;
|
||||
|
||||
/* Construct an interface-CONNECT message for the domain controller. */
|
||||
cmsg.type = CMSG_NETIF_FE;
|
||||
cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
|
||||
cmsg.length = sizeof(netif_fe_interface_connect_t);
|
||||
up.handle = status->handle;
|
||||
up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
|
||||
up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
|
||||
memcpy(cmsg.msg, &up, sizeof(up));
|
||||
|
||||
/* Tell the controller to bring up the interface. */
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CONNECTED:
|
||||
if ( np->backend_state == BEST_CLOSED )
|
||||
{
|
||||
printk(KERN_WARNING "Unexpected netif-CONNECTED message"
|
||||
" in state %d\n", np->backend_state);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(dev->dev_addr, status->mac, ETH_ALEN);
|
||||
|
||||
network_connect(dev, status);
|
||||
|
||||
np->evtchn = status->evtchn;
|
||||
np->irq = bind_evtchn_to_irq(np->evtchn);
|
||||
(void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM,
|
||||
dev->name, dev);
|
||||
netctrl_connected_count();
|
||||
vif_wake(dev);
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CHANGED:
|
||||
/* The domain controller is notifying us that a device has been
|
||||
* added or removed.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_WARNING "Status change to unknown value %d\n",
|
||||
status->status);
|
||||
break;
|
||||
static void vif_show(struct net_private *np){
|
||||
#if DEBUG
|
||||
if(np){
|
||||
IPRINTK(" <vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n",
|
||||
np->handle,
|
||||
be_state_name[np->backend_state],
|
||||
user_state_name[np->user_state],
|
||||
np->evtchn,
|
||||
np->irq,
|
||||
np->tx,
|
||||
np->rx);
|
||||
} else {
|
||||
IPRINTK("<vif NULL>\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Send a connect message to xend to tell it to bring up the interface.
|
||||
*/
|
||||
static void send_interface_connect(struct net_private *np){
|
||||
ctrl_msg_t cmsg = {
|
||||
.type = CMSG_NETIF_FE,
|
||||
.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT,
|
||||
.length = sizeof(netif_fe_interface_connect_t),
|
||||
};
|
||||
netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
|
||||
|
||||
DPRINTK(">\n"); vif_show(np);
|
||||
msg->handle = np->handle;
|
||||
msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
|
||||
msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
|
||||
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
DPRINTK("<\n");
|
||||
}
|
||||
|
||||
/* Send a driver status notification to the domain controller. */
|
||||
static int send_driver_status(int ok)
|
||||
{
|
||||
int err = 0;
|
||||
ctrl_msg_t cmsg = {
|
||||
.type = CMSG_NETIF_FE,
|
||||
.subtype = CMSG_NETIF_FE_DRIVER_STATUS,
|
||||
.length = sizeof(netif_fe_driver_status_t),
|
||||
};
|
||||
netif_fe_driver_status_t *msg = (void*)cmsg.msg;
|
||||
|
||||
msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN);
|
||||
err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Stop network device and free tx/rx queues and irq.
|
||||
*/
|
||||
static void vif_release(struct net_private *np){
|
||||
|
||||
/* Stop old i/f to prevent errors whilst we rebuild the state. */
|
||||
spin_lock_irq(&np->tx_lock);
|
||||
spin_lock(&np->rx_lock);
|
||||
netif_stop_queue(np->dev);
|
||||
//np->backend_state = BEST_DISCONNECTED;
|
||||
spin_unlock(&np->rx_lock);
|
||||
spin_unlock_irq(&np->tx_lock);
|
||||
|
||||
/* Free resources. */
|
||||
if(np->tx != NULL){
|
||||
free_irq(np->irq, np->dev);
|
||||
unbind_evtchn_from_irq(np->evtchn);
|
||||
free_page((unsigned long)np->tx);
|
||||
free_page((unsigned long)np->rx);
|
||||
np->irq = 0;
|
||||
np->evtchn = 0;
|
||||
np->tx = NULL;
|
||||
np->rx = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Release vif resources and close it down completely.
|
||||
*/
|
||||
static void vif_close(struct net_private *np){
|
||||
DPRINTK(">\n"); vif_show(np);
|
||||
WPRINTK(" Unexpected netif-CLOSED message in state %s\n",
|
||||
be_state_name[np->backend_state]);
|
||||
vif_release(np);
|
||||
np->backend_state = BEST_CLOSED;
|
||||
//todo: take dev down and free.
|
||||
vif_show(np); DPRINTK("<\n");
|
||||
}
|
||||
|
||||
/* Move the vif into disconnected state.
|
||||
* Allocates tx/rx pages.
|
||||
* Sends connect message to xend.
|
||||
*/
|
||||
static void vif_disconnect(struct net_private *np){
|
||||
DPRINTK(">\n");
|
||||
if(np->tx) free_page((unsigned long)np->tx);
|
||||
if(np->rx) free_page((unsigned long)np->rx);
|
||||
// Before this np->tx and np->rx had better be null.
|
||||
np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
|
||||
np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
|
||||
memset(np->tx, 0, PAGE_SIZE);
|
||||
memset(np->rx, 0, PAGE_SIZE);
|
||||
np->backend_state = BEST_DISCONNECTED;
|
||||
send_interface_connect(np);
|
||||
vif_show(np); DPRINTK("<\n");
|
||||
}
|
||||
|
||||
/* Begin interface recovery.
|
||||
*
|
||||
* NB. Whilst we're recovering, we turn the carrier state off. We
|
||||
* take measures to ensure that this device isn't used for
|
||||
* anything. We also stop the queue for this device. Various
|
||||
* different approaches (e.g. continuing to buffer packets) have
|
||||
* been tested but don't appear to improve the overall impact on
|
||||
* TCP connections.
|
||||
*
|
||||
* TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
|
||||
* is initiated by a special "RESET" message - disconnect could
|
||||
* just mean we're not allowed to use this interface any more.
|
||||
*/
|
||||
static void vif_reset(struct net_private *np){
|
||||
DPRINTK(">\n");
|
||||
IPRINTK(" Attempting to reconnect network interface: handle=%u\n",
|
||||
np->handle);
|
||||
|
||||
vif_release(np);
|
||||
vif_disconnect(np);
|
||||
vif_show(np); DPRINTK("<\n");
|
||||
}
|
||||
|
||||
/* Move the vif into connected state.
|
||||
* Sets the mac and event channel from the message.
|
||||
* Binds the irq to the event channel.
|
||||
*/
|
||||
static void vif_connect(struct net_private *np, netif_fe_interface_status_t *status){
|
||||
struct net_device *dev = np->dev;
|
||||
DPRINTK(">\n");
|
||||
memcpy(dev->dev_addr, status->mac, ETH_ALEN);
|
||||
network_connect(dev, status);
|
||||
np->evtchn = status->evtchn;
|
||||
np->irq = bind_evtchn_to_irq(np->evtchn);
|
||||
(void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
|
||||
netctrl_connected_count();
|
||||
vif_wake(dev);
|
||||
vif_show(np); DPRINTK("<\n");
|
||||
}
|
||||
|
||||
|
||||
/** Create a network device.
|
||||
* @param handle device handle
|
||||
* @param val return parameter for created device
|
||||
@@ -869,10 +935,12 @@ static int create_netdev(int handle, struct net_device **val)
|
||||
spin_lock_init(&np->rx_lock);
|
||||
|
||||
/* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
|
||||
for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
|
||||
for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ){
|
||||
np->tx_skbs[i] = (void *)(i+1);
|
||||
for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
|
||||
}
|
||||
for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ){
|
||||
np->rx_skbs[i] = (void *)(i+1);
|
||||
}
|
||||
|
||||
dev->open = network_open;
|
||||
dev->hard_start_xmit = network_start_xmit;
|
||||
@@ -890,58 +958,172 @@ static int create_netdev(int handle, struct net_device **val)
|
||||
list_add(&np->list, &dev_list);
|
||||
|
||||
exit:
|
||||
if ( (err != 0) && (dev != NULL ) )
|
||||
if ( (err != 0) && (dev != NULL ) ){
|
||||
kfree(dev);
|
||||
else if ( val != NULL )
|
||||
} else if ( val != NULL ) {
|
||||
*val = dev;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the network control interface. Set the number of network devices
|
||||
* and create them.
|
||||
/* Get the target interface for a status message.
|
||||
* Creates the interface when it makes sense.
|
||||
* The returned interface may be null when there is no error.
|
||||
*
|
||||
* @param status status message
|
||||
* @param np return parameter for interface state
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
|
||||
static void netif_driver_status_change(
|
||||
netif_fe_driver_status_changed_t *status)
|
||||
static int target_vif(netif_fe_interface_status_t *status, struct net_private **np)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
struct net_device *dev;
|
||||
|
||||
DPRINTK("> max_handle=%d\n", status->max_handle);
|
||||
|
||||
/* XXX FIXME: Abuse of 'max_handle' as interface count. */
|
||||
netctrl.interface_n = status->max_handle;
|
||||
netctrl.connected_n = 0;
|
||||
|
||||
for ( i = 0; i < netctrl.interface_n; i++ )
|
||||
{
|
||||
if ( (err = create_netdev(i, NULL)) != 0 )
|
||||
{
|
||||
netctrl_err(err);
|
||||
break;
|
||||
}
|
||||
DPRINTK("> handle=%d\n", status->handle);
|
||||
if(status->handle < 0) {
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
dev = find_dev_by_handle(status->handle);
|
||||
DPRINTK("> dev=%p\n", dev);
|
||||
if(dev) goto exit;
|
||||
// No good - give up.
|
||||
if(status->status == NETIF_INTERFACE_STATUS_CLOSED) goto exit;
|
||||
if(status->status == NETIF_INTERFACE_STATUS_CHANGED) goto exit;
|
||||
// It's a new interface in a good state - create it.
|
||||
DPRINTK("> create device...\n");
|
||||
err = create_netdev(status->handle, &dev);
|
||||
if(err) goto exit;
|
||||
netctrl.interface_n++;
|
||||
exit:
|
||||
if(np){
|
||||
*np = ((dev && !err) ? dev->priv : NULL);
|
||||
}
|
||||
DPRINTK("< err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Warn about an unexpected status. */
|
||||
static void unexpected(struct net_private *np,
|
||||
netif_fe_interface_status_t *status)
|
||||
{
|
||||
WPRINTK(" Unexpected netif status %s in state %s\n",
|
||||
status_name[status->status],
|
||||
be_state_name[np->backend_state]);
|
||||
}
|
||||
|
||||
/* Handle an interface status message. */
|
||||
static void netif_interface_status(netif_fe_interface_status_t *status)
|
||||
{
|
||||
int err = 0;
|
||||
struct net_private *np = NULL;
|
||||
|
||||
DPRINTK(">\n");
|
||||
DPRINTK("> status=%s handle=%d\n", status_name[status->status], status->handle);
|
||||
|
||||
err = target_vif(status, &np);
|
||||
if(err){
|
||||
WPRINTK(" Invalid netif: handle=%u\n", status->handle);
|
||||
return;
|
||||
}
|
||||
if(np == NULL){
|
||||
DPRINTK("> no vif\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTK(">\n"); vif_show(np);
|
||||
|
||||
switch (status->status) {
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CLOSED:
|
||||
switch(np->backend_state){
|
||||
|
||||
case BEST_CLOSED:
|
||||
case BEST_DISCONNECTED:
|
||||
case BEST_CONNECTED:
|
||||
vif_close(np);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_DISCONNECTED:
|
||||
switch(np->backend_state){
|
||||
|
||||
case BEST_CLOSED:
|
||||
vif_disconnect(np);
|
||||
break;
|
||||
|
||||
case BEST_DISCONNECTED:
|
||||
case BEST_CONNECTED:
|
||||
vif_reset(np);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CONNECTED:
|
||||
switch(np->backend_state){
|
||||
|
||||
case BEST_CLOSED:
|
||||
unexpected(np, status);
|
||||
vif_disconnect(np);
|
||||
vif_connect(np, status);
|
||||
break;
|
||||
|
||||
case BEST_DISCONNECTED:
|
||||
vif_connect(np, status);
|
||||
break;
|
||||
|
||||
case BEST_CONNECTED:
|
||||
//todo Do what?
|
||||
unexpected(np, status);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CHANGED:
|
||||
/* The domain controller is notifying us that a device has been
|
||||
* added or removed.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
WPRINTK(" Invalid netif status code %d\n", status->status);
|
||||
break;
|
||||
}
|
||||
vif_show(np);
|
||||
DPRINTK("<\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the network control interface.
|
||||
*/
|
||||
static void netif_driver_status(netif_fe_driver_status_t *status)
|
||||
{
|
||||
DPRINTK("> status=%d\n", status->status);
|
||||
netctrl.up = status->status;
|
||||
//netctrl.interface_n = status->max_handle;
|
||||
//netctrl.connected_n = 0;
|
||||
netctrl_connected_count();
|
||||
}
|
||||
|
||||
/* Receive handler for control messages. */
|
||||
static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
{
|
||||
int respond = 1;
|
||||
|
||||
switch ( msg->subtype )
|
||||
{
|
||||
case CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
|
||||
if ( msg->length != sizeof(netif_fe_interface_status_changed_t) )
|
||||
case CMSG_NETIF_FE_INTERFACE_STATUS:
|
||||
if ( msg->length != sizeof(netif_fe_interface_status_t) )
|
||||
goto error;
|
||||
netif_status_change((netif_fe_interface_status_changed_t *)
|
||||
&msg->msg[0]);
|
||||
netif_interface_status((netif_fe_interface_status_t *)
|
||||
&msg->msg[0]);
|
||||
break;
|
||||
|
||||
case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
|
||||
if ( msg->length != sizeof(netif_fe_driver_status_changed_t) )
|
||||
case CMSG_NETIF_FE_DRIVER_STATUS:
|
||||
if ( msg->length != sizeof(netif_fe_driver_status_t) )
|
||||
goto error;
|
||||
netif_driver_status_change((netif_fe_driver_status_changed_t *)
|
||||
&msg->msg[0]);
|
||||
netif_driver_status((netif_fe_driver_status_t *)
|
||||
&msg->msg[0]);
|
||||
break;
|
||||
|
||||
error:
|
||||
@@ -950,156 +1132,170 @@ static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( respond )
|
||||
ctrl_if_send_response(msg);
|
||||
ctrl_if_send_response(msg);
|
||||
}
|
||||
|
||||
|
||||
/* Wait for all interfaces to be connected. */
|
||||
static int wait_for_interfaces(void)
|
||||
#if 1
|
||||
/* Wait for all interfaces to be connected.
|
||||
*
|
||||
* This works OK, but we'd like to use the probing mode (see below).
|
||||
*/
|
||||
static int probe_interfaces(void)
|
||||
{
|
||||
int err = 0, conn = 0;
|
||||
int wait_i, wait_n = 100;
|
||||
|
||||
DPRINTK(">\n");
|
||||
|
||||
for ( wait_i = 0; wait_i < wait_n; wait_i++)
|
||||
{
|
||||
for ( wait_i = 0; wait_i < wait_n; wait_i++) {
|
||||
DPRINTK("> wait_i=%d\n", wait_i);
|
||||
conn = netctrl_connected();
|
||||
if(conn) break;
|
||||
DPRINTK("> schedule_timeout...\n");
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(10);
|
||||
}
|
||||
|
||||
if ( conn <= 0 )
|
||||
{
|
||||
DPRINTK("> wait finished...\n");
|
||||
if ( conn <= 0 ) {
|
||||
err = netctrl_err(-ENETDOWN);
|
||||
printk(KERN_WARNING "[XEN] Failed to connect all virtual interfaces: "
|
||||
"err=%d\n", err);
|
||||
WPRINTK(" Failed to connect all virtual interfaces: err=%d\n", err);
|
||||
}
|
||||
|
||||
DPRINTK("< err=%d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
/* Probe for interfaces until no more are found.
|
||||
*
|
||||
* This is the mode we'd like to use, but at the moment it panics the kernel.
|
||||
*/
|
||||
static int probe_interfaces(void)
|
||||
{
|
||||
int err = 0;
|
||||
int wait_i, wait_n = 100;
|
||||
ctrl_msg_t cmsg = {
|
||||
.type = CMSG_NETIF_FE,
|
||||
.subtype = CMSG_NETIF_FE_INTERFACE_STATUS,
|
||||
.length = sizeof(netif_fe_interface_status_t),
|
||||
};
|
||||
netif_fe_interface_status_t msg = {};
|
||||
ctrl_msg_t rmsg = {};
|
||||
netif_fe_interface_status_t *reply = (void*)rmsg.msg;
|
||||
int state = TASK_UNINTERRUPTIBLE;
|
||||
u32 query = -1;
|
||||
|
||||
DPRINTK(">\n");
|
||||
|
||||
netctrl.interface_n = 0;
|
||||
for (wait_i = 0; wait_i < wait_n; wait_i++) {
|
||||
DPRINTK("> wait_i=%d query=%d\n", wait_i, query);
|
||||
msg.handle = query;
|
||||
memcpy(cmsg.msg, &msg, sizeof(msg));
|
||||
DPRINTK("> set_current_state...\n");
|
||||
set_current_state(state);
|
||||
DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
|
||||
DPRINTK("> sending...\n");
|
||||
err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state);
|
||||
DPRINTK("> err=%d\n", err);
|
||||
if(err) goto exit;
|
||||
DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
|
||||
if((int)reply->handle < 0){
|
||||
// No more interfaces.
|
||||
break;
|
||||
}
|
||||
query = -reply->handle - 2;
|
||||
DPRINTK(">netif_interface_status ...\n");
|
||||
netif_interface_status(reply);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (err) {
|
||||
err = netctrl_err(-ENETDOWN);
|
||||
WPRINTK(" Connecting virtual network interfaces failed: err=%d\n", err);
|
||||
}
|
||||
|
||||
DPRINTK("< err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int __init netif_init(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
netif_fe_driver_status_changed_t st;
|
||||
int err = 0;
|
||||
|
||||
if ( (start_info.flags & SIF_INITDOMAIN) ||
|
||||
(start_info.flags & SIF_NET_BE_DOMAIN) )
|
||||
return 0;
|
||||
|
||||
printk(KERN_INFO "Initialising Xen virtual ethernet frontend driver.\n");
|
||||
|
||||
IPRINTK(" Initialising virtual ethernet driver.\n");
|
||||
INIT_LIST_HEAD(&dev_list);
|
||||
|
||||
netctrl_init();
|
||||
|
||||
(void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
|
||||
CALLBACK_IN_BLOCKING_CONTEXT);
|
||||
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_NETIF_FE;
|
||||
cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(netif_fe_driver_status_changed_t);
|
||||
st.status = NETIF_DRIVER_STATUS_UP;
|
||||
st.max_handle = 0;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
|
||||
err = wait_for_interfaces();
|
||||
send_driver_status(1);
|
||||
err = probe_interfaces();
|
||||
if ( err )
|
||||
ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
|
||||
|
||||
DPRINTK("< err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void vif_suspend(struct net_private *np)
|
||||
{
|
||||
// Avoid having tx/rx stuff happen until we're ready.
|
||||
DPRINTK(">\n");
|
||||
free_irq(np->irq, np->dev);
|
||||
unbind_evtchn_from_irq(np->evtchn);
|
||||
DPRINTK("<\n");
|
||||
}
|
||||
|
||||
static void vif_resume(struct net_private *np)
|
||||
{
|
||||
// Connect regardless of whether IFF_UP flag set.
|
||||
// Stop bad things from happening until we're back up.
|
||||
DPRINTK(">\n");
|
||||
np->backend_state = BEST_DISCONNECTED;
|
||||
memset(np->tx, 0, PAGE_SIZE);
|
||||
memset(np->rx, 0, PAGE_SIZE);
|
||||
|
||||
send_interface_connect(np);
|
||||
DPRINTK("<\n");
|
||||
}
|
||||
|
||||
void netif_suspend(void)
|
||||
{
|
||||
#if 1 /* XXX THIS IS TEMPORARY */
|
||||
struct net_device *dev = NULL;
|
||||
struct net_private *np = NULL;
|
||||
int i;
|
||||
|
||||
/* avoid having tx/rx stuff happen until we're ready */
|
||||
|
||||
for(i=0;i<netctrl.interface_n;i++)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
sprintf(name,"eth%d",i);
|
||||
dev = __dev_get_by_name(name);
|
||||
|
||||
if ( dev )
|
||||
{
|
||||
np = dev->priv;
|
||||
free_irq(np->irq, dev);
|
||||
unbind_evtchn_from_irq(np->evtchn);
|
||||
}
|
||||
struct list_head *ent;
|
||||
struct net_private *np;
|
||||
|
||||
DPRINTK(">\n");
|
||||
list_for_each(ent, &dev_list){
|
||||
np = list_entry(ent, struct net_private, list);
|
||||
vif_suspend(np);
|
||||
}
|
||||
DPRINTK("<\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void netif_resume(void)
|
||||
{
|
||||
ctrl_msg_t cmsg;
|
||||
netif_fe_interface_connect_t up;
|
||||
struct net_device *dev = NULL;
|
||||
struct net_private *np = NULL;
|
||||
int i;
|
||||
|
||||
#if 1
|
||||
/* XXX THIS IS TEMPORARY */
|
||||
struct list_head *ent;
|
||||
struct net_private *np;
|
||||
|
||||
for(i=0;i<netctrl.interface_n;i++)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
sprintf(name,"eth%d",i);
|
||||
dev = __dev_get_by_name(name);
|
||||
|
||||
if ( dev ) // connect regardless of whether IFF_UP flag set
|
||||
{
|
||||
np = dev->priv;
|
||||
|
||||
// stop bad things from happening until we're back up
|
||||
np->backend_state = BEST_DISCONNECTED;
|
||||
|
||||
memset(np->tx,0,PAGE_SIZE);
|
||||
memset(np->rx,0,PAGE_SIZE);
|
||||
|
||||
cmsg.type = CMSG_NETIF_FE;
|
||||
cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
|
||||
cmsg.length = sizeof(netif_fe_interface_connect_t);
|
||||
up.handle = np->handle;
|
||||
up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
|
||||
up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
|
||||
memcpy(cmsg.msg, &up, sizeof(up));
|
||||
|
||||
/* Tell the controller to bring up the interface. */
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
}
|
||||
DPRINTK(">\n");
|
||||
list_for_each(ent, &dev_list){
|
||||
np = list_entry(ent, struct net_private, list);
|
||||
vif_resume(np);
|
||||
}
|
||||
DPRINTK("<\n");
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Send a driver-UP notification to the domain controller. */
|
||||
cmsg.type = CMSG_NETIF_FE;
|
||||
cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
|
||||
cmsg.length = sizeof(netif_fe_driver_status_changed_t);
|
||||
st.status = NETIF_DRIVER_STATUS_UP;
|
||||
st.max_handle = 0;
|
||||
memcpy(cmsg.msg, &st, sizeof(st));
|
||||
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -324,11 +324,11 @@ static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args)
|
||||
|
||||
switch ( TYPE(xum->msg.type, xum->msg.subtype) )
|
||||
{
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
|
||||
P2C(blkif_fe_driver_status_changed_t, max_handle, u32);
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
|
||||
P2C(blkif_fe_driver_status_t, max_handle, u32);
|
||||
break;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
|
||||
P2C(netif_fe_driver_status_changed_t, max_handle, u32);
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
|
||||
P2C(netif_fe_driver_status_t, max_handle, u32);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -352,13 +352,13 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
|
||||
|
||||
switch ( TYPE(xum->msg.type, xum->msg.subtype) )
|
||||
{
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
|
||||
C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
|
||||
C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
|
||||
C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
|
||||
C2P(blkif_fe_interface_status_t, handle, Int, Long);
|
||||
C2P(blkif_fe_interface_status_t, status, Int, Long);
|
||||
C2P(blkif_fe_interface_status_t, evtchn, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
|
||||
C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
|
||||
C2P(blkif_fe_driver_status_t, status, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
|
||||
C2P(blkif_fe_interface_connect_t, handle, Int, Long);
|
||||
@@ -419,23 +419,23 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
|
||||
C2P(blkif_be_vbd_shrink_t, vdevice, Int, Long);
|
||||
C2P(blkif_be_vbd_shrink_t, status, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
|
||||
C2P(blkif_be_driver_status_changed_t, status, Int, Long);
|
||||
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS):
|
||||
C2P(blkif_be_driver_status_t, status, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
|
||||
C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, status, Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
|
||||
C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
|
||||
C2P(netif_fe_interface_status_t, handle, Int, Long);
|
||||
C2P(netif_fe_interface_status_t, status, Int, Long);
|
||||
C2P(netif_fe_interface_status_t, evtchn, Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[0], Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[1], Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[2], Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[3], Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[4], Int, Long);
|
||||
C2P(netif_fe_interface_status_t, mac[5], Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
|
||||
C2P(netif_fe_driver_status_changed_t, status, Int, Long);
|
||||
C2P(netif_fe_driver_status_changed_t, max_handle, Int, Long);
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
|
||||
C2P(netif_fe_driver_status_t, status, Int, Long);
|
||||
C2P(netif_fe_driver_status_t, max_handle, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
|
||||
C2P(netif_fe_interface_connect_t, handle, Int, Long);
|
||||
@@ -468,8 +468,8 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
|
||||
C2P(netif_be_disconnect_t, netif_handle, Int, Long);
|
||||
C2P(netif_be_disconnect_t, status, Int, Long);
|
||||
return dict;
|
||||
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
|
||||
C2P(netif_be_driver_status_changed_t, status, Int, Long);
|
||||
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS):
|
||||
C2P(netif_be_driver_status_t, status, Int, Long);
|
||||
return dict;
|
||||
}
|
||||
|
||||
@@ -543,11 +543,11 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
|
||||
|
||||
switch ( TYPE(type, subtype) )
|
||||
{
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
|
||||
P2C(blkif_fe_interface_status_changed_t, handle, u32);
|
||||
P2C(blkif_fe_interface_status_changed_t, status, u32);
|
||||
P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
|
||||
P2C(blkif_fe_interface_status_changed_t, domid, u16);
|
||||
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
|
||||
P2C(blkif_fe_interface_status_t, handle, u32);
|
||||
P2C(blkif_fe_interface_status_t, status, u32);
|
||||
P2C(blkif_fe_interface_status_t, evtchn, u16);
|
||||
P2C(blkif_fe_interface_status_t, domid, u16);
|
||||
break;
|
||||
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
|
||||
P2C(blkif_be_create_t, domid, u32);
|
||||
@@ -591,17 +591,17 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
|
||||
P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
|
||||
P2C(blkif_be_vbd_shrink_t, vdevice, blkif_vdev_t);
|
||||
break;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
|
||||
P2C(netif_fe_interface_status_changed_t, handle, u32);
|
||||
P2C(netif_fe_interface_status_changed_t, status, u32);
|
||||
P2C(netif_fe_interface_status_changed_t, evtchn, u16);
|
||||
P2C(netif_fe_interface_status_changed_t, domid, u16);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[0], u8);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[1], u8);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[2], u8);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[3], u8);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[4], u8);
|
||||
P2C(netif_fe_interface_status_changed_t, mac[5], u8);
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
|
||||
P2C(netif_fe_interface_status_t, handle, u32);
|
||||
P2C(netif_fe_interface_status_t, status, u32);
|
||||
P2C(netif_fe_interface_status_t, evtchn, u16);
|
||||
P2C(netif_fe_interface_status_t, domid, u16);
|
||||
P2C(netif_fe_interface_status_t, mac[0], u8);
|
||||
P2C(netif_fe_interface_status_t, mac[1], u8);
|
||||
P2C(netif_fe_interface_status_t, mac[2], u8);
|
||||
P2C(netif_fe_interface_status_t, mac[3], u8);
|
||||
P2C(netif_fe_interface_status_t, mac[4], u8);
|
||||
P2C(netif_fe_interface_status_t, mac[5], u8);
|
||||
break;
|
||||
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
|
||||
P2C(netif_be_create_t, domid, u32);
|
||||
@@ -628,9 +628,9 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
|
||||
P2C(netif_be_disconnect_t, domid, u32);
|
||||
P2C(netif_be_disconnect_t, netif_handle, u32);
|
||||
break;
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
|
||||
P2C(netif_fe_driver_status_changed_t, status, u32);
|
||||
P2C(netif_fe_driver_status_changed_t, max_handle, u32);
|
||||
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
|
||||
P2C(netif_fe_driver_status_t, status, u32);
|
||||
P2C(netif_fe_driver_status_t, max_handle, u32);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,14 +239,14 @@ class XendDomain:
|
||||
destroyed = 0
|
||||
for d in casualties:
|
||||
id = str(d['dom'])
|
||||
log.debug('XendDomain>reap> domain died id=%s', id)
|
||||
dominfo = self.domain_by_id.get(id)
|
||||
name = (dominfo and dominfo.name) or '??'
|
||||
log.debug('XendDomain>reap> domain died name=%s id=%s', name, id)
|
||||
if d['shutdown']:
|
||||
reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
|
||||
log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
|
||||
dominfo = self.domain_by_id.get(id)
|
||||
name = (dominfo and dominfo.name) or '??'
|
||||
if reason in ['suspend']:
|
||||
if dominfo.is_terminated():
|
||||
if dominfo and dominfo.is_terminated():
|
||||
log.debug('XendDomain>reap> Suspended domain died id=%s', id)
|
||||
else:
|
||||
eserver.inject('xend.domain.suspended', [name, id])
|
||||
|
||||
@@ -155,6 +155,7 @@ def make_disk(vm, config, uname, dev, mode, recreate=0):
|
||||
@param recreate: recreate flag (after xend restart)
|
||||
@return: deferred
|
||||
"""
|
||||
idx = vm.next_device_index('vbd')
|
||||
segments = lookup_disk_uname(uname)
|
||||
if not segments:
|
||||
raise VmError("vbd: Segments not found: uname=%s" % uname)
|
||||
@@ -166,7 +167,7 @@ def make_disk(vm, config, uname, dev, mode, recreate=0):
|
||||
if not vdev:
|
||||
raise VmError("vbd: Device not found: uname=%s dev=%s" % (uname, dev))
|
||||
ctrl = xend.blkif_create(vm.dom, recreate=recreate)
|
||||
return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
|
||||
return ctrl.attachDevice(idx, config, vdev, mode, segment, recreate=recreate)
|
||||
|
||||
def vif_up(iplist):
|
||||
"""send an unsolicited ARP reply for all non link-local IP addresses.
|
||||
|
||||
@@ -651,20 +651,6 @@ class Daemon:
|
||||
def blkif_get(self, dom):
|
||||
return self.blkifCF.getControllerByDom(dom)
|
||||
|
||||
def blkif_dev(self, dom, vdev):
|
||||
return self.blkifCF.getDomainDevice(dom, vdev)
|
||||
|
||||
def blkif_dev_create(self, dom, config, vdev, mode, segment, recreate=0):
|
||||
"""Create a block device.
|
||||
|
||||
Returns Deferred
|
||||
"""
|
||||
ctrl = self.blkifCF.getControllerByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No blkif controller: %d' % dom)
|
||||
d = ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
|
||||
return d
|
||||
|
||||
def netif_create(self, dom, recreate=0):
|
||||
"""Create or get a network interface controller.
|
||||
|
||||
@@ -677,19 +663,6 @@ class Daemon:
|
||||
def netif_get(self, dom):
|
||||
return self.netifCF.getControllerByDom(dom)
|
||||
|
||||
def netif_dev_create(self, dom, vif, config, recreate=0):
|
||||
"""Create a network device.
|
||||
|
||||
"""
|
||||
ctrl = self.netifCF.getControllerByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No netif controller: %d' % dom)
|
||||
d = ctrl.attachDevice(vif, config, recreate=recreate)
|
||||
return d
|
||||
|
||||
def netif_dev(self, dom, vif):
|
||||
return self.netifCF.getDomainDevice(dom, vif)
|
||||
|
||||
def console_create(self, dom, console_port=None):
|
||||
"""Create a console for a domain.
|
||||
"""
|
||||
|
||||
@@ -19,19 +19,19 @@ class BlkifBackendController(controller.BackendController):
|
||||
def __init__(self, factory, dom):
|
||||
controller.BackendController.__init__(self, factory, dom)
|
||||
self.addMethod(CMSG_BLKIF_BE,
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS,
|
||||
self.recv_be_driver_status)
|
||||
self.registerChannel()
|
||||
|
||||
def recv_be_driver_status_changed(self, msg, req):
|
||||
"""Request handler for be_driver_status_changed messages.
|
||||
def recv_be_driver_status(self, msg, req):
|
||||
"""Request handler for be_driver_status messages.
|
||||
|
||||
@param msg: message
|
||||
@type msg: xu message
|
||||
@param req: request flag (true if the msg is a request)
|
||||
@type req: bool
|
||||
"""
|
||||
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
|
||||
val = unpackMsg('blkif_be_driver_status_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class BlkifBackendInterface(controller.BackendInterface):
|
||||
@@ -45,10 +45,23 @@ class BlkifBackendInterface(controller.BackendInterface):
|
||||
controller.BackendInterface.__init__(self, ctrl, dom, handle)
|
||||
self.connected = 0
|
||||
self.evtchn = None
|
||||
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
|
||||
|
||||
def __str__(self):
|
||||
return '<BlkifBackendInterface %d %d>' % (self.controller.dom, self.dom)
|
||||
|
||||
def getEventChannelBackend(self):
|
||||
val = 0
|
||||
if self.evtchn:
|
||||
val = self.evtchn['port1']
|
||||
return val
|
||||
|
||||
def getEventChannelFrontend(self):
|
||||
val = 0
|
||||
if self.evtchn:
|
||||
val = self.evtchn['port2']
|
||||
return val
|
||||
|
||||
def connect(self, recreate=0):
|
||||
"""Connect to the blkif control interface.
|
||||
|
||||
@@ -105,7 +118,7 @@ class BlkifBackendInterface(controller.BackendInterface):
|
||||
msg = packMsg('blkif_be_connect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle,
|
||||
'evtchn' : self.evtchn['port1'],
|
||||
'evtchn' : self.getEventChannelBackend(),
|
||||
'shmem_frame' : val['shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_connect)
|
||||
@@ -118,31 +131,29 @@ class BlkifBackendInterface(controller.BackendInterface):
|
||||
@type msg: xu message
|
||||
"""
|
||||
val = unpackMsg('blkif_be_connect_t', msg)
|
||||
self.send_fe_interface_status_changed()
|
||||
self.status = BLKIF_INTERFACE_STATUS_CONNECTED
|
||||
self.send_fe_interface_status()
|
||||
|
||||
def send_fe_interface_status_changed(self, response=None):
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
def send_fe_interface_status(self, response=None):
|
||||
msg = packMsg('blkif_fe_interface_status_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
|
||||
'status' : self.status,
|
||||
'domid' : self.dom,
|
||||
'evtchn' : self.evtchn['port2'] })
|
||||
'evtchn' : self.getEventChannelFrontend() })
|
||||
self.controller.writeRequest(msg, response=response)
|
||||
|
||||
def interfaceDisconnected(self):
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
'domid' : self.dom,
|
||||
'evtchn' : 0 })
|
||||
self.controller.writeRequest(msg)
|
||||
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
|
||||
#todo?: Do this: self.evtchn = None
|
||||
self.send_fe_interface_status()
|
||||
|
||||
def interfaceChanged(self):
|
||||
"""Notify the front-end that devices have been added or removed.
|
||||
The front-end should then probe for devices.
|
||||
"""
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
msg = packMsg('blkif_fe_interface_status_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CHANGED,
|
||||
'status' : BLKIF_INTERFACE_STATUS,
|
||||
'domid' : self.dom,
|
||||
'evtchn' : 0 })
|
||||
self.controller.writeRequest(msg)
|
||||
@@ -199,25 +210,25 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
|
||||
blkif = self.getControllerByDom(dom)
|
||||
return (blkif and blkif.getDevices()) or []
|
||||
|
||||
def getDomainDevice(self, dom, vdev):
|
||||
def getDomainDevice(self, dom, idx):
|
||||
"""Get a block device from a domain.
|
||||
|
||||
@param dom: domain
|
||||
@type dom: int
|
||||
@param vdev: device index
|
||||
@type vdev: int
|
||||
@param idx: device index
|
||||
@type idx: int
|
||||
@return: device
|
||||
@rtype: device
|
||||
"""
|
||||
blkif = self.getControllerByDom(dom)
|
||||
return (blkif and blkif.getDevice(vdev)) or None
|
||||
return (blkif and blkif.getDevice(idx)) or None
|
||||
|
||||
class BlkDev(controller.SplitDev):
|
||||
"""Info record for a block device.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, config, vdev, mode, segment):
|
||||
controller.SplitDev.__init__(self, segment['device'], ctrl)
|
||||
def __init__(self, idx, ctrl, config, vdev, mode, segment):
|
||||
controller.SplitDev.__init__(self, idx, ctrl)
|
||||
self.config = config
|
||||
self.dev = None
|
||||
self.uname = None
|
||||
@@ -251,7 +262,7 @@ class BlkDev(controller.SplitDev):
|
||||
|
||||
@param change: change flag
|
||||
"""
|
||||
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
|
||||
log.debug("Destroying vbd domain=%d idx=%s", self.controller.dom, self.idx)
|
||||
d = self.send_be_vbd_destroy()
|
||||
if change:
|
||||
d.addCallback(lambda val: self.interfaceChanged())
|
||||
@@ -345,10 +356,9 @@ class BlkifController(controller.SplitController):
|
||||
Do not call directly - use createController() on the factory instead.
|
||||
"""
|
||||
controller.SplitController.__init__(self, factory, dom)
|
||||
self.devices = {}
|
||||
self.addMethod(CMSG_BLKIF_FE,
|
||||
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_fe_driver_status_changed)
|
||||
CMSG_BLKIF_FE_DRIVER_STATUS,
|
||||
self.recv_fe_driver_status)
|
||||
self.addMethod(CMSG_BLKIF_FE,
|
||||
CMSG_BLKIF_FE_INTERFACE_CONNECT,
|
||||
self.recv_fe_interface_connect)
|
||||
@@ -358,13 +368,7 @@ class BlkifController(controller.SplitController):
|
||||
val = ['blkif', ['dom', self.dom]]
|
||||
return val
|
||||
|
||||
def getDevices(self):
|
||||
return self.devices.values()
|
||||
|
||||
def getDevice(self, vdev):
|
||||
return self.devices.get(vdev)
|
||||
|
||||
def addDevice(self, config, vdev, mode, segment):
|
||||
def addDevice(self, idx, config, vdev, mode, segment):
|
||||
"""Add a device to the device table.
|
||||
|
||||
@param vdev: device index
|
||||
@@ -376,20 +380,18 @@ class BlkifController(controller.SplitController):
|
||||
@return: device
|
||||
@rtype: BlkDev
|
||||
"""
|
||||
if vdev in self.devices:
|
||||
raise XendError('device exists: ' + str(vdev))
|
||||
dev = BlkDev(self, config, vdev, mode, segment)
|
||||
self.devices[vdev] = dev
|
||||
if idx in self.devices:
|
||||
raise XendError('device exists: ' + str(idx))
|
||||
dev = BlkDev(idx, self, config, vdev, mode, segment)
|
||||
self.devices[idx] = dev
|
||||
return dev
|
||||
|
||||
def delDevice(self, vdev):
|
||||
if vdev in self.devices:
|
||||
del self.devices[vdev]
|
||||
|
||||
def attachDevice(self, config, vdev, mode, segment, recreate=0):
|
||||
def attachDevice(self, idx, config, vdev, mode, segment, recreate=0):
|
||||
"""Attach a device to the specified interface.
|
||||
On success the returned deferred will be called with the device.
|
||||
|
||||
@param idx: device id
|
||||
@param config: device configuration
|
||||
@param vdev: device index
|
||||
@type vdev: int
|
||||
@param mode: read/write mode
|
||||
@@ -401,7 +403,7 @@ class BlkifController(controller.SplitController):
|
||||
@return: deferred
|
||||
@rtype: Deferred
|
||||
"""
|
||||
dev = self.addDevice(config, vdev, mode, segment)
|
||||
dev = self.addDevice(idx, config, vdev, mode, segment)
|
||||
if recreate:
|
||||
d = defer.succeed(dev)
|
||||
else:
|
||||
@@ -425,8 +427,9 @@ class BlkifController(controller.SplitController):
|
||||
for backend in self.getBackendInterfaces():
|
||||
backend.destroy()
|
||||
|
||||
def recv_fe_driver_status_changed(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
|
||||
def recv_fe_driver_status(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_driver_status_t', msg)
|
||||
print 'recv_fe_driver_status>', val
|
||||
for backend in self.getBackendInterfaces():
|
||||
backend.interfaceDisconnected()
|
||||
|
||||
@@ -439,5 +442,6 @@ class BlkifController(controller.SplitController):
|
||||
else:
|
||||
log.error('interface connect on unknown interface: handle=%d', handle)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -522,6 +522,9 @@ class BackendInterface:
|
||||
def writeRequest(self, msg, response=None):
|
||||
return self.backend.writeRequest(msg, response=response)
|
||||
|
||||
def writeResponse(self, msg):
|
||||
return self.backend.writeResponse(msg)
|
||||
|
||||
def close(self):
|
||||
self.backend.deregisterInterface(self)
|
||||
self.controller.backendInterfaceClosed(self)
|
||||
@@ -536,6 +539,60 @@ class SplitController(Controller):
|
||||
Controller.__init__(self, factory, dom)
|
||||
self.backendInterfaces = {}
|
||||
self.backendHandle = 0
|
||||
self.devices = {}
|
||||
|
||||
def getDevices(self):
|
||||
"""Get a list of the devices..
|
||||
"""
|
||||
return self.devices.values()
|
||||
|
||||
def delDevice(self, idx):
|
||||
"""Remove the device with the given index from the device table.
|
||||
|
||||
@param idx device index
|
||||
"""
|
||||
if idx in self.devices:
|
||||
del self.devices[idx]
|
||||
|
||||
def getDevice(self, idx):
|
||||
"""Get the device with a given index.
|
||||
|
||||
@param idx device index
|
||||
@return device (or None)
|
||||
"""
|
||||
return self.devices.get(idx)
|
||||
|
||||
def findDevice(self, idx):
|
||||
"""Find a device. If idx is non-negative,
|
||||
get the device with the given index. If idx is negative,
|
||||
look for the device with least index greater than -idx - 2.
|
||||
For example, if idx is -2, look for devices with index
|
||||
greater than 0, i.e. 1 or above.
|
||||
|
||||
@param idx device index
|
||||
@return device (or None)
|
||||
"""
|
||||
if idx < 0:
|
||||
idx = -idx - 2
|
||||
val = None
|
||||
for dev in self.devices.values():
|
||||
if dev.idx <= idx: continue
|
||||
if (val is None) or (dev.idx < val.idx):
|
||||
val = dev
|
||||
else:
|
||||
val = getDevice(idx)
|
||||
return val
|
||||
|
||||
def getMaxDeviceIdx(self):
|
||||
"""Get the maximum id used by devices.
|
||||
|
||||
@return maximum idx
|
||||
"""
|
||||
maxIdx = 0
|
||||
for dev in self.devices:
|
||||
if dev.idx > maxIdx:
|
||||
maxIdx = dev.idx
|
||||
return maxIdx
|
||||
|
||||
def getBackendInterfaces(self):
|
||||
return self.backendInterfaces.values()
|
||||
|
||||
@@ -29,70 +29,106 @@ msg_formats.update(console_formats)
|
||||
CMSG_BLKIF_BE = 1
|
||||
CMSG_BLKIF_FE = 2
|
||||
|
||||
CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED = 0
|
||||
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED = 32
|
||||
CMSG_BLKIF_FE_INTERFACE_CONNECT = 33
|
||||
CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34
|
||||
CMSG_BLKIF_FE_INTERFACE_STATUS = 0
|
||||
CMSG_BLKIF_FE_DRIVER_STATUS = 32
|
||||
CMSG_BLKIF_FE_INTERFACE_CONNECT = 33
|
||||
CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34
|
||||
CMSG_BLKIF_FE_INTERFACE_QUERY = 35
|
||||
|
||||
CMSG_BLKIF_BE_CREATE = 0
|
||||
CMSG_BLKIF_BE_DESTROY = 1
|
||||
CMSG_BLKIF_BE_CONNECT = 2
|
||||
CMSG_BLKIF_BE_DISCONNECT = 3
|
||||
CMSG_BLKIF_BE_VBD_CREATE = 4
|
||||
CMSG_BLKIF_BE_VBD_DESTROY = 5
|
||||
CMSG_BLKIF_BE_VBD_GROW = 6
|
||||
CMSG_BLKIF_BE_VBD_SHRINK = 7
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED = 32
|
||||
CMSG_BLKIF_BE_CREATE = 0
|
||||
CMSG_BLKIF_BE_DESTROY = 1
|
||||
CMSG_BLKIF_BE_CONNECT = 2
|
||||
CMSG_BLKIF_BE_DISCONNECT = 3
|
||||
CMSG_BLKIF_BE_VBD_CREATE = 4
|
||||
CMSG_BLKIF_BE_VBD_DESTROY = 5
|
||||
CMSG_BLKIF_BE_VBD_GROW = 6
|
||||
CMSG_BLKIF_BE_VBD_SHRINK = 7
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS = 32
|
||||
|
||||
BLKIF_DRIVER_STATUS_DOWN = 0
|
||||
BLKIF_DRIVER_STATUS_UP = 1
|
||||
BLKIF_DRIVER_STATUS_DOWN = 0
|
||||
BLKIF_DRIVER_STATUS_UP = 1
|
||||
|
||||
BLKIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
|
||||
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
BLKIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
|
||||
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
|
||||
BLKIF_BE_STATUS_OKAY = 0
|
||||
BLKIF_BE_STATUS_ERROR = 1
|
||||
BLKIF_BE_STATUS_INTERFACE_EXISTS = 2
|
||||
BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
|
||||
BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
|
||||
BLKIF_BE_STATUS_VBD_EXISTS = 5
|
||||
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
|
||||
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
|
||||
BLKIF_BE_STATUS_EXTENT_NOT_FOUND = 8
|
||||
BLKIF_BE_STATUS_MAPPING_ERROR = 9
|
||||
BLKIF_BE_STATUS_OKAY = 0
|
||||
BLKIF_BE_STATUS_ERROR = 1
|
||||
BLKIF_BE_STATUS_INTERFACE_EXISTS = 2
|
||||
BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
|
||||
BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
|
||||
BLKIF_BE_STATUS_VBD_EXISTS = 5
|
||||
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
|
||||
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
|
||||
BLKIF_BE_STATUS_EXTENT_NOT_FOUND = 8
|
||||
BLKIF_BE_STATUS_MAPPING_ERROR = 9
|
||||
|
||||
blkif_formats = {
|
||||
'blkif_be_connect_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT),
|
||||
# Connect be to fe (in response to blkif_fe_interface_connect_t).
|
||||
|
||||
'blkif_be_create_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE),
|
||||
# Create be.
|
||||
|
||||
'blkif_be_disconnect_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT),
|
||||
# Disconnect be from fe.
|
||||
|
||||
'blkif_be_destroy_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY),
|
||||
# Destroy be (after disconnect).
|
||||
# Make be do this even if no disconnect (and destroy all vbd too).
|
||||
|
||||
'blkif_be_vbd_create_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
|
||||
# Create a vbd device.
|
||||
|
||||
'blkif_be_vbd_grow_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW),
|
||||
# Change the size of a vbd device. Remove?
|
||||
# Do in one go in blkif_be_vbd_create_t.
|
||||
|
||||
'blkif_be_vbd_destroy_t':
|
||||
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY),
|
||||
# Destroy a vbd.
|
||||
|
||||
'blkif_fe_interface_status_changed_t':
|
||||
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED),
|
||||
# Add message to query be for state and vbds.
|
||||
|
||||
'blkif_fe_driver_status_changed_t':
|
||||
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED),
|
||||
'blkif_fe_interface_status_t':
|
||||
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS),
|
||||
# Notify device status to fe.
|
||||
# Also used to notify 'any' device change with status BLKIF_INTERFACE_STATUS_CHANGED.
|
||||
# Rename to blkif_fe_interface_status.
|
||||
|
||||
'blkif_fe_driver_status_t':
|
||||
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS),
|
||||
# Comes from fe, treated as notifying that fe has come up/changed.
|
||||
# Xend sets be(s) to BLKIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
# sends blkif_fe_interface_status_t to fe (from each be).
|
||||
#
|
||||
# Rename to blkif_fe_driver_status.
|
||||
# Reply with i/f count.
|
||||
# The i/f sends probes (using -ve trick), we reply with the info.
|
||||
|
||||
'blkif_fe_interface_connect_t':
|
||||
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT),
|
||||
# Comes from fe, passing shmem frame to use for be.
|
||||
# fe sends when gets blkif_fe_interface_status_t with state NETIF_INTERFACE_STATUS_DISCONNECTED.
|
||||
# Xend creates event channel and notifies be.
|
||||
# Then notifies fe of event channel with blkif_fe_interface_status_t.
|
||||
|
||||
# Add message to kick fe to probe for devices.
|
||||
# Just report new devices to fe?
|
||||
|
||||
#
|
||||
# Add message for fe to probe a device.
|
||||
# And probing with id -1 should return first.
|
||||
# And probing with id -n should return first device with id > n.
|
||||
|
||||
# Add message to query fe for state and vbds.
|
||||
}
|
||||
|
||||
msg_formats.update(blkif_formats)
|
||||
@@ -104,24 +140,25 @@ msg_formats.update(blkif_formats)
|
||||
CMSG_NETIF_BE = 3
|
||||
CMSG_NETIF_FE = 4
|
||||
|
||||
CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED = 0
|
||||
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED = 32
|
||||
CMSG_NETIF_FE_INTERFACE_CONNECT = 33
|
||||
CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
|
||||
CMSG_NETIF_FE_INTERFACE_STATUS = 0
|
||||
CMSG_NETIF_FE_DRIVER_STATUS = 32
|
||||
CMSG_NETIF_FE_INTERFACE_CONNECT = 33
|
||||
CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
|
||||
CMSG_NETIF_FE_INTERFACE_QUERY = 35
|
||||
|
||||
CMSG_NETIF_BE_CREATE = 0
|
||||
CMSG_NETIF_BE_DESTROY = 1
|
||||
CMSG_NETIF_BE_CONNECT = 2
|
||||
CMSG_NETIF_BE_DISCONNECT = 3
|
||||
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED = 32
|
||||
CMSG_NETIF_BE_CREATE = 0
|
||||
CMSG_NETIF_BE_DESTROY = 1
|
||||
CMSG_NETIF_BE_CONNECT = 2
|
||||
CMSG_NETIF_BE_DISCONNECT = 3
|
||||
CMSG_NETIF_BE_DRIVER_STATUS = 32
|
||||
|
||||
NETIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
|
||||
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
NETIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
|
||||
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
|
||||
NETIF_DRIVER_STATUS_DOWN = 0
|
||||
NETIF_DRIVER_STATUS_UP = 1
|
||||
NETIF_DRIVER_STATUS_DOWN = 0
|
||||
NETIF_DRIVER_STATUS_UP = 1
|
||||
|
||||
netif_formats = {
|
||||
'netif_be_connect_t':
|
||||
@@ -136,17 +173,17 @@ netif_formats = {
|
||||
'netif_be_destroy_t':
|
||||
(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY),
|
||||
|
||||
'netif_be_driver_status_changed_t':
|
||||
(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED),
|
||||
'netif_be_driver_status_t':
|
||||
(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS),
|
||||
|
||||
'netif_fe_driver_status_changed_t':
|
||||
(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED),
|
||||
'netif_fe_driver_status_t':
|
||||
(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS),
|
||||
|
||||
'netif_fe_interface_connect_t':
|
||||
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT),
|
||||
|
||||
'netif_fe_interface_status_changed_t':
|
||||
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED),
|
||||
'netif_fe_interface_status_t':
|
||||
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS),
|
||||
}
|
||||
|
||||
msg_formats.update(netif_formats)
|
||||
@@ -241,13 +278,15 @@ def unpackMsg(ty, msg):
|
||||
macs = []
|
||||
for (k, v) in args.items():
|
||||
if k.startswith('mac['):
|
||||
macs += k
|
||||
macs.append(k)
|
||||
i = int(k[4:5])
|
||||
mac[i] = v
|
||||
else:
|
||||
pass
|
||||
if macs:
|
||||
args['mac'] = mac
|
||||
print 'macs=', macs
|
||||
print 'args=', args
|
||||
for k in macs:
|
||||
del args[k]
|
||||
if DEBUG:
|
||||
|
||||
@@ -24,12 +24,12 @@ class NetifBackendController(controller.BackendController):
|
||||
def __init__(self, ctrl, dom):
|
||||
controller.BackendController.__init__(self, ctrl, dom)
|
||||
self.addMethod(CMSG_NETIF_BE,
|
||||
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
CMSG_NETIF_BE_DRIVER_STATUS,
|
||||
self.recv_be_driver_status)
|
||||
self.registerChannel()
|
||||
|
||||
def recv_be_driver_status_changed(self, msg, req):
|
||||
val = unpackMsg('netif_be_driver_status_changed_t', msg)
|
||||
def recv_be_driver_status(self, msg, req):
|
||||
val = unpackMsg('netif_be_driver_status_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class NetifBackendInterface(controller.BackendInterface):
|
||||
@@ -98,11 +98,12 @@ class NetDev(controller.SplitDev):
|
||||
"""Info record for a network device.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, vif, config):
|
||||
def __init__(self, vif, ctrl, config):
|
||||
controller.SplitDev.__init__(self, vif, ctrl)
|
||||
self.vif = vif
|
||||
self.evtchn = None
|
||||
self.configure(config)
|
||||
self.status = NETIF_INTERFACE_STATUS_DISCONNECTED
|
||||
|
||||
def _get_config_mac(self, config):
|
||||
vmac = sxp.child_value(config, 'mac')
|
||||
@@ -245,6 +246,18 @@ class NetDev(controller.SplitDev):
|
||||
d.addCallback(self.respond_be_create)
|
||||
return d
|
||||
|
||||
def getEventChannelBackend(self):
|
||||
val = 0
|
||||
if self.evtchn:
|
||||
val = self.evtchn['port1']
|
||||
return val
|
||||
|
||||
def getEventChannelFrontend(self):
|
||||
val = 0
|
||||
if self.evtchn:
|
||||
val = self.evtchn['port2']
|
||||
return val
|
||||
|
||||
def send_be_create(self):
|
||||
d = defer.Deferred()
|
||||
msg = packMsg('netif_be_create_t',
|
||||
@@ -264,11 +277,12 @@ class NetDev(controller.SplitDev):
|
||||
|
||||
@param change: change flag
|
||||
"""
|
||||
self.status = NETIF_INTERFACE_STATUS_CLOSED
|
||||
def cb_destroy(val):
|
||||
self.send_be_destroy()
|
||||
self.getBackendInterface().close()
|
||||
if change:
|
||||
self.interfaceChanged()
|
||||
self.reportStatus()
|
||||
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
|
||||
self.vifctl('down')
|
||||
d = self.send_be_disconnect()
|
||||
@@ -295,7 +309,7 @@ class NetDev(controller.SplitDev):
|
||||
msg = packMsg('netif_be_connect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif,
|
||||
'evtchn' : self.evtchn['port1'],
|
||||
'evtchn' : self.getEventChannelBackend(),
|
||||
'tx_shmem_frame' : val['tx_shmem_frame'],
|
||||
'rx_shmem_frame' : val['rx_shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
@@ -306,34 +320,25 @@ class NetDev(controller.SplitDev):
|
||||
val = unpackMsg('netif_be_connect_t', msg)
|
||||
dom = val['domid']
|
||||
vif = val['netif_handle']
|
||||
msg = packMsg('netif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_CONNECTED,
|
||||
'evtchn' : self.evtchn['port2'],
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
self.status = NETIF_INTERFACE_STATUS_CONNECTED
|
||||
self.reportStatus()
|
||||
|
||||
def attach_fe_device(self):
|
||||
msg = packMsg('netif_fe_interface_status_changed_t',
|
||||
def reportStatus(self, resp=0):
|
||||
msg = packMsg('netif_fe_interface_status_t',
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
'evtchn' : 0,
|
||||
'status' : self.status,
|
||||
'evtchn' : self.getEventChannelFrontend(),
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
if resp:
|
||||
self.controller.writeResponse(msg)
|
||||
else:
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
def interfaceChanged(self):
|
||||
"""Notify the font-end that a device has been added or removed.
|
||||
The front-end should then probe the devices.
|
||||
"""
|
||||
msg = packMsg('netif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_CHANGED,
|
||||
'evtchn' : 0,
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
self.reportStatus()
|
||||
|
||||
class NetifController(controller.SplitController):
|
||||
"""Network interface controller. Handles all network devices for a domain.
|
||||
@@ -343,8 +348,11 @@ class NetifController(controller.SplitController):
|
||||
controller.SplitController.__init__(self, factory, dom)
|
||||
self.devices = {}
|
||||
self.addMethod(CMSG_NETIF_FE,
|
||||
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_fe_driver_status_changed)
|
||||
CMSG_NETIF_FE_DRIVER_STATUS,
|
||||
self.recv_fe_driver_status)
|
||||
self.addMethod(CMSG_NETIF_FE,
|
||||
CMSG_NETIF_FE_INTERFACE_STATUS,
|
||||
self.recv_fe_interface_status)
|
||||
self.addMethod(CMSG_NETIF_FE,
|
||||
CMSG_NETIF_FE_INTERFACE_CONNECT,
|
||||
self.recv_fe_interface_connect)
|
||||
@@ -359,19 +367,6 @@ class NetifController(controller.SplitController):
|
||||
"""
|
||||
controller.Controller.lostChannel(self)
|
||||
|
||||
def getDevices(self):
|
||||
"""Get a list of the devices.
|
||||
"""
|
||||
return self.devices.values()
|
||||
|
||||
def getDevice(self, vif):
|
||||
"""Get a device.
|
||||
|
||||
@param vif: device index
|
||||
@return: device (or None)
|
||||
"""
|
||||
return self.devices.get(vif)
|
||||
|
||||
def addDevice(self, vif, config):
|
||||
"""Add a network interface.
|
||||
|
||||
@@ -381,14 +376,10 @@ class NetifController(controller.SplitController):
|
||||
"""
|
||||
if vif in self.devices:
|
||||
raise XendError('device exists:' + str(vif))
|
||||
dev = NetDev(self, vif, config)
|
||||
dev = NetDev(vif, self, config)
|
||||
self.devices[vif] = dev
|
||||
return dev
|
||||
|
||||
def delDevice(self, vif):
|
||||
if vif in self.devices:
|
||||
del self.devices[vif]
|
||||
|
||||
def destroy(self):
|
||||
"""Destroy the controller and all devices.
|
||||
"""
|
||||
@@ -415,23 +406,64 @@ class NetifController(controller.SplitController):
|
||||
d = dev.attach()
|
||||
return d
|
||||
|
||||
def recv_fe_driver_status_changed(self, msg, req):
|
||||
def recv_fe_driver_status(self, msg, req):
|
||||
if not req: return
|
||||
msg = packMsg('netif_fe_driver_status_changed_t',
|
||||
print
|
||||
print 'recv_fe_driver_status>'
|
||||
msg = packMsg('netif_fe_driver_status_t',
|
||||
{ 'status' : NETIF_DRIVER_STATUS_UP,
|
||||
## FIXME: max_handle should be max active interface id
|
||||
'max_handle' : len(self.devices) })
|
||||
self.writeRequest(msg)
|
||||
for dev in self.devices.values():
|
||||
dev.attach_fe_device()
|
||||
'max_handle' : len(self.devices)
|
||||
#'max_handle' : self.getMaxDeviceIdx()
|
||||
})
|
||||
# Two ways of doing it:
|
||||
# 1) front-end requests driver status, we reply with the interface count,
|
||||
# front-end polls the interfaces,
|
||||
# front-end checks they are all up
|
||||
# 2) front-end requests driver status, we reply (with anything),
|
||||
# we notify the interfaces,
|
||||
# we notify driver status up with the count
|
||||
# front-end checks they are all up
|
||||
#
|
||||
# We really want to use 1), but at the moment the xenU kernel panics
|
||||
# in that mode, so we're sticking to 2) for now.
|
||||
resp = 0
|
||||
if resp:
|
||||
self.writeResponse(msg)
|
||||
else:
|
||||
for dev in self.devices.values():
|
||||
dev.reportStatus()
|
||||
self.writeRequest(msg)
|
||||
return resp
|
||||
|
||||
def recv_fe_interface_status(self, msg, req):
|
||||
if not req: return
|
||||
print
|
||||
val = unpackMsg('netif_fe_interface_status_t', msg)
|
||||
print "recv_fe_interface_status>", val
|
||||
vif = val['handle']
|
||||
dev = self.findDevice(vif)
|
||||
if dev:
|
||||
print 'recv_fe_interface_status>', 'dev=', dev
|
||||
dev.reportStatus(resp=1)
|
||||
else:
|
||||
msg = packMsg('netif_fe_interface_status_t',
|
||||
{ 'handle' : -1,
|
||||
'status' : NETIF_INTERFACE_STATUS_CLOSED,
|
||||
});
|
||||
print 'recv_fe_interface_status>', 'no dev, returning -1'
|
||||
self.writeResponse(msg)
|
||||
return 1
|
||||
|
||||
|
||||
def recv_fe_interface_connect(self, msg, req):
|
||||
val = unpackMsg('netif_fe_interface_connect_t', msg)
|
||||
vif = val['handle']
|
||||
dev = self.devices.get(vif)
|
||||
print
|
||||
print "recv_fe_interface_connect", val
|
||||
dev = self.getDevice(vif)
|
||||
if dev:
|
||||
dev.recv_fe_interface_connect(val, req)
|
||||
else:
|
||||
log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
|
||||
self.dom, vif)
|
||||
|
||||
@@ -70,10 +70,10 @@ typedef struct {
|
||||
*/
|
||||
|
||||
/* Messages from domain controller to guest. */
|
||||
#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED 0
|
||||
#define CMSG_BLKIF_FE_INTERFACE_STATUS 0
|
||||
|
||||
/* Messages from guest to domain controller. */
|
||||
#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED 32
|
||||
#define CMSG_BLKIF_FE_DRIVER_STATUS 32
|
||||
#define CMSG_BLKIF_FE_INTERFACE_CONNECT 33
|
||||
#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT 34
|
||||
#define CMSG_BLKIF_FE_INTERFACE_QUERY 35
|
||||
@@ -84,25 +84,25 @@ typedef struct {
|
||||
#define blkif_sector_t u64
|
||||
|
||||
/*
|
||||
* CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
|
||||
* CMSG_BLKIF_FE_INTERFACE_STATUS:
|
||||
* Notify a guest about a status change on one of its block interfaces.
|
||||
* If the interface is DESTROYED or DOWN then the interface is disconnected:
|
||||
* 1. The shared-memory frame is available for reuse.
|
||||
* 2. Any unacknowledged messages pending on the interface were dropped.
|
||||
*/
|
||||
#define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
|
||||
#define BLKIF_INTERFACE_STATUS_CLOSED 0 /* Interface doesn't exist. */
|
||||
#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
|
||||
#define BLKIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
|
||||
#define BLKIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */
|
||||
//#define BLKIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */
|
||||
typedef struct {
|
||||
u32 handle; /* 0 */
|
||||
u32 status; /* 4 */
|
||||
u16 evtchn; /* 8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
|
||||
domid_t domid; /* 10: status != BLKIF_INTERFACE_STATUS_DESTROYED */
|
||||
} PACKED blkif_fe_interface_status_changed_t; /* 12 bytes */
|
||||
} PACKED blkif_fe_interface_status_t; /* 12 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
|
||||
* CMSG_BLKIF_FE_DRIVER_STATUS:
|
||||
* Notify the domain controller that the front-end driver is DOWN or UP.
|
||||
* When the driver goes DOWN then the controller will send no more
|
||||
* status-change notifications.
|
||||
@@ -121,7 +121,7 @@ typedef struct {
|
||||
/* OUT */
|
||||
/* Driver should query interfaces [0..max_handle]. */
|
||||
u32 max_handle; /* 4 */
|
||||
} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
|
||||
} PACKED blkif_fe_driver_status_t; /* 8 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_BLKIF_FE_INTERFACE_CONNECT:
|
||||
@@ -172,7 +172,7 @@ typedef struct {
|
||||
#define CMSG_BLKIF_BE_VBD_SHRINK 7 /* Remove last extent from a given VBD. */
|
||||
|
||||
/* Messages to domain controller. */
|
||||
#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
|
||||
#define CMSG_BLKIF_BE_DRIVER_STATUS 32
|
||||
|
||||
/*
|
||||
* Message request/response definitions for block-device messages.
|
||||
@@ -325,14 +325,14 @@ typedef struct {
|
||||
} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
|
||||
* CMSG_BLKIF_BE_DRIVER_STATUS:
|
||||
* Notify the domain controller that the back-end driver is DOWN or UP.
|
||||
* If the driver goes DOWN while interfaces are still UP, the controller
|
||||
* will automatically send DOWN notifications.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */
|
||||
} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
|
||||
} PACKED blkif_be_driver_status_t; /* 4 bytes */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@@ -340,22 +340,22 @@ typedef struct {
|
||||
*/
|
||||
|
||||
/* Messages from domain controller to guest. */
|
||||
#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED 0
|
||||
#define CMSG_NETIF_FE_INTERFACE_STATUS 0
|
||||
|
||||
/* Messages from guest to domain controller. */
|
||||
#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED 32
|
||||
#define CMSG_NETIF_FE_DRIVER_STATUS 32
|
||||
#define CMSG_NETIF_FE_INTERFACE_CONNECT 33
|
||||
#define CMSG_NETIF_FE_INTERFACE_DISCONNECT 34
|
||||
#define CMSG_NETIF_FE_INTERFACE_QUERY 35
|
||||
|
||||
/*
|
||||
* CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
|
||||
* CMSG_NETIF_FE_INTERFACE_STATUS:
|
||||
* Notify a guest about a status change on one of its network interfaces.
|
||||
* If the interface is DESTROYED or DOWN then the interface is disconnected:
|
||||
* If the interface is CLOSED or DOWN then the interface is disconnected:
|
||||
* 1. The shared-memory frame is available for reuse.
|
||||
* 2. Any unacknowledged messgaes pending on the interface were dropped.
|
||||
*/
|
||||
#define NETIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
|
||||
#define NETIF_INTERFACE_STATUS_CLOSED 0 /* Interface doesn't exist. */
|
||||
#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
|
||||
#define NETIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
|
||||
#define NETIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */
|
||||
@@ -365,17 +365,17 @@ typedef struct {
|
||||
u16 evtchn; /* 8: status == NETIF_INTERFACE_STATUS_CONNECTED */
|
||||
u8 mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
|
||||
domid_t domid; /* 16: status != NETIF_INTERFACE_STATUS_DESTROYED */
|
||||
} PACKED netif_fe_interface_status_changed_t; /* 18 bytes */
|
||||
} PACKED netif_fe_interface_status_t; /* 18 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
|
||||
* CMSG_NETIF_FE_DRIVER_STATUS:
|
||||
* Notify the domain controller that the front-end driver is DOWN or UP.
|
||||
* When the driver goes DOWN then the controller will send no more
|
||||
* status-change notifications.
|
||||
* If the driver goes DOWN while interfaces are still UP, the domain
|
||||
* will automatically take the interfaces DOWN.
|
||||
*
|
||||
* NB. The controller should not send an INTERFACE_STATUS_CHANGED message
|
||||
* NB. The controller should not send an INTERFACE_STATUS message
|
||||
* for interfaces that are active when it receives an UP notification. We
|
||||
* expect that the frontend driver will query those interfaces itself.
|
||||
*/
|
||||
@@ -387,7 +387,7 @@ typedef struct {
|
||||
/* OUT */
|
||||
/* Driver should query interfaces [0..max_handle]. */
|
||||
u32 max_handle; /* 4 */
|
||||
} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
|
||||
} PACKED netif_fe_driver_status_t; /* 8 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_NETIF_FE_INTERFACE_CONNECT:
|
||||
@@ -437,7 +437,7 @@ typedef struct {
|
||||
#define CMSG_NETIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */
|
||||
|
||||
/* Messages to domain controller. */
|
||||
#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
|
||||
#define CMSG_NETIF_BE_DRIVER_STATUS 32
|
||||
|
||||
/*
|
||||
* Message request/response definitions for net-device messages.
|
||||
@@ -533,14 +533,14 @@ typedef struct {
|
||||
} PACKED netif_be_disconnect_t; /* 12 bytes */
|
||||
|
||||
/*
|
||||
* CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
|
||||
* CMSG_NETIF_BE_DRIVER_STATUS:
|
||||
* Notify the domain controller that the back-end driver is DOWN or UP.
|
||||
* If the driver goes DOWN while interfaces are still UP, the domain
|
||||
* will automatically send DOWN notifications.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 status; /* 0: NETIF_DRIVER_STATUS_??? */
|
||||
} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
|
||||
} PACKED netif_be_driver_status_t; /* 4 bytes */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||