ia64/xen-unstable

changeset 8309:a8be51efaf46

Merged.
author emellor@leeni.uk.xensource.com
date Fri Dec 09 10:51:35 2005 +0000 (2005-12-09)
parents 10220071deff da3b19d7bf9e
children 53cff3f88e45
files
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Dec 09 10:51:20 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Dec 09 10:51:35 2005 +0000
     1.3 @@ -12,6 +12,8 @@
     1.4   */
     1.5  
     1.6  #include <linux/spinlock.h>
     1.7 +#include <linux/kthread.h>
     1.8 +#include <linux/list.h>
     1.9  #include <asm-xen/balloon.h>
    1.10  #include <asm/hypervisor.h>
    1.11  #include "common.h"
    1.12 @@ -21,26 +23,26 @@
    1.13   * pulled from a communication ring are quite likely to end up being part of
    1.14   * the same scatter/gather request at the disc.
    1.15   * 
    1.16 - * ** TRY INCREASING 'MAX_PENDING_REQS' IF WRITE SPEEDS SEEM TOO LOW **
    1.17 + * ** TRY INCREASING 'blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW **
    1.18 + * 
    1.19   * This will increase the chances of being able to write whole tracks.
    1.20   * 64 should be enough to keep us competitive with Linux.
    1.21   */
    1.22 -#define MAX_PENDING_REQS 64
    1.23 -#define BATCH_PER_DOMAIN 16
    1.24 +static int blkif_reqs = 64;
    1.25 +static int mmap_pages;
    1.26  
    1.27 -static unsigned long mmap_vstart;
    1.28 -#define MMAP_PAGES						\
    1.29 -	(MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
    1.30 -#ifdef __ia64__
    1.31 -static void *pending_vaddrs[MMAP_PAGES];
    1.32 -#define MMAP_VADDR(_idx, _i) \
    1.33 -	(unsigned long)(pending_vaddrs[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
    1.34 -#else
    1.35 -#define MMAP_VADDR(_req,_seg)						\
    1.36 -	(mmap_vstart +							\
    1.37 -	 ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +	\
    1.38 -	 ((_seg) * PAGE_SIZE))
    1.39 -#endif
    1.40 +static int __init set_blkif_reqs(char *str)
    1.41 +{
    1.42 +	get_option(&str, &blkif_reqs);
    1.43 +	return 1;
    1.44 +}
    1.45 +__setup("blkif_reqs=", set_blkif_reqs);
    1.46 +
    1.47 +/* Run-time switchable: /sys/module/blkback/parameters/ */
    1.48 +static unsigned int log_stats = 0;
    1.49 +static unsigned int debug_lvl = 0;
    1.50 +module_param(log_stats, int, 0644);
    1.51 +module_param(debug_lvl, int, 0644);
    1.52  
    1.53  /*
    1.54   * Each outstanding request that we've passed to the lower device layers has a 
    1.55 @@ -55,43 +57,33 @@ typedef struct {
    1.56  	atomic_t       pendcnt;
    1.57  	unsigned short operation;
    1.58  	int            status;
    1.59 +	struct list_head free_list;
    1.60  } pending_req_t;
    1.61  
    1.62 -/*
    1.63 - * We can't allocate pending_req's in order, since they may complete out of 
    1.64 - * order. We therefore maintain an allocation ring. This ring also indicates 
    1.65 - * when enough work has been passed down -- at that point the allocation ring 
    1.66 - * will be empty.
    1.67 - */
    1.68 -static pending_req_t pending_reqs[MAX_PENDING_REQS];
    1.69 -static unsigned char pending_ring[MAX_PENDING_REQS];
    1.70 -static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED;
    1.71 -/* NB. We use a different index type to differentiate from shared blk rings. */
    1.72 -typedef unsigned int PEND_RING_IDX;
    1.73 -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
    1.74 -static PEND_RING_IDX pending_prod, pending_cons;
    1.75 -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
    1.76 +static pending_req_t *pending_reqs;
    1.77 +static struct list_head pending_free;
    1.78 +static spinlock_t pending_free_lock = SPIN_LOCK_UNLOCKED;
    1.79 +static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
    1.80 +
    1.81 +#define BLKBACK_INVALID_HANDLE (~0)
    1.82  
    1.83 -static request_queue_t *plugged_queue;
    1.84 -static inline void flush_plugged_queue(void)
    1.85 +static unsigned long mmap_vstart;
    1.86 +static unsigned long *pending_vaddrs;
    1.87 +static grant_handle_t *pending_grant_handles;
    1.88 +
    1.89 +static inline int vaddr_pagenr(pending_req_t *req, int seg)
    1.90  {
    1.91 -	request_queue_t *q = plugged_queue;
    1.92 -	if (q != NULL) {
    1.93 -		if ( q->unplug_fn != NULL )
    1.94 -			q->unplug_fn(q);
    1.95 -		blk_put_queue(q);
    1.96 -		plugged_queue = NULL;
    1.97 -	}
    1.98 +	return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
    1.99  }
   1.100  
   1.101 -/* When using grant tables to map a frame for device access then the
   1.102 - * handle returned must be used to unmap the frame. This is needed to
   1.103 - * drop the ref count on the frame.
   1.104 - */
   1.105 -static grant_handle_t pending_grant_handles[MMAP_PAGES];
   1.106 -#define pending_handle(_idx, _i) \
   1.107 -    (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
   1.108 -#define BLKBACK_INVALID_HANDLE (~0)
   1.109 +static inline unsigned long vaddr(pending_req_t *req, int seg)
   1.110 +{
   1.111 +	return pending_vaddrs[vaddr_pagenr(req, seg)];
   1.112 +}
   1.113 +
   1.114 +#define pending_handle(_req, _seg) \
   1.115 +	(pending_grant_handles[vaddr_pagenr(_req, _seg)])
   1.116 +
   1.117  
   1.118  #ifdef CONFIG_XEN_BLKDEV_TAP_BE
   1.119  /*
   1.120 @@ -105,26 +97,79 @@ static grant_handle_t pending_grant_hand
   1.121  static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
   1.122  #endif
   1.123  
   1.124 -static int do_block_io_op(blkif_t *blkif, int max_to_do);
   1.125 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
   1.126 +static int do_block_io_op(blkif_t *blkif);
   1.127 +static void dispatch_rw_block_io(blkif_t *blkif,
   1.128 +				 blkif_request_t *req,
   1.129 +				 pending_req_t *pending_req);
   1.130  static void make_response(blkif_t *blkif, unsigned long id, 
   1.131                            unsigned short op, int st);
   1.132  
   1.133 -static void fast_flush_area(int idx, int nr_pages)
   1.134 +/******************************************************************
   1.135 + * misc small helpers
   1.136 + */
   1.137 +static pending_req_t* alloc_req(void)
   1.138 +{
   1.139 +	pending_req_t *req = NULL;
   1.140 +	unsigned long flags;
   1.141 +
   1.142 +	spin_lock_irqsave(&pending_free_lock, flags);
   1.143 +	if (!list_empty(&pending_free)) {
   1.144 +		req = list_entry(pending_free.next, pending_req_t, free_list);
   1.145 +		list_del(&req->free_list);
   1.146 +	}
   1.147 +	spin_unlock_irqrestore(&pending_free_lock, flags);
   1.148 +	return req;
   1.149 +}
   1.150 +
   1.151 +static void free_req(pending_req_t *req)
   1.152 +{
   1.153 +	unsigned long flags;
   1.154 +	int was_empty;
   1.155 +
   1.156 +	spin_lock_irqsave(&pending_free_lock, flags);
   1.157 +	was_empty = list_empty(&pending_free);
   1.158 +	list_add(&req->free_list, &pending_free);
   1.159 +	spin_unlock_irqrestore(&pending_free_lock, flags);
   1.160 +	if (was_empty)
   1.161 +		wake_up(&pending_free_wq);
   1.162 +}
   1.163 +
   1.164 +static void unplug_queue(blkif_t *blkif)
   1.165 +{
   1.166 +	if (blkif->plug == NULL)
   1.167 +		return;
   1.168 +	if (blkif->plug->unplug_fn)
   1.169 +		blkif->plug->unplug_fn(blkif->plug);
   1.170 +	blk_put_queue(blkif->plug);
   1.171 +	blkif->plug = NULL;
   1.172 +}
   1.173 +
   1.174 +static void plug_queue(blkif_t *blkif, struct bio *bio)
   1.175 +{
   1.176 +	request_queue_t *q = bdev_get_queue(bio->bi_bdev);
   1.177 +
   1.178 +	if (q == blkif->plug)
   1.179 +		return;
   1.180 +	unplug_queue(blkif);
   1.181 +	blk_get_queue(q);
   1.182 +	blkif->plug = q;
   1.183 +}
   1.184 +
   1.185 +static void fast_flush_area(pending_req_t *req)
   1.186  {
   1.187  	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   1.188  	unsigned int i, invcount = 0;
   1.189  	grant_handle_t handle;
   1.190  	int ret;
   1.191  
   1.192 -	for (i = 0; i < nr_pages; i++) {
   1.193 -		handle = pending_handle(idx, i);
   1.194 +	for (i = 0; i < req->nr_pages; i++) {
   1.195 +		handle = pending_handle(req, i);
   1.196  		if (handle == BLKBACK_INVALID_HANDLE)
   1.197  			continue;
   1.198 -		unmap[invcount].host_addr    = MMAP_VADDR(idx, i);
   1.199 +		unmap[invcount].host_addr    = vaddr(req, i);
   1.200  		unmap[invcount].dev_bus_addr = 0;
   1.201  		unmap[invcount].handle       = handle;
   1.202 -		pending_handle(idx, i) = BLKBACK_INVALID_HANDLE;
   1.203 +		pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
   1.204  		invcount++;
   1.205  	}
   1.206  
   1.207 @@ -133,118 +178,90 @@ static void fast_flush_area(int idx, int
   1.208  	BUG_ON(ret);
   1.209  }
   1.210  
   1.211 -
   1.212 -/******************************************************************
   1.213 - * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE
   1.214 - */
   1.215 -
   1.216 -static struct list_head blkio_schedule_list;
   1.217 -static spinlock_t blkio_schedule_list_lock;
   1.218 -
   1.219 -static int __on_blkdev_list(blkif_t *blkif)
   1.220 -{
   1.221 -	return blkif->blkdev_list.next != NULL;
   1.222 -}
   1.223 -
   1.224 -static void remove_from_blkdev_list(blkif_t *blkif)
   1.225 -{
   1.226 -	unsigned long flags;
   1.227 -
   1.228 -	if (!__on_blkdev_list(blkif))
   1.229 -		return;
   1.230 -
   1.231 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
   1.232 -	if (__on_blkdev_list(blkif)) {
   1.233 -		list_del(&blkif->blkdev_list);
   1.234 -		blkif->blkdev_list.next = NULL;
   1.235 -		blkif_put(blkif);
   1.236 -	}
   1.237 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
   1.238 -}
   1.239 -
   1.240 -static void add_to_blkdev_list_tail(blkif_t *blkif)
   1.241 -{
   1.242 -	unsigned long flags;
   1.243 -
   1.244 -	if (__on_blkdev_list(blkif))
   1.245 -		return;
   1.246 -
   1.247 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
   1.248 -	if (!__on_blkdev_list(blkif) && (blkif->status == CONNECTED)) {
   1.249 -		list_add_tail(&blkif->blkdev_list, &blkio_schedule_list);
   1.250 -		blkif_get(blkif);
   1.251 -	}
   1.252 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
   1.253 -}
   1.254 -
   1.255 -
   1.256  /******************************************************************
   1.257   * SCHEDULER FUNCTIONS
   1.258   */
   1.259  
   1.260 -static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait);
   1.261 -
   1.262 -static int blkio_schedule(void *arg)
   1.263 +static void print_stats(blkif_t *blkif)
   1.264  {
   1.265 -	DECLARE_WAITQUEUE(wq, current);
   1.266 +	printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d\n",
   1.267 +	       current->comm, blkif->st_oo_req,
   1.268 +	       blkif->st_rd_req, blkif->st_wr_req);
   1.269 +	blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
   1.270 +	blkif->st_rd_req = 0;
   1.271 +	blkif->st_wr_req = 0;
   1.272 +	blkif->st_oo_req = 0;
   1.273 +}
   1.274  
   1.275 -	blkif_t          *blkif;
   1.276 -	struct list_head *ent;
   1.277 +int blkif_schedule(void *arg)
   1.278 +{
   1.279 +	blkif_t          *blkif = arg;
   1.280  
   1.281 -	daemonize("xenblkd");
   1.282 -
   1.283 +	blkif_get(blkif);
   1.284 +	if (debug_lvl)
   1.285 +		printk(KERN_DEBUG "%s: started\n", current->comm);
   1.286  	for (;;) {
   1.287 -		/* Wait for work to do. */
   1.288 -		add_wait_queue(&blkio_schedule_wait, &wq);
   1.289 -		set_current_state(TASK_INTERRUPTIBLE);
   1.290 -		if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || 
   1.291 -		     list_empty(&blkio_schedule_list) )
   1.292 -			schedule();
   1.293 -		__set_current_state(TASK_RUNNING);
   1.294 -		remove_wait_queue(&blkio_schedule_wait, &wq);
   1.295 -
   1.296 -		/* Queue up a batch of requests. */
   1.297 -		while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
   1.298 -		       !list_empty(&blkio_schedule_list)) {
   1.299 -			ent = blkio_schedule_list.next;
   1.300 -			blkif = list_entry(ent, blkif_t, blkdev_list);
   1.301 -			blkif_get(blkif);
   1.302 -			remove_from_blkdev_list(blkif);
   1.303 -			if (do_block_io_op(blkif, BATCH_PER_DOMAIN))
   1.304 -				add_to_blkdev_list_tail(blkif);
   1.305 -			blkif_put(blkif);
   1.306 +		if (kthread_should_stop()) {
   1.307 +			/* asked to quit? */
   1.308 +			if (!atomic_read(&blkif->io_pending))
   1.309 +				break;
   1.310 +			if (debug_lvl)
   1.311 +				printk(KERN_DEBUG "%s: I/O pending, "
   1.312 +				       "delaying exit\n", current->comm);
   1.313  		}
   1.314  
   1.315 -		/* Push the batch through to disc. */
   1.316 -		flush_plugged_queue();
   1.317 -	}
   1.318 -}
   1.319 +		if (!atomic_read(&blkif->io_pending)) {
   1.320 +			/* Wait for work to do. */
   1.321 +			wait_event_interruptible(
   1.322 +				blkif->wq,
   1.323 +				(atomic_read(&blkif->io_pending) ||
   1.324 +				 kthread_should_stop()));
   1.325 +		} else if (list_empty(&pending_free)) {
   1.326 +			/* Wait for pending_req becoming available. */
   1.327 +			wait_event_interruptible(
   1.328 +				pending_free_wq,
   1.329 +				!list_empty(&pending_free));
   1.330 +		}
   1.331  
   1.332 -static void maybe_trigger_blkio_schedule(void)
   1.333 -{
   1.334 -	/*
   1.335 -	 * Needed so that two processes, which together make the following
   1.336 -	 * predicate true, don't both read stale values and evaluate the
   1.337 -	 * predicate incorrectly. Incredibly unlikely to stall the scheduler
   1.338 -	 * on x86, but...
   1.339 -	 */
   1.340 -	smp_mb();
   1.341 +		if (blkif->status != CONNECTED) {
   1.342 +			/* make sure we are connected */
   1.343 +			if (debug_lvl)
   1.344 +				printk(KERN_DEBUG "%s: not connected "
   1.345 +				       "(%d pending)\n",
   1.346 +				       current->comm,
   1.347 +				       atomic_read(&blkif->io_pending));
   1.348 +			wait_event_interruptible(
   1.349 +				blkif->wq,
   1.350 +				(blkif->status == CONNECTED ||
   1.351 +				 kthread_should_stop()));
   1.352 +			continue;
   1.353 +		}
   1.354  
   1.355 -	if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
   1.356 -	    !list_empty(&blkio_schedule_list))
   1.357 -		wake_up(&blkio_schedule_wait);
   1.358 +		/* Schedule I/O */
   1.359 +		atomic_set(&blkif->io_pending, 0);
   1.360 +		if (do_block_io_op(blkif))
   1.361 +			atomic_inc(&blkif->io_pending);
   1.362 +		unplug_queue(blkif);
   1.363 +
   1.364 +		if (log_stats && time_after(jiffies, blkif->st_print))
   1.365 +			print_stats(blkif);
   1.366 +	}
   1.367 +
   1.368 +	if (log_stats)
   1.369 +		print_stats(blkif);
   1.370 +	if (debug_lvl)
   1.371 +		printk(KERN_DEBUG "%s: exiting\n", current->comm);
   1.372 +	blkif->xenblkd = NULL;
   1.373 +	blkif_put(blkif);
   1.374 +	return 0;
   1.375  }
   1.376  
   1.377 -
   1.378 -
   1.379  /******************************************************************
   1.380   * COMPLETION CALLBACK -- Called as bh->b_end_io()
   1.381   */
   1.382  
   1.383  static void __end_block_io_op(pending_req_t *pending_req, int uptodate)
   1.384  {
   1.385 -	unsigned long flags;
   1.386 -
   1.387  	/* An error fails the entire request. */
   1.388  	if (!uptodate) {
   1.389  		DPRINTK("Buffer not up-to-date at end of operation\n");
   1.390 @@ -252,15 +269,11 @@ static void __end_block_io_op(pending_re
   1.391  	}
   1.392  
   1.393  	if (atomic_dec_and_test(&pending_req->pendcnt)) {
   1.394 -		int pending_idx = pending_req - pending_reqs;
   1.395 -		fast_flush_area(pending_idx, pending_req->nr_pages);
   1.396 +		fast_flush_area(pending_req);
   1.397  		make_response(pending_req->blkif, pending_req->id,
   1.398  			      pending_req->operation, pending_req->status);
   1.399  		blkif_put(pending_req->blkif);
   1.400 -		spin_lock_irqsave(&pend_prod_lock, flags);
   1.401 -		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   1.402 -		spin_unlock_irqrestore(&pend_prod_lock, flags);
   1.403 -		maybe_trigger_blkio_schedule();
   1.404 +		free_req(pending_req);
   1.405  	}
   1.406  }
   1.407  
   1.408 @@ -281,8 +294,9 @@ static int end_block_io_op(struct bio *b
   1.409  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
   1.410  {
   1.411  	blkif_t *blkif = dev_id;
   1.412 -	add_to_blkdev_list_tail(blkif);
   1.413 -	maybe_trigger_blkio_schedule();
   1.414 +
   1.415 +	atomic_inc(&blkif->io_pending);
   1.416 +	wake_up(&blkif->wq);
   1.417  	return IRQ_HANDLED;
   1.418  }
   1.419  
   1.420 @@ -292,10 +306,11 @@ irqreturn_t blkif_be_int(int irq, void *
   1.421   * DOWNWARD CALLS -- These interface with the block-device layer proper.
   1.422   */
   1.423  
   1.424 -static int do_block_io_op(blkif_t *blkif, int max_to_do)
   1.425 +static int do_block_io_op(blkif_t *blkif)
   1.426  {
   1.427  	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
   1.428  	blkif_request_t *req;
   1.429 +	pending_req_t *pending_req;
   1.430  	RING_IDX rc, rp;
   1.431  	int more_to_do = 0;
   1.432  
   1.433 @@ -304,8 +319,10 @@ static int do_block_io_op(blkif_t *blkif
   1.434  	rmb(); /* Ensure we see queued requests up to 'rp'. */
   1.435  
   1.436  	while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) {
   1.437 -		if ((max_to_do-- == 0) ||
   1.438 -		    (NR_PENDING_REQS == MAX_PENDING_REQS)) {
   1.439 +
   1.440 +		pending_req = alloc_req();
   1.441 +		if (NULL == pending_req) {
   1.442 +			blkif->st_oo_req++;
   1.443  			more_to_do = 1;
   1.444  			break;
   1.445  		}
   1.446 @@ -315,28 +332,31 @@ static int do_block_io_op(blkif_t *blkif
   1.447  
   1.448  		switch (req->operation) {
   1.449  		case BLKIF_OP_READ:
   1.450 +			blkif->st_rd_req++;
   1.451 +			dispatch_rw_block_io(blkif, req, pending_req);
   1.452 +			break;
   1.453  		case BLKIF_OP_WRITE:
   1.454 -			dispatch_rw_block_io(blkif, req);
   1.455 +			blkif->st_wr_req++;
   1.456 +			dispatch_rw_block_io(blkif, req, pending_req);
   1.457  			break;
   1.458 -
   1.459  		default:
   1.460  			DPRINTK("error: unknown block io operation [%d]\n",
   1.461  				req->operation);
   1.462  			make_response(blkif, req->id, req->operation,
   1.463  				      BLKIF_RSP_ERROR);
   1.464 +			free_req(pending_req);
   1.465  			break;
   1.466  		}
   1.467  	}
   1.468 -
   1.469  	return more_to_do;
   1.470  }
   1.471  
   1.472 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
   1.473 +static void dispatch_rw_block_io(blkif_t *blkif,
   1.474 +				 blkif_request_t *req,
   1.475 +				 pending_req_t *pending_req)
   1.476  {
   1.477  	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
   1.478  	int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
   1.479 -	int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
   1.480 -	pending_req_t *pending_req;
   1.481  	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   1.482  	struct phys_req preq;
   1.483  	struct { 
   1.484 @@ -344,32 +364,36 @@ static void dispatch_rw_block_io(blkif_t
   1.485  	} seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   1.486  	unsigned int nseg;
   1.487  	struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   1.488 -	int nbio = 0;
   1.489 -	request_queue_t *q;
   1.490 -	int ret, errors = 0;
   1.491 +	int ret, i, nbio = 0;
   1.492  
   1.493  	/* Check that number of segments is sane. */
   1.494  	nseg = req->nr_segments;
   1.495  	if (unlikely(nseg == 0) || 
   1.496  	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
   1.497  		DPRINTK("Bad number of segments in request (%d)\n", nseg);
   1.498 -		goto bad_descriptor;
   1.499 +		goto fail_response;
   1.500  	}
   1.501  
   1.502  	preq.dev           = req->handle;
   1.503  	preq.sector_number = req->sector_number;
   1.504  	preq.nr_sects      = 0;
   1.505  
   1.506 +	pending_req->blkif     = blkif;
   1.507 +	pending_req->id        = req->id;
   1.508 +	pending_req->operation = operation;
   1.509 +	pending_req->status    = BLKIF_RSP_OKAY;
   1.510 +	pending_req->nr_pages  = nseg;
   1.511 +
   1.512  	for (i = 0; i < nseg; i++) {
   1.513  		seg[i].nsec = req->seg[i].last_sect -
   1.514  			req->seg[i].first_sect + 1;
   1.515  
   1.516  		if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
   1.517  		    (seg[i].nsec <= 0))
   1.518 -			goto bad_descriptor;
   1.519 +			goto fail_response;
   1.520  		preq.nr_sects += seg[i].nsec;
   1.521  
   1.522 -		map[i].host_addr = MMAP_VADDR(pending_idx, i);
   1.523 +		map[i].host_addr = vaddr(pending_req, i);
   1.524  		map[i].dom = blkif->domid;
   1.525  		map[i].ref = req->seg[i].gref;
   1.526  		map[i].flags = GNTMAP_host_map;
   1.527 @@ -381,26 +405,22 @@ static void dispatch_rw_block_io(blkif_t
   1.528  	BUG_ON(ret);
   1.529  
   1.530  	for (i = 0; i < nseg; i++) {
   1.531 -		if (likely(map[i].status == 0)) {
   1.532 -			pending_handle(pending_idx, i) = map[i].handle;
   1.533 +		if (unlikely(map[i].status != 0)) {
   1.534 +			DPRINTK("invalid buffer -- could not remap it\n");
   1.535 +			goto fail_flush;
   1.536 +		}
   1.537 +
   1.538 +		pending_handle(pending_req, i) = map[i].handle;
   1.539  #ifdef __ia64__
   1.540 -			MMAP_VADDR(pending_idx,i) = gnttab_map_vaddr(map[i]);
   1.541 +		pending_vaddrs[vaddr_pagenr(pending_req, i)] =
   1.542 +			= gnttab_map_vaddr(map[i]);
   1.543  #else
   1.544 -			set_phys_to_machine(__pa(MMAP_VADDR(
   1.545 -				pending_idx, i)) >> PAGE_SHIFT,
   1.546 -				FOREIGN_FRAME(map[i].dev_bus_addr>>PAGE_SHIFT));
   1.547 +		set_phys_to_machine(__pa(vaddr(
   1.548 +			pending_req, i)) >> PAGE_SHIFT,
   1.549 +			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
   1.550  #endif
   1.551 -			seg[i].buf = map[i].dev_bus_addr |
   1.552 -				(req->seg[i].first_sect << 9);
   1.553 -		} else {
   1.554 -			errors++;
   1.555 -		}
   1.556 -	}
   1.557 -
   1.558 -	if (errors) {
   1.559 -		DPRINTK("invalid buffer -- could not remap it\n");
   1.560 -		fast_flush_area(pending_idx, nseg);
   1.561 -		goto bad_descriptor;
   1.562 +		seg[i].buf  = map[i].dev_bus_addr | 
   1.563 +			(req->seg[i].first_sect << 9);
   1.564  	}
   1.565  
   1.566  	if (vbd_translate(&preq, blkif, operation) != 0) {
   1.567 @@ -408,37 +428,25 @@ static void dispatch_rw_block_io(blkif_t
   1.568  			operation == READ ? "read" : "write",
   1.569  			preq.sector_number,
   1.570  			preq.sector_number + preq.nr_sects, preq.dev); 
   1.571 -		goto bad_descriptor;
   1.572 +		goto fail_flush;
   1.573  	}
   1.574  
   1.575 -	pending_req = &pending_reqs[pending_idx];
   1.576 -	pending_req->blkif     = blkif;
   1.577 -	pending_req->id        = req->id;
   1.578 -	pending_req->operation = operation;
   1.579 -	pending_req->status    = BLKIF_RSP_OKAY;
   1.580 -	pending_req->nr_pages  = nseg;
   1.581 -
   1.582  	for (i = 0; i < nseg; i++) {
   1.583  		if (((int)preq.sector_number|(int)seg[i].nsec) &
   1.584  		    ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) {
   1.585  			DPRINTK("Misaligned I/O request from domain %d",
   1.586  				blkif->domid);
   1.587 -			goto cleanup_and_fail;
   1.588 +			goto fail_put_bio;
   1.589  		}
   1.590  
   1.591  		while ((bio == NULL) ||
   1.592  		       (bio_add_page(bio,
   1.593 -				     virt_to_page(MMAP_VADDR(pending_idx, i)),
   1.594 +				     virt_to_page(vaddr(pending_req, i)),
   1.595  				     seg[i].nsec << 9,
   1.596  				     seg[i].buf & ~PAGE_MASK) == 0)) {
   1.597  			bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i);
   1.598 -			if (unlikely(bio == NULL)) {
   1.599 -			cleanup_and_fail:
   1.600 -				for (i = 0; i < (nbio-1); i++)
   1.601 -					bio_put(biolist[i]);
   1.602 -				fast_flush_area(pending_idx, nseg);
   1.603 -				goto bad_descriptor;
   1.604 -			}
   1.605 +			if (unlikely(bio == NULL))
   1.606 +				goto fail_put_bio;
   1.607                  
   1.608  			bio->bi_bdev    = preq.bdev;
   1.609  			bio->bi_private = pending_req;
   1.610 @@ -449,14 +457,8 @@ static void dispatch_rw_block_io(blkif_t
   1.611  		preq.sector_number += seg[i].nsec;
   1.612  	}
   1.613  
   1.614 -	if ((q = bdev_get_queue(bio->bi_bdev)) != plugged_queue) {
   1.615 -		flush_plugged_queue();
   1.616 -		blk_get_queue(q);
   1.617 -		plugged_queue = q;
   1.618 -	}
   1.619 -
   1.620 +	plug_queue(blkif, bio);
   1.621  	atomic_set(&pending_req->pendcnt, nbio);
   1.622 -	pending_cons++;
   1.623  	blkif_get(blkif);
   1.624  
   1.625  	for (i = 0; i < nbio; i++)
   1.626 @@ -464,8 +466,14 @@ static void dispatch_rw_block_io(blkif_t
   1.627  
   1.628  	return;
   1.629  
   1.630 - bad_descriptor:
   1.631 + fail_put_bio:
   1.632 +	for (i = 0; i < (nbio-1); i++)
   1.633 +		bio_put(biolist[i]);
   1.634 + fail_flush:
   1.635 +	fast_flush_area(pending_req);
   1.636 + fail_response:
   1.637  	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
   1.638 +	free_req(pending_req);
   1.639  } 
   1.640  
   1.641  
   1.642 @@ -481,6 +489,7 @@ static void make_response(blkif_t *blkif
   1.643  	blkif_response_t *resp;
   1.644  	unsigned long     flags;
   1.645  	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
   1.646 +	int more_to_do = 0;
   1.647  	int notify;
   1.648  
   1.649  	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
   1.650 @@ -499,76 +508,69 @@ static void make_response(blkif_t *blkif
   1.651  		 * notifications if requests are already in flight (lower
   1.652  		 * overheads and promotes batching).
   1.653  		 */
   1.654 -		int more_to_do;
   1.655  		RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
   1.656 -		if (more_to_do) {
   1.657 -			add_to_blkdev_list_tail(blkif);
   1.658 -			maybe_trigger_blkio_schedule();
   1.659 -		}
   1.660 +
   1.661 +	} else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
   1.662 +		more_to_do = 1;
   1.663 +
   1.664  	}
   1.665 -	else if (!__on_blkdev_list(blkif)
   1.666 -		 && RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
   1.667 -		/* Keep pulling requests as they become available... */
   1.668 -		add_to_blkdev_list_tail(blkif);
   1.669 -		maybe_trigger_blkio_schedule();
   1.670 -	}
   1.671 -
   1.672  	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
   1.673  
   1.674 +	if (more_to_do) {
   1.675 +		atomic_inc(&blkif->io_pending);
   1.676 +		wake_up(&blkif->wq);
   1.677 +	}
   1.678  	if (notify)
   1.679  		notify_remote_via_irq(blkif->irq);
   1.680  }
   1.681  
   1.682 -void blkif_deschedule(blkif_t *blkif)
   1.683 -{
   1.684 -	remove_from_blkdev_list(blkif);
   1.685 -}
   1.686 -
   1.687  static int __init blkif_init(void)
   1.688  {
   1.689 +	struct page *page;
   1.690  	int i;
   1.691 -	struct page *page;
   1.692 -	int ret;
   1.693 -
   1.694 -	for (i = 0; i < MMAP_PAGES; i++)
   1.695 -		pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
   1.696  
   1.697  	if (xen_init() < 0)
   1.698  		return -ENODEV;
   1.699  
   1.700 -	blkif_interface_init();
   1.701 -
   1.702 -#ifdef __ia64__
   1.703 -    {
   1.704 -	extern unsigned long alloc_empty_foreign_map_page_range(unsigned long pages);
   1.705 -	int i;
   1.706 +	mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
   1.707 +	pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
   1.708 +					blkif_reqs, GFP_KERNEL);
   1.709 +	pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
   1.710 +					mmap_pages, GFP_KERNEL);
   1.711 +	pending_vaddrs        = kmalloc(sizeof(pending_vaddrs[0]) *
   1.712 +					mmap_pages, GFP_KERNEL);
   1.713 +	if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
   1.714 +		printk("%s: out of memory\n", __FUNCTION__);
   1.715 +		return -1;
   1.716 +	}
   1.717  
   1.718 -	mmap_vstart =  alloc_empty_foreign_map_page_range(MMAP_PAGES);
   1.719 -	printk("Allocated mmap_vstart: 0x%lx\n", mmap_vstart);
   1.720 -	for(i = 0; i < MMAP_PAGES; i++)
   1.721 -	    pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
   1.722 -	BUG_ON(mmap_vstart == NULL);
   1.723 -    }
   1.724 -#else
   1.725 -	page = balloon_alloc_empty_page_range(MMAP_PAGES);
   1.726 +	blkif_interface_init();
   1.727 +	
   1.728 +#ifdef __ia64__
   1.729 +	extern unsigned long alloc_empty_foreign_map_page_range(
   1.730 +		unsigned long pages);
   1.731 +	mmap_vstart = (unsigned long)
   1.732 +		alloc_empty_foreign_map_page_range(mmap_pages);
   1.733 +#else /* ! ia64 */
   1.734 +	page = balloon_alloc_empty_page_range(mmap_pages);
   1.735  	BUG_ON(page == NULL);
   1.736  	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
   1.737  #endif
   1.738 +	printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
   1.739 +	       __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
   1.740 +	BUG_ON(mmap_vstart == 0);
   1.741 +	for (i = 0; i < mmap_pages; i++) {
   1.742 +		pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
   1.743 +		pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
   1.744 +	}
   1.745  
   1.746 -	pending_cons = 0;
   1.747 -	pending_prod = MAX_PENDING_REQS;
   1.748  	memset(pending_reqs, 0, sizeof(pending_reqs));
   1.749 -	for (i = 0; i < MAX_PENDING_REQS; i++)
   1.750 -		pending_ring[i] = i;
   1.751 +	INIT_LIST_HEAD(&pending_free);
   1.752 +
   1.753 +	for (i = 0; i < blkif_reqs; i++)
   1.754 +		list_add_tail(&pending_reqs[i].free_list, &pending_free);
   1.755      
   1.756 -	spin_lock_init(&blkio_schedule_list_lock);
   1.757 -	INIT_LIST_HEAD(&blkio_schedule_list);
   1.758 -
   1.759 -	ret = kernel_thread(blkio_schedule, NULL, CLONE_FS | CLONE_FILES);
   1.760 -	BUG_ON(ret < 0);
   1.761 -
   1.762  	blkif_xenbus_init();
   1.763 -
   1.764  	return 0;
   1.765  }
   1.766  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Dec 09 10:51:20 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Dec 09 10:51:35 2005 +0000
     2.3 @@ -60,10 +60,20 @@ typedef struct blkif_st {
     2.4  	/* Is this a blktap frontend */
     2.5  	unsigned int     is_blktap;
     2.6  #endif
     2.7 -	struct list_head blkdev_list;
     2.8  	spinlock_t       blk_ring_lock;
     2.9  	atomic_t         refcnt;
    2.10  
    2.11 +	wait_queue_head_t   wq;
    2.12 +	struct task_struct  *xenblkd;
    2.13 +	atomic_t            io_pending;
    2.14 +	request_queue_t     *plug;
    2.15 +
    2.16 +	/* statistics */
    2.17 +	unsigned long       st_print;
    2.18 +	int                 st_rd_req;
    2.19 +	int                 st_wr_req;
    2.20 +	int                 st_oo_req;
    2.21 +
    2.22  	struct work_struct free_work;
    2.23  
    2.24  	grant_handle_t shmem_handle;
    2.25 @@ -101,11 +111,10 @@ int vbd_translate(struct phys_req *req, 
    2.26  
    2.27  void blkif_interface_init(void);
    2.28  
    2.29 -void blkif_deschedule(blkif_t *blkif);
    2.30 -
    2.31  void blkif_xenbus_init(void);
    2.32  
    2.33  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
    2.34 +int blkif_schedule(void *arg);
    2.35  
    2.36  void update_blkif_status(blkif_t *blkif); 
    2.37  
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Dec 09 10:51:20 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Dec 09 10:51:35 2005 +0000
     3.3 @@ -24,6 +24,8 @@ blkif_t *alloc_blkif(domid_t domid)
     3.4  	blkif->status = DISCONNECTED;
     3.5  	spin_lock_init(&blkif->blk_ring_lock);
     3.6  	atomic_set(&blkif->refcnt, 1);
     3.7 +	init_waitqueue_head(&blkif->wq);
     3.8 +	blkif->st_print = jiffies;
     3.9  
    3.10  	return blkif;
    3.11  }
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Dec 09 10:51:20 2005 +0000
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Dec 09 10:51:35 2005 +0000
     4.3 @@ -20,6 +20,7 @@
     4.4  
     4.5  #include <stdarg.h>
     4.6  #include <linux/module.h>
     4.7 +#include <linux/kthread.h>
     4.8  #include <asm-xen/xenbus.h>
     4.9  #include "common.h"
    4.10  
    4.11 @@ -92,6 +93,8 @@ static int blkback_remove(struct xenbus_
    4.12  	}
    4.13  	if (be->blkif) {
    4.14  		be->blkif->status = DISCONNECTED; 
    4.15 +		if (be->blkif->xenblkd)
    4.16 +			kthread_stop(be->blkif->xenblkd);
    4.17  		blkif_put(be->blkif);
    4.18  		be->blkif = NULL;
    4.19  	}
    4.20 @@ -220,6 +223,17 @@ static void backend_changed(struct xenbu
    4.21  			return;
    4.22  		}
    4.23  
    4.24 +		be->blkif->xenblkd = kthread_run(blkif_schedule, be->blkif,
    4.25 +						 "xvd %d %02x:%02x",
    4.26 +						 be->blkif->domid,
    4.27 +						 be->major, be->minor);
    4.28 +		if (IS_ERR(be->blkif->xenblkd)) {
    4.29 +			err = PTR_ERR(be->blkif->xenblkd);
    4.30 +			be->blkif->xenblkd = NULL;
    4.31 +			xenbus_dev_error(dev, err, "start xenblkd");
    4.32 +			return;
    4.33 +		}
    4.34 +
    4.35  		device_create_file(&dev->dev, &dev_attr_physical_device);
    4.36  		device_create_file(&dev->dev, &dev_attr_mode);
    4.37  
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Fri Dec 09 10:51:20 2005 +0000
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Fri Dec 09 10:51:35 2005 +0000
     5.3 @@ -55,7 +55,8 @@ typedef struct netif_st {
     5.4  	/* The shared rings and indexes. */
     5.5  	netif_tx_back_ring_t tx;
     5.6  	netif_rx_back_ring_t rx;
     5.7 -	struct vm_struct *comms_area;
     5.8 +	struct vm_struct *tx_comms_area;
     5.9 +	struct vm_struct *rx_comms_area;
    5.10  
    5.11  	/* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */
    5.12  	RING_IDX rx_req_cons_peek;
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Fri Dec 09 10:51:20 2005 +0000
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Fri Dec 09 10:51:35 2005 +0000
     6.3 @@ -117,14 +117,14 @@ static int map_frontend_pages(
     6.4  	struct gnttab_map_grant_ref op;
     6.5  	int ret;
     6.6  
     6.7 -	op.host_addr = (unsigned long)netif->comms_area->addr;
     6.8 +	op.host_addr = (unsigned long)netif->tx_comms_area->addr;
     6.9  	op.flags     = GNTMAP_host_map;
    6.10  	op.ref       = tx_ring_ref;
    6.11  	op.dom       = netif->domid;
    6.12      
    6.13 -	lock_vm_area(netif->comms_area);
    6.14 +	lock_vm_area(netif->tx_comms_area);
    6.15  	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
    6.16 -	unlock_vm_area(netif->comms_area);
    6.17 +	unlock_vm_area(netif->tx_comms_area);
    6.18  	BUG_ON(ret);
    6.19  
    6.20  	if (op.status) { 
    6.21 @@ -135,14 +135,14 @@ static int map_frontend_pages(
    6.22  	netif->tx_shmem_ref    = tx_ring_ref;
    6.23  	netif->tx_shmem_handle = op.handle;
    6.24  
    6.25 -	op.host_addr = (unsigned long)netif->comms_area->addr + PAGE_SIZE;
    6.26 +	op.host_addr = (unsigned long)netif->rx_comms_area->addr;
    6.27  	op.flags     = GNTMAP_host_map;
    6.28  	op.ref       = rx_ring_ref;
    6.29  	op.dom       = netif->domid;
    6.30  
    6.31 -	lock_vm_area(netif->comms_area);
    6.32 +	lock_vm_area(netif->rx_comms_area);
    6.33  	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
    6.34 -	unlock_vm_area(netif->comms_area);
    6.35 +	unlock_vm_area(netif->rx_comms_area);
    6.36  	BUG_ON(ret);
    6.37  
    6.38  	if (op.status) {
    6.39 @@ -161,22 +161,22 @@ static void unmap_frontend_pages(netif_t
    6.40  	struct gnttab_unmap_grant_ref op;
    6.41  	int ret;
    6.42  
    6.43 -	op.host_addr    = (unsigned long)netif->comms_area->addr;
    6.44 +	op.host_addr    = (unsigned long)netif->tx_comms_area->addr;
    6.45  	op.handle       = netif->tx_shmem_handle;
    6.46  	op.dev_bus_addr = 0;
    6.47  
    6.48 -	lock_vm_area(netif->comms_area);
    6.49 +	lock_vm_area(netif->tx_comms_area);
    6.50  	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
    6.51 -	unlock_vm_area(netif->comms_area);
    6.52 +	unlock_vm_area(netif->tx_comms_area);
    6.53  	BUG_ON(ret);
    6.54  
    6.55 -	op.host_addr    = (unsigned long)netif->comms_area->addr + PAGE_SIZE;
    6.56 +	op.host_addr    = (unsigned long)netif->rx_comms_area->addr;
    6.57  	op.handle       = netif->rx_shmem_handle;
    6.58  	op.dev_bus_addr = 0;
    6.59  
    6.60 -	lock_vm_area(netif->comms_area);
    6.61 +	lock_vm_area(netif->rx_comms_area);
    6.62  	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
    6.63 -	unlock_vm_area(netif->comms_area);
    6.64 +	unlock_vm_area(netif->rx_comms_area);
    6.65  	BUG_ON(ret);
    6.66  }
    6.67  
    6.68 @@ -195,20 +195,23 @@ int netif_map(netif_t *netif, unsigned l
    6.69  	if (netif->irq)
    6.70  		return 0;
    6.71  
    6.72 -	netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
    6.73 -	if (netif->comms_area == NULL)
    6.74 +	netif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
    6.75 +	netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
    6.76 +	if (netif->tx_comms_area == NULL || netif->rx_comms_area == NULL)
    6.77  		return -ENOMEM;
    6.78  
    6.79  	err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
    6.80  	if (err) {
    6.81 -		free_vm_area(netif->comms_area);
    6.82 +		free_vm_area(netif->tx_comms_area);
    6.83 +		free_vm_area(netif->rx_comms_area);
    6.84  		return err;
    6.85  	}
    6.86  
    6.87  	err = HYPERVISOR_event_channel_op(&op);
    6.88  	if (err) {
    6.89  		unmap_frontend_pages(netif);
    6.90 -		free_vm_area(netif->comms_area);
    6.91 +		free_vm_area(netif->tx_comms_area);
    6.92 +		free_vm_area(netif->rx_comms_area);
    6.93  		return err;
    6.94  	}
    6.95  
    6.96 @@ -218,11 +221,11 @@ int netif_map(netif_t *netif, unsigned l
    6.97  		netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
    6.98  	disable_irq(netif->irq);
    6.99  
   6.100 -	txs = (netif_tx_sring_t *)netif->comms_area->addr;
   6.101 +	txs = (netif_tx_sring_t *)netif->tx_comms_area->addr;
   6.102  	BACK_RING_INIT(&netif->tx, txs, PAGE_SIZE);
   6.103  
   6.104  	rxs = (netif_rx_sring_t *)
   6.105 -		((char *)netif->comms_area->addr + PAGE_SIZE);
   6.106 +		((char *)netif->rx_comms_area->addr);
   6.107  	BACK_RING_INIT(&netif->rx, rxs, PAGE_SIZE);
   6.108  
   6.109  	netif->rx_req_cons_peek = 0;
   6.110 @@ -255,7 +258,8 @@ static void free_netif_callback(void *ar
   6.111  
   6.112  	if (netif->tx.sring) {
   6.113  		unmap_frontend_pages(netif);
   6.114 -		free_vm_area(netif->comms_area);
   6.115 +		free_vm_area(netif->tx_comms_area);
   6.116 +		free_vm_area(netif->rx_comms_area);
   6.117  	}
   6.118  
   6.119  	free_netdev(netif->dev);
     7.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 09 10:51:20 2005 +0000
     7.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 09 10:51:35 2005 +0000
     7.3 @@ -1171,11 +1171,6 @@ class XendDomainInfo:
     7.4  
     7.5              xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
     7.6  
     7.7 -            m = self.image.getDomainMemory(self.info['memory'] * 1024)
     7.8 -            balloon.free(m)
     7.9 -            xc.domain_setmaxmem(self.domid, m)
    7.10 -            xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
    7.11 -
    7.12              # repin domain vcpus if a restricted cpus list is provided
    7.13              # this is done prior to memory allocation to aide in memory
    7.14              # distribution for NUMA systems.
    7.15 @@ -1186,6 +1181,11 @@ class XendDomainInfo:
    7.16                      cpu = [ int( cpus[v % len(cpus)] ) ]
    7.17                      xc.domain_pincpu(self.domid, v, cpu)
    7.18  
    7.19 +            m = self.image.getDomainMemory(self.info['memory'] * 1024)
    7.20 +            balloon.free(m)
    7.21 +            xc.domain_setmaxmem(self.domid, m)
    7.22 +            xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
    7.23 +
    7.24              self.createChannels()
    7.25  
    7.26              channel_details = self.image.createImage()
     8.1 --- a/tools/python/xen/xend/server/tpmif.py	Fri Dec 09 10:51:20 2005 +0000
     8.2 +++ b/tools/python/xen/xend/server/tpmif.py	Fri Dec 09 10:51:35 2005 +0000
     8.3 @@ -38,10 +38,14 @@ class TPMifController(DevController):
     8.4      def getDeviceDetails(self, config):
     8.5          """@see DevController.getDeviceDetails"""
     8.6  
     8.7 -        devid = int(sxp.child_value(config, 'pref_instance', '0'))
     8.8 -        log.info("The domain has a TPM with instance %d." % devid)
     8.9 +        devid = self.allocateDeviceID()
    8.10 +        inst = int(sxp.child_value(config, 'pref_instance', '-1'))
    8.11 +        if inst == -1:
    8.12 +            inst = int(sxp.child_value(config, 'instance' , '0'))
    8.13  
    8.14 -        back  = { 'pref_instance' : "%i" % devid }
    8.15 +        log.info("The domain has a TPM with instance %d and devid %d.",
    8.16 +                 inst, devid)
    8.17 +        back  = { 'pref_instance' : "%i" % inst }
    8.18          front = { 'handle' : "%i" % devid }
    8.19  
    8.20          return (devid, back, front)
     9.1 --- a/tools/security/Makefile	Fri Dec 09 10:51:20 2005 +0000
     9.2 +++ b/tools/security/Makefile	Fri Dec 09 10:51:35 2005 +0000
     9.3 @@ -1,16 +1,19 @@
     9.4  XEN_ROOT = ../..
     9.5  include $(XEN_ROOT)/tools/Rules.mk
     9.6  
     9.7 -SRCS     = secpol_tool.c
     9.8  CFLAGS   += -Wall
     9.9  CFLAGS   += -Werror
    9.10  CFLAGS   += -O3
    9.11  CFLAGS   += -fno-strict-aliasing
    9.12 -CFLAGS   += -I. -I/usr/include/libxml2
    9.13 -CFLAGS_XML2BIN += $(shell xml2-config --cflags --libs )
    9.14 -#if above does not work, try  -L/usr/lib -lxml2 -lz -lpthread -lm
    9.15 +CFLAGS   += -I.
    9.16 +
    9.17 +CPPFLAGS += -MMD -MF .$*.d
    9.18 +PROG_DEPS = .*.d
    9.19 +
    9.20  XML2VERSION = $(shell xml2-config --version )
    9.21 -VALIDATE_SCHEMA=$(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else echo "-DVALIDATE_SCHEMA"; fi; )
    9.22 +CFLAGS     += $(shell xml2-config --cflags )
    9.23 +CFLAGS     += $(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else echo "-DVALIDATE_SCHEMA"; fi )
    9.24 +LDFLAGS    += $(shell xml2-config --libs ) # if this does not work, try -L/usr/lib -lxml2 -lz -lpthread -lm
    9.25  
    9.26  ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_NULL_POLICY)
    9.27  POLICY=null
    9.28 @@ -24,48 +27,71 @@ endif
    9.29  ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)
    9.30  POLICY=chwall_ste
    9.31  endif
    9.32 -POLICYFILE=./policies/$(POLICY)/$(POLICY).bin
    9.33 +
    9.34 +SRCS_TOOL     = secpol_tool.c
    9.35 +OBJS_TOOL    := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_TOOL)))
    9.36 +SRCS_XML2BIN  = secpol_xml2bin.c secpol_xml2bin.h
    9.37 +OBJS_XML2BIN := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_XML2BIN)))
    9.38 +SRCS_GETD     = get_decision.c
    9.39 +OBJS_GETD    := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_GETD)))
    9.40 +
    9.41 +ACM_INST_TOOLS    = xensec_tool xensec_xml2bin
    9.42 +ACM_NOINST_TOOLS  = get_decision
    9.43 +ACM_OBJS          = $(OBJS_TOOL) $(OBJS_XML2BIN) $(OBJS_GETD)
    9.44 +ACM_SCRIPTS       = getlabel.sh setlabel.sh updategrub.sh labelfuncs.sh
    9.45 +
    9.46 +ACM_CONFIG_DIR    = /etc/xen/acm-security
    9.47 +ACM_POLICY_DIR    = $(ACM_CONFIG_DIR)/policies
    9.48 +ACM_SCRIPT_DIR    = $(ACM_CONFIG_DIR)/scripts
    9.49 +
    9.50 +ACM_SCHEMA        = security_policy.xsd
    9.51 +ACM_EXAMPLES      = null chwall ste chwall_ste
    9.52 +ACM_POLICY_SUFFIX = security_policy.xml
    9.53 +ACM_LABEL_SUFFIX  = security_label_template.xml
    9.54  
    9.55  ifeq ($(ACM_SECURITY),y)
    9.56  all: build
    9.57  
    9.58 -install:all
    9.59 -
    9.60 -default:all
    9.61 +install: all $(ACM_CONFIG_FILE)
    9.62 +	$(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
    9.63 +	$(INSTALL_PROG) -p $(ACM_INST_TOOLS) $(DESTDIR)/usr/sbin
    9.64 +	$(INSTALL_DIR) -p $(DESTDIR)$(ACM_CONFIG_DIR)
    9.65 +	$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)
    9.66 +	$(INSTALL_DATA) -p policies/$(ACM_SCHEMA) $(DESTDIR)$(ACM_POLICY_DIR)
    9.67 +	for i in $(ACM_EXAMPLES); do \
    9.68 +		$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
    9.69 +		$(INSTALL_DATA) -p policies/$$i/$$i-$(ACM_POLICY_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
    9.70 +		$(INSTALL_DATA) -p policies/$$i/$$i-$(ACM_LABEL_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
    9.71 +	done
    9.72 +	$(INSTALL_DIR) -p $(DESTDIR)$(ACM_SCRIPT_DIR)
    9.73 +	$(INSTALL_PROG) -p $(ACM_SCRIPTS) $(DESTDIR)$(ACM_SCRIPT_DIR)
    9.74  else
    9.75  all:
    9.76  
    9.77  install:
    9.78 -
    9.79 -default:
    9.80  endif
    9.81  
    9.82 -build: mk-symlinks
    9.83 -	$(MAKE) secpol_tool
    9.84 -	$(MAKE) secpol_xml2bin
    9.85 -	$(MAKE) get_decision
    9.86 -	chmod 700 ./setlabel.sh
    9.87 -	chmod 700 ./updategrub.sh
    9.88 -	chmod 700 ./getlabel.sh
    9.89 +build: mk-symlinks $(ACM_INST_TOOLS) $(ACM_NOINST_TOOLS)
    9.90 +	chmod 700 $(ACM_SCRIPTS)
    9.91 +
    9.92 +xensec_tool: $(OBJS_TOOL)
    9.93 +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
    9.94  
    9.95 -secpol_tool : secpol_tool.c
    9.96 -	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
    9.97 +xensec_xml2bin: $(OBJS_XML2BIN)
    9.98 +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
    9.99  
   9.100 -secpol_xml2bin : secpol_xml2bin.c secpol_xml2bin.h
   9.101 -	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_XML2BIN) $(VALIDATE_SCHEMA) -o $@ $<
   9.102 +get_decision: $(OBJS_GETD)
   9.103 +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
   9.104  
   9.105  clean:
   9.106 -	rm -rf secpol_tool secpol_xml2bin xen get_decision
   9.107 -
   9.108 -policy_clean:
   9.109 -	rm -rf policies/*/*.bin policies/*/*.map
   9.110 -
   9.111 -mrproper: clean policy_clean
   9.112 +	$(RM) $(ACM_INST_TOOLS) $(ACM_NOINST_TOOLS)
   9.113 +	$(RM) $(ACM_OBJS)
   9.114 +	$(RM) $(PROG_DEPS)
   9.115 +	$(RM) -r xen
   9.116  
   9.117 -
   9.118 -$(POLICYFILE) : build
   9.119 -	@./secpol_xml2bin $(POLICY) > /dev/null
   9.120 +mrproper: clean
   9.121  
   9.122 -boot_install: $(POLICYFILE)
   9.123 -	@cp $(POLICYFILE) /boot
   9.124 -	@./updategrub.sh $(POLICY) $(PWD)/$(XEN_ROOT)
   9.125 +boot_install: install
   9.126 +	$(ACM_SCRIPT_DIR)/updategrub.sh $(POLICY) $(KERNEL_VERSION)
   9.127 +
   9.128 +-include $(PROG_DEPS)
    10.1 --- a/tools/security/example.txt	Fri Dec 09 10:51:20 2005 +0000
    10.2 +++ b/tools/security/example.txt	Fri Dec 09 10:51:35 2005 +0000
    10.3 @@ -9,23 +9,23 @@
    10.4  # and to label domains and resources.
    10.5  ##
    10.6  
    10.7 -We will show how to install and use the chwall_ste policy.
    10.8 +We will show how to install and use the example chwall_ste policy.
    10.9  Other policies work similarly. Feedback welcome!
   10.10  
   10.11  
   10.12  
   10.13 -1. Using secpol_xml2bin to translate the chwall_ste policy:
   10.14 +1. Using xensec_xml2bin to translate the chwall_ste policy:
   10.15  ===========================================================
   10.16  
   10.17 -#tools/security/secpol_xml2bin chwall_ste
   10.18 +#xensec_xml2bin chwall_ste
   10.19  
   10.20  Successful execution should print:
   10.21  
   10.22 -    [root@laptopxn security]# ./secpol_xml2bin chwall_ste
   10.23 -    Validating label file policies/chwall_ste/chwall_ste-security_label_template.xml...
   10.24 -    XML Schema policies/security_policy.xsd valid.
   10.25 -    Validating policy file policies/chwall_ste/chwall_ste-security_policy.xml...
   10.26 -    XML Schema policies/security_policy.xsd valid.
   10.27 +    [root@laptopxn security]# xensec_xml2bin chwall_ste
   10.28 +    Validating label file /etc/xen/acm-security/policies/chwall_ste/chwall_ste-security_label_template.xml...
   10.29 +    XML Schema /etc/xen/acm-security/policies/security_policy.xsd valid.
   10.30 +    Validating policy file /etc/xen/acm-security/policies/chwall_ste/chwall_ste-security_policy.xml...
   10.31 +    XML Schema /etc/xen/acm-security/policies/security_policy.xsd valid.
   10.32      Creating ssid mappings ...
   10.33      Creating label mappings ...
   10.34      Max chwall labels:  7
   10.35 @@ -35,10 +35,15 @@ Successful execution should print:
   10.36      Max ste-types:      6
   10.37      Max ste-ssids:      10
   10.38  
   10.39 -The tool looks in directory policies/chwall_ste for
   10.40 +By default, the tool looks in directory /etc/xen/acm-security/policies
   10.41 +for a directory that matches the policy name (i.e. chwall_ste) to find
   10.42  the label and policy files.
   10.43 +The '-d' option can be used to override the /etc/xen/acm-security/policies
   10.44 +directory, for example if running the tool in the Xen security tool build
   10.45 +directory.
   10.46  
   10.47 -The default policy directory structure under tools/security looks like:
   10.48 +The default policy directory structure under /etc/xen/acm-security (and
   10.49 +the Xen security tool build directory - tools/security) looks like:
   10.50  
   10.51  policies
   10.52  |-- security_policy.xsd
   10.53 @@ -55,25 +60,25 @@ policies
   10.54      |-- ste-security_label_template.xml
   10.55      `-- ste-security_policy.xml
   10.56  
   10.57 -policies/security_policy.xsd contains the schema against which both the
   10.58 +The security_policy.xsd file contains the schema against which both the
   10.59  label-template and the policy files must validate during translation.
   10.60  
   10.61 -policies/chwall_ste/chwall_ste-security_policy.xml defines the
   10.62 -policies and the types known to the policies.
   10.63 +The files ending in -security_policy.xml define the policies and the
   10.64 +types known to the policies.
   10.65  
   10.66 -policies/chwall_ste/chwall_ste-security_label_template.xml contains
   10.67 -label definitions that group chwall and ste types together and make
   10.68 -them easier to use for users
   10.69 +The files ending in -security_label_template.xml contain the label
   10.70 +definitions that group types together and make them easier to use for
   10.71 +users.
   10.72  
   10.73 -After executing the above secpol_xml2bin command, you will find 2 new
   10.74 -files in the policies/chwall_ste sub-directory:
   10.75 +After executing the above xensec_xml2bin command, you will find 2 new
   10.76 +files in the /etc/xen/acm-security/policies/chwall_ste sub-directory:
   10.77  
   10.78 -policies/chwall_ste/chwall_ste.map ... this file includes the mapping
   10.79 -of names from the xml files into their binary code representation.
   10.80 +  chwall_ste.map ... this file includes the mapping
   10.81 +    of names from the xml files into their binary code representation.
   10.82  
   10.83 -policies/chwall_ste/chwall_ste.bin ... this is the binary policy file,
   10.84 -the result of parsing the xml files and using the mapping to extract a
   10.85 -binary version that can be loaded into the hypervisor.
   10.86 +  chwall_ste.bin ... this is the binary policy file,
   10.87 +    the result of parsing the xml files and using the mapping to extract a
   10.88 +    binary version that can be loaded into the hypervisor.
   10.89  
   10.90  
   10.91  
   10.92 @@ -85,13 +90,13 @@ please refer to install.txt for instruct
   10.93  
   10.94  To activate the policy from the command line (assuming that the
   10.95  currently established policy is the minimal boot-policy that is
   10.96 -hard-coded into the hypervisor:
   10.97 +hard-coded into the hypervisor):
   10.98  
   10.99 -# ./secpol_tool loadpolicy policies/chwall_ste/chwall_ste.bin
  10.100 +# xensec_tool loadpolicy /etc/xen/acm-security/policies/chwall_ste/chwall_ste.bin
  10.101  
  10.102  To activate the policy at next reboot:
  10.103  
  10.104 -# cp policies/chwall_ste/chwall_ste.bin /boot
  10.105 +# cp /etc/xen/acm-security/policies/chwall_ste/chwall_ste.bin /boot
  10.106  
  10.107  Add a module line to your /boot/grub/grub.conf Xen entry.
  10.108  My boot entry with chwall_ste enabled looks like this:
  10.109 @@ -129,12 +134,12 @@ assign labels to user domains.
  10.110  
  10.111  To show available labels for the chwall_ste policy:
  10.112  
  10.113 -#tools/security/setlabel.sh -l
  10.114 +# /etc/xen/acm-security/scripts/setlabel.sh -l
  10.115  
  10.116  lists all available labels. For the default chwall_ste it should print
  10.117  the following:
  10.118  
  10.119 -    [root@laptopxn security]# ./setlabel.sh -l chwall_ste
  10.120 +    [root@laptopxn security]# /etc/xen/acm-security/scripts/setlabel.sh -l chwall_ste
  10.121      The following labels are available:
  10.122      dom_SystemManagement
  10.123      dom_HomeBanking
  10.124 @@ -156,8 +161,8 @@ Setlabel.sh only prints VM labels (which
  10.125  since only those are used at this time.
  10.126  
  10.127  If you would like to assign the dom_HomeBanking label to one of your
  10.128 -user domains (which you hopefully keep clean), look at an example
  10.129 -domain configuration homebanking.xm:
  10.130 +user domains (which you hopefully keep clean), look at the hypothetical
  10.131 +domain configuration contained in /etc/xen/homebanking.xm:
  10.132  
  10.133      #------HOMEBANKING---------
  10.134      kernel = "/boot/vmlinuz-2.6.12-xenU"
  10.135 @@ -172,7 +177,7 @@ domain configuration homebanking.xm:
  10.136  
  10.137  Now we label this domain
  10.138  
  10.139 -[root@laptopxn security]# ./setlabel.sh homebanking.xm dom_HomeBanking chwall_ste
  10.140 +[root@laptopxn security]# /etc/xen/acm-securit/scripts/setlabel.sh /etc/xen/homebanking.xm dom_HomeBanking chwall_ste
  10.141  Mapped label 'dom_HomeBanking' to ssidref '0x00020002'.
  10.142  
  10.143  The domain configuration my look now like:
  10.144 @@ -223,9 +228,8 @@ because of the defined conflict set
  10.145  				<type>cw_Distrusted</type>
  10.146  			</conflictset>
  10.147  
  10.148 -(in policies/chwall_ste/chwall_ste-security_policy.xml), which says
  10.149 -that only one of the types cw_sensitive and cw_Distrusted can run at a
  10.150 -time.
  10.151 +(in chwall_ste-security_policy.xml), which says that only one of the
  10.152 +types cw_Sensitive and cw_Distrusted can run at a time.
  10.153  
  10.154  If you save or shutdown the HomeBanking domain, you will be able to
  10.155  start the "Fun" domain. You can look into the Xen log to see if a
  10.156 @@ -255,15 +259,15 @@ a) the policy definition (types etc.) fi
  10.157  b) the label template definition (labels etc.) file
  10.158  
  10.159  If your policy name is "mypolicy", you need to create a
  10.160 -subdirectory mypolicy in tools/security/policies.
  10.161 +subdirectory mypolicy in /etc/xen/acm-security/policies.
  10.162  
  10.163  Then you create
  10.164 -tools/security/policies/mypolicy/mypolicy-security_policy.xml and
  10.165 -tools/security/policies/mypolicy/mypolicy-security_label_template.xml.
  10.166 +/etc/xen/acm-security/policies/mypolicy/mypolicy-security_policy.xml and
  10.167 +/etc/xen/acm-security/policies/mypolicy/mypolicy-security_label_template.xml.
  10.168  
  10.169  You need to keep to the schema as defined in
  10.170 -tools/security/security_policy.xsd since the translation tool
  10.171 -secpol_xml2bin is written against this schema.
  10.172 +/etc/xen/acm-security/security_policy.xsd since the translation tool
  10.173 +xensec_xml2bin is written against this schema.
  10.174  
  10.175  If you keep to the security policy schema, then you can use all the
  10.176  tools described above. Refer to install.txt to install it.
    11.1 --- a/tools/security/getlabel.sh	Fri Dec 09 10:51:20 2005 +0000
    11.2 +++ b/tools/security/getlabel.sh	Fri Dec 09 10:51:35 2005 +0000
    11.3 @@ -32,20 +32,24 @@ fi
    11.4  
    11.5  
    11.6  export PATH=$PATH:.
    11.7 -source labelfuncs.sh
    11.8 +dir=`dirname $0`
    11.9 +source $dir/labelfuncs.sh
   11.10  
   11.11  usage ()
   11.12  {
   11.13 +	prg=`basename $0`
   11.14  echo "Use this tool to display the label of a domain or the label that is
   11.15  corresponding to an ssidref given the name of the running policy.
   11.16  
   11.17 -Usage: $0 -sid <ssidref> [<policy name>] or
   11.18 -       $0 -dom <domid>   [<policy name>]
   11.19 +Usage: $prg -sid <ssidref> [<policy name> [<policy dir>]] or
   11.20 +       $prg -dom <domid>   [<policy name> [<policy dir>]]
   11.21  
   11.22  policy name : the name of the policy, i.e. 'chwall'
   11.23                If the policy name is omitted, the grub.conf
   11.24                entry of the running system is tried to be read
   11.25                and the policy name determined from there.
   11.26 +policy dir  : the directory where the <policy name> policy is located
   11.27 +              The default location is '/etc/xen/acm-security/policies'
   11.28  ssidref     : an ssidref in hex or decimal format, i.e., '0x00010002'
   11.29                or '65538'
   11.30  domid       : id of the domain, i.e., '1'; Use numbers from the 2nd
   11.31 @@ -55,79 +59,36 @@ domid       : id of the domain, i.e., '1
   11.32  
   11.33  
   11.34  
   11.35 -if [ "$1" == "-?" ]; then
   11.36 -	mode="usage"
   11.37 +if [ "$1" == "-h" ]; then
   11.38 +	usage
   11.39 +	exit 0
   11.40  elif [ "$1" == "-dom" ]; then
   11.41  	mode="domid"
   11.42  	shift
   11.43  elif [ "$1" == "-sid" ]; then
   11.44  	mode="sid"
   11.45  	shift
   11.46 -elif [ "$1" == "" ]; then
   11.47 +else
   11.48  	usage
   11.49  	exit -1
   11.50  fi
   11.51  
   11.52 +setPolicyVars $2 $3
   11.53 +findMapFile $policy $policydir
   11.54 +ret=$?
   11.55 +if [ $ret -eq 0 ]; then
   11.56 +	echo "Could not find map file for policy '$policy'."
   11.57 +	exit -1
   11.58 +fi
   11.59  
   11.60 -if [ "$mode" == "usage" ]; then
   11.61 -	usage
   11.62 -elif [ "$mode" == "domid" ]; then
   11.63 -	if [ "$2" == "" ]; then
   11.64 -		findGrubConf
   11.65 -		ret=$?
   11.66 -		if [ $ret -eq 0 ]; then
   11.67 -			echo "Could not find grub.conf"
   11.68 -			exit -1;
   11.69 -		fi
   11.70 -		findPolicyInGrub $grubconf
   11.71 -		if [ "$policy" != "" ]; then
   11.72 -			echo "Assuming policy to be '$policy'.";
   11.73 -		else
   11.74 -			echo "Could not find policy."
   11.75 -			exit -1;
   11.76 -		fi
   11.77 -	else
   11.78 -		policy=$2
   11.79 +if [ "$mode" == "domid" ]; then
   11.80 +	getSSIDUsingSecpolTool $1
   11.81 +	ret=$?
   11.82 +	if [ $ret -eq 0 ]; then
   11.83 +		echo "Could not determine the SSID of the domain."
   11.84 +		exit -1
   11.85  	fi
   11.86 -	findMapFile $policy
   11.87 -	res=$?
   11.88 -	if [ "$res" != "0" ]; then
   11.89 -		getSSIDUsingSecpolTool $1
   11.90 -		res=$?
   11.91 -		if [ "$res" != "0" ]; then
   11.92 -			translateSSIDREF $ssid $mapfile
   11.93 -		else
   11.94 -			echo "Could not determine the SSID of the domain."
   11.95 -		fi
   11.96 -	else
   11.97 -		echo "Could not find map file for policy '$policy'."
   11.98 -	fi
   11.99 -elif [ "$mode" == "sid" ]; then
  11.100 -	if [ "$2" == "" ]; then
  11.101 -		findGrubConf
  11.102 -		ret=$?
  11.103 -		if [ $ret -eq 0 ]; then
  11.104 -			echo "Could not find grub.conf"
  11.105 -			exit -1;
  11.106 -		fi
  11.107 -		findPolicyInGrub $grubconf
  11.108 -		if [ "$policy" != "" ]; then
  11.109 -			echo "Assuming policy to be '$policy'.";
  11.110 -		else
  11.111 -			echo "Could not find policy."
  11.112 -			exit -1;
  11.113 -		fi
  11.114 -	else
  11.115 -		policy=$2
  11.116 -	fi
  11.117 -	findMapFile $policy
  11.118 -	res=$?
  11.119 -	if [ "$res" != "0" ]; then
  11.120 -		translateSSIDREF $1 $mapfile
  11.121 -	else
  11.122 -		echo "Could not find map file for policy '$policy'."
  11.123 -	fi
  11.124 -
  11.125 -else
  11.126 -    usage
  11.127 +	translateSSIDREF $ssid $mapfile
  11.128 +else # mode == sid
  11.129 +	translateSSIDREF $1 $mapfile
  11.130  fi
    12.1 --- a/tools/security/install.txt	Fri Dec 09 10:51:20 2005 +0000
    12.2 +++ b/tools/security/install.txt	Fri Dec 09 10:51:35 2005 +0000
    12.3 @@ -41,11 +41,11 @@ 2. compile the policy from xml to a bina
    12.4         # make
    12.5  
    12.6         manual steps (alternative to make boot_install):
    12.7 -       #./secpol_xml2bin chwall_ste
    12.8 -       #cp policies/chwall_ste/chwall_ste.bin /boot
    12.9 -       #edit /boot/grub/grub.conf
   12.10 +       # ./xensec_xml2bin -d policies/ chwall_ste
   12.11 +       # cp policies/chwall_ste/chwall_ste.bin /boot
   12.12 +       # edit /boot/grub/grub.conf
   12.13          add the follwoing line to your xen boot entry:
   12.14 -       "module chwall_ste.bin"
   12.15 +       "module /boot/chwall_ste.bin"
   12.16  
   12.17         alternatively, you can try our automatic translation and
   12.18         installation of the policy:
   12.19 @@ -61,9 +61,9 @@ 2. compile the policy from xml to a bina
   12.20  3. reboot into the newly compiled hypervisor
   12.21  
   12.22          after boot
   12.23 -	#xm dmesg should show an entry about the policy being loaded
   12.24 +	# xm dmesg should show an entry about the policy being loaded
   12.25              during the boot process
   12.26  
   12.27 -        #tools/security/secpol_tool getpolicy
   12.28 +        # xensec_tool getpolicy
   12.29              should print the new chwall_ste binary policy representation
   12.30  
    13.1 --- a/tools/security/labelfuncs.sh	Fri Dec 09 10:51:20 2005 +0000
    13.2 +++ b/tools/security/labelfuncs.sh	Fri Dec 09 10:51:35 2005 +0000
    13.3 @@ -17,10 +17,53 @@
    13.4  #
    13.5  
    13.6  
    13.7 +#Some global variables for tools using this module
    13.8 +ACM_DEFAULT_ROOT="/etc/xen/acm-security"
    13.9 +
   13.10 +# Set the policy and policydir variables
   13.11 +# Parameters:
   13.12 +# 1st : possible policy name
   13.13 +# 2nd : possible policy directory
   13.14 +# Results:
   13.15 +# The variables policy and policydir will hold the values for locating
   13.16 +# policy information
   13.17 +# If there are no errors, the functions returns a '1',
   13.18 +# a '0' otherwise.
   13.19 +setPolicyVars ()
   13.20 +{
   13.21 +	local ret
   13.22 +	# Set default values
   13.23 +	policydir="$ACM_DEFAULT_ROOT/policies"
   13.24 +	policy=""
   13.25 +
   13.26 +	if [ "$1" == "" ]; then
   13.27 +		findGrubConf
   13.28 +		ret=$?
   13.29 +		if [ $ret -eq 0 ]; then
   13.30 +			echo "Could not find grub.conf."
   13.31 +			return 0;
   13.32 +		fi
   13.33 +		findPolicyInGrub $grubconf
   13.34 +		if [ "$policy" == "" ]; then
   13.35 +			echo "Could not find policy in grub.conf. Looked for entry using kernel $linux."
   13.36 +			return 0;
   13.37 +		fi
   13.38 +		echo "Assuming policy to be '$policy'.";
   13.39 +	else
   13.40 +		policy=$1
   13.41 +		if [ "$2" != "" ]; then
   13.42 +			policydir=$2
   13.43 +		fi
   13.44 +	fi
   13.45 +
   13.46 +	return 1
   13.47 +}
   13.48 +
   13.49  # Find the mapfile given a policy nmame
   13.50  # Parameters:
   13.51  # 1st : the name of the policy whose map file is to be found, i.e.,
   13.52  #       chwall
   13.53 +# 2nd : the policy directory for locating the map file
   13.54  # Results:
   13.55  # The variable mapfile will hold the realtive path to the mapfile
   13.56  # for the given policy.
   13.57 @@ -28,16 +71,10 @@
   13.58  # a '0' otherwise.
   13.59  findMapFile ()
   13.60  {
   13.61 -	mapfile="./$1.map"
   13.62 +	mapfile="$2/$1/$1.map"
   13.63  	if [ -r "$mapfile" ]; then
   13.64  		return 1
   13.65  	fi
   13.66 -
   13.67 -	mapfile="./policies/$1/$1.map"
   13.68 -	if [ -r "$mapfile" ]; then
   13.69 -		return 1
   13.70 -	fi
   13.71 -
   13.72  	return 0
   13.73  }
   13.74  
   13.75 @@ -50,7 +87,7 @@ findMapFile ()
   13.76  # The variable primary will hold the name of the primary policy
   13.77  getPrimaryPolicy ()
   13.78  {
   13.79 -	mapfile=$1
   13.80 +	local mapfile=$1
   13.81  	primary=`cat $mapfile  |   \
   13.82  	         awk '             \
   13.83  	          {                \
   13.84 @@ -71,7 +108,7 @@ getPrimaryPolicy ()
   13.85  # The variable secondary will hold the name of the secondary policy
   13.86  getSecondaryPolicy ()
   13.87  {
   13.88 -	mapfile=$1
   13.89 +	local mapfile=$1
   13.90  	secondary=`cat $mapfile  |   \
   13.91  	         awk '             \
   13.92  	          {                \
   13.93 @@ -86,6 +123,10 @@ getSecondaryPolicy ()
   13.94  
   13.95  #Return where the grub.conf file is.
   13.96  #I only know of one place it can be.
   13.97 +#Returns:
   13.98 +# 1 : if the file is writeable and readable
   13.99 +# 2 : if the file is only readable
  13.100 +# 0 : if the file does not exist
  13.101  findGrubConf()
  13.102  {
  13.103  	grubconf="/boot/grub/grub.conf"
  13.104 @@ -112,16 +153,37 @@ findGrubConf()
  13.105  # kernel, i.e., 'vmlinuz-2.6.12-xen0'
  13.106  getLinuxVersion ()
  13.107  {
  13.108 -	path=$1
  13.109 +	local path
  13.110 +	local versionfile
  13.111 +	local lnx
  13.112 +	if [ "$1" == "" ]; then
  13.113 +		path="/lib/modules/*-xen0"
  13.114 +	else
  13.115 +		path="/lib/modules/$1"
  13.116 +	fi
  13.117 +
  13.118  	linux=""
  13.119  	for f in $path/linux-*-xen0 ; do
  13.120 -		versionfile=$f/include/linux/version.h
  13.121 +		versionfile=$f/build/include/linux/version.h
  13.122  		if [ -r $versionfile ]; then
  13.123  			lnx=`cat $versionfile | \
  13.124  			     grep UTS_RELEASE | \
  13.125  			     awk '{             \
  13.126  			       len=length($3);  \
  13.127 -			       print substr($3,2,len-2) }'`
  13.128 +			       version=substr($3,2,len-2);     \
  13.129 +			       split(version,numbers,".");     \
  13.130 +			       if (numbers[4]=="") {           \
  13.131 +			         printf("%s.%s.%s",            \
  13.132 +			                 numbers[1],           \
  13.133 +			                 numbers[2],           \
  13.134 +			                 numbers[3]);          \
  13.135 +			       } else {                        \
  13.136 +			         printf("%s.%s.%s[.0-9]*-xen0",\
  13.137 +			                numbers[1],            \
  13.138 +			                numbers[2],            \
  13.139 +			                numbers[3]);           \
  13.140 +			       }                               \
  13.141 +			     }'`
  13.142  		fi
  13.143  		if [ "$lnx" != "" ]; then
  13.144  			linux="[./0-9a-zA-z]*$lnx"
  13.145 @@ -137,11 +199,12 @@ getLinuxVersion ()
  13.146  # Find out with which policy the hypervisor was booted with.
  13.147  # Parameters
  13.148  # 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
  13.149 -#
  13.150 +# Result:
  13.151 +# Sets the variable 'policy' to the name of the policy
  13.152  findPolicyInGrub ()
  13.153  {
  13.154 -	grubconf=$1
  13.155 -	linux=`uname -r`
  13.156 +	local grubconf=$1
  13.157 +	local linux=`uname -r`
  13.158  	policy=`cat $grubconf |                        \
  13.159  	         awk -vlinux=$linux '{                 \
  13.160  	           if ( $1 == "title" ) {              \
  13.161 @@ -184,9 +247,9 @@ findPolicyInGrub ()
  13.162  # The funtion returns '1' on success, '0' on failure
  13.163  getSSIDUsingSecpolTool ()
  13.164  {
  13.165 -	domid=$1
  13.166 +	local domid=$1
  13.167  	export PATH=$PATH:.
  13.168 -	ssid=`secpol_tool getssid -d $domid -f | \
  13.169 +	ssid=`xensec_tool getssid -d $domid -f | \
  13.170  	        grep -E "SSID:" |          \
  13.171  	        awk '{ print $4 }'`
  13.172  
  13.173 @@ -206,7 +269,7 @@ getSSIDUsingSecpolTool ()
  13.174  # high ssid values as integers.
  13.175  getSSIDLOHI ()
  13.176  {
  13.177 -	ssid=$1
  13.178 +	local ssid=$1
  13.179  	ssidlo_int=`echo $ssid | awk          \
  13.180  	            '{                        \
  13.181  	               len=length($0);        \
  13.182 @@ -289,11 +352,11 @@ getSSIDLOHI ()
  13.183  #
  13.184  updateGrub ()
  13.185  {
  13.186 -	grubconf=$1
  13.187 -	policyfile=$2
  13.188 -	linux=$3
  13.189 +	local grubconf=$1
  13.190 +	local policyfile=$2
  13.191 +	local linux=$3
  13.192  
  13.193 -	tmpfile="/tmp/new_grub.conf"
  13.194 +	local tmpfile="/tmp/new_grub.conf"
  13.195  
  13.196  	cat $grubconf |                                \
  13.197  	         awk -vpolicy=$policyfile              \
  13.198 @@ -343,7 +406,59 @@ updateGrub ()
  13.199  		echo "Could not create temporary file! Aborting."
  13.200  		exit -1
  13.201  	fi
  13.202 -	mv -f $tmpfile $grubconf
  13.203 +	diff $tmpfile $grubconf > /dev/null
  13.204 +	RES=$?
  13.205 +	if [ "$RES" == "0" ]; then
  13.206 +		echo "No changes were made to $grubconf."
  13.207 +	else
  13.208 +		echo "Successfully updated $grubconf."
  13.209 +		mv -f $tmpfile $grubconf
  13.210 +	fi
  13.211 +}
  13.212 +
  13.213 +
  13.214 +#Compile a policy into its binary representation
  13.215 +# Parameters:
  13.216 +# 1st: The directory where the ./policies directory is located at
  13.217 +# 2nd: The name of the policy
  13.218 +genBinPolicy ()
  13.219 +{
  13.220 +	local root=$1
  13.221 +	local policy=$2
  13.222 +	pushd $root > /dev/null
  13.223 +	xensec_xml2bin -d policies $policy > /dev/null
  13.224 +	popd > /dev/null
  13.225 +}
  13.226 +
  13.227 +
  13.228 +# Copy the bootpolicy into the destination directory
  13.229 +# Generate the policy's .bin and .map files if necessary
  13.230 +# Parameters:
  13.231 +# 1st: Destination directory
  13.232 +# 2nd: The root directory of the security tools; this is where the
  13.233 +#      policies directory is located at
  13.234 +# 3rd: The policy name
  13.235 +# Returns  '1' on success, '0' on failure.
  13.236 +cpBootPolicy ()
  13.237 +{
  13.238 +	local dest=$1
  13.239 +	local root=$2
  13.240 +	local policy=$3
  13.241 +	local binfile=$root/policies/$policy/$policy.bin
  13.242 +	local dstfile=$dest/$policy.bin
  13.243 +	if [ ! -e $binfile ]; then
  13.244 +		genBinPolicy $root $policy
  13.245 +		if [ ! -e $binfile ]; then
  13.246 +			echo "Could not compile policy '$policy'."
  13.247 +			return 0
  13.248 +		fi
  13.249 +	fi
  13.250 +
  13.251 +	if [ ! -e $dstfile -o \
  13.252 +	     $binfile -nt $dstfile ]; then
  13.253 +		cp -f $binfile $dstfile
  13.254 +	fi
  13.255 +	return 1
  13.256  }
  13.257  
  13.258  
  13.259 @@ -352,7 +467,11 @@ updateGrub ()
  13.260  # 1st: Full or relative path to the policy's mapfile
  13.261  showLabels ()
  13.262  {
  13.263 -	mapfile=$1
  13.264 +	local mapfile=$1
  13.265 +	local line
  13.266 +	local ITEM
  13.267 +	local found=0
  13.268 +
  13.269  	if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
  13.270  		echo "Cannot read from vm configuration file $vmfile."
  13.271  		return -1
  13.272 @@ -417,8 +536,8 @@ showLabels ()
  13.273  # 2nd: the name of the policy
  13.274  getDefaultSsid ()
  13.275  {
  13.276 -	mapfile=$1
  13.277 -	pol=$2
  13.278 +	local mapfile=$1
  13.279 +	local pol=$2
  13.280  	RES=`cat $mapfile    \
  13.281  	     awk -vpol=$pol  \
  13.282  	      {              \
  13.283 @@ -446,10 +565,13 @@ getDefaultSsid ()
  13.284  #      other     : Prompts the user whether to proceed
  13.285  relabel ()
  13.286  {
  13.287 -	vmfile=$1
  13.288 -	label=$2
  13.289 -	mapfile=$3
  13.290 -	mode=$4
  13.291 +	local vmfile=$1
  13.292 +	local label=$2
  13.293 +	local mapfile=$3
  13.294 +	local mode=$4
  13.295 +	local SSIDLO
  13.296 +	local SSIDHI
  13.297 +	local RES
  13.298  
  13.299  	if [ ! -r "$vmfile" ]; then
  13.300  		echo "Cannot read from vm configuration file $vmfile."
  13.301 @@ -556,8 +678,8 @@ relabel ()
  13.302  	fi
  13.303  
  13.304  	#Write the output
  13.305 -	vmtmp1="/tmp/__setlabel.tmp1"
  13.306 -	vmtmp2="/tmp/__setlabel.tmp2"
  13.307 +	local vmtmp1="/tmp/__setlabel.tmp1"
  13.308 +	local vmtmp2="/tmp/__setlabel.tmp2"
  13.309  	touch $vmtmp1
  13.310  	touch $vmtmp2
  13.311  	if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
  13.312 @@ -584,8 +706,10 @@ relabel ()
  13.313  # 2nd: Full or relative path to the policy's mapfile
  13.314  translateSSIDREF ()
  13.315  {
  13.316 -	ssidref=$1
  13.317 -	mapfile=$2
  13.318 +	local ssidref=$1
  13.319 +	local mapfile=$2
  13.320 +	local line1
  13.321 +	local line2
  13.322  
  13.323  	if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
  13.324  		echo "Cannot read from vm configuration file $vmfile."
    14.1 --- a/tools/security/secpol_tool.c	Fri Dec 09 10:51:20 2005 +0000
    14.2 +++ b/tools/security/secpol_tool.c	Fri Dec 09 10:51:35 2005 +0000
    14.3 @@ -44,12 +44,13 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)
    14.4  
    14.5  void usage(char *progname)
    14.6  {
    14.7 -    printf("Use: %s \n"
    14.8 +    printf("Usage: %s ACTION\n"
    14.9 +           "ACTION is one of:\n"
   14.10             "\t getpolicy\n"
   14.11             "\t dumpstats\n"
   14.12             "\t loadpolicy <binary policy file>\n"
   14.13             "\t getssid -d <domainid> [-f]\n"
   14.14 -		   "\t getssid -s <ssidref> [-f]\n", progname);
   14.15 +           "\t getssid -s <ssidref> [-f]\n", progname);
   14.16      exit(-1);
   14.17  }
   14.18  
   14.19 @@ -85,6 +86,7 @@ static inline int do_acm_op(int xc_handl
   14.20  
   14.21      if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
   14.22      {
   14.23 +        printf( "ACM operation failed: errno=%d\n", errno );
   14.24          if (errno == EACCES)
   14.25              fprintf(stderr, "ACM operation failed -- need to"
   14.26                      " rebuild the user-space tool set?\n");
    15.1 --- a/tools/security/secpol_xml2bin.c	Fri Dec 09 10:51:20 2005 +0000
    15.2 +++ b/tools/security/secpol_xml2bin.c	Fri Dec 09 10:51:35 2005 +0000
    15.3 @@ -17,7 +17,7 @@
    15.4   * sHype policy translation tool. This tool takes an XML
    15.5   * policy specification as input and produces a binary
    15.6   * policy file that can be loaded into Xen through the
    15.7 - * ACM operations (secpol_tool loadpolicy) interface or at
    15.8 + * ACM operations (xensec_tool loadpolicy) interface or at
    15.9   * boot time (grub module parameter)
   15.10   *
   15.11   * indent -i4 -kr -nut
   15.12 @@ -102,12 +102,22 @@ int have_chwall = 0;
   15.13  /* input/output file names */
   15.14  char *policy_filename = NULL,
   15.15      *label_filename = NULL,
   15.16 -    *binary_filename = NULL, *mapping_filename = NULL;
   15.17 +    *binary_filename = NULL, *mapping_filename = NULL,
   15.18 +    *schema_filename = NULL;
   15.19  
   15.20  void usage(char *prg)
   15.21  {
   15.22 -    printf("usage:\n%s policyname[-policy.xml/-security_label_template.xml]\n",
   15.23 -         prg);
   15.24 +    printf("Usage: %s [OPTIONS] POLICYNAME\n", prg);
   15.25 +    printf("POLICYNAME is the directory name within the policy directory\n");
   15.26 +    printf("that contains the policy files.  The default policy directory\n");
   15.27 +    printf("is '%s' (see the '-d' option below to change it)\n", POLICY_DIR);
   15.28 +    printf("The policy files contained in the POLICYNAME directory must be named:\n");
   15.29 +    printf("\tPOLICYNAME-security_policy.xml\n");
   15.30 +    printf("\tPOLICYNAME-security_label_template.xml\n\n");
   15.31 +    printf("OPTIONS:\n");
   15.32 +    printf("\t-d POLICYDIR\n");
   15.33 +    printf("\t\tUse POLICYDIR as the policy directory. This directory must contain\n");
   15.34 +    printf("\t\tthe policy schema file 'security_policy.xsd'\n");
   15.35      exit(EXIT_FAILURE);
   15.36  }
   15.37  
   15.38 @@ -1237,7 +1247,7 @@ int is_valid(xmlDocPtr doc)
   15.39      xmlSchemaParserCtxtPtr schemaparser_ctxt = NULL;
   15.40      xmlSchemaValidCtxtPtr schemavalid_ctxt = NULL;
   15.41  
   15.42 -    schemaparser_ctxt = xmlSchemaNewParserCtxt(SCHEMA_FILENAME);
   15.43 +    schemaparser_ctxt = xmlSchemaNewParserCtxt(schema_filename);
   15.44      schema_ctxt = xmlSchemaParse(schemaparser_ctxt);
   15.45      schemavalid_ctxt = xmlSchemaNewValidCtxt(schema_ctxt);
   15.46  
   15.47 @@ -1246,12 +1256,12 @@ int is_valid(xmlDocPtr doc)
   15.48      if ((err = xmlSchemaIsValid(schemavalid_ctxt)) != 1)
   15.49      {
   15.50          printf("ERROR: Invalid schema file %s (err=%d)\n",
   15.51 -               SCHEMA_FILENAME, err);
   15.52 +               schema_filename, err);
   15.53          err = -EIO;
   15.54          goto out;
   15.55      }
   15.56      else
   15.57 -        printf("XML Schema %s valid.\n", SCHEMA_FILENAME);
   15.58 +        printf("XML Schema %s valid.\n", schema_filename);
   15.59  #endif
   15.60      if ((err = xmlSchemaValidateDoc(schemavalid_ctxt, doc)))
   15.61      {
   15.62 @@ -1275,37 +1285,59 @@ int main(int argc, char **argv)
   15.63      char *file_prefix;
   15.64      int prefix_len;
   15.65  
   15.66 +    int opt_char;
   15.67 +    char *policy_dir = POLICY_DIR;
   15.68 +
   15.69      if (ACM_POLICY_VERSION != WRITTEN_AGAINST_ACM_POLICY_VERSION)
   15.70      {
   15.71          printf("ERROR: This program was written against an older ACM version.\n");
   15.72          exit(EXIT_FAILURE);
   15.73      }
   15.74  
   15.75 -    if (argc != 2)
   15.76 +    while ((opt_char = getopt(argc, argv, "d:")) != -1) {
   15.77 +        switch (opt_char) {
   15.78 +        case 'd':
   15.79 +            policy_dir = malloc(strlen(optarg) + 2); // null terminator and possibly "/"
   15.80 +            if (!policy_dir) {
   15.81 +                printf("ERROR allocating directory name memory.\n");
   15.82 +                exit(EXIT_FAILURE);
   15.83 +            }
   15.84 +            strcpy(policy_dir, optarg);
   15.85 +            if (policy_dir[strlen(policy_dir) - 1] != '/')
   15.86 +                strcat(policy_dir, "/");
   15.87 +            break;
   15.88 +
   15.89 +        default:
   15.90 +            usage(basename(argv[0]));
   15.91 +        }
   15.92 +    }
   15.93 +
   15.94 +    if ((argc - optind) != 1)
   15.95          usage(basename(argv[0]));
   15.96  
   15.97 -    prefix_len = strlen(POLICY_SUBDIR) +
   15.98 -        strlen(argv[1]) + 1 /* "/" */  +
   15.99 -        strlen(argv[1]) + 1 /* "/" */ ;
  15.100 +    prefix_len = strlen(policy_dir) +
  15.101 +        strlen(argv[optind]) + 1 /* "/" */  +
  15.102 +        strlen(argv[optind]) + 1 /* null terminator */ ;
  15.103  
  15.104      file_prefix = malloc(prefix_len);
  15.105      policy_filename = malloc(prefix_len + strlen(POLICY_EXTENSION));
  15.106      label_filename = malloc(prefix_len + strlen(LABEL_EXTENSION));
  15.107      binary_filename = malloc(prefix_len + strlen(BINARY_EXTENSION));
  15.108      mapping_filename = malloc(prefix_len + strlen(MAPPING_EXTENSION));
  15.109 +    schema_filename = malloc(strlen(policy_dir) + strlen(SCHEMA_FILENAME) + 1);
  15.110  
  15.111      if (!file_prefix || !policy_filename || !label_filename ||
  15.112 -        !binary_filename || !mapping_filename)
  15.113 +        !binary_filename || !mapping_filename || !schema_filename)
  15.114      {
  15.115          printf("ERROR allocating file name memory.\n");
  15.116          goto out2;
  15.117      }
  15.118  
  15.119      /* create input/output filenames out of prefix */
  15.120 -    strcat(file_prefix, POLICY_SUBDIR);
  15.121 -    strcat(file_prefix, argv[1]);
  15.122 +    strcpy(file_prefix, policy_dir);
  15.123 +    strcat(file_prefix, argv[optind]);
  15.124      strcat(file_prefix, "/");
  15.125 -    strcat(file_prefix, argv[1]);
  15.126 +    strcat(file_prefix, argv[optind]);
  15.127  
  15.128      strcpy(policy_filename, file_prefix);
  15.129      strcpy(label_filename, file_prefix);
  15.130 @@ -1317,11 +1349,14 @@ int main(int argc, char **argv)
  15.131      strcat(binary_filename, BINARY_EXTENSION);
  15.132      strcat(mapping_filename, MAPPING_EXTENSION);
  15.133  
  15.134 +    strcpy(schema_filename, policy_dir);
  15.135 +    strcat(schema_filename, SCHEMA_FILENAME);
  15.136 +
  15.137      labeldoc = xmlParseFile(label_filename);
  15.138  
  15.139      if (labeldoc == NULL)
  15.140      {
  15.141 -        printf("Error: could not parse file %s.\n", argv[1]);
  15.142 +        printf("Error: could not parse file %s.\n", argv[optind]);
  15.143          goto out2;
  15.144      }
  15.145  
  15.146 @@ -1337,7 +1372,7 @@ int main(int argc, char **argv)
  15.147  
  15.148      if (policydoc == NULL)
  15.149      {
  15.150 -        printf("Error: could not parse file %s.\n", argv[1]);
  15.151 +        printf("Error: could not parse file %s.\n", argv[optind]);
  15.152          goto out1;
  15.153      }
  15.154  
    16.1 --- a/tools/security/secpol_xml2bin.h	Fri Dec 09 10:51:20 2005 +0000
    16.2 +++ b/tools/security/secpol_xml2bin.h	Fri Dec 09 10:51:35 2005 +0000
    16.3 @@ -12,7 +12,7 @@
    16.4   * License.
    16.5   *
    16.6   */
    16.7 -#define POLICY_SUBDIR       "policies/"
    16.8 +#define POLICY_DIR          "/etc/xen/acm-security/policies/"
    16.9  #define POLICY_EXTENSION    "-security_policy.xml"
   16.10  #define LABEL_EXTENSION     "-security_label_template.xml"
   16.11  #define BINARY_EXTENSION    ".bin"
   16.12 @@ -20,7 +20,7 @@
   16.13  #define PRIMARY_COMPONENT_ATTR_NAME "order"
   16.14  #define BOOTSTRAP_LABEL_ATTR_NAME   "bootstrap"
   16.15  #define PRIMARY_COMPONENT   "PrimaryPolicyComponent"
   16.16 -#define SCHEMA_FILENAME     "policies/security_policy.xsd"
   16.17 +#define SCHEMA_FILENAME     "security_policy.xsd"
   16.18  
   16.19  /* basic states (used as 1 << X) */
   16.20  #define XML2BIN_SECPOL		    0   /* policy tokens */
    17.1 --- a/tools/security/setlabel.sh	Fri Dec 09 10:51:20 2005 +0000
    17.2 +++ b/tools/security/setlabel.sh	Fri Dec 09 10:51:35 2005 +0000
    17.3 @@ -35,102 +35,72 @@ if [ -z "$runbash" ]; then
    17.4  fi
    17.5  
    17.6  export PATH=$PATH:.
    17.7 -source labelfuncs.sh
    17.8 +dir=`dirname $0`
    17.9 +source $dir/labelfuncs.sh
   17.10  
   17.11  usage ()
   17.12  {
   17.13 +	prg=`basename $0`
   17.14  echo "Use this tool to put the ssidref corresponding to a label of a policy into
   17.15  the VM configuration file, or use it to display all labels of a policy.
   17.16  
   17.17 -Usage: $0 [Option] <vmfile> <label> [<policy name>]
   17.18 -    or $0 -l [<policy name>]
   17.19 +Usage: $prg [-r] <vmfile> <label> [<policy name> [<policy dir>]] or
   17.20 +       $prg -l [<policy name> [<policy dir>]]
   17.21  
   17.22 -Valid options are:
   17.23  -r          : to relabel a file without being prompted
   17.24 -
   17.25 +-l          : to show the valid labels in a map file
   17.26  vmfile      : XEN vm configuration file; give complete path
   17.27  label       : the label to map to an ssidref
   17.28  policy name : the name of the policy, i.e. 'chwall'
   17.29                If the policy name is omitted, it is attempted
   17.30                to find the current policy's name in grub.conf.
   17.31 -
   17.32 --l [<policy name>] is used to show valid labels in the map file of
   17.33 -                   the given or current policy. If the policy name
   17.34 -                   is omitted, it will be tried to determine the
   17.35 -                   current policy from grub.conf (/boot/grub/grub.conf)
   17.36 -
   17.37 +policy dir  : the directory where the <policy name> policy is located
   17.38 +              The default location is '/etc/xen/acm-security/policies'
   17.39  "
   17.40  }
   17.41  
   17.42 -
   17.43  if [ "$1" == "-r" ]; then
   17.44  	mode="relabel"
   17.45  	shift
   17.46  elif [ "$1" == "-l" ]; then
   17.47  	mode="show"
   17.48  	shift
   17.49 -elif [ "$1" == "-?" ]; then
   17.50 +elif [ "$1" == "-h" ]; then
   17.51  	mode="usage"
   17.52  fi
   17.53  
   17.54 -if [ "$mode" == "show" ]; then
   17.55 -	if [ "$1" == "" ]; then
   17.56 -		findGrubConf
   17.57 -		ret=$?
   17.58 -		if [ $ret -eq 0 ]; then
   17.59 -			echo "Could not find grub.conf"
   17.60 -			exit -1;
   17.61 -		fi
   17.62 -		findPolicyInGrub $grubconf
   17.63 -		if [ "$policy" != "" ]; then
   17.64 -			echo "Assuming policy to be '$policy'.";
   17.65 -		else
   17.66 -			echo "Could not find policy."
   17.67 -			exit -1;
   17.68 -		fi
   17.69 -	else
   17.70 -		policy=$1;
   17.71 +if [ "$mode" == "usage" ]; then
   17.72 +	usage
   17.73 +elif [ "$mode" == "show" ]; then
   17.74 +	setPolicyVars $1 $2
   17.75 +	ret=$?
   17.76 +	if [ $ret -eq 0 ]; then
   17.77 +		echo "Error when trying to find policy-related information."
   17.78 +		exit -1
   17.79  	fi
   17.80 -
   17.81 -
   17.82 -	findMapFile $policy
   17.83 -	res=$?
   17.84 -	if [ "$res" != "0" ]; then
   17.85 -		showLabels $mapfile
   17.86 -	else
   17.87 +	findMapFile $policy $policydir
   17.88 +	ret=$?
   17.89 +	if [ $ret -eq 0 ]; then
   17.90  		echo "Could not find map file for policy '$policy'."
   17.91 +		exit -1
   17.92  	fi
   17.93 -elif [ "$mode" == "usage" ]; then
   17.94 -	usage
   17.95 +	showLabels $mapfile
   17.96  else
   17.97  	if [ "$2" == "" ]; then
   17.98  		usage
   17.99  		exit -1
  17.100  	fi
  17.101 -	if [ "$3" == "" ]; then
  17.102 -		findGrubConf
  17.103 -		ret=$?
  17.104 -		if [ $ret -eq 0 ]; then
  17.105 -			echo "Could not find grub.conf"
  17.106 -			exit -1;
  17.107 -		fi
  17.108 -		findPolicyInGrub $grubconf
  17.109 -		if [ "$policy" != "" ]; then
  17.110 -			echo "Assuming policy to be '$policy'.";
  17.111 -		else
  17.112 -			echo "Could not find policy."
  17.113 -			exit -1;
  17.114 -		fi
  17.115 -
  17.116 -	else
  17.117 -		policy=$3;
  17.118 +	setPolicyVars $3 $4
  17.119 +	ret=$?
  17.120 +	if [ $ret -eq 0 ]; then
  17.121 +		echo "Error when trying to find policy-related information."
  17.122 +		exit -1
  17.123  	fi
  17.124 -	findMapFile $policy
  17.125 -	res=$?
  17.126 -	if [ "$res" != "0" ]; then
  17.127 -		relabel $1 $2 $mapfile $mode
  17.128 -	else
  17.129 -		echo "Could not find map file for policy '$3'."
  17.130 +	findMapFile $policy $policydir
  17.131 +	ret=$?
  17.132 +	if [ $ret -eq 0 ]; then
  17.133 +		echo "Could not find map file for policy '$policy'."
  17.134 +		exit -1
  17.135  	fi
  17.136 -
  17.137 +	relabel $1 $2 $mapfile $mode
  17.138  fi
    18.1 --- a/tools/security/updategrub.sh	Fri Dec 09 10:51:20 2005 +0000
    18.2 +++ b/tools/security/updategrub.sh	Fri Dec 09 10:51:35 2005 +0000
    18.3 @@ -22,166 +22,49 @@ if [ -z "$runbash" ]; then
    18.4  	exit
    18.5  fi
    18.6  
    18.7 +dir=`dirname $0`
    18.8 +source $dir/labelfuncs.sh
    18.9 +
   18.10 +acmroot=$ACM_DEFAULT_ROOT
   18.11 +
   18.12  
   18.13  # Show usage of this program
   18.14  usage ()
   18.15  {
   18.16 +	prg=`basename $0`
   18.17  echo "Use this tool to add the binary policy to the Xen grub entry and
   18.18  have Xen automatically enforce the policy when starting.
   18.19  
   18.20 -Usage: $0 <policy name> <root of xen repository>
   18.21 -
   18.22 -<policy name>             : The name of the policy, i.e. xen_null
   18.23 -<root of xen repository>  : The root of the XEN repository. Give
   18.24 -                            complete path.
   18.25 -
   18.26 -"
   18.27 -}
   18.28 +Usage: $prg [-d <policies root>] <policy name> [<kernel version>]
   18.29  
   18.30 -# This function sets the global variable 'linux'
   18.31 -# to the name of the linux kernel that was compiled
   18.32 -# For now a pattern should do the trick
   18.33 -getLinuxVersion ()
   18.34 -{
   18.35 -	path=$1
   18.36 -	linux=""
   18.37 -	for f in $path/linux-*-xen0 ; do
   18.38 -		versionfile=$f/include/linux/version.h
   18.39 -		if [ -r $versionfile ]; then
   18.40 -			lnx=`cat $versionfile |                \
   18.41 -			     grep UTS_RELEASE |                \
   18.42 -			     awk '{                            \
   18.43 -			       len=length($3);                 \
   18.44 -			       version=substr($3,2,len-2);     \
   18.45 -			       split(version,numbers,".");     \
   18.46 -			       if (numbers[4]=="") {           \
   18.47 -			         printf("%s.%s.%s",            \
   18.48 -			                 numbers[1],           \
   18.49 -			                 numbers[2],           \
   18.50 -			                 numbers[3]);          \
   18.51 -			       } else {                        \
   18.52 -			         printf("%s.%s.%s[.0-9]*-xen0",\
   18.53 -			                numbers[1],            \
   18.54 -			                numbers[2],            \
   18.55 -			                numbers[3]);           \
   18.56 -			       }                               \
   18.57 -			     }'`
   18.58 -		fi
   18.59 -		if [ "$lnx" != "" ]; then
   18.60 -			linux="[./0-9a-zA-z]*$lnx"
   18.61 -			return;
   18.62 -		fi
   18.63 -	done
   18.64 -
   18.65 -	#Last resort.
   18.66 -	linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
   18.67 -}
   18.68 -
   18.69 -#Return where the grub.conf file is.
   18.70 -#I only know of one place it can be.
   18.71 -findGrubConf()
   18.72 -{
   18.73 -	grubconf="/boot/grub/grub.conf"
   18.74 -	if [ -w $grubconf ]; then
   18.75 -		return 1
   18.76 -	fi
   18.77 -	return 0
   18.78 +<policies root>  : The directory where the policies directory is located in;
   18.79 +                   default is $acmroot
   18.80 +<policy name>    : The name of the policy, i.e. xen_null
   18.81 +<kernel version> : The version of the kernel to apply the policy
   18.82 +                   against, i.e. 2.6.12.6-xen0
   18.83 +                   If not specified, a kernel version ending with '-xen0'
   18.84 +                   will be searched for in '/lib/modules'
   18.85 +"
   18.86  }
   18.87  
   18.88  
   18.89 -#Update the grub configuration file.
   18.90 -#Search for existing entries and replace the current
   18.91 -#policy entry with the policy passed to this script
   18.92 -#
   18.93 -#Arguments passed to this function
   18.94 -# 1st : the grub configuration file
   18.95 -# 2nd : the binary policy file name
   18.96 -# 3rd : the name or pattern of the linux kernel name to match
   18.97 -#
   18.98 -# The algorithm here is based on pattern matching
   18.99 -# and is working correctly if
  18.100 -# - under a title a line beginning with 'kernel' is found
  18.101 -#   whose following item ends with "xen.gz"
  18.102 -#   Example:  kernel /xen.gz dom0_mem=....
  18.103 -# - a module line matching the 3rd parameter is found
  18.104 -#
  18.105 -updateGrub ()
  18.106 -{
  18.107 -	grubconf=$1
  18.108 -	policyfile=$2
  18.109 -	linux=$3
  18.110 -
  18.111 -	tmpfile="/tmp/new_grub.conf"
  18.112  
  18.113 -	cat $grubconf |                                \
  18.114 -	         awk -vpolicy=$policyfile              \
  18.115 -	             -vlinux=$linux '{                 \
  18.116 -	           if ( $1 == "title" ) {              \
  18.117 -	             kernelfound = 0;                  \
  18.118 -	             if ( policymaycome == 1 ){        \
  18.119 -	               printf ("\tmodule %s%s\n", path, policy);      \
  18.120 -	             }                                 \
  18.121 -	             policymaycome = 0;                \
  18.122 -	           }                                   \
  18.123 -	           else if ( $1 == "kernel" ) {        \
  18.124 -	             if ( match($2,"xen.gz$") ) {      \
  18.125 -	               path=substr($2,1,RSTART-1);     \
  18.126 -	               kernelfound = 1;                \
  18.127 -	             }                                 \
  18.128 -	           }                                   \
  18.129 -	           else if ( $1 == "module" &&         \
  18.130 -	                     kernelfound == 1 &&       \
  18.131 -	                     match($2,linux) ) {       \
  18.132 -	              policymaycome = 1;               \
  18.133 -	           }                                   \
  18.134 -	           else if ( $1 == "module" &&         \
  18.135 -	                     kernelfound == 1 &&       \
  18.136 -	                     policymaycome == 1 &&     \
  18.137 -	                     match($2,"[0-9a-zA-Z]*.bin$") ) { \
  18.138 -	              printf ("\tmodule %s%s\n", path, policy); \
  18.139 -	              policymaycome = 0;               \
  18.140 -	              kernelfound = 0;                 \
  18.141 -	              dontprint = 1;                   \
  18.142 -	           }                                   \
  18.143 -	           else if ( $1 == "" &&               \
  18.144 -	                     kernelfound == 1 &&       \
  18.145 -	                     policymaycome == 1) {     \
  18.146 -	              dontprint = 1;                   \
  18.147 -	           }                                   \
  18.148 -	           if (dontprint == 0) {               \
  18.149 -	             printf ("%s\n", $0);              \
  18.150 -	           }                                   \
  18.151 -	           dontprint = 0;                      \
  18.152 -	         } END {                               \
  18.153 -	           if ( policymaycome == 1 ) {         \
  18.154 -	             printf ("\tmodule %s%s\n", path, policy);  \
  18.155 -	           }                                   \
  18.156 -	         }' > $tmpfile
  18.157 -	if [ ! -r $tmpfile ]; then
  18.158 -		echo "Could not create temporary file! Aborting."
  18.159 -		exit -1
  18.160 -	fi
  18.161 -	diff $tmpfile $grubconf > /dev/null
  18.162 -	RES=$?
  18.163 -	if [ "$RES" == "0" ]; then
  18.164 -		echo "No changes were made to $grubconf."
  18.165 -	else
  18.166 -		echo "Successfully updated $grubconf."
  18.167 -		mv -f $tmpfile $grubconf
  18.168 -	fi
  18.169 -}
  18.170 +if [ "$1" == "-h" ]; then
  18.171 +	usage
  18.172 +	exit 0
  18.173 +elif [ "$1" == "-d" ]; then
  18.174 +	shift
  18.175 +	acmroot=$1
  18.176 +	shift
  18.177 +fi
  18.178  
  18.179 -if [ "$1" == "" -o "$2" == "" ]; then
  18.180 +if [ "$1" == "" ]; then
  18.181  	echo "Error: Not enough command line parameters."
  18.182  	echo ""
  18.183  	usage
  18.184  	exit -1
  18.185  fi
  18.186  
  18.187 -if [ "$1" == "-?" ]; then
  18.188 -	usage
  18.189 -	exit 0
  18.190 -fi
  18.191  
  18.192  policy=$1
  18.193  policyfile=$policy.bin
  18.194 @@ -189,10 +72,19 @@ policyfile=$policy.bin
  18.195  getLinuxVersion $2
  18.196  
  18.197  findGrubConf
  18.198 -ERR=$?
  18.199 -if [ $ERR -eq 0 ]; then
  18.200 -	echo "Could not find grub.conf. Aborting."
  18.201 +ret=$?
  18.202 +if [ $ret -eq 0 ]; then
  18.203 +	echo "Could not find grub.conf."
  18.204 +	exit -1
  18.205 +elif [ $ret -eq 2 ]; then
  18.206 +	echo "Need to have write-access to $grubconf. Exiting."
  18.207  	exit -1
  18.208  fi
  18.209  
  18.210 +cpBootPolicy /boot $acmroot $policy
  18.211 +ret=$?
  18.212 +if [ $ret -ne 1 ]; then
  18.213 +	echo "Error copying or generating the binary policy."
  18.214 +	exit -1
  18.215 +fi
  18.216  updateGrub $grubconf $policyfile $linux
    19.1 --- a/tools/xm-test/configure.ac	Fri Dec 09 10:51:20 2005 +0000
    19.2 +++ b/tools/xm-test/configure.ac	Fri Dec 09 10:51:35 2005 +0000
    19.3 @@ -52,6 +52,7 @@ AC_CONFIG_FILES([
    19.4      tests/memset/Makefile
    19.5      tests/migrate/Makefile
    19.6      tests/network-attach/Makefile
    19.7 +    tests/network/Makefile
    19.8      tests/pause/Makefile
    19.9      tests/reboot/Makefile
   19.10      tests/restore/Makefile
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/xm-test/lib/XmTestLib/Network.py	Fri Dec 09 10:51:35 2005 +0000
    20.3 @@ -0,0 +1,79 @@
    20.4 +#!/usr/bin/python
    20.5 +"""
    20.6 + Network.py - Common utilities for network tests
    20.7 +
    20.8 + Copyright (C) International Business Machines Corp., 2005
    20.9 + Author: Jim Dykman <dykman@us.ibm.com>
   20.10 +
   20.11 + This program is free software; you can redistribute it and/or modify
   20.12 + it under the terms of the GNU General Public License as published by
   20.13 + the Free Software Foundation; under version 2 of the License.
   20.14 +
   20.15 + This program is distributed in the hope that it will be useful,
   20.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.18 + GNU General Public License for more details.
   20.19 +
   20.20 + You should have received a copy of the GNU General Public License
   20.21 + along with this program; if not, write to the Free Software
   20.22 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.23 +
   20.24 +"""
   20.25 +import sys;
   20.26 +import os;
   20.27 +import atexit;
   20.28 +
   20.29 +from Test import *
   20.30 +from Xm import *
   20.31 +
   20.32 +class NetworkError(Exception):
   20.33 +    def __init__(self, msg):
   20.34 +        self.errMsg = msg
   20.35 +
   20.36 +    def __str__(self):
   20.37 +        return str(self.errMsg)
   20.38 +
   20.39 +def undo_dom0_alias(eth, ip):
   20.40 +    traceCommand("ip addr del " + ip + " dev " + eth)
   20.41 +
   20.42 +class XmNetwork:
   20.43 +
   20.44 +    def __init__(self):
   20.45 +        # Check for existing zeroconf address. We are using the zeroconf 
   20.46 +        # address range as static IP addresses.... if someone is using 
   20.47 +        # real zeroconf addresses, then we're going to skip tests to 
   20.48 +        # avoid interfering with them.
   20.49 +        rc, out = traceCommand(
   20.50 +                  "ip addr show |grep \"inet 169.254\" | grep -v vif")
   20.51 +
   20.52 +        if rc == 0:
   20.53 +            SKIP("Zeroconf address found: " + out)
   20.54 +
   20.55 +    def calc_ip_address(self, dom, interface):
   20.56 +        # Generate an IP address from the dom# and eth#:
   20.57 +        #      169.254.(eth#+153).(dom#+10)
   20.58 +        ethnum = int(interface[len("eth"):])
   20.59 +        domnum = int(dom[len("dom"):])
   20.60 +        return "169.254."+ str(ethnum+153) + "." + str(domnum+10)
   20.61 +
   20.62 +    def ip(self, dom, interface, todomname=None, toeth=None):
   20.63 +        newip = self.calc_ip_address(dom, interface)
   20.64 +
   20.65 +        # If the testcase is going to talk to dom0, we need to add an 
   20.66 +        # IP address in the proper subnet
   20.67 +        if dom == "dom0":
   20.68 +            # The domain's vif is a convenient place to add to
   20.69 +            vifname = "vif" + str(domid(todomname)) + "." + toeth[3:]
   20.70 +
   20.71 +            # register the exit handler FIRST, just in case
   20.72 +            atexit.register(undo_dom0_alias, vifname, newip)
   20.73 +
   20.74 +            # add the alias
   20.75 +            status, output = traceCommand("ip addr add " + newip + 
   20.76 +                                              " dev " + vifname)
   20.77 +            if status:
   20.78 +                SKIP("\"ip addr add\" failed")
   20.79 +        return newip
   20.80 +
   20.81 +    def mask(self, dom, interface):
   20.82 +        return "255.255.255.0"
    21.1 --- a/tools/xm-test/lib/XmTestLib/__init__.py	Fri Dec 09 10:51:20 2005 +0000
    21.2 +++ b/tools/xm-test/lib/XmTestLib/__init__.py	Fri Dec 09 10:51:35 2005 +0000
    21.3 @@ -4,6 +4,7 @@
    21.4  #
    21.5  
    21.6  from Console import *
    21.7 +from Network import *
    21.8  from Test import *
    21.9  from Xm import *
   21.10  from XenDomain import *
    22.1 --- a/tools/xm-test/tests/Makefile.am	Fri Dec 09 10:51:20 2005 +0000
    22.2 +++ b/tools/xm-test/tests/Makefile.am	Fri Dec 09 10:51:35 2005 +0000
    22.3 @@ -13,6 +13,7 @@ SUBDIRS = 	               	\
    22.4  		list		\
    22.5  		memmax		\
    22.6  		memset		\
    22.7 +		network		\
    22.8  		network-attach	\
    22.9  		pause		\
   22.10  		reboot 		\
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/xm-test/tests/network/02_network_local_ping_pos.py	Fri Dec 09 10:51:35 2005 +0000
    23.3 @@ -0,0 +1,84 @@
    23.4 +#!/usr/bin/python
    23.5 +
    23.6 +# Copyright (C) International Business Machines Corp., 2005
    23.7 +# Author:  <dykman@us.ibm.com>
    23.8 +
    23.9 +# Ping tests on local interfaces.
   23.10 +#  - creates a single guest domain
   23.11 +#  - sets up a single NIC
   23.12 +#  - conducts ping tests to the local loopback and IP address.
   23.13 +
   23.14 +# ping -c 1 -s $size 127.0.0.1
   23.15 +# ping -c 1 -s $size $local_IP 
   23.16 +#   where $size = 1, 48, 64, 512, 1440, 1500, 1505, 
   23.17 +#                 4096, 4192, 32767, 65507, 65508
   23.18 +
   23.19 +pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
   23.20 +              32767, 65507 ]
   23.21 +
   23.22 +
   23.23 +
   23.24 +from XmTestLib import *
   23.25 +rc = 0
   23.26 +
   23.27 +Net = XmNetwork()
   23.28 +
   23.29 +# read an IP address from the config
   23.30 +ip   = Net.ip("dom1", "eth0")
   23.31 +mask = Net.mask("dom1", "eth0")
   23.32 +
   23.33 +# Fire up a guest domain w/1 nic
   23.34 +domain = XmTestDomain(extraOpts={ 'nics' : 1 })
   23.35 +try:
   23.36 +    domain.configSetVar('vif', " [ 'ip=" + ip + "' ]")
   23.37 +    domain.start()
   23.38 +except DomainError, e:
   23.39 +    if verbose:
   23.40 +        print "Failed to create test domain because:"
   23.41 +        print e.extra
   23.42 +    FAIL(str(e))
   23.43 +
   23.44 +
   23.45 +# Attach a console
   23.46 +try:
   23.47 +    console = XmConsole(domain.getName(), historySaveCmds=True)
   23.48 +except ConsoleError, e:
   23.49 +    FAIL(str(e))
   23.50 +
   23.51 +try:
   23.52 +    # Activate the console
   23.53 +    console.sendInput("bhs")
   23.54 +
   23.55 +    # Bring up the "lo" interface.
   23.56 +    console.runCmd("ifconfig lo up")
   23.57 +
   23.58 +    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   23.59 +
   23.60 +    # First the loopback pings
   23.61 +    lofails=""
   23.62 +    for size in pingsizes:
   23.63 +        out = console.runCmd("ping -q -c 1 -s " + str(size) + " 127.0.0.1")
   23.64 +        if out["return"]:
   23.65 +            lofails += " " + str(size)
   23.66 +
   23.67 +    # Next comes eth0
   23.68 +    eth0fails=""
   23.69 +    for size in pingsizes:
   23.70 +        out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip)
   23.71 +        if out["return"]:
   23.72 +            eth0fails += " " + str(size) 
   23.73 +except ConsoleError, e:
   23.74 +        FAIL(str(e))
   23.75 +except NetworkError, e:
   23.76 +        FAIL(str(e))
   23.77 +
   23.78 +
   23.79 +# Tally up failures
   23.80 +failures=""
   23.81 +if len(lofails):
   23.82 +        failures += "ping loopback failed for size" + lofails + ". "
   23.83 +if len(eth0fails):
   23.84 +        failures += "ping eth0 failed for size" + eth0fails + "."
   23.85 +if len(failures):
   23.86 +    FAIL(failures)
   23.87 +
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py	Fri Dec 09 10:51:35 2005 +0000
    24.3 @@ -0,0 +1,73 @@
    24.4 +#!/usr/bin/python
    24.5 +
    24.6 +# Copyright (C) International Business Machines Corp., 2005
    24.7 +# Author:  <dykman@us.ibm.com>
    24.8 +
    24.9 +# Ping tests to dom0 interface
   24.10 +#  - determines dom0 network
   24.11 +#  - creates a single guest domain
   24.12 +#  - sets up a single NIC on same subnet as dom0
   24.13 +#  - conducts ping tests to the dom0 IP address.
   24.14 +
   24.15 +# ping -c 1 -s $size $dom0_IP 
   24.16 +#   where $size = 1, 48, 64, 512, 1440, 1500, 1505, 
   24.17 +#                 4096, 4192, 32767, 65507, 65508
   24.18 +
   24.19 +pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
   24.20 +                32767, 65507 ]
   24.21 +
   24.22 +
   24.23 +
   24.24 +from XmTestLib import *
   24.25 +rc = 0
   24.26 +
   24.27 +Net = XmNetwork()
   24.28 +
   24.29 +try:
   24.30 +    # read an IP address from the config
   24.31 +    ip     = Net.ip("dom1", "eth0")
   24.32 +    mask   = Net.mask("dom1", "eth0")
   24.33 +except NetworkError, e:
   24.34 +        FAIL(str(e))
   24.35 +
   24.36 +# Fire up a guest domain w/1 nic
   24.37 +domain = XmTestDomain(extraOpts={ 'nics' : 1 })
   24.38 +try:
   24.39 +    domain.configSetVar('vif', " [ 'ip=" + ip + "' ]")
   24.40 +    domain.start()
   24.41 +except DomainError, e:
   24.42 +    if verbose:
   24.43 +        print "Failed to create test domain because:"
   24.44 +        print e.extra
   24.45 +    FAIL(str(e))
   24.46 +
   24.47 +
   24.48 +# Attach a console
   24.49 +try:
   24.50 +    console = XmConsole(domain.getName(), historySaveCmds=True)
   24.51 +    # Activate the console
   24.52 +    console.sendInput("bhs")
   24.53 +except ConsoleError, e:
   24.54 +    FAIL(str(e))
   24.55 +
   24.56 +try:
   24.57 +    # Add a suitable dom0 IP address 
   24.58 +    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0")
   24.59 +except NetworkError, e:
   24.60 +        FAIL(str(e))
   24.61 +
   24.62 +try:
   24.63 +    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   24.64 +
   24.65 +    # Ping dom0
   24.66 +    fails=""
   24.67 +    for size in pingsizes:
   24.68 +        out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + dom0ip)
   24.69 +        if out["return"]:
   24.70 +            fails += " " + str(size) 
   24.71 +except ConsoleError, e:
   24.72 +        FAIL(str(e))
   24.73 +
   24.74 +if len(fails):
   24.75 +    FAIL("Ping to dom0 failed for size" + fails + ".")
   24.76 +
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py	Fri Dec 09 10:51:35 2005 +0000
    25.3 @@ -0,0 +1,79 @@
    25.4 +#!/usr/bin/python
    25.5 +
    25.6 +# Copyright (C) International Business Machines Corp., 2005
    25.7 +# Author:  <dykman@us.ibm.com>
    25.8 +
    25.9 +# Ping tests to domU interface
   25.10 +#  - creates two guest domains
   25.11 +#  - sets up a single NIC on each on same subnet 
   25.12 +#  - conducts ping tests to the domU IP address.
   25.13 +
   25.14 +# ping -c 1 -s $size $domU_IP 
   25.15 +#   where $size = 1, 48, 64, 512, 1440, 1500, 1505, 
   25.16 +#                 4096, 4192, 32767, 65507, 65508
   25.17 +
   25.18 +pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
   25.19 +              32767, 65507 ]
   25.20 +
   25.21 +
   25.22 +
   25.23 +from XmTestLib import *
   25.24 +
   25.25 +
   25.26 +def netDomain(ip):
   25.27 +    dom = XmTestDomain(extraOpts={ 'nics' : 1 })
   25.28 +    try:
   25.29 +        dom.configSetVar('vif', " [ 'ip=" + ip + "' ]")
   25.30 +        dom.start()
   25.31 +    except DomainError, e:
   25.32 +        if verbose:
   25.33 +            print "Failed to create test domain because:"
   25.34 +            print e.extra
   25.35 +        FAIL(str(e))
   25.36 +    try:
   25.37 +        # Attach a console
   25.38 +        console = XmConsole(dom.getName(), historySaveCmds=True)
   25.39 +        # Activate the console
   25.40 +        console.sendInput("bhs")
   25.41 +    except ConsoleError, e:
   25.42 +        FAIL(str(e))
   25.43 +    return console
   25.44 +    
   25.45 +rc = 0
   25.46 +
   25.47 +Net = XmNetwork()
   25.48 +
   25.49 +try:
   25.50 +    # pick an IP address 
   25.51 +    ip1   = Net.ip("dom1", "eth2")
   25.52 +    mask1 = Net.mask("dom1", "eth2")
   25.53 +except NetworkError, e:
   25.54 +    FAIL(str(e))
   25.55 +
   25.56 +try:
   25.57 +    # pick another IP address 
   25.58 +    ip2   = Net.ip("dom2", "eth2")
   25.59 +    mask2 = Net.mask("dom2", "eth2")
   25.60 +except NetworkError, e:
   25.61 +    FAIL(str(e))
   25.62 +
   25.63 +# Fire up a pair of guest domains w/1 nic each
   25.64 +pinger_console = netDomain(ip1)
   25.65 +victim_console = netDomain(ip2)
   25.66 +
   25.67 +try:
   25.68 +    pinger_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
   25.69 +    victim_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
   25.70 +
   25.71 +    # Ping the victim over eth0
   25.72 +    fails=""
   25.73 +    for size in pingsizes:
   25.74 +        out = pinger_console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip2)
   25.75 +        if out["return"]:
   25.76 +            fails += " " + str(size) 
   25.77 +except ConsoleError, e:
   25.78 +    FAIL(str(e))
   25.79 +
   25.80 +if len(fails):
   25.81 +    FAIL("Ping failed for size" + fails + ".")
   25.82 +
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/xm-test/tests/network/Makefile.am	Fri Dec 09 10:51:35 2005 +0000
    26.3 @@ -0,0 +1,29 @@
    26.4 +
    26.5 +SUBDIRS =
    26.6 +
    26.7 +TESTS = \
    26.8 +	02_network_local_ping_pos.test		\
    26.9 +	05_network_dom0_ping_pos.test		\
   26.10 +	11_network_domU_ping_pos.test
   26.11 +
   26.12 +
   26.13 +
   26.14 +XFAIL_TESTS = 				\
   26.15 +	02_network_local_ping_pos.test		\
   26.16 +	05_network_dom0_ping_pos.test		\
   26.17 +	11_network_domU_ping_pos.test
   26.18 +
   26.19 +EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
   26.20 +
   26.21 +TESTS_ENVIRONMENT=@TENV@
   26.22 +
   26.23 +%.test: %.py
   26.24 +	cp $< $@
   26.25 +	chmod +x $@
   26.26 +
   26.27 +clean-local: am_config_clean-local
   26.28 +
   26.29 +am_config_clean-local:
   26.30 +	rm -f *test
   26.31 +	rm -f *log
   26.32 +	rm -f *~