bitkeeper revision 1.1108.7.1 (40fd3300BIfHRgHP5-DpQTLgUmNmEQ)

Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
This commit is contained in:
xenbk@gandalf.hpl.hp.com committed 2004-07-20 14:58:08 +00:00
commit 8cf5ca68b7
42 files changed
+1225 -935

No files matched your search

+28 -2
View File
@@ -72,7 +72,6 @@
4097ba837h2tuiweIWp-voNVzCRI6g linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c
4087cf0d5dudKw_DecIJgOhLlBF_0Q linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c
405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/Makefile
405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c
4097ba83Qy2eafeFUhGhm6_4iMIIDw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/netif.h
3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile
4075806dE5mQwlVUf8-t3YXjiMMWDQ linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c
@@ -199,7 +198,7 @@
40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.7-xen-sparse/drivers/xen/evtchn/evtchn.c
40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.7-xen-sparse/drivers/xen/net/Kconfig
40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile
40f56239vUsbJCS9tGFfRVi1YZlGEg linux-2.6.7-xen-sparse/drivers/xen/net/network.c
405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.7-xen-sparse/drivers/xen/net/network.c
40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h
40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h
40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
@@ -366,6 +365,33 @@
40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py
40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py
40c9c469ZqILEQ8x6yWy0_51jopiCg tools/python/xen/xend/server/params.py
40fcefb2qm13BbRZBydAatOavaS0fQ tools/python/xen/xend/sv/DomInfo.py
40fcefb2-RIU8GB67mJMRzybME9bxw tools/python/xen/xend/sv/DomList.py
40fcefb23FfQn-ZBCbcHqA0cPGqQxw tools/python/xen/xend/sv/GenTabbed.py
40fcefb2QZAn3u3sX-M7NXBjOv5HGg tools/python/xen/xend/sv/HTMLBase.py
40fcefb2vnfDbl4w_yCTedROPuqs0g tools/python/xen/xend/sv/Main.py
40fcefb2K1xqVVT4D-p7nL2GzS4scg tools/python/xen/xend/sv/Main.rpy
40fcefb24h-04WaHag-Tg4nxWPhTig tools/python/xen/xend/sv/NodeInfo.py
40fcefb2Sif__6AqrANeBQZZfvP-6w tools/python/xen/xend/sv/TabView.py
40fcefb23s0sQlDfl4sPP0Un8oZGhg tools/python/xen/xend/sv/XendClientDeferred.py
40fcefb2DqteqCCZYDCvvh4Q5jBd0w tools/python/xen/xend/sv/__init__.py
40fcefb2Nhe-sT74KBB_3mYQg9Dl4Q tools/python/xen/xend/sv/images/internet copy.jpg
40fcefb2QmVa4xdjdnSTXEdF2fZCDA tools/python/xen/xend/sv/images/internet.jpg
40fcefb2g8Ez5jJIPHGN_KX7GtxV4w tools/python/xen/xend/sv/images/internet.psd
40fcefb3wXQMsl9WkgQAVtdrupm4sw tools/python/xen/xend/sv/images/left-end-highlight.jpg
40fcefb3K6ESt5sQhD9aCQRscQIlXQ tools/python/xen/xend/sv/images/left-end-no-highlight.jpg
40fcefb3BUT98zPzW8kAFKuxGdh4XA tools/python/xen/xend/sv/images/middle-highlight.jpg
40fcefb38OTgsUKHBpwshLLIsiIaCA tools/python/xen/xend/sv/images/middle-no-highlight.jpg
40fcefb32SPtrw36c4S6YGFlLvkKuw tools/python/xen/xend/sv/images/orb_01.jpg
40fcefb3Ok5qkX3iM7ZEPVkRInrUpg tools/python/xen/xend/sv/images/orb_02.jpg
40fcefb3JnT5XeKTuVF4yUMGOtuNZg tools/python/xen/xend/sv/images/right-end-highlight.jpg
40fcefb3-DuYOS7noo2W7b_0p7TOUg tools/python/xen/xend/sv/images/right-end-no-highlight.jpg
40fcefb3qNbAZR5FYGPAZ9sFPVMTDA tools/python/xen/xend/sv/images/seperator-left-highlight.jpg
40fcefb3dgsa24WLk_BJeYQHrDLuOg tools/python/xen/xend/sv/images/seperator-right-highlight.jpg
40fcefb3FtiX4Pd2kT8wDlp8u8xRhQ tools/python/xen/xend/sv/images/seperator.jpg
40fcefb3yMSrZvApO9ToIi-iQwnchA tools/python/xen/xend/sv/images/xen.png
40fcefb3zGC9XNBkSwTEobCoq8YClA tools/python/xen/xend/sv/inc/style.css
40fcefb4rnaZNjqsBu7A5V2rlLyqRw tools/python/xen/xend/sv/util.py
40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
@@ -93,7 +93,8 @@ static void fast_flush_area(int idx, int nr_pages)
}
mcl[nr_pages-1].args[2] = UVMF_FLUSH_TLB;
(void)HYPERVISOR_multicall(mcl, nr_pages);
if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
BUG();
}
@@ -402,7 +403,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
phys_seg[i].buffer >> PAGE_SHIFT;
}
(void)HYPERVISOR_multicall(mcl, nr_psegs);
if ( unlikely(HYPERVISOR_multicall(mcl, nr_psegs) != 0) )
BUG();
for ( i = 0; i < nr_psegs; i++ )
{
@@ -73,10 +73,7 @@ static void __refresh_mfn_list(void)
int ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
mfn_list, MAX_MFN_ALLOC);
if ( unlikely(ret != MAX_MFN_ALLOC) )
{
printk(KERN_ALERT "Unable to increase memory reservation (%d)\n", ret);
BUG();
}
alloc_index = MAX_MFN_ALLOC;
}
@@ -97,8 +94,8 @@ static void dealloc_mfn(unsigned long mfn)
spin_lock_irqsave(&mfn_lock, flags);
if ( alloc_index != MAX_MFN_ALLOC )
mfn_list[alloc_index++] = mfn;
else
(void)HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, &mfn, 1);
else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, &mfn, 1) != 1 )
BUG();
spin_unlock_irqrestore(&mfn_lock, flags);
}
@@ -238,7 +235,8 @@ static void net_rx_action(unsigned long unused)
return;
mcl[-2].args[2] = UVMF_FLUSH_TLB;
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) )
BUG();
mcl = rx_mcl;
mmu = rx_mmu;
@@ -252,31 +250,27 @@ static void net_rx_action(unsigned long unused)
mdata = ((mmu[2].ptr & PAGE_MASK) |
((unsigned long)skb->data & ~PAGE_MASK));
phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
netif->stats.rx_bytes += size;
netif->stats.rx_packets++;
/* The update_va_mapping() must not fail. */
if ( unlikely(mcl[0].args[5] != 0) )
BUG();
/* Check the reassignment error code. */
status = NETIF_RSP_OKAY;
if ( unlikely(mcl[1].args[5] != 0) )
{
DPRINTK("Failed MMU update transferring to DOM%u\n",
netif->domid);
(void)HYPERVISOR_update_va_mapping(
(unsigned long)skb->head >> PAGE_SHIFT,
(pte_t) { (mdata & PAGE_MASK) | __PAGE_KERNEL },
UVMF_INVLPG);
dealloc_mfn(new_mfn);
DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid);
dealloc_mfn(mdata >> PAGE_SHIFT);
status = NETIF_RSP_ERROR;
}
else
{
phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
netif->stats.rx_bytes += size;
netif->stats.rx_packets++;
status = NETIF_RSP_OKAY;
}
evtchn = netif->evtchn;
id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
@@ -380,14 +374,15 @@ static void net_tx_action(unsigned long unused)
NETIF_RING_IDX i;
struct page *page;
multicall_entry_t *mcl;
PEND_RING_IDX dc, dp;
if ( (i = dealloc_cons) == dealloc_prod )
if ( (dc = dealloc_cons) == (dp = dealloc_prod) )
goto skip_dealloc;
mcl = tx_mcl;
while ( i != dealloc_prod )
while ( dc != dp )
{
pending_idx = dealloc_ring[MASK_PEND_IDX(i++)];
pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
mcl[0].op = __HYPERVISOR_update_va_mapping;
mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT;
mcl[0].args[1] = 0;
@@ -396,10 +391,16 @@ static void net_tx_action(unsigned long unused)
}
mcl[-1].args[2] = UVMF_FLUSH_TLB;
(void)HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl);
if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
BUG();
while ( dealloc_cons != dealloc_prod )
mcl = tx_mcl;
while ( dealloc_cons != dp )
{
/* The update_va_mapping() must not fail. */
if ( unlikely(mcl[0].args[5] != 0) )
BUG();
pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
netif = pending_tx_info[pending_idx].netif;
@@ -421,6 +422,8 @@ static void net_tx_action(unsigned long unused)
add_to_net_schedule_list_tail(netif);
netif_put(netif);
mcl++;
}
skip_dealloc:
@@ -495,7 +498,7 @@ static void net_tx_action(unsigned long unused)
pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
if ( unlikely((skb = dev_alloc_skb(PKT_PROT_LEN)) == NULL) )
if ( unlikely((skb = alloc_skb(PKT_PROT_LEN+16, GFP_ATOMIC)) == NULL) )
{
DPRINTK("Can't allocate a skb in start_xmit.\n");
make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
@@ -503,6 +506,9 @@ static void net_tx_action(unsigned long unused)
break;
}
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain;
mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT;
mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL;
@@ -526,7 +532,8 @@ static void net_tx_action(unsigned long unused)
if ( mcl == tx_mcl )
return;
(void)HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl);
if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
BUG();
mcl = tx_mcl;
while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
@@ -1,867 +0,0 @@
/******************************************************************************
* arch/xen/drivers/netif/frontend/main.c
*
* Virtual network driver for conversing with remote driver backends.
*
* Copyright (c) 2002-2004, K A Fraser
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <asm/io.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#include <asm/evtchn.h>
#include <asm/ctrl_if.h>
#include <asm/page.h>
#include "../netif.h"
#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */
static void network_tx_buf_gc(struct net_device *dev);
static void network_alloc_rx_buffers(struct net_device *dev);
static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
static struct list_head dev_list;
struct net_private
{
struct list_head list;
struct net_device *dev;
struct net_device_stats stats;
NETIF_RING_IDX rx_resp_cons, tx_resp_cons;
unsigned int tx_full;
netif_tx_interface_t *tx;
netif_rx_interface_t *rx;
spinlock_t tx_lock;
spinlock_t rx_lock;
unsigned int handle;
unsigned int evtchn;
unsigned int irq;
/* What is the status of our connection to the remote backend? */
#define BEST_CLOSED 0
#define BEST_DISCONNECTED 1
#define BEST_CONNECTED 2
unsigned int backend_state;
/* Is this interface open or closed (down or up)? */
#define UST_CLOSED 0
#define UST_OPEN 1
unsigned int user_state;
/*
* {tx,rx}_skbs store outstanding skbuffs. The first entry in each
* array is an index into a chain of free entries.
*/
struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1];
struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
};
/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
#define ADD_ID_TO_FREELIST(_list, _id) \
(_list)[(_id)] = (_list)[0]; \
(_list)[0] = (void *)(unsigned long)(_id);
#define GET_ID_FROM_FREELIST(_list) \
({ unsigned long _id = (unsigned long)(_list)[0]; \
(_list)[0] = (_list)[_id]; \
(unsigned short)_id; })
static struct net_device *find_dev_by_handle(unsigned int handle)
{
struct list_head *ent;
struct net_private *np;
list_for_each ( ent, &dev_list )
{
np = list_entry(ent, struct net_private, list);
if ( np->handle == handle )
return np->dev;
}
return NULL;
}
/** Network interface info. */
struct netif_ctrl {
/** Number of interfaces. */
int interface_n;
/** Number of connected interfaces. */
int connected_n;
/** Error code. */
int err;
};
static struct netif_ctrl netctrl;
static void netctrl_init(void)
{
memset(&netctrl, 0, sizeof(netctrl));
netctrl.interface_n = -1;
}
/** Get or set a network interface error.
*/
static int netctrl_err(int err)
{
if(err < 0 && !netctrl.err){
netctrl.err = err;
printk(KERN_WARNING "%s> err=%d\n", __FUNCTION__, err);
}
return netctrl.err;
}
/** Test if all network interfaces are connected.
*
* @return 1 if all connected, 0 if not, negative error code otherwise
*/
static int netctrl_connected(void)
{
int ok = 0;
ok = (netctrl.err ? netctrl.err :
(netctrl.connected_n == netctrl.interface_n));
return ok;
}
/** Count the connected network interfaces.
*
* @return connected count
*/
static int netctrl_connected_count(void)
{
struct list_head *ent;
struct net_private *np;
unsigned int connected;
connected = 0;
list_for_each(ent, &dev_list)
{
np = list_entry(ent, struct net_private, list);
if ( np->backend_state == BEST_CONNECTED )
connected++;
}
netctrl.connected_n = connected;
return connected;
}
static int network_open(struct net_device *dev)
{
struct net_private *np = dev->priv;
memset(&np->stats, 0, sizeof(np->stats));
np->user_state = UST_OPEN;
network_alloc_rx_buffers(dev);
np->rx->event = np->rx_resp_cons + 1;
netif_start_queue(dev);
return 0;
}
static void network_tx_buf_gc(struct net_device *dev)
{
NETIF_RING_IDX i, prod;
unsigned short id;
struct net_private *np = dev->priv;
struct sk_buff *skb;
if ( np->backend_state != BEST_CONNECTED )
return;
do {
prod = np->tx->resp_prod;
for ( i = np->tx_resp_cons; i != prod; i++ )
{
id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
skb = np->tx_skbs[id];
ADD_ID_TO_FREELIST(np->tx_skbs, id);
dev_kfree_skb_any(skb);
}
np->tx_resp_cons = prod;
/*
* Set a new event, then check for race with update of tx_cons. Note
* that it is essential to schedule a callback, no matter how few
* buffers are pending. Even if there is space in the transmit ring,
* higher layers may be blocked because too much data is outstanding:
* in such cases notification from Xen is likely to be the only kick
* that we'll get.
*/
np->tx->event =
prod + ((np->tx->req_prod - prod) >> 1) + 1;
mb();
}
while ( prod != np->tx->resp_prod );
if ( np->tx_full &&
((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) )
{
np->tx_full = 0;
if ( np->user_state == UST_OPEN )
netif_wake_queue(dev);
}
}
static void network_alloc_rx_buffers(struct net_device *dev)
{
unsigned short id;
struct net_private *np = dev->priv;
struct sk_buff *skb;
NETIF_RING_IDX i = np->rx->req_prod;
int nr_pfns = 0;
/* Make sure the batch is large enough to be worthwhile (1/2 ring). */
if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) ||
unlikely(np->backend_state != BEST_CONNECTED) )
return;
do {
skb = dev_alloc_skb(RX_BUF_SIZE);
if ( unlikely(skb == NULL) )
break;
skb->dev = dev;
if ( unlikely(((unsigned long)skb->head & (PAGE_SIZE-1)) != 0) )
panic("alloc_skb needs to provide us page-aligned buffers.");
id = GET_ID_FROM_FREELIST(np->rx_skbs);
np->rx_skbs[id] = skb;
np->rx->ring[MASK_NETIF_RX_IDX(i)].req.id = id;
rx_pfn_array[nr_pfns] = virt_to_machine(skb->head) >> PAGE_SHIFT;
rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping;
rx_mcl[nr_pfns].args[0] = (unsigned long)skb->head >> PAGE_SHIFT;
rx_mcl[nr_pfns].args[1] = 0;
rx_mcl[nr_pfns].args[2] = 0;
nr_pfns++;
}
while ( (++i - np->rx_resp_cons) != NETIF_RX_RING_SIZE );
/*
* We may have allocated buffers which have entries outstanding in the page
* update queue -- make sure we flush those first!
*/
flush_page_update_queue();
/* After all PTEs have been zapped we blow away stale TLB entries. */
rx_mcl[nr_pfns-1].args[2] = UVMF_FLUSH_TLB;
/* Give away a batch of pages. */
rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op;
rx_mcl[nr_pfns].args[0] = MEMOP_decrease_reservation;
rx_mcl[nr_pfns].args[1] = (unsigned long)rx_pfn_array;
rx_mcl[nr_pfns].args[2] = (unsigned long)nr_pfns;
/* Zap PTEs and give away pages in one big multicall. */
(void)HYPERVISOR_multicall(rx_mcl, nr_pfns+1);
/* Check return status of HYPERVISOR_dom_mem_op(). */
if ( rx_mcl[nr_pfns].args[5] != nr_pfns )
panic("Unable to reduce memory reservation\n");
np->rx->req_prod = i;
}
static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned short id;
struct net_private *np = (struct net_private *)dev->priv;
netif_tx_request_t *tx;
NETIF_RING_IDX i;
if ( unlikely(np->tx_full) )
{
printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name);
netif_stop_queue(dev);
return -ENOBUFS;
}
if ( unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
PAGE_SIZE) )
{
struct sk_buff *new_skb = dev_alloc_skb(RX_BUF_SIZE);
if ( unlikely(new_skb == NULL) )
return 1;
skb_put(new_skb, skb->len);
memcpy(new_skb->data, skb->data, skb->len);
dev_kfree_skb(skb);
skb = new_skb;
}
spin_lock_irq(&np->tx_lock);
if ( np->backend_state != BEST_CONNECTED )
{
spin_unlock_irq(&np->tx_lock);
return 1;
}
i = np->tx->req_prod;
id = GET_ID_FROM_FREELIST(np->tx_skbs);
np->tx_skbs[id] = skb;
tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
tx->id = id;
tx->addr = virt_to_machine(skb->data);
tx->size = skb->len;
wmb();
np->tx->req_prod = i + 1;
network_tx_buf_gc(dev);
if ( (i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1) )
{
np->tx_full = 1;
netif_stop_queue(dev);
}
spin_unlock_irq(&np->tx_lock);
np->stats.tx_bytes += skb->len;
np->stats.tx_packets++;
/* Only notify Xen if there are no outstanding responses. */
mb();
if ( np->tx->resp_prod == i )
notify_via_evtchn(np->evtchn);
return 0;
}
static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
struct net_device *dev = dev_id;
struct net_private *np = dev->priv;
unsigned long flags;
spin_lock_irqsave(&np->tx_lock, flags);
network_tx_buf_gc(dev);
spin_unlock_irqrestore(&np->tx_lock, flags);
if ( (np->rx_resp_cons != np->rx->resp_prod) &&
(np->user_state == UST_OPEN) )
netif_rx_schedule(dev);
}
static int netif_poll(struct net_device *dev, int *pbudget)
{
struct net_private *np = dev->priv;
struct sk_buff *skb;
netif_rx_response_t *rx;
NETIF_RING_IDX i;
mmu_update_t *mmu = rx_mmu;
multicall_entry_t *mcl = rx_mcl;
int work_done, budget, more_to_do = 1;
struct sk_buff_head rxq;
unsigned long flags;
spin_lock(&np->rx_lock);
if ( np->backend_state != BEST_CONNECTED )
{
spin_unlock(&np->rx_lock);
return 0;
}
skb_queue_head_init(&rxq);
if ( (budget = *pbudget) > dev->quota )
budget = dev->quota;
for ( i = np->rx_resp_cons, work_done = 0;
(i != np->rx->resp_prod) && (work_done < budget);
i++, work_done++ )
{
rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
skb = np->rx_skbs[rx->id];
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
if ( unlikely(rx->status <= 0) )
{
/* Gate this error. We get a (valid) slew of them on suspend. */
if ( np->user_state != UST_OPEN )
printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
dev_kfree_skb(skb);
continue;
}
skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK);
skb_put(skb, rx->status);
np->stats.rx_packets++;
np->stats.rx_bytes += rx->status;
/* Remap the page. */
mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
mmu->val = __pa(skb->head) >> PAGE_SHIFT;
mmu++;
mcl->op = __HYPERVISOR_update_va_mapping;
mcl->args[0] = (unsigned long)skb->head >> PAGE_SHIFT;
mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL;
mcl->args[2] = 0;
mcl++;
phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] =
rx->addr >> PAGE_SHIFT;
__skb_queue_tail(&rxq, skb);
}
/* Do all the remapping work, and M->P updates, in one big hypercall. */
if ( likely((mcl - rx_mcl) != 0) )
{
mcl->op = __HYPERVISOR_mmu_update;
mcl->args[0] = (unsigned long)rx_mmu;
mcl->args[1] = mmu - rx_mmu;
mcl->args[2] = 0;
mcl++;
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
}
while ( (skb = __skb_dequeue(&rxq)) != NULL )
{
/* Set the shared-info area, which is hidden behind the real data. */
atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
/* Ethernet-specific work. Delayed to here as it peeks the header. */
skb->protocol = eth_type_trans(skb, dev);
/* Pass it up. */
netif_rx(skb);
dev->last_rx = jiffies;
}
np->rx_resp_cons = i;
network_alloc_rx_buffers(dev);
*pbudget -= work_done;
dev->quota -= work_done;
if ( work_done < budget )
{
local_irq_save(flags);
np->rx->event = i + 1;
/* Deal with hypervisor racing our resetting of rx_event. */
mb();
if ( np->rx->resp_prod == i )
{
__netif_rx_complete(dev);
more_to_do = 0;
}
local_irq_restore(flags);
}
spin_unlock(&np->rx_lock);
return more_to_do;
}
static int network_close(struct net_device *dev)
{
struct net_private *np = dev->priv;
np->user_state = UST_CLOSED;
netif_stop_queue(np->dev);
return 0;
}
static struct net_device_stats *network_get_stats(struct net_device *dev)
{
struct net_private *np = (struct net_private *)dev->priv;
return &np->stats;
}
static void network_connect(struct net_device *dev,
netif_fe_interface_status_changed_t *status)
{
struct net_private *np;
int i, requeue_idx;
netif_tx_request_t *tx;
np = dev->priv;
spin_lock_irq(&np->rx_lock);
spin_lock(&np->tx_lock);
/* Recovery procedure: */
/* Step 1: Reinitialise variables. */
np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
np->rx->event = 1;
/* Step 2: Rebuild the RX and TX ring contents.
* NB. We could just free the queued TX packets now but we hope
* that sending them out might do some good. We have to rebuild
* the RX ring because some of our pages are currently flipped out
* so we can't just free the RX skbs.
* NB2. Freelist index entries are always going to be less than
* __PAGE_OFFSET, whereas pointers to skbs will always be equal or
* greater than __PAGE_OFFSET: we use this property to distinguish
* them.
*/
/* Rebuild the TX buffer freelist and the TX ring itself.
* NB. This reorders packets. We could keep more private state
* to avoid this but maybe it doesn't matter so much given the
* interface has been down.
*/
for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ )
{
if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET )
{
struct sk_buff *skb = np->tx_skbs[i];
tx = &np->tx->ring[requeue_idx++].req;
tx->id = i;
tx->addr = virt_to_machine(skb->data);
tx->size = skb->len;
np->stats.tx_bytes += skb->len;
np->stats.tx_packets++;
}
}
wmb();
np->tx->req_prod = requeue_idx;
/* Rebuild the RX buffer freelist and the RX ring itself. */
for ( requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++ )
if ( (unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET )
np->rx->ring[requeue_idx++].req.id = i;
wmb();
np->rx->req_prod = requeue_idx;
/* Step 3: All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
* packets.
*/
np->backend_state = BEST_CONNECTED;
notify_via_evtchn(status->evtchn);
network_tx_buf_gc(dev);
if ( np->user_state == UST_OPEN )
netif_start_queue(dev);
spin_unlock(&np->tx_lock);
spin_unlock_irq(&np->rx_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;
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();
break;
default:
printk(KERN_WARNING "Status change to unknown value %d\n",
status->status);
break;
}
}
/** Create a network device.
* @param handle device handle
* @param val return parameter for created device
* @return 0 on success, error code otherwise
*/
static int create_netdev(int handle, struct net_device **val)
{
int i, err = 0;
struct net_device *dev = NULL;
struct net_private *np = NULL;
if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL )
{
printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
err = -ENOMEM;
goto exit;
}
np = dev->priv;
np->backend_state = BEST_CLOSED;
np->user_state = UST_CLOSED;
np->handle = handle;
spin_lock_init(&np->tx_lock);
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++ )
np->tx_skbs[i] = (void *)(i+1);
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;
dev->stop = network_close;
dev->get_stats = network_get_stats;
dev->poll = netif_poll;
dev->weight = 64;
if ( (err = register_netdev(dev)) != 0 )
{
printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
goto exit;
}
np->dev = dev;
list_add(&np->list, &dev_list);
exit:
if ( (err != 0) && (dev != NULL ) )
kfree(dev);
else if ( val != NULL )
*val = dev;
return err;
}
/*
* Initialize the network control interface. Set the number of network devices
* and create them.
*/
static void netif_driver_status_change(
netif_fe_driver_status_changed_t *status)
{
int err = 0;
int i;
netctrl.interface_n = status->nr_interfaces;
netctrl.connected_n = 0;
for ( i = 0; i < netctrl.interface_n; i++ )
{
if ( (err = create_netdev(i, NULL)) != 0 )
{
netctrl_err(err);
break;
}
}
}
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) )
goto error;
netif_status_change((netif_fe_interface_status_changed_t *)
&msg->msg[0]);
break;
case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
if ( msg->length != sizeof(netif_fe_driver_status_changed_t) )
goto error;
netif_driver_status_change((netif_fe_driver_status_changed_t *)
&msg->msg[0]);
/* Message is a response */
respond = 0;
break;
error:
default:
msg->length = 0;
break;
}
if ( respond )
ctrl_if_send_response(msg);
}
static int __init netif_init(void)
{
ctrl_msg_t cmsg;
netif_fe_driver_status_changed_t st;
int err = 0, wait_i, wait_n = 20;
if ( (start_info.flags & SIF_INITDOMAIN) ||
(start_info.flags & SIF_NET_BE_DOMAIN) )
return 0;
printk("Initialising Xen virtual ethernet frontend driver");
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.nr_interfaces = 0;
memcpy(cmsg.msg, &st, sizeof(st));
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
/* Wait for all interfaces to be connected. */
for ( wait_i = 0; ; wait_i++)
{
if ( (err = (wait_i < wait_n) ? netctrl_connected() : -ENETDOWN) != 0 )
{
err = (err > 0) ? 0 : err;
break;
}
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if ( err )
ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
return err;
}
__initcall(netif_init);
+2 -2
View File
@@ -225,5 +225,5 @@ ln -sf ../../i386/mm/extable.c
ln -sf ../../i386/mm/pageattr.c
cd ../drivers/console
ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c
#cd ../netif/frontend
#ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c
cd ../netif/frontend
ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c
+4
View File
@@ -16,6 +16,10 @@ config ARCH_XEN
default y
config NO_IDLE_HZ
bool
default y
source "init/Kconfig"
#config VT
@@ -87,6 +87,17 @@ EXPORT_SYMBOL(i8253_lock);
struct timer_opts *cur_timer = &timer_none;
/* These are peridically updated in shared_info, and then copied here. */
static u32 shadow_tsc_stamp;
static u64 shadow_system_time;
static u32 shadow_time_version;
static struct timeval shadow_tv;
/* Keep track of last time we did processing/updating of jiffies and xtime. */
static u64 processed_system_time; /* System time (ns) at last processing. */
#define NS_PER_TICK (1000000000ULL/HZ)
/*
* This version of gettimeofday has microsecond resolution
* and better than microsecond precision on fast x86 machines with TSC.
@@ -203,6 +214,24 @@ unsigned long long monotonic_clock(void)
EXPORT_SYMBOL(monotonic_clock);
/*
* Reads a consistent set of time-base values from Xen, into a shadow data
* area. Must be called with the xtime_lock held for writing.
*/
static void __get_time_values_from_xen(void)
{
do {
shadow_time_version = HYPERVISOR_shared_info->time_version2;
rmb();
shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits;
shadow_system_time = HYPERVISOR_shared_info->system_time;
rmb();
}
while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 );
}
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
@@ -210,6 +239,9 @@ EXPORT_SYMBOL(monotonic_clock);
static inline void do_timer_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
s64 delta;
unsigned long ticks = 0;
#ifdef CONFIG_X86_IO_APIC
if (timer_ack) {
/*
@@ -226,7 +258,23 @@ static inline void do_timer_interrupt(int irq, void *dev_id,
}
#endif
do_timer_interrupt_hook(regs);
__get_time_values_from_xen();
delta = (s64)(shadow_system_time - processed_system_time);
if (delta < 0) {
printk("Timer ISR: Time went backwards: %lld\n", delta);
return;
}
/* Process elapsed jiffies since last call. */
while (delta >= NS_PER_TICK) {
ticks++;
delta -= NS_PER_TICK;
processed_system_time += NS_PER_TICK;
if (regs)
do_timer_interrupt_hook(regs);
}
#if 0 /* XEN PRIV */
/*
@@ -288,8 +336,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
cur_timer->mark_offset();
if (regs) /* XXXcl check regs in do_timer_interrupt */
do_timer_interrupt(irq, NULL, regs);
do_timer_interrupt(irq, NULL, regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
@@ -410,3 +457,45 @@ void __init time_init(void)
(void)setup_irq(time_irq, &irq_timer);
}
/* Convert jiffies to system time. Call with xtime_lock held for reading. */
static inline u64 __jiffies_to_st(unsigned long j)
{
return processed_system_time + ((j - jiffies) * NS_PER_TICK);
}
/*
* This function works out when the the next timer function has to be
* executed (by looking at the timer list) and sets the Xen one-shot
* domain timer to the appropriate value. This is typically called in
* cpu_idle() before the domain blocks.
*
* The function returns a non-0 value on error conditions.
*
* It must be called with interrupts disabled.
*/
extern spinlock_t timerlist_lock;
int set_timeout_timer(void)
{
u64 alarm = 0;
int ret = 0;
int cpu = smp_processor_id();
spin_lock(&timerlist_lock);
/*
* This is safe against long blocking (since calculations are not based on
* TSC deltas). It is also safe against warped system time since
* suspend-resume is cooperative and we would first get locked out. It is
* safe against normal updates of jiffies since interrupts are off.
*/
alarm = __jiffies_to_st(next_timer_interrupt());
/* Failure is pretty bad, but we'd best soldier on. */
if ( HYPERVISOR_set_timer_op(alarm) != 0 )
ret = -1;
spin_unlock(&timerlist_lock);
return ret;
}
@@ -10,11 +10,16 @@
void xen_cpu_idle (void)
{
// local_irq_disable();
if (need_resched()) {
// local_irq_enable();
local_irq_disable();
if (need_resched() || !list_empty(&RCU_curlist(cpu)))
local_irq_enable();
return;
}
// local_irq_enable();
if (set_timeout_timer() == 0) {
/* NB. Blocking reenable events in a race-free manner. */
HYPERVISOR_block();
return;
}
local_irq_enable();
HYPERVISOR_yield();
}
@@ -1,6 +1,4 @@
/******************************************************************************
* network.c
*
* Virtual network driver for conversing with remote driver backends.
*
* Copyright (c) 2002-2004, K A Fraser
@@ -8,13 +6,12 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
@@ -30,7 +27,13 @@
#include <asm/page.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#include <asm-xen/netif.h>
#else
#include "../netif.h"
#define irqreturn_t void
#define IRQ_HANDLED
#endif
#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */
@@ -368,7 +371,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
struct net_device *dev = dev_id;
struct net_private *np = dev->priv;
@@ -381,8 +384,6 @@ static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
if ( (np->rx_resp_cons != np->rx->resp_prod) &&
(np->user_state == UST_OPEN) )
netif_rx_schedule(dev);
return IRQ_HANDLED;
}
@@ -417,18 +418,25 @@ static int netif_poll(struct net_device *dev, int *pbudget)
{
rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
skb = np->rx_skbs[rx->id];
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
/*
* An error here is very odd. Usually indicates a backend bug,
* low-memory condition, or that we didn't have reservation headroom.
* Whatever - print an error and queue the id again straight away.
*/
if ( unlikely(rx->status <= 0) )
{
/* Gate this error. We get a (valid) slew of them on suspend. */
if ( np->user_state != UST_OPEN )
if ( np->user_state == UST_OPEN )
printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
dev_kfree_skb(skb);
np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
wmb();
np->rx->req_prod++;
continue;
}
skb = np->rx_skbs[rx->id];
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK);
skb_put(skb, rx->status);
+1
View File
@@ -41,6 +41,7 @@ setup(name = 'xen',
'xen.util',
'xen.xend',
'xen.xend.server',
'xen.xend.sv',
'xen.xm',
],
ext_package = "xen.lowlevel",
+1 -1
View File
@@ -100,7 +100,7 @@ def lookup_raw_partn(name):
if line:
return [ { 'device' : blkdev_name_to_number(p),
'start_sector' : long(0),
'nr_sectors' : long(line) * 2,
'nr_sectors' : long(1L<<63),
'type' : 'Disk' } ]
else:
# see if this is a hex device number
+6 -2
View File
@@ -25,8 +25,8 @@
# todo Support security settings etc. in the config file.
# todo Support command-line args.
from twisted.web import server
from twisted.web import resource
from twisted.web import server, static
from twisted.web import resource, script
from twisted.internet import reactor
from xen.xend import XendRoot
@@ -44,8 +44,12 @@ def create(port=None, interface=None, bridge=0):
if bridge or xroot.rebooted:
Vifctl.network('start')
root = resource.Resource()
sv = static.File( "/usr/lib/python2.2/site-packages/xen/xend/sv/" )
sv.indexNames=['Main.rpy']
sv.processors={'.rpy':script.ResourceScript}
xend = SrvRoot()
root.putChild('xend', xend)
root.putChild('sv', sv)
site = server.Site(root)
reactor.listenTCP(port, site, interface=interface)
+99
View File
@@ -0,0 +1,99 @@
from HTMLBase import HTMLBase
from XendClientDeferred import server
from xen.xend import PrettyPrint
from xen.xend.sv.util import *
from xen.xend.sv.GenTabbed import *
class DomInfo( GenTabbed ):
def __init__( self, urlWriter, callback ):
self.dom = 0;
def tabUrlWriter( tab ):
return urlWriter( "mod=info&dom=%s%s" % ( self.dom, tab ) )
GenTabbed.__init__( self, tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGenTab, DomSXPTab, NullTab ], callback )
def write_BODY( self, request ):
dom = request.args.get('dom')
if dom is None or len(dom) != 1:
request.write( "<p>Please Select a Domain</p>" )
return None
else:
self.dom = dom[0]
GenTabbed.write_BODY( self, request )
class DomGenTab( GeneralTab ):
def __init__( self ):
titles = {}
titles[ 'ID' ] = 'dom'
titles[ 'Name' ] = 'name'
titles[ 'CPU' ] = 'cpu'
titles[ 'Memory' ] = ( 'mem', memoryFormatter )
titles[ 'State' ] = ( 'state', stateFormatter )
titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter )
titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter )
GeneralTab.__init__( self, "General Domain Info", {}, titles )
def write_BODY( self, request, callback ):
dom = request.args.get('dom')
if dom is None or len(dom) != 1:
request.write( "<p>Please Select a Domain</p>" )
return None
else:
self.dom = dom[0]
deferred = getDomInfoHash( self.dom )
deferred.addCallback( self.continue_BODY, request, callback )
def continue_BODY( self, dict, request, callback ):
self.dict = dict
GeneralTab.write_BODY( self, request, callback )
class DomSXPTab( PreTab ):
def __init__( self ):
self.dom = 0
PreTab.__init__( self, "" )
def fn( self, x, request ):
class tmp:
def __init__( self ):
self.str = ""
def write( self, str ):
self.str = self.str + str
temp = tmp()
PrettyPrint.prettyprint( x, out=temp )
self.source = temp.str
return request
def fn2( self, request, callback ):
PreTab.write_BODY( self, request, callback )
def write_BODY( self, request, callback ):
dom = request.args.get('dom')
if dom is None or len(dom) != 1:
request.write( "<p>Please Select a Domain</p>" )
return None
else:
self.dom = dom[0]
deferred = server.xend_domain( self.dom )
deferred.addCallback( self.fn, request )
deferred.addCallback( self.fn2, callback )
def errback( x ):
print ">err ", x
deferred.addErrback( errback )
+101
View File
@@ -0,0 +1,101 @@
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET
from XendClientDeferred import server as XendServer
from xen.xend import sxp
from xen.xend.sv.HTMLBase import HTMLBase
from xen.xend.sv.util import *
from twisted.internet import reactor
class DomList( HTMLBase ):
isLeaf = True
def __init__( self, urlWriter, callback ):
HTMLBase.__init__(self)
self.urlWriter = urlWriter
self.head = None
self.long = None
self.rendered_domains = {}
self.domCount = 0
self.callback = callback
def write_BODY( self, request, head=True, long=True ):
deferred = XendServer.xend_domains()
deferred.addCallback( self.get_domain_info, request )
deferred.addErrback( self.errback )
self.head = head
self.long = long
def errback( self, err ):
print 'errback>', err
def get_domain_info( self, domains, request ):
self.domCount = len( domains )
for domain in domains:
deferred = getDomInfoHash( domain )
deferred.addCallback( self.render_domain, request )
deferred.addErrback( self.errback )
def render_domain( self, domInfoHash, request ):
domStr = "<td class='domainInfo' align='center'>%(dom)-4d</td>\n" % domInfoHash
url = self.urlWriter( "mod=info&dom=%(dom)-4d" % domInfoHash )
domStr += "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] )
if self.long:
domStr += "<td class='domainInfo' align='center'>%(mem)7d</td>\n" % domInfoHash
domStr += "<td class='domainInfo' align='center'>%(cpu)3d</td>\n" % domInfoHash
domStr += "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash
if self.long:
domStr += "<td class='domainInfo' align='center'>%(cpu_time)7.1f</td>\n" % domInfoHash
self.rendered_domains[ domInfoHash[ 'dom' ] ] = domStr
self.domCount -= 1
if self.domCount == 0:
self.finish_write_BODY( request )
def finish_write_BODY( self, request ):
request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" )
if self.head:
request.write( "<tr class='domainInfoHead'>" )
self.write_DOMAIN_HEAD( request, self.long )
request.write( "</tr>" )
odd = True
for domain in self.rendered_domains.values():
if odd:
request.write( "<tr class='domainInfoOdd'>\n" )
odd = False
else:
request.write( "<tr class='domainInfoEven'>\n" )
odd = True
request.write( domain )
request.write( "</tr>\n" )
request.write( "</table>\n" )
self.callback( request )
def write_DOMAIN_HEAD( self, request, long=True ):
request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" )
request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" )
if long:
request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" )
request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" )
request.write( "<td class='domainInfoHead' align='center'>State</td>\n" )
if long:
request.write( "<td class='domainInfoHead' align='center'>CPU time / s</td>\n" )
+103
View File
@@ -0,0 +1,103 @@
import types
from HTMLBase import HTMLBase
from TabView import TabView
class GenTabbed( HTMLBase ):
def __init__( self, urlWriter, tabStrings, tabObjects, callback ):
HTMLBase.__init__(self)
self.tab = 0;
self.tabStrings = tabStrings
self.tabObjects = tabObjects
self.urlWriter = urlWriter
self.callback = callback
def write_BODY( self, request, urlWriter = None ):
tab = request.args.get('tab')
if tab is None or len( tab) != 1:
self.tab = 0
else:
self.tab = int( tab[0] )
request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" )
request.write( "<tr><td>" )
TabView( self.tab, self.tabStrings, self.urlWriter ).write_BODY( request )
request.write( "</td></tr><tr><td>" )
render_tab = self.tabObjects[ self.tab ]()
if render_tab is None:
request.write( "<p>Bad Tab</p>" )
self.finish_BODY( request )
else:
render_tab.write_BODY( request, self.finish_BODY )
def finish_BODY( self, request ):
request.write( "</td></tr></table>" )
self.callback( request )
class PreTab( HTMLBase ):
def __init__( self, source ):
HTMLBase.__init__( self )
self.source = source
def write_BODY( self, request, callback ):
request.write( "<div style='display: block; overflow: auto; border: 0px solid black; height: 400px; width: 540px; padding: 5px; z-index:0; align: center'><pre>" )
request.write( self.source )
request.write( "</pre></div>" )
callback( request )
class GeneralTab( HTMLBase ):
def __init__( self, title, dict, titles ):
HTMLBase.__init__( self )
self.title = title
self.dict = dict
self.titles = titles
def write_BODY( self, request, callback ):
request.write( "<p><u>%s</u></p>" % self.title )
request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" )
def writeAttr( niceName, attr, formatter=None ):
if type( attr ) is types.TupleType:
( attr, formatter ) = attr
if attr in self.dict:
if formatter:
temp = formatter( self.dict[ attr ] )
else:
temp = str( self.dict[ attr ] )
request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) )
for niceName, attr in self.titles.items():
writeAttr( niceName, attr )
request.write( "</table>" )
callback( request )
class NullTab( HTMLBase ):
def __init__( self ):
HTMLBase.__init__( self )
self.title = "Null Tab"
def write_BODY( self, request, callback ):
request.write( "<p>%s</p>" % self.title )
callback( request )
+27
View File
@@ -0,0 +1,27 @@
from twisted.web import server, resource
from twisted.internet import reactor
class HTMLBase( resource.Resource ):
isLeaf = True
def __init__( self ):
resource.Resource.__init__(self)
def render_GET( self, request ):
self.write_TOP( request )
return self.write_BODY( request, self.finish_render_GET )
def finish_render_GET( self, request ):
self.write_BOTTOM( request )
request.finish()
def write_BODY( self, request ):
request.write( "BODY" )
def write_TOP( self, request ):
request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' )
request.write( '</head><body>' )
def write_BOTTOM( self, request ):
request.write( "</body></html>" )
+81
View File
@@ -0,0 +1,81 @@
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET
from xen.xend.XendClient import server as XendServer
from xen.xend import sxp
from HTMLBase import HTMLBase
from xen.xend.sv import DomList, NodeInfo, DomInfo
class Main( HTMLBase ):
isLeaf = True
def __init__( self ):
HTMLBase.__init__(self)
def render_POST( self, request ):
return self.render_GET( request )
def mainUrlWriter( self, s ):
return "Main.rpy?%s" % s
def write_BODY( self, request, callback ):
self.callback = callback
request.write( "\n<table style='border:0px solid black; background: url(images/orb_01.jpg) no-repeat' cellspacing='0' cellpadding='0' border='0' width='780px' height='536px'>\n" )
request.write( "<tr>\n" )
request.write( " <td width='15px'>&nbsp;</td>" )
request.write( " <td width='175px' align='center' valign'center'>" )
request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
request.write( " <tr><td height='200px' align='center' valign='center'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" )
request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a></td></tr>" )
request.write( " <tr><td align='center' valign='top'>" )
request.write( " <p class='small'><a href='Main.rpy?mod=node'>Node details</a></p>" )
request.write( " <p class='small'><a href='Main.rpy?mod=list'>Domains summary</a></p>" )
DomList.DomList( self.mainUrlWriter, self.continue_BODY ).write_BODY( request, True, False )
return NOT_DONE_YET
def continue_BODY( self, request ):
request.write( " </td></tr>" )
request.write( " </table>" )
request.write( " &nbsp;" )
request.write( " </td>\n" )
request.write( " <td width='15px'>&nbsp;</td>" )
request.write( " <td width='558px' align='left' valign='top'>" )
request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
request.write( " <tr><td height='20px'></td></tr>" )
request.write( " <tr><td align='center' valign='top'>" )
mod = request.args.get('mod')
if mod is None or len(mod) != 1:
request.write( '<p>Please select a module</p>' )
self.finish_BODY( request )
elif mod[0] == 'info':
DomInfo.DomInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request )
elif mod[0] == 'list':
DomList.DomList( self.mainUrlWriter, self.finish_BODY ).write_BODY( request )
elif mod[0] == 'node':
NodeInfo.NodeInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request )
else:
request.write( '<p>Invalid module. Please select another</p>' )
self.finish_BODY( request )
def finish_BODY( self, request ):
request.write( " </td></tr>" )
request.write( " </table>" )
request.write( " </td>\n" )
request.write( " <td width='17px'>&nbsp;</td>" )
request.write( "</tr>\n" )
request.write( "</table>\n" )
self.callback( request )
+3
View File
@@ -0,0 +1,3 @@
from xen.xend.sv.Main import *
resource = Main()
+47
View File
@@ -0,0 +1,47 @@
from xen.xend import XendDmesg
from xen.xend import XendNode
from xen.xend.sv.util import *
from xen.xend.sv.GenTabbed import *
from xen.xend.sv.HTMLBase import HTMLBase
class NodeInfo( GenTabbed ):
def __init__( self, urlWriter, callback ):
def newUrlWriter( url ):
return urlWriter( "mod=node%s" % url )
GenTabbed.__init__( self, newUrlWriter, [ 'General', 'Dmesg' ], [ NodeGeneralTab, NodeDmesgTab ], callback )
class NodeGeneralTab( GeneralTab ):
def __init__( self ):
nodeInfo = XendNode.instance().info()
dictNodeInfo = {}
for l in nodeInfo:
dictNodeInfo[ l[0] ] = l[1]
dictTitles = {}
dictTitles[ 'System' ] = 'system'
dictTitles[ 'Hostname' ] = 'host'
dictTitles[ 'Release' ] = 'release'
dictTitles[ 'Version' ] ='version'
dictTitles[ 'Machine' ] = 'machine'
dictTitles[ 'Cores' ] = 'cores'
dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter )
dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter )
dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter )
dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter )
GeneralTab.__init__( self, title="General Node Info", dict=dictNodeInfo, titles=dictTitles )
class NodeDmesgTab( PreTab ):
def __init__( self ):
self.xd = XendDmesg.instance()
PreTab.__init__( self, self.xd.info()[0] )
+49
View File
@@ -0,0 +1,49 @@
from xen.xend.sv.HTMLBase import HTMLBase
class TabView( HTMLBase ):
def __init__( self, tab, tabs, urlWriter ):
HTMLBase.__init__(self)
self.tab = tab # interger - tab id
self.tabs = tabs
self.urlWriter = urlWriter
def write_BODY( self, request ):
request.write( "<table style='' border='0' cellspacing='0' cellpadding='0' align='center'>" )
request.write( "<tr height='22'>" )
if self.tab == 0:
image = "left-end-highlight.jpg"
else:
image = "left-end-no-highlight.jpg"
request.write( "<td height='22' width='14'><image src='images/%s' width='14' height='22'></td>" % image )
count = len( self.tabs )
for i in range( count ):
if i == self.tab:
image = "middle-highlight.jpg"
else:
image = "middle-no-highlight.jpg"
request.write( "<td style='background: url(images/%s)'><p align='center'><a href='%s'>%s</a></p></td>" % ( image, self.urlWriter( "&tab=%s" % i ), self.tabs[ i ] ) )
if i < count-1:
if i == self.tab:
image = "seperator-left-highlight.jpg"
elif self.tab == i+1:
image = "seperator-right-highlight.jpg"
else:
image = "seperator.jpg"
request.write( "<td height='22' width='23'><image src='images/%s' width='23' height='22'></td>" % image )
if self.tab == count - 1:
image = "right-end-highlight.jpg"
else:
image = "right-end-no-highlight.jpg"
request.write( "<td height='22' width='14'><image src='images/%s' width='14' height='22'></td>" % image )
request.write( "</tr></table>" )
+363
View File
@@ -0,0 +1,363 @@
# Copyright (C) 2004 Tom Wilkie <tw275@cam.ac.uk>
# Copyright (C) 2004 Mike Wray
"""Client API for the HTTP interface on xend.
Callable as a script - see main().
This API is the 'control-plane' for xend.
The 'data-plane' is done separately. For example, consoles
are accessed via sockets on xend, but the list of consoles
is accessible via this API.
This one is similar to mikes, but works in an async fashion
"""
import sys
import httplib
import types
from StringIO import StringIO
import urlparse
from xen.xend.encode import *
from xen.xend.sxp import *
from xen.xend.PrettyPrint import prettyprint
from twisted.protocols.http import HTTPClient
from twisted.internet.protocol import ClientCreator
from twisted.internet.defer import Deferred
from twisted.internet import reactor
DEBUG = 0
class XendRequest( HTTPClient ):
def __init__(self, deferred, urls):
self.urls = urls
self.deferred = deferred
def connectionMade(self):
self.sendCommand('GET', self.urls[2])
self.sendHeader('Host', '%s:%d' % (self.urls[0], self.urls[1]) )
self.endHeaders()
def handleResponse(self, data):
self.deferred.callback( data )
def process_SXP( sexp ):
pin = Parser()
pin.input(sexp)
pin.input_eof()
return pin.get_val()
def xend_request(url, method, data=None):
"""Make a request to xend.
url xend request url
method http method: POST or GET
data request argument data (dict)
"""
urlinfo = urlparse.urlparse(url)
(uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo
(hdr, args) = encode_data(data)
if data and method == 'GET':
upath += '?' + args
args = None
if method == "POST" and upath.endswith('/'):
upath = upath[:-1]
deferred = Deferred()
clientCreator = ClientCreator( reactor, XendRequest, deferred, (ulocation, 8000, upath) )
clientCreator.connectTCP( ulocation, 8000 )
deferred.addCallback( process_SXP )
return deferred
class XendError(RuntimeError):
pass
class Foo(httplib.HTTPResponse):
def begin(self):
fin = self.fp
while(1):
buf = fin.readline()
print "***", buf
if buf == '':
print
sys.exit()
def sxprio(sxpr):
"""Convert an sxpr to a string.
"""
io = StringIO()
sxp.show(sxpr, out=io)
print >> io
io.seek(0)
return io
def fileof(val):
"""Converter for passing configs.
Handles lists, files directly.
Assumes a string is a file name and passes its contents.
"""
if isinstance(val, types.ListType):
return sxprio(val)
if isinstance(val, types.StringType):
return file(val)
if hasattr(val, 'readlines'):
return val
# todo: need to sort of what urls/paths are using for objects.
# e.g. for domains at the moment return '0'.
# should probably return abs path w.r.t. server, e.g. /xend/domain/0.
# As an arg, assume abs path is obj uri, otherwise just id.
# Function to convert to full url: Xend.uri(path), e.g.
# maps /xend/domain/0 to http://wray-m-3.hpl.hp.com:8000/xend/domain/0
# And should accept urls for ids?
def urljoin(location, root, prefix='', rest=''):
prefix = str(prefix)
rest = str(rest)
base = 'http://' + location + root + prefix
url = urlparse.urljoin(base, rest)
return url
def nodeurl(location, root, id=''):
return urljoin(location, root, 'node/', id)
def domainurl(location, root, id=''):
return urljoin(location, root, 'domain/', id)
def consoleurl(location, root, id=''):
return urljoin(location, root, 'console/', id)
def deviceurl(location, root, id=''):
return urljoin(location, root, 'device/', id)
def vneturl(location, root, id=''):
return urljoin(location, root, 'vnet/', id)
def eventurl(location, root, id=''):
return urljoin(location, root, 'event/', id)
def xend_get(url, args=None):
"""Make a xend request using GET.
Requests using GET are 'safe' and may be repeated without
nasty side-effects.
"""
return xend_request(url, "GET", args)
def xend_call(url, data):
"""Make xend request using POST.
Requests using POST potentially cause side-effects and should
not be repeated unless it really is wanted to do the side
effect again.
"""
return xend_request(url, "POST", data)
class Xend:
"""Default location of the xend server."""
SRV_DEFAULT = "localhost"
"""Default path to the xend root on the server."""
ROOT_DEFAULT = "/xend/"
def __init__(self, srv=None, root=None):
self.bind(srv, root)
def bind(self, srv=None, root=None):
"""Bind to a given server.
srv server location (host:port)
root server xend root path
"""
if srv is None: srv = self.SRV_DEFAULT
if root is None: root = self.ROOT_DEFAULT
if not root.endswith('/'): root += '/'
self.location = srv
self.root = root
def nodeurl(self, id=''):
return nodeurl(self.location, self.root, id)
def domainurl(self, id=''):
return domainurl(self.location, self.root, id)
def consoleurl(self, id=''):
return consoleurl(self.location, self.root, id)
def deviceurl(self, id=''):
return deviceurl(self.location, self.root, id)
def vneturl(self, id=''):
return vneturl(self.location, self.root, id)
def eventurl(self, id=''):
return eventurl(self.location, self.root, id)
def xend(self):
return xend_get(urljoin(self.location, self.root))
def xend_node(self):
return xend_get(self.nodeurl())
def xend_node_cpu_rrobin_slice_set(self, slice):
return xend_call(self.nodeurl(),
{'op' : 'cpu_rrobin_slice_set',
'slice' : slice })
def xend_node_cpu_bvt_slice_set(self, ctx_allow):
return xend_call(self.nodeurl(),
{'op' : 'cpu_bvt_slice_set',
'ctx_allow' : ctx_allow })
def xend_node_cpu_fbvt_slice_set(self, ctx_allow):
return xend_call(self.nodeurl(),
{'op' : 'cpu_fbvt_slice_set',
'ctx_allow' : ctx_allow })
def xend_domains(self):
return xend_get(self.domainurl())
def xend_domain_create(self, conf):
return xend_call(self.domainurl(),
{'op' : 'create',
'config' : fileof(conf) })
def xend_domain(self, id):
return xend_get(self.domainurl(id))
def xend_domain_unpause(self, id):
return xend_call(self.domainurl(id),
{'op' : 'unpause'})
def xend_domain_pause(self, id):
return xend_call(self.domainurl(id),
{'op' : 'pause'})
def xend_domain_shutdown(self, id, reason):
return xend_call(self.domainurl(id),
{'op' : 'shutdown',
'reason' : reason })
def xend_domain_destroy(self, id):
return xend_call(self.domainurl(id),
{'op' : 'destroy'})
def xend_domain_save(self, id, filename):
return xend_call(self.domainurl(id),
{'op' : 'save',
'file' : filename})
def xend_domain_restore(self, id, filename):
return xend_call(self.domainurl(id),
{'op' : 'restore',
'file' : filename })
def xend_domain_migrate(self, id, dst):
return xend_call(self.domainurl(id),
{'op' : 'migrate',
'destination': dst})
def xend_domain_pincpu(self, id, cpu):
return xend_call(self.domainurl(id),
{'op' : 'pincpu',
'cpu' : cpu})
def xend_domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
return xend_call(self.domainurl(id),
{'op' : 'cpu_bvt_set',
'mcuadv' : mcuadv,
'warp' : warp,
'warpl' : warpl,
'warpu' : warpu })
def xend_domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu):
return xend_call(self.domainurl(id),
{'op' : 'cpu_fbvt_set',
'mcuadv' : mcuadv,
'warp' : warp,
'warpl' : warpl,
'warpu' : warpu })
def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime):
return xend_call(self.domainurl(id),
{'op' : 'cpu_atropos_set',
'period' : period,
'slice' : slice,
'latency' : latency,
'xtratime': xtratime })
def xend_domain_vifs(self, id):
return xend_get(self.domainurl(id),
{ 'op' : 'vifs' })
def xend_domain_vif_ip_add(self, id, vif, ipaddr):
return xend_call(self.domainurl(id),
{'op' : 'vif_ip_add',
'vif' : vif,
'ip' : ipaddr })
def xend_domain_vbds(self, id):
return xend_get(self.domainurl(id),
{'op' : 'vbds'})
def xend_domain_vbd(self, id, vbd):
return xend_get(self.domainurl(id),
{'op' : 'vbd',
'vbd' : vbd})
def xend_consoles(self):
return xend_get(self.consoleurl())
def xend_console(self, id):
return xend_get(self.consoleurl(id))
def xend_vnets(self):
return xend_get(self.vneturl())
def xend_vnet_create(self, conf):
return xend_call(self.vneturl(),
{'op': 'create', 'config': fileof(conf) })
def xend_vnet(self, id):
return xend_get(self.vneturl(id))
def xend_vnet_delete(self, id):
return xend_call(self.vneturl(id),
{'op': 'delete'})
def xend_event_inject(self, sxpr):
val = xend_call(self.eventurl(),
{'op': 'inject', 'event': fileof(sxpr) })
def main(argv):
"""Call an API function:
python XendClient.py fn args...
The leading 'xend_' on the function can be omitted.
Example:
> python XendClient.py domains
(domain 0 8)
> python XendClient.py domain 0
(domain (id 0) (name Domain-0) (memory 128))
"""
server = Xend()
fn = argv[1]
if not fn.startswith('xend'):
fn = 'xend_' + fn
args = argv[2:]
deferred = getattr(server, fn)(*args)
deferred.addCallback( prettyprint )
reactor.run()
print
if __name__ == "__main__":
main(sys.argv)
else:
server = Xend()
+1
View File
@@ -0,0 +1 @@
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+30
View File
@@ -0,0 +1,30 @@
P {font-family: verdana, arial; font-size: 12px; color: black}
.small {font-size: 10px}
TD.domainInfo {font-family: verdana, arial; font-size: 10px; color: black}
TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold}
TD.domainInfoHead {background-color: black}
TR.domainInfoOdd {background-color: white}
TR.domainInfoEven {background-color: lightgrey}
body {
width: 670px;
margin: 0px;
padding: 0px;
background-color: #fff;
background-image: url(../images/orb_02.jpg);
background-repeat: repeat-y;
background-position: left top;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #333333;
letter-spacing: 0px;
scrollbar-base-color: #333333;
scrollbar-track-color: #666666;
scrollbar-face-color: #fff;
}
+64
View File
@@ -0,0 +1,64 @@
from xen.xend.sv.XendClientDeferred import server
from xen.xend import sxp
def getDomInfoHash( domain ):
deferred = server.xend_domain( int( domain ) )
deferred.addCallback( procDomInfo, domain )
return deferred
def procDomInfo( domInfo, domain ):
d = {}
d['dom'] = int( domain )
d['name'] = sxp.child_value( domInfo, 'name' )
d['mem'] = int( sxp.child_value( domInfo, 'memory' ) )
d['cpu'] = int( sxp.child_value( domInfo, 'cpu' ) )
d['state'] = sxp.child_value( domInfo, 'state' )
d['cpu_time'] = float( sxp.child_value( domInfo, 'cpu_time' ) )
if( sxp.child_value( domInfo, 'up_time' ) ):
d['up_time'] = float( sxp.child_value( domInfo, 'up_time' ) )
if( sxp.child_value( domInfo, 'start_time' ) ):
d['start_time'] = float( sxp.child_value( domInfo, 'start_time' ) )
return d
def bigTimeFormatter( time ):
weeks = time // 604800
remainder = time % 604800
days = remainder // 86400
remainder = remainder % 86400
hms = smallTimeFormatter( remainder )
return "%d weeks, %d days, %s" % ( weeks, days, hms )
def smallTimeFormatter( time ):
hours = time // 3600
remainder = time % 3600
mins = remainder // 60
secs = time % 60
return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs )
def stateFormatter( state ):
states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ]
for i in range( len( state ) ):
if state[i] != "-":
return states[ i ] + " (%s)" % state
return state
def memoryFormatter( mem ):
return "%7dMb" % mem
def cpuFormatter( mhz ):
if mhz > 1000:
ghz = float( mhz ) / 1000.0
return "%4.2fGHz" % ghz
else:
return "%4dMHz" % mhz
def hyperthreadFormatter( threads ):
if int( threads ) > 1:
return "Yes (%d)" % threads
else:
return "No"
+16 -1
View File
@@ -105,8 +105,23 @@ class Xm:
def getprog(self, name, val=None):
"""Get a sub-program.
name Name of the sub-program (or optionally, an unambiguous
prefix of its name)
val Default return value if no (unique) match is found
"""
return self.progs.get(name, val)
match = None
for progname in self.progs.keys():
if progname == name:
match = progname
break
if progname.startswith(name):
if not match:
match = progname
else:
return val # name is ambiguous - bail out
return self.progs.get(match, val)
def proglist(self):
"""Get a list of sub-programs, ordered by group.
+4 -3
View File
@@ -840,7 +840,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
if ( unlikely((e = percpu_info[cpu].gps) == NULL) )
{
MEM_LOG("No GPS to reassign pfn %08lx to\n", pfn);
MEM_LOG("No GPS to reassign pfn %08lx to", pfn);
okay = 0;
break;
}
@@ -865,6 +865,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
if ( unlikely(test_bit(DF_DYING, &e->flags)) ||
unlikely(IS_XEN_HEAP_FRAME(page)) )
{
MEM_LOG("Reassignment page is Xen heap, or dest dom is dying.");
okay = 0;
goto reassign_fail;
}
@@ -1051,8 +1052,8 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
* If in log-dirty mode, mark the corresponding pseudo-physical
* page as dirty.
*/
if( unlikely(current->mm.shadow_mode == SHM_logdirty) )
mark_dirty( &current->mm, pfn );
if ( unlikely(current->mm.shadow_mode == SHM_logdirty) )
mark_dirty(&current->mm, pfn);
put_page(&frame_table[pfn]);
break;
+30 -3
View File
@@ -30,6 +30,10 @@
#include <xen/perfc.h>
#include <asm/processor.h>
/* Make the scary benign errors go away. */
#undef DPRINTK
#define DPRINTK(_f, _a...) ((void)0)
/*
* Obtain the base and limit associated with the given segment selector.
* The selector must identify a 32-bit code or data segment. Any segment that
@@ -495,9 +499,34 @@ int gpf_emulate_4gb(struct pt_regs *regs)
goto undecodeable;
}
#if 0
{
char str1[] = { 0x65,0x8b,0x00,0x8b,0x30 };
char str2[] = { 0x65,0x8b,0x02,0x8b,0x40,0x0c };
char str3[] = { 0x65,0x8b,0x30,0x85,0xf6 };
char str4[] = { 0x65,0x8b,0x00,0x5d,0x8b,0x00 };
char str5[] = { 0x65,0x89,0x30,0x8b,0x45,0x08 };
char str6[] = { 0x65,0x8b,0x00,0x8b,0x50,0x0c };
char str7[] = { 0x65,0x89,0x51,0x00,0x83,0xc8,0xff };
if ( (memcmp(eip,str1,5) == 0) ||
(memcmp(eip,str2,6) == 0) ) goto out;
if ( (memcmp(eip,str3,5) == 0) ||
(memcmp(eip,str4,6) == 0) ) goto out;
if ( (memcmp(eip,str5,6) == 0) ||
(memcmp(eip,str6,6) == 0) ) goto out;
if ( (memcmp(eip,str7,7) == 0) ||
(memcmp(eip,str7,7) == 0) ) goto out;
}
printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
eip[-8],eip[-7],eip[-6],eip[-5],eip[-4],eip[-3],eip[-2],eip[-1]);
printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
eip[0],eip[1],eip[2],eip[3],eip[4],eip[5],eip[6],eip[7]);
printk(" @ %04x:%08lx\n", regs->xcs, regs->eip);
#endif
/* Success! */
regs->eip += pb - eip;
perfc_incrc(emulations);
regs->eip += pb - eip;
return 1;
undecodeable:
@@ -530,5 +559,3 @@ int gpf_emulate_4gb(struct pt_regs *regs)
d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
return 1;
}
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.