ia64/xen-unstable
changeset 1844:bdb9b919d55e
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
Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
line diff
1.1 --- a/.rootkeys Mon Jul 19 11:49:45 2004 +0000 1.2 +++ b/.rootkeys Tue Jul 20 14:58:08 2004 +0000 1.3 @@ -72,7 +72,6 @@ 4097ba83glWYwQTkbPqgLIlYDOPVLg linux-2.4 1.4 4097ba837h2tuiweIWp-voNVzCRI6g linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c 1.5 4087cf0d5dudKw_DecIJgOhLlBF_0Q linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c 1.6 405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/Makefile 1.7 -405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c 1.8 4097ba83Qy2eafeFUhGhm6_4iMIIDw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/netif.h 1.9 3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile 1.10 4075806dE5mQwlVUf8-t3YXjiMMWDQ linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c 1.11 @@ -199,7 +198,7 @@ 40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6 1.12 40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.7-xen-sparse/drivers/xen/evtchn/evtchn.c 1.13 40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.7-xen-sparse/drivers/xen/net/Kconfig 1.14 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile 1.15 -40f56239vUsbJCS9tGFfRVi1YZlGEg linux-2.6.7-xen-sparse/drivers/xen/net/network.c 1.16 +405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.7-xen-sparse/drivers/xen/net/network.c 1.17 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h 1.18 40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h 1.19 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h 1.20 @@ -366,6 +365,33 @@ 40d83983OXjt-y3HjSCcuoPp9rzvmw tools/pyt 1.21 40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py 1.22 40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py 1.23 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/python/xen/xend/server/params.py 1.24 +40fcefb2qm13BbRZBydAatOavaS0fQ tools/python/xen/xend/sv/DomInfo.py 1.25 +40fcefb2-RIU8GB67mJMRzybME9bxw tools/python/xen/xend/sv/DomList.py 1.26 +40fcefb23FfQn-ZBCbcHqA0cPGqQxw tools/python/xen/xend/sv/GenTabbed.py 1.27 +40fcefb2QZAn3u3sX-M7NXBjOv5HGg tools/python/xen/xend/sv/HTMLBase.py 1.28 +40fcefb2vnfDbl4w_yCTedROPuqs0g tools/python/xen/xend/sv/Main.py 1.29 +40fcefb2K1xqVVT4D-p7nL2GzS4scg tools/python/xen/xend/sv/Main.rpy 1.30 +40fcefb24h-04WaHag-Tg4nxWPhTig tools/python/xen/xend/sv/NodeInfo.py 1.31 +40fcefb2Sif__6AqrANeBQZZfvP-6w tools/python/xen/xend/sv/TabView.py 1.32 +40fcefb23s0sQlDfl4sPP0Un8oZGhg tools/python/xen/xend/sv/XendClientDeferred.py 1.33 +40fcefb2DqteqCCZYDCvvh4Q5jBd0w tools/python/xen/xend/sv/__init__.py 1.34 +40fcefb2Nhe-sT74KBB_3mYQg9Dl4Q tools/python/xen/xend/sv/images/internet copy.jpg 1.35 +40fcefb2QmVa4xdjdnSTXEdF2fZCDA tools/python/xen/xend/sv/images/internet.jpg 1.36 +40fcefb2g8Ez5jJIPHGN_KX7GtxV4w tools/python/xen/xend/sv/images/internet.psd 1.37 +40fcefb3wXQMsl9WkgQAVtdrupm4sw tools/python/xen/xend/sv/images/left-end-highlight.jpg 1.38 +40fcefb3K6ESt5sQhD9aCQRscQIlXQ tools/python/xen/xend/sv/images/left-end-no-highlight.jpg 1.39 +40fcefb3BUT98zPzW8kAFKuxGdh4XA tools/python/xen/xend/sv/images/middle-highlight.jpg 1.40 +40fcefb38OTgsUKHBpwshLLIsiIaCA tools/python/xen/xend/sv/images/middle-no-highlight.jpg 1.41 +40fcefb32SPtrw36c4S6YGFlLvkKuw tools/python/xen/xend/sv/images/orb_01.jpg 1.42 +40fcefb3Ok5qkX3iM7ZEPVkRInrUpg tools/python/xen/xend/sv/images/orb_02.jpg 1.43 +40fcefb3JnT5XeKTuVF4yUMGOtuNZg tools/python/xen/xend/sv/images/right-end-highlight.jpg 1.44 +40fcefb3-DuYOS7noo2W7b_0p7TOUg tools/python/xen/xend/sv/images/right-end-no-highlight.jpg 1.45 +40fcefb3qNbAZR5FYGPAZ9sFPVMTDA tools/python/xen/xend/sv/images/seperator-left-highlight.jpg 1.46 +40fcefb3dgsa24WLk_BJeYQHrDLuOg tools/python/xen/xend/sv/images/seperator-right-highlight.jpg 1.47 +40fcefb3FtiX4Pd2kT8wDlp8u8xRhQ tools/python/xen/xend/sv/images/seperator.jpg 1.48 +40fcefb3yMSrZvApO9ToIi-iQwnchA tools/python/xen/xend/sv/images/xen.png 1.49 +40fcefb3zGC9XNBkSwTEobCoq8YClA tools/python/xen/xend/sv/inc/style.css 1.50 +40fcefb4rnaZNjqsBu7A5V2rlLyqRw tools/python/xen/xend/sv/util.py 1.51 40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py 1.52 40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py 1.53 40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c Mon Jul 19 11:49:45 2004 +0000 2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c Tue Jul 20 14:58:08 2004 +0000 2.3 @@ -93,7 +93,8 @@ static void fast_flush_area(int idx, int 2.4 } 2.5 2.6 mcl[nr_pages-1].args[2] = UVMF_FLUSH_TLB; 2.7 - (void)HYPERVISOR_multicall(mcl, nr_pages); 2.8 + if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) ) 2.9 + BUG(); 2.10 } 2.11 2.12 2.13 @@ -402,7 +403,8 @@ static void dispatch_rw_block_io(blkif_t 2.14 phys_seg[i].buffer >> PAGE_SHIFT; 2.15 } 2.16 2.17 - (void)HYPERVISOR_multicall(mcl, nr_psegs); 2.18 + if ( unlikely(HYPERVISOR_multicall(mcl, nr_psegs) != 0) ) 2.19 + BUG(); 2.20 2.21 for ( i = 0; i < nr_psegs; i++ ) 2.22 {
3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c Mon Jul 19 11:49:45 2004 +0000 3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c Tue Jul 20 14:58:08 2004 +0000 3.3 @@ -73,10 +73,7 @@ static void __refresh_mfn_list(void) 3.4 int ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation, 3.5 mfn_list, MAX_MFN_ALLOC); 3.6 if ( unlikely(ret != MAX_MFN_ALLOC) ) 3.7 - { 3.8 - printk(KERN_ALERT "Unable to increase memory reservation (%d)\n", ret); 3.9 BUG(); 3.10 - } 3.11 alloc_index = MAX_MFN_ALLOC; 3.12 } 3.13 3.14 @@ -97,8 +94,8 @@ static void dealloc_mfn(unsigned long mf 3.15 spin_lock_irqsave(&mfn_lock, flags); 3.16 if ( alloc_index != MAX_MFN_ALLOC ) 3.17 mfn_list[alloc_index++] = mfn; 3.18 - else 3.19 - (void)HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, &mfn, 1); 3.20 + else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, &mfn, 1) != 1 ) 3.21 + BUG(); 3.22 spin_unlock_irqrestore(&mfn_lock, flags); 3.23 } 3.24 3.25 @@ -238,7 +235,8 @@ static void net_rx_action(unsigned long 3.26 return; 3.27 3.28 mcl[-2].args[2] = UVMF_FLUSH_TLB; 3.29 - (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); 3.30 + if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) ) 3.31 + BUG(); 3.32 3.33 mcl = rx_mcl; 3.34 mmu = rx_mmu; 3.35 @@ -252,31 +250,27 @@ static void net_rx_action(unsigned long 3.36 mdata = ((mmu[2].ptr & PAGE_MASK) | 3.37 ((unsigned long)skb->data & ~PAGE_MASK)); 3.38 3.39 + phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn; 3.40 + 3.41 + atomic_set(&(skb_shinfo(skb)->dataref), 1); 3.42 + skb_shinfo(skb)->nr_frags = 0; 3.43 + skb_shinfo(skb)->frag_list = NULL; 3.44 + 3.45 + netif->stats.rx_bytes += size; 3.46 + netif->stats.rx_packets++; 3.47 + 3.48 + /* The update_va_mapping() must not fail. */ 3.49 + if ( unlikely(mcl[0].args[5] != 0) ) 3.50 + BUG(); 3.51 + 3.52 /* Check the reassignment error code. */ 3.53 + status = NETIF_RSP_OKAY; 3.54 if ( unlikely(mcl[1].args[5] != 0) ) 3.55 { 3.56 - DPRINTK("Failed MMU update transferring to DOM%u\n", 3.57 - netif->domid); 3.58 - (void)HYPERVISOR_update_va_mapping( 3.59 - (unsigned long)skb->head >> PAGE_SHIFT, 3.60 - (pte_t) { (mdata & PAGE_MASK) | __PAGE_KERNEL }, 3.61 - UVMF_INVLPG); 3.62 - dealloc_mfn(new_mfn); 3.63 + DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid); 3.64 + dealloc_mfn(mdata >> PAGE_SHIFT); 3.65 status = NETIF_RSP_ERROR; 3.66 } 3.67 - else 3.68 - { 3.69 - phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn; 3.70 - 3.71 - atomic_set(&(skb_shinfo(skb)->dataref), 1); 3.72 - skb_shinfo(skb)->nr_frags = 0; 3.73 - skb_shinfo(skb)->frag_list = NULL; 3.74 - 3.75 - netif->stats.rx_bytes += size; 3.76 - netif->stats.rx_packets++; 3.77 - 3.78 - status = NETIF_RSP_OKAY; 3.79 - } 3.80 3.81 evtchn = netif->evtchn; 3.82 id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id; 3.83 @@ -380,14 +374,15 @@ static void net_tx_action(unsigned long 3.84 NETIF_RING_IDX i; 3.85 struct page *page; 3.86 multicall_entry_t *mcl; 3.87 + PEND_RING_IDX dc, dp; 3.88 3.89 - if ( (i = dealloc_cons) == dealloc_prod ) 3.90 + if ( (dc = dealloc_cons) == (dp = dealloc_prod) ) 3.91 goto skip_dealloc; 3.92 3.93 mcl = tx_mcl; 3.94 - while ( i != dealloc_prod ) 3.95 + while ( dc != dp ) 3.96 { 3.97 - pending_idx = dealloc_ring[MASK_PEND_IDX(i++)]; 3.98 + pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; 3.99 mcl[0].op = __HYPERVISOR_update_va_mapping; 3.100 mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; 3.101 mcl[0].args[1] = 0; 3.102 @@ -396,10 +391,16 @@ static void net_tx_action(unsigned long 3.103 } 3.104 3.105 mcl[-1].args[2] = UVMF_FLUSH_TLB; 3.106 - (void)HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl); 3.107 + if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) ) 3.108 + BUG(); 3.109 3.110 - while ( dealloc_cons != dealloc_prod ) 3.111 + mcl = tx_mcl; 3.112 + while ( dealloc_cons != dp ) 3.113 { 3.114 + /* The update_va_mapping() must not fail. */ 3.115 + if ( unlikely(mcl[0].args[5] != 0) ) 3.116 + BUG(); 3.117 + 3.118 pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; 3.119 3.120 netif = pending_tx_info[pending_idx].netif; 3.121 @@ -421,6 +422,8 @@ static void net_tx_action(unsigned long 3.122 add_to_net_schedule_list_tail(netif); 3.123 3.124 netif_put(netif); 3.125 + 3.126 + mcl++; 3.127 } 3.128 3.129 skip_dealloc: 3.130 @@ -495,7 +498,7 @@ static void net_tx_action(unsigned long 3.131 3.132 pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; 3.133 3.134 - if ( unlikely((skb = dev_alloc_skb(PKT_PROT_LEN)) == NULL) ) 3.135 + if ( unlikely((skb = alloc_skb(PKT_PROT_LEN+16, GFP_ATOMIC)) == NULL) ) 3.136 { 3.137 DPRINTK("Can't allocate a skb in start_xmit.\n"); 3.138 make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); 3.139 @@ -503,6 +506,9 @@ static void net_tx_action(unsigned long 3.140 break; 3.141 } 3.142 3.143 + /* Packets passed to netif_rx() must have some headroom. */ 3.144 + skb_reserve(skb, 16); 3.145 + 3.146 mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain; 3.147 mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; 3.148 mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL; 3.149 @@ -526,7 +532,8 @@ static void net_tx_action(unsigned long 3.150 if ( mcl == tx_mcl ) 3.151 return; 3.152 3.153 - (void)HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl); 3.154 + if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) ) 3.155 + BUG(); 3.156 3.157 mcl = tx_mcl; 3.158 while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c Mon Jul 19 11:49:45 2004 +0000 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,867 +0,0 @@ 4.4 -/****************************************************************************** 4.5 - * arch/xen/drivers/netif/frontend/main.c 4.6 - * 4.7 - * Virtual network driver for conversing with remote driver backends. 4.8 - * 4.9 - * Copyright (c) 2002-2004, K A Fraser 4.10 - */ 4.11 - 4.12 -#include <linux/config.h> 4.13 -#include <linux/module.h> 4.14 - 4.15 -#include <linux/kernel.h> 4.16 -#include <linux/sched.h> 4.17 -#include <linux/slab.h> 4.18 -#include <linux/string.h> 4.19 -#include <linux/errno.h> 4.20 - 4.21 -#include <linux/netdevice.h> 4.22 -#include <linux/inetdevice.h> 4.23 -#include <linux/etherdevice.h> 4.24 -#include <linux/skbuff.h> 4.25 -#include <linux/init.h> 4.26 - 4.27 -#include <asm/io.h> 4.28 -#include <net/sock.h> 4.29 -#include <net/pkt_sched.h> 4.30 - 4.31 -#include <asm/evtchn.h> 4.32 -#include <asm/ctrl_if.h> 4.33 - 4.34 -#include <asm/page.h> 4.35 - 4.36 -#include "../netif.h" 4.37 - 4.38 -#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */ 4.39 - 4.40 -static void network_tx_buf_gc(struct net_device *dev); 4.41 -static void network_alloc_rx_buffers(struct net_device *dev); 4.42 - 4.43 -static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE]; 4.44 -static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1]; 4.45 -static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; 4.46 - 4.47 -static struct list_head dev_list; 4.48 - 4.49 -struct net_private 4.50 -{ 4.51 - struct list_head list; 4.52 - struct net_device *dev; 4.53 - 4.54 - struct net_device_stats stats; 4.55 - NETIF_RING_IDX rx_resp_cons, tx_resp_cons; 4.56 - unsigned int tx_full; 4.57 - 4.58 - netif_tx_interface_t *tx; 4.59 - netif_rx_interface_t *rx; 4.60 - 4.61 - spinlock_t tx_lock; 4.62 - spinlock_t rx_lock; 4.63 - 4.64 - unsigned int handle; 4.65 - unsigned int evtchn; 4.66 - unsigned int irq; 4.67 - 4.68 - /* What is the status of our connection to the remote backend? */ 4.69 -#define BEST_CLOSED 0 4.70 -#define BEST_DISCONNECTED 1 4.71 -#define BEST_CONNECTED 2 4.72 - unsigned int backend_state; 4.73 - 4.74 - /* Is this interface open or closed (down or up)? */ 4.75 -#define UST_CLOSED 0 4.76 -#define UST_OPEN 1 4.77 - unsigned int user_state; 4.78 - 4.79 - /* 4.80 - * {tx,rx}_skbs store outstanding skbuffs. The first entry in each 4.81 - * array is an index into a chain of free entries. 4.82 - */ 4.83 - struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1]; 4.84 - struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; 4.85 -}; 4.86 - 4.87 -/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ 4.88 -#define ADD_ID_TO_FREELIST(_list, _id) \ 4.89 - (_list)[(_id)] = (_list)[0]; \ 4.90 - (_list)[0] = (void *)(unsigned long)(_id); 4.91 -#define GET_ID_FROM_FREELIST(_list) \ 4.92 - ({ unsigned long _id = (unsigned long)(_list)[0]; \ 4.93 - (_list)[0] = (_list)[_id]; \ 4.94 - (unsigned short)_id; }) 4.95 - 4.96 -static struct net_device *find_dev_by_handle(unsigned int handle) 4.97 -{ 4.98 - struct list_head *ent; 4.99 - struct net_private *np; 4.100 - list_for_each ( ent, &dev_list ) 4.101 - { 4.102 - np = list_entry(ent, struct net_private, list); 4.103 - if ( np->handle == handle ) 4.104 - return np->dev; 4.105 - } 4.106 - return NULL; 4.107 -} 4.108 - 4.109 -/** Network interface info. */ 4.110 -struct netif_ctrl { 4.111 - /** Number of interfaces. */ 4.112 - int interface_n; 4.113 - /** Number of connected interfaces. */ 4.114 - int connected_n; 4.115 - /** Error code. */ 4.116 - int err; 4.117 -}; 4.118 - 4.119 -static struct netif_ctrl netctrl; 4.120 - 4.121 -static void netctrl_init(void) 4.122 -{ 4.123 - memset(&netctrl, 0, sizeof(netctrl)); 4.124 - netctrl.interface_n = -1; 4.125 -} 4.126 - 4.127 -/** Get or set a network interface error. 4.128 - */ 4.129 -static int netctrl_err(int err) 4.130 -{ 4.131 - if(err < 0 && !netctrl.err){ 4.132 - netctrl.err = err; 4.133 - printk(KERN_WARNING "%s> err=%d\n", __FUNCTION__, err); 4.134 - } 4.135 - return netctrl.err; 4.136 -} 4.137 - 4.138 -/** Test if all network interfaces are connected. 4.139 - * 4.140 - * @return 1 if all connected, 0 if not, negative error code otherwise 4.141 - */ 4.142 -static int netctrl_connected(void) 4.143 -{ 4.144 - int ok = 0; 4.145 - ok = (netctrl.err ? netctrl.err : 4.146 - (netctrl.connected_n == netctrl.interface_n)); 4.147 - return ok; 4.148 -} 4.149 - 4.150 -/** Count the connected network interfaces. 4.151 - * 4.152 - * @return connected count 4.153 - */ 4.154 -static int netctrl_connected_count(void) 4.155 -{ 4.156 - 4.157 - struct list_head *ent; 4.158 - struct net_private *np; 4.159 - unsigned int connected; 4.160 - 4.161 - connected = 0; 4.162 - 4.163 - list_for_each(ent, &dev_list) 4.164 - { 4.165 - np = list_entry(ent, struct net_private, list); 4.166 - if ( np->backend_state == BEST_CONNECTED ) 4.167 - connected++; 4.168 - } 4.169 - 4.170 - netctrl.connected_n = connected; 4.171 - return connected; 4.172 -} 4.173 - 4.174 -static int network_open(struct net_device *dev) 4.175 -{ 4.176 - struct net_private *np = dev->priv; 4.177 - 4.178 - memset(&np->stats, 0, sizeof(np->stats)); 4.179 - 4.180 - np->user_state = UST_OPEN; 4.181 - 4.182 - network_alloc_rx_buffers(dev); 4.183 - np->rx->event = np->rx_resp_cons + 1; 4.184 - 4.185 - netif_start_queue(dev); 4.186 - 4.187 - return 0; 4.188 -} 4.189 - 4.190 - 4.191 -static void network_tx_buf_gc(struct net_device *dev) 4.192 -{ 4.193 - NETIF_RING_IDX i, prod; 4.194 - unsigned short id; 4.195 - struct net_private *np = dev->priv; 4.196 - struct sk_buff *skb; 4.197 - 4.198 - if ( np->backend_state != BEST_CONNECTED ) 4.199 - return; 4.200 - 4.201 - do { 4.202 - prod = np->tx->resp_prod; 4.203 - 4.204 - for ( i = np->tx_resp_cons; i != prod; i++ ) 4.205 - { 4.206 - id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; 4.207 - skb = np->tx_skbs[id]; 4.208 - ADD_ID_TO_FREELIST(np->tx_skbs, id); 4.209 - dev_kfree_skb_any(skb); 4.210 - } 4.211 - 4.212 - np->tx_resp_cons = prod; 4.213 - 4.214 - /* 4.215 - * Set a new event, then check for race with update of tx_cons. Note 4.216 - * that it is essential to schedule a callback, no matter how few 4.217 - * buffers are pending. Even if there is space in the transmit ring, 4.218 - * higher layers may be blocked because too much data is outstanding: 4.219 - * in such cases notification from Xen is likely to be the only kick 4.220 - * that we'll get. 4.221 - */ 4.222 - np->tx->event = 4.223 - prod + ((np->tx->req_prod - prod) >> 1) + 1; 4.224 - mb(); 4.225 - } 4.226 - while ( prod != np->tx->resp_prod ); 4.227 - 4.228 - if ( np->tx_full && 4.229 - ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) ) 4.230 - { 4.231 - np->tx_full = 0; 4.232 - if ( np->user_state == UST_OPEN ) 4.233 - netif_wake_queue(dev); 4.234 - } 4.235 -} 4.236 - 4.237 - 4.238 -static void network_alloc_rx_buffers(struct net_device *dev) 4.239 -{ 4.240 - unsigned short id; 4.241 - struct net_private *np = dev->priv; 4.242 - struct sk_buff *skb; 4.243 - NETIF_RING_IDX i = np->rx->req_prod; 4.244 - int nr_pfns = 0; 4.245 - 4.246 - /* Make sure the batch is large enough to be worthwhile (1/2 ring). */ 4.247 - if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) || 4.248 - unlikely(np->backend_state != BEST_CONNECTED) ) 4.249 - return; 4.250 - 4.251 - do { 4.252 - skb = dev_alloc_skb(RX_BUF_SIZE); 4.253 - if ( unlikely(skb == NULL) ) 4.254 - break; 4.255 - 4.256 - skb->dev = dev; 4.257 - 4.258 - if ( unlikely(((unsigned long)skb->head & (PAGE_SIZE-1)) != 0) ) 4.259 - panic("alloc_skb needs to provide us page-aligned buffers."); 4.260 - 4.261 - id = GET_ID_FROM_FREELIST(np->rx_skbs); 4.262 - 4.263 - np->rx_skbs[id] = skb; 4.264 - 4.265 - np->rx->ring[MASK_NETIF_RX_IDX(i)].req.id = id; 4.266 - 4.267 - rx_pfn_array[nr_pfns] = virt_to_machine(skb->head) >> PAGE_SHIFT; 4.268 - 4.269 - rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping; 4.270 - rx_mcl[nr_pfns].args[0] = (unsigned long)skb->head >> PAGE_SHIFT; 4.271 - rx_mcl[nr_pfns].args[1] = 0; 4.272 - rx_mcl[nr_pfns].args[2] = 0; 4.273 - 4.274 - nr_pfns++; 4.275 - } 4.276 - while ( (++i - np->rx_resp_cons) != NETIF_RX_RING_SIZE ); 4.277 - 4.278 - /* 4.279 - * We may have allocated buffers which have entries outstanding in the page 4.280 - * update queue -- make sure we flush those first! 4.281 - */ 4.282 - flush_page_update_queue(); 4.283 - 4.284 - /* After all PTEs have been zapped we blow away stale TLB entries. */ 4.285 - rx_mcl[nr_pfns-1].args[2] = UVMF_FLUSH_TLB; 4.286 - 4.287 - /* Give away a batch of pages. */ 4.288 - rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op; 4.289 - rx_mcl[nr_pfns].args[0] = MEMOP_decrease_reservation; 4.290 - rx_mcl[nr_pfns].args[1] = (unsigned long)rx_pfn_array; 4.291 - rx_mcl[nr_pfns].args[2] = (unsigned long)nr_pfns; 4.292 - 4.293 - /* Zap PTEs and give away pages in one big multicall. */ 4.294 - (void)HYPERVISOR_multicall(rx_mcl, nr_pfns+1); 4.295 - 4.296 - /* Check return status of HYPERVISOR_dom_mem_op(). */ 4.297 - if ( rx_mcl[nr_pfns].args[5] != nr_pfns ) 4.298 - panic("Unable to reduce memory reservation\n"); 4.299 - 4.300 - np->rx->req_prod = i; 4.301 -} 4.302 - 4.303 - 4.304 -static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) 4.305 -{ 4.306 - unsigned short id; 4.307 - struct net_private *np = (struct net_private *)dev->priv; 4.308 - netif_tx_request_t *tx; 4.309 - NETIF_RING_IDX i; 4.310 - 4.311 - if ( unlikely(np->tx_full) ) 4.312 - { 4.313 - printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name); 4.314 - netif_stop_queue(dev); 4.315 - return -ENOBUFS; 4.316 - } 4.317 - 4.318 - if ( unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= 4.319 - PAGE_SIZE) ) 4.320 - { 4.321 - struct sk_buff *new_skb = dev_alloc_skb(RX_BUF_SIZE); 4.322 - if ( unlikely(new_skb == NULL) ) 4.323 - return 1; 4.324 - skb_put(new_skb, skb->len); 4.325 - memcpy(new_skb->data, skb->data, skb->len); 4.326 - dev_kfree_skb(skb); 4.327 - skb = new_skb; 4.328 - } 4.329 - 4.330 - spin_lock_irq(&np->tx_lock); 4.331 - 4.332 - if ( np->backend_state != BEST_CONNECTED ) 4.333 - { 4.334 - spin_unlock_irq(&np->tx_lock); 4.335 - return 1; 4.336 - } 4.337 - 4.338 - i = np->tx->req_prod; 4.339 - 4.340 - id = GET_ID_FROM_FREELIST(np->tx_skbs); 4.341 - np->tx_skbs[id] = skb; 4.342 - 4.343 - tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req; 4.344 - 4.345 - tx->id = id; 4.346 - tx->addr = virt_to_machine(skb->data); 4.347 - tx->size = skb->len; 4.348 - 4.349 - wmb(); 4.350 - np->tx->req_prod = i + 1; 4.351 - 4.352 - network_tx_buf_gc(dev); 4.353 - 4.354 - if ( (i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1) ) 4.355 - { 4.356 - np->tx_full = 1; 4.357 - netif_stop_queue(dev); 4.358 - } 4.359 - 4.360 - spin_unlock_irq(&np->tx_lock); 4.361 - 4.362 - np->stats.tx_bytes += skb->len; 4.363 - np->stats.tx_packets++; 4.364 - 4.365 - /* Only notify Xen if there are no outstanding responses. */ 4.366 - mb(); 4.367 - if ( np->tx->resp_prod == i ) 4.368 - notify_via_evtchn(np->evtchn); 4.369 - 4.370 - return 0; 4.371 -} 4.372 - 4.373 - 4.374 -static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 4.375 -{ 4.376 - struct net_device *dev = dev_id; 4.377 - struct net_private *np = dev->priv; 4.378 - unsigned long flags; 4.379 - 4.380 - spin_lock_irqsave(&np->tx_lock, flags); 4.381 - network_tx_buf_gc(dev); 4.382 - spin_unlock_irqrestore(&np->tx_lock, flags); 4.383 - 4.384 - if ( (np->rx_resp_cons != np->rx->resp_prod) && 4.385 - (np->user_state == UST_OPEN) ) 4.386 - netif_rx_schedule(dev); 4.387 -} 4.388 - 4.389 - 4.390 -static int netif_poll(struct net_device *dev, int *pbudget) 4.391 -{ 4.392 - struct net_private *np = dev->priv; 4.393 - struct sk_buff *skb; 4.394 - netif_rx_response_t *rx; 4.395 - NETIF_RING_IDX i; 4.396 - mmu_update_t *mmu = rx_mmu; 4.397 - multicall_entry_t *mcl = rx_mcl; 4.398 - int work_done, budget, more_to_do = 1; 4.399 - struct sk_buff_head rxq; 4.400 - unsigned long flags; 4.401 - 4.402 - spin_lock(&np->rx_lock); 4.403 - 4.404 - if ( np->backend_state != BEST_CONNECTED ) 4.405 - { 4.406 - spin_unlock(&np->rx_lock); 4.407 - return 0; 4.408 - } 4.409 - 4.410 - skb_queue_head_init(&rxq); 4.411 - 4.412 - if ( (budget = *pbudget) > dev->quota ) 4.413 - budget = dev->quota; 4.414 - 4.415 - for ( i = np->rx_resp_cons, work_done = 0; 4.416 - (i != np->rx->resp_prod) && (work_done < budget); 4.417 - i++, work_done++ ) 4.418 - { 4.419 - rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; 4.420 - 4.421 - skb = np->rx_skbs[rx->id]; 4.422 - ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 4.423 - 4.424 - if ( unlikely(rx->status <= 0) ) 4.425 - { 4.426 - /* Gate this error. We get a (valid) slew of them on suspend. */ 4.427 - if ( np->user_state != UST_OPEN ) 4.428 - printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); 4.429 - dev_kfree_skb(skb); 4.430 - continue; 4.431 - } 4.432 - 4.433 - skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK); 4.434 - skb_put(skb, rx->status); 4.435 - 4.436 - np->stats.rx_packets++; 4.437 - np->stats.rx_bytes += rx->status; 4.438 - 4.439 - /* Remap the page. */ 4.440 - mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE; 4.441 - mmu->val = __pa(skb->head) >> PAGE_SHIFT; 4.442 - mmu++; 4.443 - mcl->op = __HYPERVISOR_update_va_mapping; 4.444 - mcl->args[0] = (unsigned long)skb->head >> PAGE_SHIFT; 4.445 - mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL; 4.446 - mcl->args[2] = 0; 4.447 - mcl++; 4.448 - 4.449 - phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 4.450 - rx->addr >> PAGE_SHIFT; 4.451 - 4.452 - __skb_queue_tail(&rxq, skb); 4.453 - } 4.454 - 4.455 - /* Do all the remapping work, and M->P updates, in one big hypercall. */ 4.456 - if ( likely((mcl - rx_mcl) != 0) ) 4.457 - { 4.458 - mcl->op = __HYPERVISOR_mmu_update; 4.459 - mcl->args[0] = (unsigned long)rx_mmu; 4.460 - mcl->args[1] = mmu - rx_mmu; 4.461 - mcl->args[2] = 0; 4.462 - mcl++; 4.463 - (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); 4.464 - } 4.465 - 4.466 - while ( (skb = __skb_dequeue(&rxq)) != NULL ) 4.467 - { 4.468 - /* Set the shared-info area, which is hidden behind the real data. */ 4.469 - atomic_set(&(skb_shinfo(skb)->dataref), 1); 4.470 - skb_shinfo(skb)->nr_frags = 0; 4.471 - skb_shinfo(skb)->frag_list = NULL; 4.472 - 4.473 - /* Ethernet-specific work. Delayed to here as it peeks the header. */ 4.474 - skb->protocol = eth_type_trans(skb, dev); 4.475 - 4.476 - /* Pass it up. */ 4.477 - netif_rx(skb); 4.478 - dev->last_rx = jiffies; 4.479 - } 4.480 - 4.481 - np->rx_resp_cons = i; 4.482 - 4.483 - network_alloc_rx_buffers(dev); 4.484 - 4.485 - *pbudget -= work_done; 4.486 - dev->quota -= work_done; 4.487 - 4.488 - if ( work_done < budget ) 4.489 - { 4.490 - local_irq_save(flags); 4.491 - 4.492 - np->rx->event = i + 1; 4.493 - 4.494 - /* Deal with hypervisor racing our resetting of rx_event. */ 4.495 - mb(); 4.496 - if ( np->rx->resp_prod == i ) 4.497 - { 4.498 - __netif_rx_complete(dev); 4.499 - more_to_do = 0; 4.500 - } 4.501 - 4.502 - local_irq_restore(flags); 4.503 - } 4.504 - 4.505 - spin_unlock(&np->rx_lock); 4.506 - 4.507 - return more_to_do; 4.508 -} 4.509 - 4.510 - 4.511 -static int network_close(struct net_device *dev) 4.512 -{ 4.513 - struct net_private *np = dev->priv; 4.514 - np->user_state = UST_CLOSED; 4.515 - netif_stop_queue(np->dev); 4.516 - return 0; 4.517 -} 4.518 - 4.519 - 4.520 -static struct net_device_stats *network_get_stats(struct net_device *dev) 4.521 -{ 4.522 - struct net_private *np = (struct net_private *)dev->priv; 4.523 - return &np->stats; 4.524 -} 4.525 - 4.526 - 4.527 -static void network_connect(struct net_device *dev, 4.528 - netif_fe_interface_status_changed_t *status) 4.529 -{ 4.530 - struct net_private *np; 4.531 - int i, requeue_idx; 4.532 - netif_tx_request_t *tx; 4.533 - 4.534 - np = dev->priv; 4.535 - spin_lock_irq(&np->rx_lock); 4.536 - spin_lock(&np->tx_lock); 4.537 - 4.538 - /* Recovery procedure: */ 4.539 - 4.540 - /* Step 1: Reinitialise variables. */ 4.541 - np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0; 4.542 - np->rx->event = 1; 4.543 - 4.544 - /* Step 2: Rebuild the RX and TX ring contents. 4.545 - * NB. We could just free the queued TX packets now but we hope 4.546 - * that sending them out might do some good. We have to rebuild 4.547 - * the RX ring because some of our pages are currently flipped out 4.548 - * so we can't just free the RX skbs. 4.549 - * NB2. Freelist index entries are always going to be less than 4.550 - * __PAGE_OFFSET, whereas pointers to skbs will always be equal or 4.551 - * greater than __PAGE_OFFSET: we use this property to distinguish 4.552 - * them. 4.553 - */ 4.554 - 4.555 - /* Rebuild the TX buffer freelist and the TX ring itself. 4.556 - * NB. This reorders packets. We could keep more private state 4.557 - * to avoid this but maybe it doesn't matter so much given the 4.558 - * interface has been down. 4.559 - */ 4.560 - for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ) 4.561 - { 4.562 - if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET ) 4.563 - { 4.564 - struct sk_buff *skb = np->tx_skbs[i]; 4.565 - 4.566 - tx = &np->tx->ring[requeue_idx++].req; 4.567 - 4.568 - tx->id = i; 4.569 - tx->addr = virt_to_machine(skb->data); 4.570 - tx->size = skb->len; 4.571 - 4.572 - np->stats.tx_bytes += skb->len; 4.573 - np->stats.tx_packets++; 4.574 - } 4.575 - } 4.576 - wmb(); 4.577 - np->tx->req_prod = requeue_idx; 4.578 - 4.579 - /* Rebuild the RX buffer freelist and the RX ring itself. */ 4.580 - for ( requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++ ) 4.581 - if ( (unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET ) 4.582 - np->rx->ring[requeue_idx++].req.id = i; 4.583 - wmb(); 4.584 - np->rx->req_prod = requeue_idx; 4.585 - 4.586 - /* Step 3: All public and private state should now be sane. Get 4.587 - * ready to start sending and receiving packets and give the driver 4.588 - * domain a kick because we've probably just requeued some 4.589 - * packets. 4.590 - */ 4.591 - np->backend_state = BEST_CONNECTED; 4.592 - notify_via_evtchn(status->evtchn); 4.593 - network_tx_buf_gc(dev); 4.594 - 4.595 - if ( np->user_state == UST_OPEN ) 4.596 - netif_start_queue(dev); 4.597 - 4.598 - spin_unlock(&np->tx_lock); 4.599 - spin_unlock_irq(&np->rx_lock); 4.600 -} 4.601 - 4.602 -static void netif_status_change(netif_fe_interface_status_changed_t *status) 4.603 -{ 4.604 - ctrl_msg_t cmsg; 4.605 - netif_fe_interface_connect_t up; 4.606 - struct net_device *dev; 4.607 - struct net_private *np; 4.608 - 4.609 - if ( netctrl.interface_n <= 0 ) 4.610 - { 4.611 - printk(KERN_WARNING "Status change: no interfaces\n"); 4.612 - return; 4.613 - } 4.614 - 4.615 - dev = find_dev_by_handle(status->handle); 4.616 - if(!dev){ 4.617 - printk(KERN_WARNING "Status change: invalid netif handle %u\n", 4.618 - status->handle); 4.619 - return; 4.620 - } 4.621 - np = dev->priv; 4.622 - 4.623 - switch ( status->status ) 4.624 - { 4.625 - case NETIF_INTERFACE_STATUS_DESTROYED: 4.626 - printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n", 4.627 - np->backend_state); 4.628 - break; 4.629 - 4.630 - case NETIF_INTERFACE_STATUS_DISCONNECTED: 4.631 - if ( np->backend_state != BEST_CLOSED ) 4.632 - { 4.633 - printk(KERN_WARNING "Unexpected netif-DISCONNECTED message" 4.634 - " in state %d\n", np->backend_state); 4.635 - printk(KERN_INFO "Attempting to reconnect network interface\n"); 4.636 - 4.637 - /* Begin interface recovery. 4.638 - * 4.639 - * NB. Whilst we're recovering, we turn the carrier state off. We 4.640 - * take measures to ensure that this device isn't used for 4.641 - * anything. We also stop the queue for this device. Various 4.642 - * different approaches (e.g. continuing to buffer packets) have 4.643 - * been tested but don't appear to improve the overall impact on 4.644 - * TCP connections. 4.645 - * 4.646 - * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery 4.647 - * is initiated by a special "RESET" message - disconnect could 4.648 - * just mean we're not allowed to use this interface any more. 4.649 - */ 4.650 - 4.651 - /* Stop old i/f to prevent errors whilst we rebuild the state. */ 4.652 - spin_lock_irq(&np->tx_lock); 4.653 - spin_lock(&np->rx_lock); 4.654 - netif_stop_queue(dev); 4.655 - np->backend_state = BEST_DISCONNECTED; 4.656 - spin_unlock(&np->rx_lock); 4.657 - spin_unlock_irq(&np->tx_lock); 4.658 - 4.659 - /* Free resources. */ 4.660 - free_irq(np->irq, dev); 4.661 - unbind_evtchn_from_irq(np->evtchn); 4.662 - free_page((unsigned long)np->tx); 4.663 - free_page((unsigned long)np->rx); 4.664 - } 4.665 - 4.666 - /* Move from CLOSED to DISCONNECTED state. */ 4.667 - np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); 4.668 - np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); 4.669 - memset(np->tx, 0, PAGE_SIZE); 4.670 - memset(np->rx, 0, PAGE_SIZE); 4.671 - np->backend_state = BEST_DISCONNECTED; 4.672 - 4.673 - /* Construct an interface-CONNECT message for the domain controller. */ 4.674 - cmsg.type = CMSG_NETIF_FE; 4.675 - cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT; 4.676 - cmsg.length = sizeof(netif_fe_interface_connect_t); 4.677 - up.handle = status->handle; 4.678 - up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT; 4.679 - up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT; 4.680 - memcpy(cmsg.msg, &up, sizeof(up)); 4.681 - 4.682 - /* Tell the controller to bring up the interface. */ 4.683 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 4.684 - break; 4.685 - 4.686 - case NETIF_INTERFACE_STATUS_CONNECTED: 4.687 - if ( np->backend_state == BEST_CLOSED ) 4.688 - { 4.689 - printk(KERN_WARNING "Unexpected netif-CONNECTED message" 4.690 - " in state %d\n", np->backend_state); 4.691 - break; 4.692 - } 4.693 - 4.694 - memcpy(dev->dev_addr, status->mac, ETH_ALEN); 4.695 - 4.696 - network_connect(dev, status); 4.697 - 4.698 - np->evtchn = status->evtchn; 4.699 - np->irq = bind_evtchn_to_irq(np->evtchn); 4.700 - (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 4.701 - dev->name, dev); 4.702 - 4.703 - netctrl_connected_count(); 4.704 - break; 4.705 - 4.706 - default: 4.707 - printk(KERN_WARNING "Status change to unknown value %d\n", 4.708 - status->status); 4.709 - break; 4.710 - } 4.711 -} 4.712 - 4.713 -/** Create a network device. 4.714 - * @param handle device handle 4.715 - * @param val return parameter for created device 4.716 - * @return 0 on success, error code otherwise 4.717 - */ 4.718 -static int create_netdev(int handle, struct net_device **val) 4.719 -{ 4.720 - int i, err = 0; 4.721 - struct net_device *dev = NULL; 4.722 - struct net_private *np = NULL; 4.723 - 4.724 - if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL ) 4.725 - { 4.726 - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); 4.727 - err = -ENOMEM; 4.728 - goto exit; 4.729 - } 4.730 - 4.731 - np = dev->priv; 4.732 - np->backend_state = BEST_CLOSED; 4.733 - np->user_state = UST_CLOSED; 4.734 - np->handle = handle; 4.735 - 4.736 - spin_lock_init(&np->tx_lock); 4.737 - spin_lock_init(&np->rx_lock); 4.738 - 4.739 - /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ 4.740 - for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ) 4.741 - np->tx_skbs[i] = (void *)(i+1); 4.742 - for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ) 4.743 - np->rx_skbs[i] = (void *)(i+1); 4.744 - 4.745 - dev->open = network_open; 4.746 - dev->hard_start_xmit = network_start_xmit; 4.747 - dev->stop = network_close; 4.748 - dev->get_stats = network_get_stats; 4.749 - dev->poll = netif_poll; 4.750 - dev->weight = 64; 4.751 - 4.752 - if ( (err = register_netdev(dev)) != 0 ) 4.753 - { 4.754 - printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); 4.755 - goto exit; 4.756 - } 4.757 - np->dev = dev; 4.758 - list_add(&np->list, &dev_list); 4.759 - 4.760 - exit: 4.761 - if ( (err != 0) && (dev != NULL ) ) 4.762 - kfree(dev); 4.763 - else if ( val != NULL ) 4.764 - *val = dev; 4.765 - return err; 4.766 -} 4.767 - 4.768 -/* 4.769 - * Initialize the network control interface. Set the number of network devices 4.770 - * and create them. 4.771 - */ 4.772 -static void netif_driver_status_change( 4.773 - netif_fe_driver_status_changed_t *status) 4.774 -{ 4.775 - int err = 0; 4.776 - int i; 4.777 - 4.778 - netctrl.interface_n = status->nr_interfaces; 4.779 - netctrl.connected_n = 0; 4.780 - 4.781 - for ( i = 0; i < netctrl.interface_n; i++ ) 4.782 - { 4.783 - if ( (err = create_netdev(i, NULL)) != 0 ) 4.784 - { 4.785 - netctrl_err(err); 4.786 - break; 4.787 - } 4.788 - } 4.789 -} 4.790 - 4.791 -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 4.792 -{ 4.793 - int respond = 1; 4.794 - 4.795 - switch ( msg->subtype ) 4.796 - { 4.797 - case CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED: 4.798 - if ( msg->length != sizeof(netif_fe_interface_status_changed_t) ) 4.799 - goto error; 4.800 - netif_status_change((netif_fe_interface_status_changed_t *) 4.801 - &msg->msg[0]); 4.802 - break; 4.803 - 4.804 - case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED: 4.805 - if ( msg->length != sizeof(netif_fe_driver_status_changed_t) ) 4.806 - goto error; 4.807 - netif_driver_status_change((netif_fe_driver_status_changed_t *) 4.808 - &msg->msg[0]); 4.809 - /* Message is a response */ 4.810 - respond = 0; 4.811 - break; 4.812 - 4.813 - error: 4.814 - default: 4.815 - msg->length = 0; 4.816 - break; 4.817 - } 4.818 - 4.819 - if ( respond ) 4.820 - ctrl_if_send_response(msg); 4.821 -} 4.822 - 4.823 - 4.824 -static int __init netif_init(void) 4.825 -{ 4.826 - ctrl_msg_t cmsg; 4.827 - netif_fe_driver_status_changed_t st; 4.828 - int err = 0, wait_i, wait_n = 20; 4.829 - 4.830 - if ( (start_info.flags & SIF_INITDOMAIN) || 4.831 - (start_info.flags & SIF_NET_BE_DOMAIN) ) 4.832 - return 0; 4.833 - 4.834 - printk("Initialising Xen virtual ethernet frontend driver"); 4.835 - 4.836 - INIT_LIST_HEAD(&dev_list); 4.837 - 4.838 - netctrl_init(); 4.839 - 4.840 - (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, 4.841 - CALLBACK_IN_BLOCKING_CONTEXT); 4.842 - 4.843 - /* Send a driver-UP notification to the domain controller. */ 4.844 - cmsg.type = CMSG_NETIF_FE; 4.845 - cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED; 4.846 - cmsg.length = sizeof(netif_fe_driver_status_changed_t); 4.847 - st.status = NETIF_DRIVER_STATUS_UP; 4.848 - st.nr_interfaces = 0; 4.849 - memcpy(cmsg.msg, &st, sizeof(st)); 4.850 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 4.851 - 4.852 - /* Wait for all interfaces to be connected. */ 4.853 - for ( wait_i = 0; ; wait_i++) 4.854 - { 4.855 - if ( (err = (wait_i < wait_n) ? netctrl_connected() : -ENETDOWN) != 0 ) 4.856 - { 4.857 - err = (err > 0) ? 0 : err; 4.858 - break; 4.859 - } 4.860 - set_current_state(TASK_INTERRUPTIBLE); 4.861 - schedule_timeout(1); 4.862 - } 4.863 - 4.864 - if ( err ) 4.865 - ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); 4.866 - 4.867 - return err; 4.868 -} 4.869 - 4.870 -__initcall(netif_init);
5.1 --- a/linux-2.4.26-xen-sparse/mkbuildtree Mon Jul 19 11:49:45 2004 +0000 5.2 +++ b/linux-2.4.26-xen-sparse/mkbuildtree Tue Jul 20 14:58:08 2004 +0000 5.3 @@ -225,5 +225,5 @@ ln -sf ../../i386/mm/extable.c 5.4 ln -sf ../../i386/mm/pageattr.c 5.5 cd ../drivers/console 5.6 ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c 5.7 -#cd ../netif/frontend 5.8 -#ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c 5.9 +cd ../netif/frontend 5.10 +ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c
6.1 --- a/linux-2.6.7-xen-sparse/arch/xen/Kconfig Mon Jul 19 11:49:45 2004 +0000 6.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Kconfig Tue Jul 20 14:58:08 2004 +0000 6.3 @@ -16,6 +16,10 @@ config ARCH_XEN 6.4 default y 6.5 6.6 6.7 +config NO_IDLE_HZ 6.8 + bool 6.9 + default y 6.10 + 6.11 source "init/Kconfig" 6.12 6.13 #config VT
7.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c Mon Jul 19 11:49:45 2004 +0000 7.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c Tue Jul 20 14:58:08 2004 +0000 7.3 @@ -87,6 +87,17 @@ EXPORT_SYMBOL(i8253_lock); 7.4 7.5 struct timer_opts *cur_timer = &timer_none; 7.6 7.7 +/* These are peridically updated in shared_info, and then copied here. */ 7.8 +static u32 shadow_tsc_stamp; 7.9 +static u64 shadow_system_time; 7.10 +static u32 shadow_time_version; 7.11 +static struct timeval shadow_tv; 7.12 + 7.13 +/* Keep track of last time we did processing/updating of jiffies and xtime. */ 7.14 +static u64 processed_system_time; /* System time (ns) at last processing. */ 7.15 + 7.16 +#define NS_PER_TICK (1000000000ULL/HZ) 7.17 + 7.18 /* 7.19 * This version of gettimeofday has microsecond resolution 7.20 * and better than microsecond precision on fast x86 machines with TSC. 7.21 @@ -204,12 +215,33 @@ EXPORT_SYMBOL(monotonic_clock); 7.22 7.23 7.24 /* 7.25 + * Reads a consistent set of time-base values from Xen, into a shadow data 7.26 + * area. Must be called with the xtime_lock held for writing. 7.27 + */ 7.28 +static void __get_time_values_from_xen(void) 7.29 +{ 7.30 + do { 7.31 + shadow_time_version = HYPERVISOR_shared_info->time_version2; 7.32 + rmb(); 7.33 + shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; 7.34 + shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; 7.35 + shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits; 7.36 + shadow_system_time = HYPERVISOR_shared_info->system_time; 7.37 + rmb(); 7.38 + } 7.39 + while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 ); 7.40 +} 7.41 + 7.42 +/* 7.43 * timer_interrupt() needs to keep up the real-time clock, 7.44 * as well as call the "do_timer()" routine every clocktick 7.45 */ 7.46 static inline void do_timer_interrupt(int irq, void *dev_id, 7.47 struct pt_regs *regs) 7.48 { 7.49 + s64 delta; 7.50 + unsigned long ticks = 0; 7.51 + 7.52 #ifdef CONFIG_X86_IO_APIC 7.53 if (timer_ack) { 7.54 /* 7.55 @@ -226,7 +258,23 @@ static inline void do_timer_interrupt(in 7.56 } 7.57 #endif 7.58 7.59 - do_timer_interrupt_hook(regs); 7.60 + __get_time_values_from_xen(); 7.61 + 7.62 + delta = (s64)(shadow_system_time - processed_system_time); 7.63 + if (delta < 0) { 7.64 + printk("Timer ISR: Time went backwards: %lld\n", delta); 7.65 + return; 7.66 + } 7.67 + 7.68 + /* Process elapsed jiffies since last call. */ 7.69 + while (delta >= NS_PER_TICK) { 7.70 + ticks++; 7.71 + delta -= NS_PER_TICK; 7.72 + processed_system_time += NS_PER_TICK; 7.73 + 7.74 + if (regs) 7.75 + do_timer_interrupt_hook(regs); 7.76 + } 7.77 7.78 #if 0 /* XEN PRIV */ 7.79 /* 7.80 @@ -288,8 +336,7 @@ irqreturn_t timer_interrupt(int irq, voi 7.81 7.82 cur_timer->mark_offset(); 7.83 7.84 - if (regs) /* XXXcl check regs in do_timer_interrupt */ 7.85 - do_timer_interrupt(irq, NULL, regs); 7.86 + do_timer_interrupt(irq, NULL, regs); 7.87 7.88 write_sequnlock(&xtime_lock); 7.89 return IRQ_HANDLED; 7.90 @@ -410,3 +457,45 @@ void __init time_init(void) 7.91 7.92 (void)setup_irq(time_irq, &irq_timer); 7.93 } 7.94 + 7.95 +/* Convert jiffies to system time. Call with xtime_lock held for reading. */ 7.96 +static inline u64 __jiffies_to_st(unsigned long j) 7.97 +{ 7.98 + return processed_system_time + ((j - jiffies) * NS_PER_TICK); 7.99 +} 7.100 + 7.101 +/* 7.102 + * This function works out when the the next timer function has to be 7.103 + * executed (by looking at the timer list) and sets the Xen one-shot 7.104 + * domain timer to the appropriate value. This is typically called in 7.105 + * cpu_idle() before the domain blocks. 7.106 + * 7.107 + * The function returns a non-0 value on error conditions. 7.108 + * 7.109 + * It must be called with interrupts disabled. 7.110 + */ 7.111 +extern spinlock_t timerlist_lock; 7.112 +int set_timeout_timer(void) 7.113 +{ 7.114 + u64 alarm = 0; 7.115 + int ret = 0; 7.116 + int cpu = smp_processor_id(); 7.117 + 7.118 + spin_lock(&timerlist_lock); 7.119 + 7.120 + /* 7.121 + * This is safe against long blocking (since calculations are not based on 7.122 + * TSC deltas). It is also safe against warped system time since 7.123 + * suspend-resume is cooperative and we would first get locked out. It is 7.124 + * safe against normal updates of jiffies since interrupts are off. 7.125 + */ 7.126 + alarm = __jiffies_to_st(next_timer_interrupt()); 7.127 + 7.128 + /* Failure is pretty bad, but we'd best soldier on. */ 7.129 + if ( HYPERVISOR_set_timer_op(alarm) != 0 ) 7.130 + ret = -1; 7.131 + 7.132 + spin_unlock(&timerlist_lock); 7.133 + 7.134 + return ret; 7.135 +}
8.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/process.c Mon Jul 19 11:49:45 2004 +0000 8.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/process.c Tue Jul 20 14:58:08 2004 +0000 8.3 @@ -10,11 +10,16 @@ 8.4 8.5 void xen_cpu_idle (void) 8.6 { 8.7 - // local_irq_disable(); 8.8 - if (need_resched()) { 8.9 - // local_irq_enable(); 8.10 + local_irq_disable(); 8.11 + if (need_resched() || !list_empty(&RCU_curlist(cpu))) 8.12 + local_irq_enable(); 8.13 return; 8.14 } 8.15 - // local_irq_enable(); 8.16 + if (set_timeout_timer() == 0) { 8.17 + /* NB. Blocking reenable events in a race-free manner. */ 8.18 + HYPERVISOR_block(); 8.19 + return; 8.20 + } 8.21 + local_irq_enable(); 8.22 HYPERVISOR_yield(); 8.23 }
9.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/net/network.c Mon Jul 19 11:49:45 2004 +0000 9.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/net/network.c Tue Jul 20 14:58:08 2004 +0000 9.3 @@ -1,6 +1,4 @@ 9.4 /****************************************************************************** 9.5 - * network.c 9.6 - * 9.7 * Virtual network driver for conversing with remote driver backends. 9.8 * 9.9 * Copyright (c) 2002-2004, K A Fraser 9.10 @@ -8,13 +6,12 @@ 9.11 9.12 #include <linux/config.h> 9.13 #include <linux/module.h> 9.14 - 9.15 +#include <linux/version.h> 9.16 #include <linux/kernel.h> 9.17 #include <linux/sched.h> 9.18 #include <linux/slab.h> 9.19 #include <linux/string.h> 9.20 #include <linux/errno.h> 9.21 - 9.22 #include <linux/netdevice.h> 9.23 #include <linux/inetdevice.h> 9.24 #include <linux/etherdevice.h> 9.25 @@ -30,7 +27,13 @@ 9.26 9.27 #include <asm/page.h> 9.28 9.29 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 9.30 #include <asm-xen/netif.h> 9.31 +#else 9.32 +#include "../netif.h" 9.33 +#define irqreturn_t void 9.34 +#define IRQ_HANDLED 9.35 +#endif 9.36 9.37 #define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */ 9.38 9.39 @@ -368,7 +371,7 @@ static int network_start_xmit(struct sk_ 9.40 } 9.41 9.42 9.43 -static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 9.44 +static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 9.45 { 9.46 struct net_device *dev = dev_id; 9.47 struct net_private *np = dev->priv; 9.48 @@ -381,8 +384,6 @@ static irqreturn_t netif_int(int irq, vo 9.49 if ( (np->rx_resp_cons != np->rx->resp_prod) && 9.50 (np->user_state == UST_OPEN) ) 9.51 netif_rx_schedule(dev); 9.52 - 9.53 - return IRQ_HANDLED; 9.54 } 9.55 9.56 9.57 @@ -417,18 +418,25 @@ static int netif_poll(struct net_device 9.58 { 9.59 rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; 9.60 9.61 - skb = np->rx_skbs[rx->id]; 9.62 - ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 9.63 - 9.64 + /* 9.65 + * An error here is very odd. Usually indicates a backend bug, 9.66 + * low-memory condition, or that we didn't have reservation headroom. 9.67 + * Whatever - print an error and queue the id again straight away. 9.68 + */ 9.69 if ( unlikely(rx->status <= 0) ) 9.70 { 9.71 /* Gate this error. We get a (valid) slew of them on suspend. */ 9.72 - if ( np->user_state != UST_OPEN ) 9.73 + if ( np->user_state == UST_OPEN ) 9.74 printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); 9.75 - dev_kfree_skb(skb); 9.76 + np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; 9.77 + wmb(); 9.78 + np->rx->req_prod++; 9.79 continue; 9.80 } 9.81 9.82 + skb = np->rx_skbs[rx->id]; 9.83 + ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 9.84 + 9.85 skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK); 9.86 skb_put(skb, rx->status); 9.87
10.1 --- a/tools/python/setup.py Mon Jul 19 11:49:45 2004 +0000 10.2 +++ b/tools/python/setup.py Tue Jul 20 14:58:08 2004 +0000 10.3 @@ -41,6 +41,7 @@ setup(name = 'xen', 10.4 'xen.util', 10.5 'xen.xend', 10.6 'xen.xend.server', 10.7 + 'xen.xend.sv', 10.8 'xen.xm', 10.9 ], 10.10 ext_package = "xen.lowlevel",
11.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 19 11:49:45 2004 +0000 11.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Jul 20 14:58:08 2004 +0000 11.3 @@ -100,7 +100,7 @@ def lookup_raw_partn(name): 11.4 if line: 11.5 return [ { 'device' : blkdev_name_to_number(p), 11.6 'start_sector' : long(0), 11.7 - 'nr_sectors' : long(line) * 2, 11.8 + 'nr_sectors' : long(1L<<63), 11.9 'type' : 'Disk' } ] 11.10 else: 11.11 # see if this is a hex device number
12.1 --- a/tools/python/xen/xend/server/SrvServer.py Mon Jul 19 11:49:45 2004 +0000 12.2 +++ b/tools/python/xen/xend/server/SrvServer.py Tue Jul 20 14:58:08 2004 +0000 12.3 @@ -25,8 +25,8 @@ 12.4 # todo Support security settings etc. in the config file. 12.5 # todo Support command-line args. 12.6 12.7 -from twisted.web import server 12.8 -from twisted.web import resource 12.9 +from twisted.web import server, static 12.10 +from twisted.web import resource, script 12.11 from twisted.internet import reactor 12.12 12.13 from xen.xend import XendRoot 12.14 @@ -44,8 +44,12 @@ def create(port=None, interface=None, br 12.15 if bridge or xroot.rebooted: 12.16 Vifctl.network('start') 12.17 root = resource.Resource() 12.18 + sv = static.File( "/usr/lib/python2.2/site-packages/xen/xend/sv/" ) 12.19 + sv.indexNames=['Main.rpy'] 12.20 + sv.processors={'.rpy':script.ResourceScript} 12.21 xend = SrvRoot() 12.22 root.putChild('xend', xend) 12.23 + root.putChild('sv', sv) 12.24 site = server.Site(root) 12.25 reactor.listenTCP(port, site, interface=interface) 12.26
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/tools/python/xen/xend/sv/DomInfo.py Tue Jul 20 14:58:08 2004 +0000 13.3 @@ -0,0 +1,99 @@ 13.4 +from HTMLBase import HTMLBase 13.5 +from XendClientDeferred import server 13.6 +from xen.xend import PrettyPrint 13.7 + 13.8 +from xen.xend.sv.util import * 13.9 +from xen.xend.sv.GenTabbed import * 13.10 + 13.11 +class DomInfo( GenTabbed ): 13.12 + 13.13 + def __init__( self, urlWriter, callback ): 13.14 + 13.15 + self.dom = 0; 13.16 + 13.17 + def tabUrlWriter( tab ): 13.18 + return urlWriter( "mod=info&dom=%s%s" % ( self.dom, tab ) ) 13.19 + 13.20 + GenTabbed.__init__( self, tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGenTab, DomSXPTab, NullTab ], callback ) 13.21 + 13.22 + def write_BODY( self, request ): 13.23 + dom = request.args.get('dom') 13.24 + 13.25 + if dom is None or len(dom) != 1: 13.26 + request.write( "<p>Please Select a Domain</p>" ) 13.27 + return None 13.28 + else: 13.29 + self.dom = dom[0] 13.30 + 13.31 + GenTabbed.write_BODY( self, request ) 13.32 + 13.33 +class DomGenTab( GeneralTab ): 13.34 + 13.35 + def __init__( self ): 13.36 + 13.37 + titles = {} 13.38 + 13.39 + titles[ 'ID' ] = 'dom' 13.40 + titles[ 'Name' ] = 'name' 13.41 + titles[ 'CPU' ] = 'cpu' 13.42 + titles[ 'Memory' ] = ( 'mem', memoryFormatter ) 13.43 + titles[ 'State' ] = ( 'state', stateFormatter ) 13.44 + titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter ) 13.45 + titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter ) 13.46 + 13.47 + GeneralTab.__init__( self, "General Domain Info", {}, titles ) 13.48 + 13.49 + def write_BODY( self, request, callback ): 13.50 + dom = request.args.get('dom') 13.51 + 13.52 + if dom is None or len(dom) != 1: 13.53 + request.write( "<p>Please Select a Domain</p>" ) 13.54 + return None 13.55 + else: 13.56 + self.dom = dom[0] 13.57 + 13.58 + deferred = getDomInfoHash( self.dom ) 13.59 + deferred.addCallback( self.continue_BODY, request, callback ) 13.60 + 13.61 + def continue_BODY( self, dict, request, callback ): 13.62 + 13.63 + self.dict = dict 13.64 + 13.65 + GeneralTab.write_BODY( self, request, callback ) 13.66 + 13.67 +class DomSXPTab( PreTab ): 13.68 + 13.69 + def __init__( self ): 13.70 + self.dom = 0 13.71 + PreTab.__init__( self, "" ) 13.72 + 13.73 + def fn( self, x, request ): 13.74 + class tmp: 13.75 + def __init__( self ): 13.76 + self.str = "" 13.77 + def write( self, str ): 13.78 + self.str = self.str + str 13.79 + temp = tmp() 13.80 + PrettyPrint.prettyprint( x, out=temp ) 13.81 + self.source = temp.str 13.82 + return request 13.83 + 13.84 + def fn2( self, request, callback ): 13.85 + PreTab.write_BODY( self, request, callback ) 13.86 + 13.87 + def write_BODY( self, request, callback ): 13.88 + dom = request.args.get('dom') 13.89 + 13.90 + if dom is None or len(dom) != 1: 13.91 + request.write( "<p>Please Select a Domain</p>" ) 13.92 + return None 13.93 + else: 13.94 + self.dom = dom[0] 13.95 + 13.96 + deferred = server.xend_domain( self.dom ) 13.97 + 13.98 + deferred.addCallback( self.fn, request ) 13.99 + deferred.addCallback( self.fn2, callback ) 13.100 + def errback( x ): 13.101 + print ">err ", x 13.102 + deferred.addErrback( errback ) 13.103 \ No newline at end of file
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/tools/python/xen/xend/sv/DomList.py Tue Jul 20 14:58:08 2004 +0000 14.3 @@ -0,0 +1,101 @@ 14.4 +from twisted.web import resource 14.5 +from twisted.web.server import NOT_DONE_YET 14.6 + 14.7 +from XendClientDeferred import server as XendServer 14.8 +from xen.xend import sxp 14.9 + 14.10 +from xen.xend.sv.HTMLBase import HTMLBase 14.11 +from xen.xend.sv.util import * 14.12 + 14.13 +from twisted.internet import reactor 14.14 + 14.15 +class DomList( HTMLBase ): 14.16 + 14.17 + isLeaf = True 14.18 + 14.19 + def __init__( self, urlWriter, callback ): 14.20 + HTMLBase.__init__(self) 14.21 + self.urlWriter = urlWriter 14.22 + self.head = None 14.23 + self.long = None 14.24 + self.rendered_domains = {} 14.25 + self.domCount = 0 14.26 + self.callback = callback 14.27 + 14.28 + def write_BODY( self, request, head=True, long=True ): 14.29 + deferred = XendServer.xend_domains() 14.30 + deferred.addCallback( self.get_domain_info, request ) 14.31 + deferred.addErrback( self.errback ) 14.32 + 14.33 + self.head = head 14.34 + self.long = long 14.35 + 14.36 + def errback( self, err ): 14.37 + print 'errback>', err 14.38 + 14.39 + def get_domain_info( self, domains, request ): 14.40 + 14.41 + self.domCount = len( domains ) 14.42 + 14.43 + for domain in domains: 14.44 + deferred = getDomInfoHash( domain ) 14.45 + deferred.addCallback( self.render_domain, request ) 14.46 + deferred.addErrback( self.errback ) 14.47 + 14.48 + def render_domain( self, domInfoHash, request ): 14.49 + 14.50 + domStr = "<td class='domainInfo' align='center'>%(dom)-4d</td>\n" % domInfoHash 14.51 + 14.52 + url = self.urlWriter( "mod=info&dom=%(dom)-4d" % domInfoHash ) 14.53 + 14.54 + domStr += "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] ) 14.55 + 14.56 + if self.long: 14.57 + domStr += "<td class='domainInfo' align='center'>%(mem)7d</td>\n" % domInfoHash 14.58 + domStr += "<td class='domainInfo' align='center'>%(cpu)3d</td>\n" % domInfoHash 14.59 + 14.60 + domStr += "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash 14.61 + 14.62 + if self.long: 14.63 + domStr += "<td class='domainInfo' align='center'>%(cpu_time)7.1f</td>\n" % domInfoHash 14.64 + 14.65 + self.rendered_domains[ domInfoHash[ 'dom' ] ] = domStr 14.66 + self.domCount -= 1 14.67 + 14.68 + if self.domCount == 0: 14.69 + self.finish_write_BODY( request ) 14.70 + 14.71 + def finish_write_BODY( self, request ): 14.72 + 14.73 + request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" ) 14.74 + 14.75 + if self.head: 14.76 + request.write( "<tr class='domainInfoHead'>" ) 14.77 + self.write_DOMAIN_HEAD( request, self.long ) 14.78 + request.write( "</tr>" ) 14.79 + 14.80 + odd = True 14.81 + for domain in self.rendered_domains.values(): 14.82 + if odd: 14.83 + request.write( "<tr class='domainInfoOdd'>\n" ) 14.84 + odd = False 14.85 + else: 14.86 + request.write( "<tr class='domainInfoEven'>\n" ) 14.87 + odd = True 14.88 + request.write( domain ) 14.89 + request.write( "</tr>\n" ) 14.90 + 14.91 + request.write( "</table>\n" ) 14.92 + 14.93 + self.callback( request ) 14.94 + 14.95 + def write_DOMAIN_HEAD( self, request, long=True ): 14.96 + request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" ) 14.97 + request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" ) 14.98 + if long: 14.99 + request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" ) 14.100 + request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" ) 14.101 + request.write( "<td class='domainInfoHead' align='center'>State</td>\n" ) 14.102 + if long: 14.103 + request.write( "<td class='domainInfoHead' align='center'>CPU time / s</td>\n" ) 14.104 +
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/tools/python/xen/xend/sv/GenTabbed.py Tue Jul 20 14:58:08 2004 +0000 15.3 @@ -0,0 +1,103 @@ 15.4 +import types 15.5 + 15.6 +from HTMLBase import HTMLBase 15.7 +from TabView import TabView 15.8 + 15.9 +class GenTabbed( HTMLBase ): 15.10 + 15.11 + def __init__( self, urlWriter, tabStrings, tabObjects, callback ): 15.12 + HTMLBase.__init__(self) 15.13 + self.tab = 0; 15.14 + self.tabStrings = tabStrings 15.15 + self.tabObjects = tabObjects 15.16 + self.urlWriter = urlWriter 15.17 + self.callback = callback 15.18 + 15.19 + def write_BODY( self, request, urlWriter = None ): 15.20 + tab = request.args.get('tab') 15.21 + 15.22 + if tab is None or len( tab) != 1: 15.23 + self.tab = 0 15.24 + else: 15.25 + self.tab = int( tab[0] ) 15.26 + 15.27 + request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" ) 15.28 + request.write( "<tr><td>" ) 15.29 + 15.30 + TabView( self.tab, self.tabStrings, self.urlWriter ).write_BODY( request ) 15.31 + 15.32 + request.write( "</td></tr><tr><td>" ) 15.33 + 15.34 + render_tab = self.tabObjects[ self.tab ]() 15.35 + 15.36 + if render_tab is None: 15.37 + request.write( "<p>Bad Tab</p>" ) 15.38 + self.finish_BODY( request ) 15.39 + else: 15.40 + render_tab.write_BODY( request, self.finish_BODY ) 15.41 + 15.42 + def finish_BODY( self, request ): 15.43 + 15.44 + request.write( "</td></tr></table>" ) 15.45 + 15.46 + self.callback( request ) 15.47 + 15.48 +class PreTab( HTMLBase ): 15.49 + 15.50 + def __init__( self, source ): 15.51 + HTMLBase.__init__( self ) 15.52 + self.source = source 15.53 + 15.54 + def write_BODY( self, request, callback ): 15.55 + 15.56 + request.write( "<div style='display: block; overflow: auto; border: 0px solid black; height: 400px; width: 540px; padding: 5px; z-index:0; align: center'><pre>" ) 15.57 + 15.58 + request.write( self.source ) 15.59 + 15.60 + request.write( "</pre></div>" ) 15.61 + 15.62 + callback( request ) 15.63 + 15.64 +class GeneralTab( HTMLBase ): 15.65 + 15.66 + def __init__( self, title, dict, titles ): 15.67 + HTMLBase.__init__( self ) 15.68 + self.title = title 15.69 + self.dict = dict 15.70 + self.titles = titles 15.71 + 15.72 + def write_BODY( self, request, callback ): 15.73 + 15.74 + request.write( "<p><u>%s</u></p>" % self.title ) 15.75 + 15.76 + request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" ) 15.77 + 15.78 + def writeAttr( niceName, attr, formatter=None ): 15.79 + if type( attr ) is types.TupleType: 15.80 + ( attr, formatter ) = attr 15.81 + 15.82 + if attr in self.dict: 15.83 + if formatter: 15.84 + temp = formatter( self.dict[ attr ] ) 15.85 + else: 15.86 + temp = str( self.dict[ attr ] ) 15.87 + request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) ) 15.88 + 15.89 + for niceName, attr in self.titles.items(): 15.90 + writeAttr( niceName, attr ) 15.91 + 15.92 + request.write( "</table>" ) 15.93 + 15.94 + callback( request ) 15.95 + 15.96 +class NullTab( HTMLBase ): 15.97 + 15.98 + def __init__( self ): 15.99 + HTMLBase.__init__( self ) 15.100 + self.title = "Null Tab" 15.101 + 15.102 + def write_BODY( self, request, callback ): 15.103 + request.write( "<p>%s</p>" % self.title ) 15.104 + callback( request ) 15.105 + 15.106 + 15.107 \ No newline at end of file
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/tools/python/xen/xend/sv/HTMLBase.py Tue Jul 20 14:58:08 2004 +0000 16.3 @@ -0,0 +1,27 @@ 16.4 +from twisted.web import server, resource 16.5 +from twisted.internet import reactor 16.6 + 16.7 +class HTMLBase( resource.Resource ): 16.8 + 16.9 + isLeaf = True 16.10 + 16.11 + def __init__( self ): 16.12 + resource.Resource.__init__(self) 16.13 + 16.14 + def render_GET( self, request ): 16.15 + self.write_TOP( request ) 16.16 + return self.write_BODY( request, self.finish_render_GET ) 16.17 + 16.18 + def finish_render_GET( self, request ): 16.19 + self.write_BOTTOM( request ) 16.20 + request.finish() 16.21 + 16.22 + def write_BODY( self, request ): 16.23 + request.write( "BODY" ) 16.24 + 16.25 + def write_TOP( self, request ): 16.26 + request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' ) 16.27 + request.write( '</head><body>' ) 16.28 + 16.29 + def write_BOTTOM( self, request ): 16.30 + request.write( "</body></html>" ) 16.31 \ No newline at end of file
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/tools/python/xen/xend/sv/Main.py Tue Jul 20 14:58:08 2004 +0000 17.3 @@ -0,0 +1,81 @@ 17.4 +from twisted.web import resource 17.5 +from twisted.web.server import NOT_DONE_YET 17.6 + 17.7 +from xen.xend.XendClient import server as XendServer 17.8 +from xen.xend import sxp 17.9 + 17.10 +from HTMLBase import HTMLBase 17.11 + 17.12 +from xen.xend.sv import DomList, NodeInfo, DomInfo 17.13 + 17.14 +class Main( HTMLBase ): 17.15 + 17.16 + isLeaf = True 17.17 + 17.18 + def __init__( self ): 17.19 + HTMLBase.__init__(self) 17.20 + 17.21 + def render_POST( self, request ): 17.22 + return self.render_GET( request ) 17.23 + 17.24 + def mainUrlWriter( self, s ): 17.25 + return "Main.rpy?%s" % s 17.26 + 17.27 + def write_BODY( self, request, callback ): 17.28 + 17.29 + self.callback = callback 17.30 + 17.31 + 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" ) 17.32 + request.write( "<tr>\n" ) 17.33 + request.write( " <td width='15px'> </td>" ) 17.34 + request.write( " <td width='175px' align='center' valign'center'>" ) 17.35 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 17.36 + request.write( " <tr><td height='200px' align='center' valign='center'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" ) 17.37 + request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a></td></tr>" ) 17.38 + request.write( " <tr><td align='center' valign='top'>" ) 17.39 + 17.40 + request.write( " <p class='small'><a href='Main.rpy?mod=node'>Node details</a></p>" ) 17.41 + request.write( " <p class='small'><a href='Main.rpy?mod=list'>Domains summary</a></p>" ) 17.42 + 17.43 + DomList.DomList( self.mainUrlWriter, self.continue_BODY ).write_BODY( request, True, False ) 17.44 + 17.45 + return NOT_DONE_YET 17.46 + 17.47 + def continue_BODY( self, request ): 17.48 + request.write( " </td></tr>" ) 17.49 + request.write( " </table>" ) 17.50 + request.write( " " ) 17.51 + request.write( " </td>\n" ) 17.52 + request.write( " <td width='15px'> </td>" ) 17.53 + request.write( " <td width='558px' align='left' valign='top'>" ) 17.54 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 17.55 + request.write( " <tr><td height='20px'></td></tr>" ) 17.56 + request.write( " <tr><td align='center' valign='top'>" ) 17.57 + 17.58 + mod = request.args.get('mod') 17.59 + 17.60 + if mod is None or len(mod) != 1: 17.61 + request.write( '<p>Please select a module</p>' ) 17.62 + self.finish_BODY( request ) 17.63 + elif mod[0] == 'info': 17.64 + DomInfo.DomInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) 17.65 + elif mod[0] == 'list': 17.66 + DomList.DomList( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) 17.67 + elif mod[0] == 'node': 17.68 + NodeInfo.NodeInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) 17.69 + else: 17.70 + request.write( '<p>Invalid module. Please select another</p>' ) 17.71 + self.finish_BODY( request ) 17.72 + 17.73 + def finish_BODY( self, request ): 17.74 + 17.75 + request.write( " </td></tr>" ) 17.76 + request.write( " </table>" ) 17.77 + request.write( " </td>\n" ) 17.78 + request.write( " <td width='17px'> </td>" ) 17.79 + request.write( "</tr>\n" ) 17.80 + 17.81 + request.write( "</table>\n" ) 17.82 + 17.83 + self.callback( request ) 17.84 + 17.85 \ No newline at end of file
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/tools/python/xen/xend/sv/Main.rpy Tue Jul 20 14:58:08 2004 +0000 18.3 @@ -0,0 +1,3 @@ 18.4 +from xen.xend.sv.Main import * 18.5 + 18.6 +resource = Main() 18.7 \ No newline at end of file
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/tools/python/xen/xend/sv/NodeInfo.py Tue Jul 20 14:58:08 2004 +0000 19.3 @@ -0,0 +1,47 @@ 19.4 +from xen.xend import XendDmesg 19.5 +from xen.xend import XendNode 19.6 + 19.7 +from xen.xend.sv.util import * 19.8 +from xen.xend.sv.GenTabbed import * 19.9 +from xen.xend.sv.HTMLBase import HTMLBase 19.10 + 19.11 +class NodeInfo( GenTabbed ): 19.12 + 19.13 + def __init__( self, urlWriter, callback ): 19.14 + 19.15 + def newUrlWriter( url ): 19.16 + return urlWriter( "mod=node%s" % url ) 19.17 + 19.18 + GenTabbed.__init__( self, newUrlWriter, [ 'General', 'Dmesg' ], [ NodeGeneralTab, NodeDmesgTab ], callback ) 19.19 + 19.20 +class NodeGeneralTab( GeneralTab ): 19.21 + 19.22 + def __init__( self ): 19.23 + 19.24 + nodeInfo = XendNode.instance().info() 19.25 + 19.26 + dictNodeInfo = {} 19.27 + 19.28 + for l in nodeInfo: 19.29 + dictNodeInfo[ l[0] ] = l[1] 19.30 + 19.31 + dictTitles = {} 19.32 + dictTitles[ 'System' ] = 'system' 19.33 + dictTitles[ 'Hostname' ] = 'host' 19.34 + dictTitles[ 'Release' ] = 'release' 19.35 + dictTitles[ 'Version' ] ='version' 19.36 + dictTitles[ 'Machine' ] = 'machine' 19.37 + dictTitles[ 'Cores' ] = 'cores' 19.38 + dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter ) 19.39 + dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter ) 19.40 + dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter ) 19.41 + dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter ) 19.42 + 19.43 + GeneralTab.__init__( self, title="General Node Info", dict=dictNodeInfo, titles=dictTitles ) 19.44 + 19.45 +class NodeDmesgTab( PreTab ): 19.46 + 19.47 + def __init__( self ): 19.48 + self.xd = XendDmesg.instance() 19.49 + PreTab.__init__( self, self.xd.info()[0] ) 19.50 + 19.51 \ No newline at end of file
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/tools/python/xen/xend/sv/TabView.py Tue Jul 20 14:58:08 2004 +0000 20.3 @@ -0,0 +1,49 @@ 20.4 +from xen.xend.sv.HTMLBase import HTMLBase 20.5 + 20.6 +class TabView( HTMLBase ): 20.7 + 20.8 + def __init__( self, tab, tabs, urlWriter ): 20.9 + HTMLBase.__init__(self) 20.10 + self.tab = tab # interger - tab id 20.11 + self.tabs = tabs 20.12 + self.urlWriter = urlWriter 20.13 + 20.14 + def write_BODY( self, request ): 20.15 + request.write( "<table style='' border='0' cellspacing='0' cellpadding='0' align='center'>" ) 20.16 + request.write( "<tr height='22'>" ) 20.17 + 20.18 + if self.tab == 0: 20.19 + image = "left-end-highlight.jpg" 20.20 + else: 20.21 + image = "left-end-no-highlight.jpg" 20.22 + 20.23 + request.write( "<td height='22' width='14'><image src='images/%s' width='14' height='22'></td>" % image ) 20.24 + 20.25 + count = len( self.tabs ) 20.26 + 20.27 + for i in range( count ): 20.28 + 20.29 + if i == self.tab: 20.30 + image = "middle-highlight.jpg" 20.31 + else: 20.32 + image = "middle-no-highlight.jpg" 20.33 + 20.34 + 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 ] ) ) 20.35 + 20.36 + if i < count-1: 20.37 + if i == self.tab: 20.38 + image = "seperator-left-highlight.jpg" 20.39 + elif self.tab == i+1: 20.40 + image = "seperator-right-highlight.jpg" 20.41 + else: 20.42 + image = "seperator.jpg" 20.43 + 20.44 + request.write( "<td height='22' width='23'><image src='images/%s' width='23' height='22'></td>" % image ) 20.45 + 20.46 + if self.tab == count - 1: 20.47 + image = "right-end-highlight.jpg" 20.48 + else: 20.49 + image = "right-end-no-highlight.jpg" 20.50 + 20.51 + request.write( "<td height='22' width='14'><image src='images/%s' width='14' height='22'></td>" % image ) 20.52 + request.write( "</tr></table>" )
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/tools/python/xen/xend/sv/XendClientDeferred.py Tue Jul 20 14:58:08 2004 +0000 21.3 @@ -0,0 +1,363 @@ 21.4 +# Copyright (C) 2004 Tom Wilkie <tw275@cam.ac.uk> 21.5 +# Copyright (C) 2004 Mike Wray 21.6 +"""Client API for the HTTP interface on xend. 21.7 +Callable as a script - see main(). 21.8 + 21.9 +This API is the 'control-plane' for xend. 21.10 +The 'data-plane' is done separately. For example, consoles 21.11 +are accessed via sockets on xend, but the list of consoles 21.12 +is accessible via this API. 21.13 + 21.14 +This one is similar to mikes, but works in an async fashion 21.15 +""" 21.16 +import sys 21.17 +import httplib 21.18 +import types 21.19 +from StringIO import StringIO 21.20 +import urlparse 21.21 + 21.22 +from xen.xend.encode import * 21.23 +from xen.xend.sxp import * 21.24 +from xen.xend.PrettyPrint import prettyprint 21.25 + 21.26 +from twisted.protocols.http import HTTPClient 21.27 +from twisted.internet.protocol import ClientCreator 21.28 +from twisted.internet.defer import Deferred 21.29 +from twisted.internet import reactor 21.30 + 21.31 +DEBUG = 0 21.32 + 21.33 +class XendRequest( HTTPClient ): 21.34 + def __init__(self, deferred, urls): 21.35 + self.urls = urls 21.36 + self.deferred = deferred 21.37 + 21.38 + def connectionMade(self): 21.39 + self.sendCommand('GET', self.urls[2]) 21.40 + self.sendHeader('Host', '%s:%d' % (self.urls[0], self.urls[1]) ) 21.41 + self.endHeaders() 21.42 + 21.43 + def handleResponse(self, data): 21.44 + self.deferred.callback( data ) 21.45 + 21.46 +def process_SXP( sexp ): 21.47 + pin = Parser() 21.48 + pin.input(sexp) 21.49 + pin.input_eof() 21.50 + return pin.get_val() 21.51 + 21.52 +def xend_request(url, method, data=None): 21.53 + """Make a request to xend. 21.54 + 21.55 + url xend request url 21.56 + method http method: POST or GET 21.57 + data request argument data (dict) 21.58 + """ 21.59 + urlinfo = urlparse.urlparse(url) 21.60 + (uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo 21.61 + (hdr, args) = encode_data(data) 21.62 + if data and method == 'GET': 21.63 + upath += '?' + args 21.64 + args = None 21.65 + if method == "POST" and upath.endswith('/'): 21.66 + upath = upath[:-1] 21.67 + 21.68 + deferred = Deferred() 21.69 + 21.70 + clientCreator = ClientCreator( reactor, XendRequest, deferred, (ulocation, 8000, upath) ) 21.71 + clientCreator.connectTCP( ulocation, 8000 ) 21.72 + 21.73 + deferred.addCallback( process_SXP ) 21.74 + 21.75 + return deferred 21.76 + 21.77 +class XendError(RuntimeError): 21.78 + pass 21.79 + 21.80 +class Foo(httplib.HTTPResponse): 21.81 + 21.82 + def begin(self): 21.83 + fin = self.fp 21.84 + while(1): 21.85 + buf = fin.readline() 21.86 + print "***", buf 21.87 + if buf == '': 21.88 + print 21.89 + sys.exit() 21.90 + 21.91 + 21.92 +def sxprio(sxpr): 21.93 + """Convert an sxpr to a string. 21.94 + """ 21.95 + io = StringIO() 21.96 + sxp.show(sxpr, out=io) 21.97 + print >> io 21.98 + io.seek(0) 21.99 + return io 21.100 + 21.101 +def fileof(val): 21.102 + """Converter for passing configs. 21.103 + Handles lists, files directly. 21.104 + Assumes a string is a file name and passes its contents. 21.105 + """ 21.106 + if isinstance(val, types.ListType): 21.107 + return sxprio(val) 21.108 + if isinstance(val, types.StringType): 21.109 + return file(val) 21.110 + if hasattr(val, 'readlines'): 21.111 + return val 21.112 + 21.113 +# todo: need to sort of what urls/paths are using for objects. 21.114 +# e.g. for domains at the moment return '0'. 21.115 +# should probably return abs path w.r.t. server, e.g. /xend/domain/0. 21.116 +# As an arg, assume abs path is obj uri, otherwise just id. 21.117 + 21.118 +# Function to convert to full url: Xend.uri(path), e.g. 21.119 +# maps /xend/domain/0 to http://wray-m-3.hpl.hp.com:8000/xend/domain/0 21.120 +# And should accept urls for ids? 21.121 + 21.122 +def urljoin(location, root, prefix='', rest=''): 21.123 + prefix = str(prefix) 21.124 + rest = str(rest) 21.125 + base = 'http://' + location + root + prefix 21.126 + url = urlparse.urljoin(base, rest) 21.127 + return url 21.128 + 21.129 +def nodeurl(location, root, id=''): 21.130 + return urljoin(location, root, 'node/', id) 21.131 + 21.132 +def domainurl(location, root, id=''): 21.133 + return urljoin(location, root, 'domain/', id) 21.134 + 21.135 +def consoleurl(location, root, id=''): 21.136 + return urljoin(location, root, 'console/', id) 21.137 + 21.138 +def deviceurl(location, root, id=''): 21.139 + return urljoin(location, root, 'device/', id) 21.140 + 21.141 +def vneturl(location, root, id=''): 21.142 + return urljoin(location, root, 'vnet/', id) 21.143 + 21.144 +def eventurl(location, root, id=''): 21.145 + return urljoin(location, root, 'event/', id) 21.146 + 21.147 +def xend_get(url, args=None): 21.148 + """Make a xend request using GET. 21.149 + Requests using GET are 'safe' and may be repeated without 21.150 + nasty side-effects. 21.151 + """ 21.152 + return xend_request(url, "GET", args) 21.153 + 21.154 +def xend_call(url, data): 21.155 + """Make xend request using POST. 21.156 + Requests using POST potentially cause side-effects and should 21.157 + not be repeated unless it really is wanted to do the side 21.158 + effect again. 21.159 + """ 21.160 + return xend_request(url, "POST", data) 21.161 + 21.162 +class Xend: 21.163 + 21.164 + """Default location of the xend server.""" 21.165 + SRV_DEFAULT = "localhost" 21.166 + 21.167 + """Default path to the xend root on the server.""" 21.168 + ROOT_DEFAULT = "/xend/" 21.169 + 21.170 + def __init__(self, srv=None, root=None): 21.171 + self.bind(srv, root) 21.172 + 21.173 + def bind(self, srv=None, root=None): 21.174 + """Bind to a given server. 21.175 + 21.176 + srv server location (host:port) 21.177 + root server xend root path 21.178 + """ 21.179 + if srv is None: srv = self.SRV_DEFAULT 21.180 + if root is None: root = self.ROOT_DEFAULT 21.181 + if not root.endswith('/'): root += '/' 21.182 + self.location = srv 21.183 + self.root = root 21.184 + 21.185 + def nodeurl(self, id=''): 21.186 + return nodeurl(self.location, self.root, id) 21.187 + 21.188 + def domainurl(self, id=''): 21.189 + return domainurl(self.location, self.root, id) 21.190 + 21.191 + def consoleurl(self, id=''): 21.192 + return consoleurl(self.location, self.root, id) 21.193 + 21.194 + def deviceurl(self, id=''): 21.195 + return deviceurl(self.location, self.root, id) 21.196 + 21.197 + def vneturl(self, id=''): 21.198 + return vneturl(self.location, self.root, id) 21.199 + 21.200 + def eventurl(self, id=''): 21.201 + return eventurl(self.location, self.root, id) 21.202 + 21.203 + def xend(self): 21.204 + return xend_get(urljoin(self.location, self.root)) 21.205 + 21.206 + def xend_node(self): 21.207 + return xend_get(self.nodeurl()) 21.208 + 21.209 + def xend_node_cpu_rrobin_slice_set(self, slice): 21.210 + return xend_call(self.nodeurl(), 21.211 + {'op' : 'cpu_rrobin_slice_set', 21.212 + 'slice' : slice }) 21.213 + 21.214 + def xend_node_cpu_bvt_slice_set(self, ctx_allow): 21.215 + return xend_call(self.nodeurl(), 21.216 + {'op' : 'cpu_bvt_slice_set', 21.217 + 'ctx_allow' : ctx_allow }) 21.218 + 21.219 + def xend_node_cpu_fbvt_slice_set(self, ctx_allow): 21.220 + return xend_call(self.nodeurl(), 21.221 + {'op' : 'cpu_fbvt_slice_set', 21.222 + 'ctx_allow' : ctx_allow }) 21.223 + 21.224 + def xend_domains(self): 21.225 + return xend_get(self.domainurl()) 21.226 + 21.227 + def xend_domain_create(self, conf): 21.228 + return xend_call(self.domainurl(), 21.229 + {'op' : 'create', 21.230 + 'config' : fileof(conf) }) 21.231 + 21.232 + def xend_domain(self, id): 21.233 + return xend_get(self.domainurl(id)) 21.234 + 21.235 + def xend_domain_unpause(self, id): 21.236 + return xend_call(self.domainurl(id), 21.237 + {'op' : 'unpause'}) 21.238 + 21.239 + def xend_domain_pause(self, id): 21.240 + return xend_call(self.domainurl(id), 21.241 + {'op' : 'pause'}) 21.242 + 21.243 + def xend_domain_shutdown(self, id, reason): 21.244 + return xend_call(self.domainurl(id), 21.245 + {'op' : 'shutdown', 21.246 + 'reason' : reason }) 21.247 + 21.248 + def xend_domain_destroy(self, id): 21.249 + return xend_call(self.domainurl(id), 21.250 + {'op' : 'destroy'}) 21.251 + 21.252 + def xend_domain_save(self, id, filename): 21.253 + return xend_call(self.domainurl(id), 21.254 + {'op' : 'save', 21.255 + 'file' : filename}) 21.256 + 21.257 + def xend_domain_restore(self, id, filename): 21.258 + return xend_call(self.domainurl(id), 21.259 + {'op' : 'restore', 21.260 + 'file' : filename }) 21.261 + 21.262 + def xend_domain_migrate(self, id, dst): 21.263 + return xend_call(self.domainurl(id), 21.264 + {'op' : 'migrate', 21.265 + 'destination': dst}) 21.266 + 21.267 + def xend_domain_pincpu(self, id, cpu): 21.268 + return xend_call(self.domainurl(id), 21.269 + {'op' : 'pincpu', 21.270 + 'cpu' : cpu}) 21.271 + 21.272 + def xend_domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu): 21.273 + return xend_call(self.domainurl(id), 21.274 + {'op' : 'cpu_bvt_set', 21.275 + 'mcuadv' : mcuadv, 21.276 + 'warp' : warp, 21.277 + 'warpl' : warpl, 21.278 + 'warpu' : warpu }) 21.279 + 21.280 + def xend_domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu): 21.281 + return xend_call(self.domainurl(id), 21.282 + {'op' : 'cpu_fbvt_set', 21.283 + 'mcuadv' : mcuadv, 21.284 + 'warp' : warp, 21.285 + 'warpl' : warpl, 21.286 + 'warpu' : warpu }) 21.287 + 21.288 + 21.289 + def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime): 21.290 + return xend_call(self.domainurl(id), 21.291 + {'op' : 'cpu_atropos_set', 21.292 + 'period' : period, 21.293 + 'slice' : slice, 21.294 + 'latency' : latency, 21.295 + 'xtratime': xtratime }) 21.296 + 21.297 + def xend_domain_vifs(self, id): 21.298 + return xend_get(self.domainurl(id), 21.299 + { 'op' : 'vifs' }) 21.300 + 21.301 + def xend_domain_vif_ip_add(self, id, vif, ipaddr): 21.302 + return xend_call(self.domainurl(id), 21.303 + {'op' : 'vif_ip_add', 21.304 + 'vif' : vif, 21.305 + 'ip' : ipaddr }) 21.306 + 21.307 + def xend_domain_vbds(self, id): 21.308 + return xend_get(self.domainurl(id), 21.309 + {'op' : 'vbds'}) 21.310 + 21.311 + def xend_domain_vbd(self, id, vbd): 21.312 + return xend_get(self.domainurl(id), 21.313 + {'op' : 'vbd', 21.314 + 'vbd' : vbd}) 21.315 + 21.316 + def xend_consoles(self): 21.317 + return xend_get(self.consoleurl()) 21.318 + 21.319 + def xend_console(self, id): 21.320 + return xend_get(self.consoleurl(id)) 21.321 + 21.322 + def xend_vnets(self): 21.323 + return xend_get(self.vneturl()) 21.324 + 21.325 + def xend_vnet_create(self, conf): 21.326 + return xend_call(self.vneturl(), 21.327 + {'op': 'create', 'config': fileof(conf) }) 21.328 + 21.329 + def xend_vnet(self, id): 21.330 + return xend_get(self.vneturl(id)) 21.331 + 21.332 + def xend_vnet_delete(self, id): 21.333 + return xend_call(self.vneturl(id), 21.334 + {'op': 'delete'}) 21.335 + 21.336 + def xend_event_inject(self, sxpr): 21.337 + val = xend_call(self.eventurl(), 21.338 + {'op': 'inject', 'event': fileof(sxpr) }) 21.339 + 21.340 +def main(argv): 21.341 + """Call an API function: 21.342 + 21.343 + python XendClient.py fn args... 21.344 + 21.345 + The leading 'xend_' on the function can be omitted. 21.346 + Example: 21.347 + 21.348 + > python XendClient.py domains 21.349 + (domain 0 8) 21.350 + > python XendClient.py domain 0 21.351 + (domain (id 0) (name Domain-0) (memory 128)) 21.352 + """ 21.353 + server = Xend() 21.354 + fn = argv[1] 21.355 + if not fn.startswith('xend'): 21.356 + fn = 'xend_' + fn 21.357 + args = argv[2:] 21.358 + deferred = getattr(server, fn)(*args) 21.359 + deferred.addCallback( prettyprint ) 21.360 + reactor.run() 21.361 + print 21.362 + 21.363 +if __name__ == "__main__": 21.364 + main(sys.argv) 21.365 +else: 21.366 + server = Xend()
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/tools/python/xen/xend/sv/__init__.py Tue Jul 20 14:58:08 2004 +0000 22.3 @@ -0,0 +1,1 @@ 22.4 +
23.1 Binary file tools/python/xen/xend/sv/images/internet copy.jpg has changed
24.1 Binary file tools/python/xen/xend/sv/images/internet.jpg has changed
25.1 Binary file tools/python/xen/xend/sv/images/internet.psd has changed
26.1 Binary file tools/python/xen/xend/sv/images/left-end-highlight.jpg has changed
27.1 Binary file tools/python/xen/xend/sv/images/left-end-no-highlight.jpg has changed
28.1 Binary file tools/python/xen/xend/sv/images/middle-highlight.jpg has changed
29.1 Binary file tools/python/xen/xend/sv/images/middle-no-highlight.jpg has changed
30.1 Binary file tools/python/xen/xend/sv/images/orb_01.jpg has changed
31.1 Binary file tools/python/xen/xend/sv/images/orb_02.jpg has changed
32.1 Binary file tools/python/xen/xend/sv/images/right-end-highlight.jpg has changed
33.1 Binary file tools/python/xen/xend/sv/images/right-end-no-highlight.jpg has changed
34.1 Binary file tools/python/xen/xend/sv/images/seperator-left-highlight.jpg has changed
35.1 Binary file tools/python/xen/xend/sv/images/seperator-right-highlight.jpg has changed
36.1 Binary file tools/python/xen/xend/sv/images/seperator.jpg has changed
37.1 Binary file tools/python/xen/xend/sv/images/xen.png has changed
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/tools/python/xen/xend/sv/inc/style.css Tue Jul 20 14:58:08 2004 +0000 38.3 @@ -0,0 +1,30 @@ 38.4 + 38.5 +P {font-family: verdana, arial; font-size: 12px; color: black} 38.6 +.small {font-size: 10px} 38.7 + 38.8 +TD.domainInfo {font-family: verdana, arial; font-size: 10px; color: black} 38.9 +TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold} 38.10 + 38.11 +TD.domainInfoHead {background-color: black} 38.12 +TR.domainInfoOdd {background-color: white} 38.13 +TR.domainInfoEven {background-color: lightgrey} 38.14 + 38.15 +body { 38.16 + width: 670px; 38.17 + margin: 0px; 38.18 + padding: 0px; 38.19 + background-color: #fff; 38.20 + background-image: url(../images/orb_02.jpg); 38.21 + background-repeat: repeat-y; 38.22 + background-position: left top; 38.23 + font-family: Arial, Helvetica, sans-serif; 38.24 + font-weight: bold; 38.25 + color: #333333; 38.26 + letter-spacing: 0px; 38.27 + scrollbar-base-color: #333333; 38.28 + scrollbar-track-color: #666666; 38.29 + scrollbar-face-color: #fff; 38.30 + 38.31 + 38.32 + } 38.33 + 38.34 \ No newline at end of file
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/tools/python/xen/xend/sv/util.py Tue Jul 20 14:58:08 2004 +0000 39.3 @@ -0,0 +1,64 @@ 39.4 +from xen.xend.sv.XendClientDeferred import server 39.5 +from xen.xend import sxp 39.6 + 39.7 +def getDomInfoHash( domain ): 39.8 + deferred = server.xend_domain( int( domain ) ) 39.9 + deferred.addCallback( procDomInfo, domain ) 39.10 + return deferred 39.11 + 39.12 +def procDomInfo( domInfo, domain ): 39.13 + d = {} 39.14 + d['dom'] = int( domain ) 39.15 + d['name'] = sxp.child_value( domInfo, 'name' ) 39.16 + d['mem'] = int( sxp.child_value( domInfo, 'memory' ) ) 39.17 + d['cpu'] = int( sxp.child_value( domInfo, 'cpu' ) ) 39.18 + d['state'] = sxp.child_value( domInfo, 'state' ) 39.19 + d['cpu_time'] = float( sxp.child_value( domInfo, 'cpu_time' ) ) 39.20 + if( sxp.child_value( domInfo, 'up_time' ) ): 39.21 + d['up_time'] = float( sxp.child_value( domInfo, 'up_time' ) ) 39.22 + if( sxp.child_value( domInfo, 'start_time' ) ): 39.23 + d['start_time'] = float( sxp.child_value( domInfo, 'start_time' ) ) 39.24 + return d 39.25 + 39.26 +def bigTimeFormatter( time ): 39.27 + weeks = time // 604800 39.28 + remainder = time % 604800 39.29 + days = remainder // 86400 39.30 + 39.31 + remainder = remainder % 86400 39.32 + 39.33 + hms = smallTimeFormatter( remainder ) 39.34 + 39.35 + return "%d weeks, %d days, %s" % ( weeks, days, hms ) 39.36 + 39.37 +def smallTimeFormatter( time ): 39.38 + hours = time // 3600 39.39 + remainder = time % 3600 39.40 + mins = remainder // 60 39.41 + secs = time % 60 39.42 + return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) 39.43 + 39.44 +def stateFormatter( state ): 39.45 + states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ] 39.46 + 39.47 + for i in range( len( state ) ): 39.48 + if state[i] != "-": 39.49 + return states[ i ] + " (%s)" % state 39.50 + 39.51 + return state 39.52 + 39.53 +def memoryFormatter( mem ): 39.54 + return "%7dMb" % mem 39.55 + 39.56 +def cpuFormatter( mhz ): 39.57 + if mhz > 1000: 39.58 + ghz = float( mhz ) / 1000.0 39.59 + return "%4.2fGHz" % ghz 39.60 + else: 39.61 + return "%4dMHz" % mhz 39.62 + 39.63 +def hyperthreadFormatter( threads ): 39.64 + if int( threads ) > 1: 39.65 + return "Yes (%d)" % threads 39.66 + else: 39.67 + return "No" 39.68 \ No newline at end of file
40.1 --- a/tools/python/xen/xm/main.py Mon Jul 19 11:49:45 2004 +0000 40.2 +++ b/tools/python/xen/xm/main.py Tue Jul 20 14:58:08 2004 +0000 40.3 @@ -105,8 +105,23 @@ class Xm: 40.4 40.5 def getprog(self, name, val=None): 40.6 """Get a sub-program. 40.7 + name Name of the sub-program (or optionally, an unambiguous 40.8 + prefix of its name) 40.9 + val Default return value if no (unique) match is found 40.10 """ 40.11 - return self.progs.get(name, val) 40.12 + 40.13 + match = None 40.14 + for progname in self.progs.keys(): 40.15 + if progname == name: 40.16 + match = progname 40.17 + break 40.18 + if progname.startswith(name): 40.19 + if not match: 40.20 + match = progname 40.21 + else: 40.22 + return val # name is ambiguous - bail out 40.23 + 40.24 + return self.progs.get(match, val) 40.25 40.26 def proglist(self): 40.27 """Get a list of sub-programs, ordered by group.
41.1 --- a/xen/arch/x86/memory.c Mon Jul 19 11:49:45 2004 +0000 41.2 +++ b/xen/arch/x86/memory.c Tue Jul 20 14:58:08 2004 +0000 41.3 @@ -840,7 +840,7 @@ static int do_extended_command(unsigned 41.4 41.5 if ( unlikely((e = percpu_info[cpu].gps) == NULL) ) 41.6 { 41.7 - MEM_LOG("No GPS to reassign pfn %08lx to\n", pfn); 41.8 + MEM_LOG("No GPS to reassign pfn %08lx to", pfn); 41.9 okay = 0; 41.10 break; 41.11 } 41.12 @@ -865,6 +865,7 @@ static int do_extended_command(unsigned 41.13 if ( unlikely(test_bit(DF_DYING, &e->flags)) || 41.14 unlikely(IS_XEN_HEAP_FRAME(page)) ) 41.15 { 41.16 + MEM_LOG("Reassignment page is Xen heap, or dest dom is dying."); 41.17 okay = 0; 41.18 goto reassign_fail; 41.19 } 41.20 @@ -1051,8 +1052,8 @@ int do_mmu_update(mmu_update_t *ureqs, i 41.21 * If in log-dirty mode, mark the corresponding pseudo-physical 41.22 * page as dirty. 41.23 */ 41.24 - if( unlikely(current->mm.shadow_mode == SHM_logdirty) ) 41.25 - mark_dirty( ¤t->mm, pfn ); 41.26 + if ( unlikely(current->mm.shadow_mode == SHM_logdirty) ) 41.27 + mark_dirty(¤t->mm, pfn); 41.28 41.29 put_page(&frame_table[pfn]); 41.30 break;
42.1 --- a/xen/arch/x86/x86_32/emulate.c Mon Jul 19 11:49:45 2004 +0000 42.2 +++ b/xen/arch/x86/x86_32/emulate.c Tue Jul 20 14:58:08 2004 +0000 42.3 @@ -30,6 +30,10 @@ 42.4 #include <xen/perfc.h> 42.5 #include <asm/processor.h> 42.6 42.7 +/* Make the scary benign errors go away. */ 42.8 +#undef DPRINTK 42.9 +#define DPRINTK(_f, _a...) ((void)0) 42.10 + 42.11 /* 42.12 * Obtain the base and limit associated with the given segment selector. 42.13 * The selector must identify a 32-bit code or data segment. Any segment that 42.14 @@ -495,9 +499,34 @@ int gpf_emulate_4gb(struct pt_regs *regs 42.15 goto undecodeable; 42.16 } 42.17 42.18 +#if 0 42.19 + { 42.20 + char str1[] = { 0x65,0x8b,0x00,0x8b,0x30 }; 42.21 + char str2[] = { 0x65,0x8b,0x02,0x8b,0x40,0x0c }; 42.22 + char str3[] = { 0x65,0x8b,0x30,0x85,0xf6 }; 42.23 + char str4[] = { 0x65,0x8b,0x00,0x5d,0x8b,0x00 }; 42.24 + char str5[] = { 0x65,0x89,0x30,0x8b,0x45,0x08 }; 42.25 + char str6[] = { 0x65,0x8b,0x00,0x8b,0x50,0x0c }; 42.26 + char str7[] = { 0x65,0x89,0x51,0x00,0x83,0xc8,0xff }; 42.27 + if ( (memcmp(eip,str1,5) == 0) || 42.28 + (memcmp(eip,str2,6) == 0) ) goto out; 42.29 + if ( (memcmp(eip,str3,5) == 0) || 42.30 + (memcmp(eip,str4,6) == 0) ) goto out; 42.31 + if ( (memcmp(eip,str5,6) == 0) || 42.32 + (memcmp(eip,str6,6) == 0) ) goto out; 42.33 + if ( (memcmp(eip,str7,7) == 0) || 42.34 + (memcmp(eip,str7,7) == 0) ) goto out; 42.35 + } 42.36 + printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", 42.37 + eip[-8],eip[-7],eip[-6],eip[-5],eip[-4],eip[-3],eip[-2],eip[-1]); 42.38 + printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", 42.39 + eip[0],eip[1],eip[2],eip[3],eip[4],eip[5],eip[6],eip[7]); 42.40 + printk(" @ %04x:%08lx\n", regs->xcs, regs->eip); 42.41 +#endif 42.42 + 42.43 /* Success! */ 42.44 + perfc_incrc(emulations); 42.45 regs->eip += pb - eip; 42.46 - perfc_incrc(emulations); 42.47 return 1; 42.48 42.49 undecodeable: 42.50 @@ -530,5 +559,3 @@ int gpf_emulate_4gb(struct pt_regs *regs 42.51 d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1; 42.52 return 1; 42.53 } 42.54 - 42.55 -