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:
mjw@wray-m-3.hpl.hp.com committed 2004-09-23 13:44:29 +00:00
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
}
+46 -46
View File
@@ -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;
}
+4 -4
View File
@@ -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])
+2 -1
View File
@@ -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.
-27
View File
@@ -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.
"""
+52 -48
View File
@@ -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()
+94 -55
View File
@@ -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:
+87 -55
View File
@@ -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 */
/******************************************************************************
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.