ia64/xen-unstable

changeset 7295:f1e8d5f64105

Extend xenbus/xenstore client interface to include a transaction
handle on appropriate operations. Next step is to plug this
through to the store daemon and get rid of the nasty serialisation
mutex for transactions.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Oct 09 21:29:10 2005 +0100 (2005-10-09)
parents 5df423407700
children b67873a9e3ac
files linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-xen/xenbus.h tools/console/client/main.c tools/console/daemon/io.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/xend/xenstore/xstransact.py tools/xenstore/Makefile tools/xenstore/xenstore_client.c tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_test.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Sun Oct 09 20:55:53 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Sun Oct 09 21:29:10 2005 +0100
     1.3 @@ -1364,7 +1364,7 @@ static void handle_vcpu_hotplug_event(st
     1.4  			return;
     1.5  
     1.6  		/* get the state value */
     1.7 -		err = xenbus_scanf(dir, "availability", "%s", state);
     1.8 +		err = xenbus_scanf(NULL, dir, "availability", "%s", state);
     1.9  
    1.10  		if (err != 1) {
    1.11  			printk(KERN_ERR
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Sun Oct 09 20:55:53 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Sun Oct 09 21:29:10 2005 +0100
     2.3 @@ -275,22 +275,23 @@ static void shutdown_handler(struct xenb
     2.4  {
     2.5  	static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
     2.6  	char *str;
     2.7 +	struct xenbus_transaction *xbt;
     2.8  	int err;
     2.9  
    2.10   again:
    2.11 -	err = xenbus_transaction_start();
    2.12 -	if (err)
    2.13 +	xbt = xenbus_transaction_start();
    2.14 +	if (IS_ERR(xbt))
    2.15  		return;
    2.16 -	str = (char *)xenbus_read("control", "shutdown", NULL);
    2.17 +	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
    2.18  	/* Ignore read errors and empty reads. */
    2.19  	if (XENBUS_IS_ERR_READ(str)) {
    2.20 -		xenbus_transaction_end(1);
    2.21 +		xenbus_transaction_end(xbt, 1);
    2.22  		return;
    2.23  	}
    2.24  
    2.25 -	xenbus_write("control", "shutdown", "");
    2.26 +	xenbus_write(xbt, "control", "shutdown", "");
    2.27  
    2.28 -	err = xenbus_transaction_end(0);
    2.29 +	err = xenbus_transaction_end(xbt, 0);
    2.30  	if (err == -EAGAIN) {
    2.31  		kfree(str);
    2.32  		goto again;
    2.33 @@ -320,23 +321,24 @@ static void sysrq_handler(struct xenbus_
    2.34  			  unsigned int len)
    2.35  {
    2.36  	char sysrq_key = '\0';
    2.37 +	struct xenbus_transaction *xbt;
    2.38  	int err;
    2.39  
    2.40   again:
    2.41 -	err = xenbus_transaction_start();
    2.42 -	if (err)
    2.43 +	xbt  = xenbus_transaction_start();
    2.44 +	if (IS_ERR(xbt))
    2.45  		return;
    2.46 -	if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
    2.47 +	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
    2.48  		printk(KERN_ERR "Unable to read sysrq code in "
    2.49  		       "control/sysrq\n");
    2.50 -		xenbus_transaction_end(1);
    2.51 +		xenbus_transaction_end(xbt, 1);
    2.52  		return;
    2.53  	}
    2.54  
    2.55  	if (sysrq_key != '\0')
    2.56 -		xenbus_printf("control", "sysrq", "%c", '\0');
    2.57 +		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
    2.58  
    2.59 -	err = xenbus_transaction_end(0);
    2.60 +	err = xenbus_transaction_end(xbt, 0);
    2.61  	if (err == -EAGAIN)
    2.62  		goto again;
    2.63  
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Sun Oct 09 20:55:53 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Sun Oct 09 21:29:10 2005 +0100
     3.3 @@ -357,7 +357,7 @@ static void watch_target(struct xenbus_w
     3.4  	unsigned long long new_target;
     3.5  	int err;
     3.6  
     3.7 -	err = xenbus_scanf("memory", "target", "%llu", &new_target);
     3.8 +	err = xenbus_scanf(NULL, "memory", "target", "%llu", &new_target);
     3.9  	if (err != 1) {
    3.10  		printk(KERN_ERR "Unable to read memory/target\n");
    3.11  		return;
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Sun Oct 09 20:55:53 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Sun Oct 09 21:29:10 2005 +0100
     4.3 @@ -61,18 +61,19 @@ static void frontend_changed(struct xenb
     4.4  	unsigned long ring_ref;
     4.5  	unsigned int evtchn;
     4.6  	int err;
     4.7 +	struct xenbus_transaction *xbt;
     4.8  	struct backend_info *be
     4.9  		= container_of(watch, struct backend_info, watch);
    4.10  
    4.11  	/* If other end is gone, delete ourself. */
    4.12 -	if (vec && !xenbus_exists(be->frontpath, "")) {
    4.13 +	if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
    4.14  		device_unregister(&be->dev->dev);
    4.15  		return;
    4.16  	}
    4.17  	if (be->blkif == NULL || be->blkif->status == CONNECTED)
    4.18  		return;
    4.19  
    4.20 -	err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
    4.21 +	err = xenbus_gather(NULL, be->frontpath, "ring-ref", "%lu", &ring_ref,
    4.22  			    "event-channel", "%u", &evtchn, NULL);
    4.23  	if (err) {
    4.24  		xenbus_dev_error(be->dev, err,
    4.25 @@ -84,7 +85,8 @@ static void frontend_changed(struct xenb
    4.26  	/* Map the shared frame, irq etc. */
    4.27  	err = blkif_map(be->blkif, ring_ref, evtchn);
    4.28  	if (err) {
    4.29 -		xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
    4.30 +		xenbus_dev_error(be->dev, err,
    4.31 +				 "mapping ring-ref %lu port %u",
    4.32  				 ring_ref, evtchn);
    4.33  		return;
    4.34  	}
    4.35 @@ -92,13 +94,13 @@ static void frontend_changed(struct xenb
    4.36  
    4.37  again:
    4.38  	/* Supply the information about the device the frontend needs */
    4.39 -	err = xenbus_transaction_start();
    4.40 -	if (err) {
    4.41 +	xbt = xenbus_transaction_start();
    4.42 +	if (IS_ERR(xbt)) {
    4.43  		xenbus_dev_error(be->dev, err, "starting transaction");
    4.44  		return;
    4.45  	}
    4.46  
    4.47 -	err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
    4.48 +	err = xenbus_printf(xbt, be->dev->nodename, "sectors", "%lu",
    4.49  			    vbd_size(&be->blkif->vbd));
    4.50  	if (err) {
    4.51  		xenbus_dev_error(be->dev, err, "writing %s/sectors",
    4.52 @@ -107,14 +109,14 @@ again:
    4.53  	}
    4.54  
    4.55  	/* FIXME: use a typename instead */
    4.56 -	err = xenbus_printf(be->dev->nodename, "info", "%u",
    4.57 +	err = xenbus_printf(xbt, be->dev->nodename, "info", "%u",
    4.58  			    vbd_info(&be->blkif->vbd));
    4.59  	if (err) {
    4.60  		xenbus_dev_error(be->dev, err, "writing %s/info",
    4.61  				 be->dev->nodename);
    4.62  		goto abort;
    4.63  	}
    4.64 -	err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
    4.65 +	err = xenbus_printf(xbt, be->dev->nodename, "sector-size", "%lu",
    4.66  			    vbd_secsize(&be->blkif->vbd));
    4.67  	if (err) {
    4.68  		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
    4.69 @@ -122,7 +124,7 @@ again:
    4.70  		goto abort;
    4.71  	}
    4.72  
    4.73 -	err = xenbus_transaction_end(0);
    4.74 +	err = xenbus_transaction_end(xbt, 0);
    4.75  	if (err == -EAGAIN)
    4.76  		goto again;
    4.77  	if (err) {
    4.78 @@ -136,7 +138,7 @@ again:
    4.79  	return;
    4.80  
    4.81   abort:
    4.82 -	xenbus_transaction_end(1);
    4.83 +	xenbus_transaction_end(xbt, 1);
    4.84  }
    4.85  
    4.86  /* 
    4.87 @@ -154,7 +156,8 @@ static void backend_changed(struct xenbu
    4.88  		= container_of(watch, struct backend_info, backend_watch);
    4.89  	struct xenbus_device *dev = be->dev;
    4.90  
    4.91 -	err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
    4.92 +	err = xenbus_scanf(NULL, dev->nodename,
    4.93 +			   "physical-device", "%li", &pdev);
    4.94  	if (XENBUS_EXIST_ERR(err))
    4.95  		return;
    4.96  	if (err < 0) {
    4.97 @@ -169,7 +172,7 @@ static void backend_changed(struct xenbu
    4.98  	be->pdev = pdev;
    4.99  
   4.100  	/* If there's a read-only node, we're read only. */
   4.101 -	p = xenbus_read(dev->nodename, "read-only", NULL);
   4.102 +	p = xenbus_read(NULL, dev->nodename, "read-only", NULL);
   4.103  	if (!IS_ERR(p)) {
   4.104  		be->readonly = 1;
   4.105  		kfree(p);
   4.106 @@ -184,7 +187,8 @@ static void backend_changed(struct xenbu
   4.107  		if (IS_ERR(be->blkif)) {
   4.108  			err = PTR_ERR(be->blkif);
   4.109  			be->blkif = NULL;
   4.110 -			xenbus_dev_error(dev, err, "creating block interface");
   4.111 +			xenbus_dev_error(dev, err,
   4.112 +					 "creating block interface");
   4.113  			return;
   4.114  		}
   4.115  
   4.116 @@ -192,7 +196,8 @@ static void backend_changed(struct xenbu
   4.117  		if (err) {
   4.118  			blkif_put(be->blkif);
   4.119  			be->blkif = NULL;
   4.120 -			xenbus_dev_error(dev, err, "creating vbd structure");
   4.121 +			xenbus_dev_error(dev, err,
   4.122 +					 "creating vbd structure");
   4.123  			return;
   4.124  		}
   4.125  
   4.126 @@ -210,13 +215,14 @@ static int blkback_probe(struct xenbus_d
   4.127  
   4.128  	be = kmalloc(sizeof(*be), GFP_KERNEL);
   4.129  	if (!be) {
   4.130 -		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
   4.131 +		xenbus_dev_error(dev, -ENOMEM,
   4.132 +				 "allocating backend structure");
   4.133  		return -ENOMEM;
   4.134  	}
   4.135  	memset(be, 0, sizeof(*be));
   4.136  
   4.137  	frontend = NULL;
   4.138 -	err = xenbus_gather(dev->nodename,
   4.139 +	err = xenbus_gather(NULL, dev->nodename,
   4.140  			    "frontend-id", "%li", &be->frontend_id,
   4.141  			    "frontend", NULL, &frontend,
   4.142  			    NULL);
   4.143 @@ -228,7 +234,7 @@ static int blkback_probe(struct xenbus_d
   4.144  				 dev->nodename);
   4.145  		goto free_be;
   4.146  	}
   4.147 -	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
   4.148 +	if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
   4.149  		/* If we can't get a frontend path and a frontend-id,
   4.150  		 * then our bus-id is no longer valid and we need to
   4.151  		 * destroy the backend device.
   4.152 @@ -244,7 +250,8 @@ static int blkback_probe(struct xenbus_d
   4.153  	err = register_xenbus_watch(&be->backend_watch);
   4.154  	if (err) {
   4.155  		be->backend_watch.node = NULL;
   4.156 -		xenbus_dev_error(dev, err, "adding backend watch on %s",
   4.157 +		xenbus_dev_error(dev, err,
   4.158 +				 "adding backend watch on %s",
   4.159  				 dev->nodename);
   4.160  		goto free_be;
   4.161  	}
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sun Oct 09 20:55:53 2005 +0100
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sun Oct 09 21:29:10 2005 +0100
     5.3 @@ -460,7 +460,7 @@ static void watch_for_status(struct xenb
     5.4  	if (info->connected == BLKIF_STATE_CONNECTED)
     5.5  		return;
     5.6  
     5.7 -	err = xenbus_gather(watch->node,
     5.8 +	err = xenbus_gather(NULL, watch->node,
     5.9  			    "sectors", "%lu", &sectors,
    5.10  			    "info", "%u", &binfo,
    5.11  			    "sector-size", "%lu", &sector_size,
    5.12 @@ -532,10 +532,11 @@ static int talk_to_backend(struct xenbus
    5.13  {
    5.14  	char *backend;
    5.15  	const char *message;
    5.16 +	struct xenbus_transaction *xbt;
    5.17  	int err;
    5.18  
    5.19  	backend = NULL;
    5.20 -	err = xenbus_gather(dev->nodename,
    5.21 +	err = xenbus_gather(NULL, dev->nodename,
    5.22  			    "backend-id", "%i", &info->backend_id,
    5.23  			    "backend", NULL, &backend,
    5.24  			    NULL);
    5.25 @@ -559,25 +560,26 @@ static int talk_to_backend(struct xenbus
    5.26  	}
    5.27  
    5.28  again:
    5.29 -	err = xenbus_transaction_start();
    5.30 -	if (err) {
    5.31 +	xbt = xenbus_transaction_start();
    5.32 +	if (IS_ERR(xbt)) {
    5.33  		xenbus_dev_error(dev, err, "starting transaction");
    5.34  		goto destroy_blkring;
    5.35  	}
    5.36  
    5.37 -	err = xenbus_printf(dev->nodename, "ring-ref","%u", info->ring_ref);
    5.38 +	err = xenbus_printf(xbt, dev->nodename,
    5.39 +			    "ring-ref","%u", info->ring_ref);
    5.40  	if (err) {
    5.41  		message = "writing ring-ref";
    5.42  		goto abort_transaction;
    5.43  	}
    5.44 -	err = xenbus_printf(dev->nodename,
    5.45 +	err = xenbus_printf(xbt, dev->nodename,
    5.46  			    "event-channel", "%u", info->evtchn);
    5.47  	if (err) {
    5.48  		message = "writing event-channel";
    5.49  		goto abort_transaction;
    5.50  	}
    5.51  
    5.52 -	err = xenbus_transaction_end(0);
    5.53 +	err = xenbus_transaction_end(xbt, 0);
    5.54  	if (err) {
    5.55  		if (err == -EAGAIN)
    5.56  			goto again;
    5.57 @@ -598,8 +600,7 @@ again:
    5.58  	return 0;
    5.59  
    5.60   abort_transaction:
    5.61 -	xenbus_transaction_end(1);
    5.62 -	/* Have to do this *outside* transaction.  */
    5.63 +	xenbus_transaction_end(xbt, 1);
    5.64  	xenbus_dev_error(dev, err, "%s", message);
    5.65   destroy_blkring:
    5.66  	blkif_free(info);
    5.67 @@ -620,7 +621,8 @@ static int blkfront_probe(struct xenbus_
    5.68  	struct blkfront_info *info;
    5.69  
    5.70  	/* FIXME: Use dynamic device id if this is not set. */
    5.71 -	err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
    5.72 +	err = xenbus_scanf(NULL, dev->nodename,
    5.73 +			   "virtual-device", "%i", &vdevice);
    5.74  	if (XENBUS_EXIST_ERR(err))
    5.75  		return err;
    5.76  	if (err < 0) {
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Sun Oct 09 20:55:53 2005 +0100
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Sun Oct 09 21:29:10 2005 +0100
     6.3 @@ -69,15 +69,15 @@ static void frontend_changed(struct xenb
     6.4  	int i;
     6.5  
     6.6  	/* If other end is gone, delete ourself. */
     6.7 -	if (vec && !xenbus_exists(be->frontpath, "")) {
     6.8 -		xenbus_rm(be->dev->nodename, "");
     6.9 +	if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
    6.10 +		xenbus_rm(NULL, be->dev->nodename, "");
    6.11  		device_unregister(&be->dev->dev);
    6.12  		return;
    6.13  	}
    6.14  	if (be->netif == NULL || be->netif->status == CONNECTED)
    6.15  		return;
    6.16  
    6.17 -	mac = xenbus_read(be->frontpath, "mac", NULL);
    6.18 +	mac = xenbus_read(NULL, be->frontpath, "mac", NULL);
    6.19  	if (IS_ERR(mac)) {
    6.20  		err = PTR_ERR(mac);
    6.21  		xenbus_dev_error(be->dev, err, "reading %s/mac",
    6.22 @@ -98,7 +98,8 @@ static void frontend_changed(struct xenb
    6.23  	}
    6.24  	kfree(mac);
    6.25  
    6.26 -	err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref,
    6.27 +	err = xenbus_gather(NULL, be->frontpath,
    6.28 +			    "tx-ring-ref", "%lu", &tx_ring_ref,
    6.29  			    "rx-ring-ref", "%lu", &rx_ring_ref,
    6.30  			    "event-channel", "%u", &evtchn, NULL);
    6.31  	if (err) {
    6.32 @@ -137,7 +138,7 @@ static void backend_changed(struct xenbu
    6.33  	struct xenbus_device *dev = be->dev;
    6.34  	u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
    6.35  
    6.36 -	err = xenbus_scanf(dev->nodename, "handle", "%li", &handle);
    6.37 +	err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle);
    6.38  	if (XENBUS_EXIST_ERR(err))
    6.39  		return;
    6.40  	if (err < 0) {
    6.41 @@ -188,7 +189,7 @@ static int netback_hotplug(struct xenbus
    6.42  
    6.43  	key = env_vars;
    6.44  	while (*key != NULL) {
    6.45 -		val = xenbus_read(xdev->nodename, *key, NULL);
    6.46 +		val = xenbus_read(NULL, xdev->nodename, *key, NULL);
    6.47  		if (!IS_ERR(val)) {
    6.48  			char buf[strlen(*key) + 4];
    6.49  			sprintf(buf, "%s=%%s", *key);
    6.50 @@ -220,7 +221,7 @@ static int netback_probe(struct xenbus_d
    6.51  	memset(be, 0, sizeof(*be));
    6.52  
    6.53  	frontend = NULL;
    6.54 -	err = xenbus_gather(dev->nodename,
    6.55 +	err = xenbus_gather(NULL, dev->nodename,
    6.56  			    "frontend-id", "%li", &be->frontend_id,
    6.57  			    "frontend", NULL, &frontend,
    6.58  			    NULL);
    6.59 @@ -232,7 +233,7 @@ static int netback_probe(struct xenbus_d
    6.60  				 dev->nodename);
    6.61  		goto free_be;
    6.62  	}
    6.63 -	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
    6.64 +	if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
    6.65  		/* If we can't get a frontend path and a frontend-id,
    6.66  		 * then our bus-id is no longer valid and we need to
    6.67  		 * destroy the backend device.
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sun Oct 09 20:55:53 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sun Oct 09 21:29:10 2005 +0100
     7.3 @@ -1083,10 +1083,11 @@ static int talk_to_backend(struct xenbus
     7.4  {
     7.5  	char *backend, *mac, *e, *s;
     7.6  	const char *message;
     7.7 +	struct xenbus_transaction *xbt;
     7.8  	int err, i;
     7.9  
    7.10  	backend = NULL;
    7.11 -	err = xenbus_gather(dev->nodename,
    7.12 +	err = xenbus_gather(NULL, dev->nodename,
    7.13  			    "backend-id", "%i", &info->backend_id,
    7.14  			    "backend", NULL, &backend,
    7.15  			    NULL);
    7.16 @@ -1102,7 +1103,7 @@ static int talk_to_backend(struct xenbus
    7.17  		goto out;
    7.18  	}
    7.19  
    7.20 -	mac = xenbus_read(dev->nodename, "mac", NULL);
    7.21 +	mac = xenbus_read(NULL, dev->nodename, "mac", NULL);
    7.22  	if (IS_ERR(mac)) {
    7.23  		err = PTR_ERR(mac);
    7.24  		xenbus_dev_error(dev, err, "reading %s/mac",
    7.25 @@ -1131,32 +1132,32 @@ static int talk_to_backend(struct xenbus
    7.26  	}
    7.27  
    7.28  again:
    7.29 -	err = xenbus_transaction_start();
    7.30 -	if (err) {
    7.31 +	xbt = xenbus_transaction_start();
    7.32 +	if (IS_ERR(xbt)) {
    7.33  		xenbus_dev_error(dev, err, "starting transaction");
    7.34  		goto destroy_ring;
    7.35  	}
    7.36  
    7.37 -	err = xenbus_printf(dev->nodename, "tx-ring-ref","%u",
    7.38 +	err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
    7.39  			    info->tx_ring_ref);
    7.40  	if (err) {
    7.41  		message = "writing tx ring-ref";
    7.42  		goto abort_transaction;
    7.43  	}
    7.44 -	err = xenbus_printf(dev->nodename, "rx-ring-ref","%u",
    7.45 +	err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
    7.46  			    info->rx_ring_ref);
    7.47  	if (err) {
    7.48  		message = "writing rx ring-ref";
    7.49  		goto abort_transaction;
    7.50  	}
    7.51 -	err = xenbus_printf(dev->nodename,
    7.52 +	err = xenbus_printf(xbt, dev->nodename,
    7.53  			    "event-channel", "%u", info->evtchn);
    7.54  	if (err) {
    7.55  		message = "writing event-channel";
    7.56  		goto abort_transaction;
    7.57  	}
    7.58  
    7.59 -	err = xenbus_transaction_end(0);
    7.60 +	err = xenbus_transaction_end(xbt, 0);
    7.61  	if (err) {
    7.62  		if (err == -EAGAIN)
    7.63  			goto again;
    7.64 @@ -1177,8 +1178,7 @@ again:
    7.65  	return 0;
    7.66  
    7.67   abort_transaction:
    7.68 -	xenbus_transaction_end(1);
    7.69 -	/* Have to do this *outside* transaction.  */
    7.70 +	xenbus_transaction_end(xbt, 1);
    7.71  	xenbus_dev_error(dev, err, "%s", message);
    7.72   destroy_ring:
    7.73  	shutdown_device(info);
    7.74 @@ -1201,7 +1201,7 @@ static int netfront_probe(struct xenbus_
    7.75  	struct netfront_info *info;
    7.76  	unsigned int handle;
    7.77  
    7.78 -	err = xenbus_scanf(dev->nodename, "handle", "%u", &handle);
    7.79 +	err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
    7.80  	if (XENBUS_EXIST_ERR(err))
    7.81  		return err;
    7.82  	if (err < 0) {
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Sun Oct 09 20:55:53 2005 +0100
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Sun Oct 09 21:29:10 2005 +0100
     8.3 @@ -66,12 +66,13 @@ static void frontend_changed(struct xenb
     8.4  	unsigned int evtchn;
     8.5  	unsigned long ready = 1;
     8.6  	int err;
     8.7 +	struct xenbus_transaction *xbt;
     8.8  	struct backend_info *be
     8.9  		= container_of(watch, struct backend_info, watch);
    8.10  
    8.11  	/* If other end is gone, delete ourself. */
    8.12 -	if (vec && !xenbus_exists(be->frontpath, "")) {
    8.13 -		xenbus_rm(be->dev->nodename, "");
    8.14 +	if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
    8.15 +		xenbus_rm(NULL, be->dev->nodename, "");
    8.16  		device_unregister(&be->dev->dev);
    8.17  		return;
    8.18  	}
    8.19 @@ -79,7 +80,7 @@ static void frontend_changed(struct xenb
    8.20  	if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
    8.21  		return;
    8.22  
    8.23 -	err = xenbus_gather(be->frontpath,
    8.24 +	err = xenbus_gather(NULL, be->frontpath,
    8.25  	                    "ring-ref", "%lu", &ringref,
    8.26  			    "event-channel", "%u", &evtchn, NULL);
    8.27  	if (err) {
    8.28 @@ -115,20 +116,20 @@ static void frontend_changed(struct xenb
    8.29  	 * unless something bad happens
    8.30  	 */
    8.31  again:
    8.32 -	err = xenbus_transaction_start();
    8.33 -	if (err) {
    8.34 +	xbt = xenbus_transaction_start();
    8.35 +	if (IS_ERR(xbt)) {
    8.36  		xenbus_dev_error(be->dev, err, "starting transaction");
    8.37  		return;
    8.38  	}
    8.39  
    8.40 -	err = xenbus_printf(be->dev->nodename,
    8.41 +	err = xenbus_printf(xbt, be->dev->nodename,
    8.42  	                    "ready", "%lu", ready);
    8.43  	if (err) {
    8.44  		xenbus_dev_error(be->dev, err, "writing 'ready'");
    8.45  		goto abort;
    8.46  	}
    8.47  
    8.48 -	err = xenbus_transaction_end(0);
    8.49 +	err = xenbus_transaction_end(xbt, 0);
    8.50  	if (err == -EAGAIN)
    8.51  		goto again;
    8.52  	if (err) {
    8.53 @@ -139,7 +140,7 @@ again:
    8.54  	xenbus_dev_ok(be->dev);
    8.55  	return;
    8.56  abort:
    8.57 -	xenbus_transaction_end(1);
    8.58 +	xenbus_transaction_end(xbt, 1);
    8.59  }
    8.60  
    8.61  
    8.62 @@ -152,7 +153,7 @@ static void backend_changed(struct xenbu
    8.63  		= container_of(watch, struct backend_info, backend_watch);
    8.64  	struct xenbus_device *dev = be->dev;
    8.65  
    8.66 -	err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
    8.67 +	err = xenbus_scanf(NULL, dev->nodename, "instance", "%li", &instance);
    8.68  	if (XENBUS_EXIST_ERR(err))
    8.69  		return;
    8.70  	if (err < 0) {
    8.71 @@ -205,7 +206,7 @@ static int tpmback_probe(struct xenbus_d
    8.72  	memset(be, 0, sizeof(*be));
    8.73  
    8.74  	frontend = NULL;
    8.75 -	err = xenbus_gather(dev->nodename,
    8.76 +	err = xenbus_gather(NULL, dev->nodename,
    8.77  			    "frontend-id", "%li", &be->frontend_id,
    8.78  			    "frontend", NULL, &frontend,
    8.79  			    NULL);
    8.80 @@ -217,7 +218,7 @@ static int tpmback_probe(struct xenbus_d
    8.81  				 dev->nodename);
    8.82  		goto free_be;
    8.83  	}
    8.84 -	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
    8.85 +	if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
    8.86  		/* If we can't get a frontend path and a frontend-id,
    8.87  		 * then our bus-id is no longer valid and we need to
    8.88  		 * destroy the backend device.
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Sun Oct 09 20:55:53 2005 +0100
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Sun Oct 09 21:29:10 2005 +0100
     9.3 @@ -226,7 +226,7 @@ static void watch_for_status(struct xenb
     9.4  	if (tp->connected)
     9.5  		return;
     9.6  
     9.7 -	err = xenbus_gather(watch->node,
     9.8 +	err = xenbus_gather(NULL, watch->node,
     9.9  	                    "ready", "%lu", &ready,
    9.10  	                    NULL);
    9.11  	if (err) {
    9.12 @@ -311,9 +311,10 @@ static int talk_to_backend(struct xenbus
    9.13  	const char *message;
    9.14  	int err;
    9.15  	int backend_id;
    9.16 +	struct xenbus_transaction *xbt;
    9.17  
    9.18  	backend = NULL;
    9.19 -	err = xenbus_gather(dev->nodename,
    9.20 +	err = xenbus_gather(NULL, dev->nodename,
    9.21  			    "backend-id", "%i", &backend_id,
    9.22  			    "backend", NULL, &backend,
    9.23  			    NULL);
    9.24 @@ -339,27 +340,27 @@ static int talk_to_backend(struct xenbus
    9.25  	}
    9.26  
    9.27  again:
    9.28 -	err = xenbus_transaction_start();
    9.29 -	if (err) {
    9.30 +	xbt = xenbus_transaction_start();
    9.31 +	if (IS_ERR(xbt)) {
    9.32  		xenbus_dev_error(dev, err, "starting transaction");
    9.33  		goto destroy_tpmring;
    9.34  	}
    9.35  
    9.36 -	err = xenbus_printf(dev->nodename,
    9.37 +	err = xenbus_printf(xbt, dev->nodename,
    9.38  	                    "ring-ref","%u", info->ring_ref);
    9.39  	if (err) {
    9.40  		message = "writing ring-ref";
    9.41  		goto abort_transaction;
    9.42  	}
    9.43  
    9.44 -	err = xenbus_printf(dev->nodename,
    9.45 +	err = xenbus_printf(xbt, dev->nodename,
    9.46  			    "event-channel", "%u", my_private.evtchn);
    9.47  	if (err) {
    9.48  		message = "writing event-channel";
    9.49  		goto abort_transaction;
    9.50  	}
    9.51  
    9.52 -	err = xenbus_transaction_end(0);
    9.53 +	err = xenbus_transaction_end(xbt, 0);
    9.54  	if (err == -EAGAIN)
    9.55  		goto again;
    9.56  	if (err) {
    9.57 @@ -380,8 +381,7 @@ again:
    9.58  	return 0;
    9.59  
    9.60  abort_transaction:
    9.61 -	xenbus_transaction_end(1);
    9.62 -	/* Have to do this *outside* transaction.  */
    9.63 +	xenbus_transaction_end(xbt, 1);
    9.64  	xenbus_dev_error(dev, err, "%s", message);
    9.65  destroy_tpmring:
    9.66  	destroy_tpmring(info, &my_private);
    9.67 @@ -399,7 +399,7 @@ static int tpmfront_probe(struct xenbus_
    9.68  	struct tpmfront_info *info;
    9.69  	int handle;
    9.70  
    9.71 -	err = xenbus_scanf(dev->nodename,
    9.72 +	err = xenbus_scanf(NULL, dev->nodename,
    9.73  	                   "handle", "%i", &handle);
    9.74  	if (XENBUS_EXIST_ERR(err))
    9.75  		return err;
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Sun Oct 09 20:55:53 2005 +0100
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Sun Oct 09 21:29:10 2005 +0100
    10.3 @@ -181,7 +181,7 @@ static int xenbus_dev_release(struct ino
    10.4  	struct xenbus_dev_data *u = filp->private_data;
    10.5  
    10.6  	if (u->in_transaction)
    10.7 -		xenbus_transaction_end(1);
    10.8 +		xenbus_transaction_end((struct xenbus_transaction *)1, 1);
    10.9  
   10.10  	kfree(u);
   10.11  
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Sun Oct 09 20:55:53 2005 +0100
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Sun Oct 09 21:29:10 2005 +0100
    11.3 @@ -128,7 +128,7 @@ static int backend_bus_id(char bus_id[BU
    11.4  
    11.5  	devid = strrchr(nodename, '/') + 1;
    11.6  
    11.7 -	err = xenbus_gather(nodename, "frontend-id", "%i", &domid,
    11.8 +	err = xenbus_gather(NULL, nodename, "frontend-id", "%i", &domid,
    11.9  			    "frontend", NULL, &frontend,
   11.10  			    NULL);
   11.11  	if (err)
   11.12 @@ -136,7 +136,7 @@ static int backend_bus_id(char bus_id[BU
   11.13  	if (strlen(frontend) == 0)
   11.14  		err = -ERANGE;
   11.15  
   11.16 -	if (!err && !xenbus_exists(frontend, ""))
   11.17 +	if (!err && !xenbus_exists(NULL, frontend, ""))
   11.18  		err = -ENOENT;
   11.19  
   11.20  	if (err) {
   11.21 @@ -450,7 +450,7 @@ static int xenbus_probe_backend(const ch
   11.22  	if (!nodename)
   11.23  		return -ENOMEM;
   11.24  
   11.25 -	dir = xenbus_directory(nodename, "", &dir_n);
   11.26 +	dir = xenbus_directory(NULL, nodename, "", &dir_n);
   11.27  	if (IS_ERR(dir)) {
   11.28  		kfree(nodename);
   11.29  		return PTR_ERR(dir);
   11.30 @@ -473,7 +473,7 @@ static int xenbus_probe_device_type(stru
   11.31  	unsigned int dir_n = 0;
   11.32  	int i;
   11.33  
   11.34 -	dir = xenbus_directory(bus->root, type, &dir_n);
   11.35 +	dir = xenbus_directory(NULL, bus->root, type, &dir_n);
   11.36  	if (IS_ERR(dir))
   11.37  		return PTR_ERR(dir);
   11.38  
   11.39 @@ -492,7 +492,7 @@ static int xenbus_probe_devices(struct x
   11.40  	char **dir;
   11.41  	unsigned int i, dir_n;
   11.42  
   11.43 -	dir = xenbus_directory(bus->root, "", &dir_n);
   11.44 +	dir = xenbus_directory(NULL, bus->root, "", &dir_n);
   11.45  	if (IS_ERR(dir))
   11.46  		return PTR_ERR(dir);
   11.47  
   11.48 @@ -538,7 +538,7 @@ static void dev_changed(const char *node
   11.49  	if (char_count(node, '/') < 2)
   11.50   		return;
   11.51  
   11.52 -	exists = xenbus_exists(node, "");
   11.53 +	exists = xenbus_exists(NULL, node, "");
   11.54  	if (!exists) {
   11.55  		xenbus_cleanup_devices(node, &bus->bus);
   11.56  		return;
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Sun Oct 09 20:55:53 2005 +0100
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Sun Oct 09 21:29:10 2005 +0100
    12.3 @@ -316,7 +316,8 @@ static char **split(char *strings, unsig
    12.4  	return ret;
    12.5  }
    12.6  
    12.7 -char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
    12.8 +char **xenbus_directory(struct xenbus_transaction *t,
    12.9 +			const char *dir, const char *node, unsigned int *num)
   12.10  {
   12.11  	char *strings;
   12.12  	unsigned int len;
   12.13 @@ -330,12 +331,13 @@ char **xenbus_directory(const char *dir,
   12.14  EXPORT_SYMBOL(xenbus_directory);
   12.15  
   12.16  /* Check if a path exists. Return 1 if it does. */
   12.17 -int xenbus_exists(const char *dir, const char *node)
   12.18 +int xenbus_exists(struct xenbus_transaction *t,
   12.19 +		  const char *dir, const char *node)
   12.20  {
   12.21  	char **d;
   12.22  	int dir_n;
   12.23  
   12.24 -	d = xenbus_directory(dir, node, &dir_n);
   12.25 +	d = xenbus_directory(t, dir, node, &dir_n);
   12.26  	if (IS_ERR(d))
   12.27  		return 0;
   12.28  	kfree(d);
   12.29 @@ -347,7 +349,8 @@ EXPORT_SYMBOL(xenbus_exists);
   12.30   * Returns a kmalloced value: call free() on it after use.
   12.31   * len indicates length in bytes.
   12.32   */
   12.33 -void *xenbus_read(const char *dir, const char *node, unsigned int *len)
   12.34 +void *xenbus_read(struct xenbus_transaction *t,
   12.35 +		  const char *dir, const char *node, unsigned int *len)
   12.36  {
   12.37  	return xs_single(XS_READ, join(dir, node), len);
   12.38  }
   12.39 @@ -356,7 +359,8 @@ EXPORT_SYMBOL(xenbus_read);
   12.40  /* Write the value of a single file.
   12.41   * Returns -err on failure.
   12.42   */
   12.43 -int xenbus_write(const char *dir, const char *node, const char *string)
   12.44 +int xenbus_write(struct xenbus_transaction *t,
   12.45 +		 const char *dir, const char *node, const char *string)
   12.46  {
   12.47  	const char *path;
   12.48  	struct kvec iovec[2];
   12.49 @@ -373,14 +377,15 @@ int xenbus_write(const char *dir, const 
   12.50  EXPORT_SYMBOL(xenbus_write);
   12.51  
   12.52  /* Create a new directory. */
   12.53 -int xenbus_mkdir(const char *dir, const char *node)
   12.54 +int xenbus_mkdir(struct xenbus_transaction *t,
   12.55 +		 const char *dir, const char *node)
   12.56  {
   12.57  	return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL));
   12.58  }
   12.59  EXPORT_SYMBOL(xenbus_mkdir);
   12.60  
   12.61  /* Destroy a file or directory (directories must be empty). */
   12.62 -int xenbus_rm(const char *dir, const char *node)
   12.63 +int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
   12.64  {
   12.65  	return xs_error(xs_single(XS_RM, join(dir, node), NULL));
   12.66  }
   12.67 @@ -388,9 +393,8 @@ EXPORT_SYMBOL(xenbus_rm);
   12.68  
   12.69  /* Start a transaction: changes by others will not be seen during this
   12.70   * transaction, and changes will not be visible to others until end.
   12.71 - * You can only have one transaction at any time.
   12.72   */
   12.73 -int xenbus_transaction_start(void)
   12.74 +struct xenbus_transaction *xenbus_transaction_start(void)
   12.75  {
   12.76  	int err;
   12.77  
   12.78 @@ -403,18 +407,20 @@ int xenbus_transaction_start(void)
   12.79  		up(&xs_state.transaction_mutex);
   12.80  	}
   12.81  
   12.82 -	return err;
   12.83 +	return err ? ERR_PTR(err) : (struct xenbus_transaction *)1;
   12.84  }
   12.85  EXPORT_SYMBOL(xenbus_transaction_start);
   12.86  
   12.87  /* End a transaction.
   12.88   * If abandon is true, transaction is discarded instead of committed.
   12.89   */
   12.90 -int xenbus_transaction_end(int abort)
   12.91 +int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
   12.92  {
   12.93  	char abortstr[2];
   12.94  	int err;
   12.95  
   12.96 +	BUG_ON(t == NULL);
   12.97 +
   12.98  	if (abort)
   12.99  		strcpy(abortstr, "F");
  12.100  	else
  12.101 @@ -430,13 +436,14 @@ int xenbus_transaction_end(int abort)
  12.102  EXPORT_SYMBOL(xenbus_transaction_end);
  12.103  
  12.104  /* Single read and scanf: returns -errno or num scanned. */
  12.105 -int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
  12.106 +int xenbus_scanf(struct xenbus_transaction *t,
  12.107 +		 const char *dir, const char *node, const char *fmt, ...)
  12.108  {
  12.109  	va_list ap;
  12.110  	int ret;
  12.111  	char *val;
  12.112  
  12.113 -	val = xenbus_read(dir, node, NULL);
  12.114 +	val = xenbus_read(t, dir, node, NULL);
  12.115  	if (IS_ERR(val))
  12.116  		return PTR_ERR(val);
  12.117  
  12.118 @@ -452,7 +459,8 @@ int xenbus_scanf(const char *dir, const 
  12.119  EXPORT_SYMBOL(xenbus_scanf);
  12.120  
  12.121  /* Single printf and write: returns -errno or 0. */
  12.122 -int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
  12.123 +int xenbus_printf(struct xenbus_transaction *t,
  12.124 +		  const char *dir, const char *node, const char *fmt, ...)
  12.125  {
  12.126  	va_list ap;
  12.127  	int ret;
  12.128 @@ -468,7 +476,7 @@ int xenbus_printf(const char *dir, const
  12.129  	va_end(ap);
  12.130  
  12.131  	BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
  12.132 -	ret = xenbus_write(dir, node, printf_buffer);
  12.133 +	ret = xenbus_write(t, dir, node, printf_buffer);
  12.134  
  12.135  	kfree(printf_buffer);
  12.136  
  12.137 @@ -495,7 +503,7 @@ void xenbus_dev_error(struct xenbus_devi
  12.138  
  12.139  	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
  12.140  	dev->has_error = 1;
  12.141 -	if (xenbus_write(dev->nodename, "error", printf_buffer) != 0)
  12.142 +	if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0)
  12.143  		goto fail;
  12.144  
  12.145  	kfree(printf_buffer);
  12.146 @@ -511,7 +519,7 @@ EXPORT_SYMBOL(xenbus_dev_error);
  12.147  void xenbus_dev_ok(struct xenbus_device *dev)
  12.148  {
  12.149  	if (dev->has_error) {
  12.150 -		if (xenbus_rm(dev->nodename, "error") != 0)
  12.151 +		if (xenbus_rm(NULL, dev->nodename, "error") != 0)
  12.152  			printk("xenbus: failed to clear error node for %s\n",
  12.153  			       dev->nodename);
  12.154  		else
  12.155 @@ -521,7 +529,7 @@ void xenbus_dev_ok(struct xenbus_device 
  12.156  EXPORT_SYMBOL(xenbus_dev_ok);
  12.157  	
  12.158  /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
  12.159 -int xenbus_gather(const char *dir, ...)
  12.160 +int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
  12.161  {
  12.162  	va_list ap;
  12.163  	const char *name;
  12.164 @@ -533,7 +541,7 @@ int xenbus_gather(const char *dir, ...)
  12.165  		void *result = va_arg(ap, void *);
  12.166  		char *p;
  12.167  
  12.168 -		p = xenbus_read(dir, name, NULL);
  12.169 +		p = xenbus_read(t, dir, name, NULL);
  12.170  		if (IS_ERR(p)) {
  12.171  			ret = PTR_ERR(p);
  12.172  			break;
    13.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Sun Oct 09 20:55:53 2005 +0100
    13.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Sun Oct 09 21:29:10 2005 +0100
    13.3 @@ -78,26 +78,35 @@ int xenbus_register_driver(struct xenbus
    13.4  int xenbus_register_backend(struct xenbus_driver *drv);
    13.5  void xenbus_unregister_driver(struct xenbus_driver *drv);
    13.6  
    13.7 -char **xenbus_directory(const char *dir, const char *node, unsigned int *num);
    13.8 -void *xenbus_read(const char *dir, const char *node, unsigned int *len);
    13.9 -int xenbus_write(const char *dir, const char *node, const char *string);
   13.10 -int xenbus_mkdir(const char *dir, const char *node);
   13.11 -int xenbus_exists(const char *dir, const char *node);
   13.12 -int xenbus_rm(const char *dir, const char *node);
   13.13 -int xenbus_transaction_start(void);
   13.14 -int xenbus_transaction_end(int abort);
   13.15 +struct xenbus_transaction;
   13.16 +
   13.17 +char **xenbus_directory(struct xenbus_transaction *t,
   13.18 +			const char *dir, const char *node, unsigned int *num);
   13.19 +void *xenbus_read(struct xenbus_transaction *t,
   13.20 +		  const char *dir, const char *node, unsigned int *len);
   13.21 +int xenbus_write(struct xenbus_transaction *t,
   13.22 +		 const char *dir, const char *node, const char *string);
   13.23 +int xenbus_mkdir(struct xenbus_transaction *t,
   13.24 +		 const char *dir, const char *node);
   13.25 +int xenbus_exists(struct xenbus_transaction *t,
   13.26 +		  const char *dir, const char *node);
   13.27 +int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
   13.28 +struct xenbus_transaction *xenbus_transaction_start(void);
   13.29 +int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
   13.30  
   13.31  /* Single read and scanf: returns -errno or num scanned if > 0. */
   13.32 -int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
   13.33 -	__attribute__((format(scanf, 3, 4)));
   13.34 +int xenbus_scanf(struct xenbus_transaction *t,
   13.35 +		 const char *dir, const char *node, const char *fmt, ...)
   13.36 +	__attribute__((format(scanf, 4, 5)));
   13.37  
   13.38  /* Single printf and write: returns -errno or 0. */
   13.39 -int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
   13.40 -	__attribute__((format(printf, 3, 4)));
   13.41 +int xenbus_printf(struct xenbus_transaction *t,
   13.42 +		  const char *dir, const char *node, const char *fmt, ...)
   13.43 +	__attribute__((format(printf, 4, 5)));
   13.44  
   13.45  /* Generic read function: NULL-terminated triples of name,
   13.46   * sprintf-style type string, and pointer. Returns 0 or errno.*/
   13.47 -int xenbus_gather(const char *dir, ...);
   13.48 +int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
   13.49  
   13.50  /* Report a (negative) errno into the store, with explanation. */
   13.51  void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,...);
    14.1 --- a/tools/console/client/main.c	Sun Oct 09 20:55:53 2005 +0100
    14.2 +++ b/tools/console/client/main.c	Sun Oct 09 21:29:10 2005 +0100
    14.3 @@ -220,7 +220,7 @@ int main(int argc, char **argv)
    14.4  	if (path == NULL)
    14.5  		err(ENOMEM, "realloc");
    14.6  	strcat(path, "/console/tty");
    14.7 -	str_pty = xs_read(xs, path, &len);
    14.8 +	str_pty = xs_read(xs, NULL, path, &len);
    14.9  
   14.10  	/* FIXME consoled currently does not assume domain-0 doesn't have a
   14.11  	   console which is good when we break domain-0 up.  To keep us
   14.12 @@ -245,7 +245,7 @@ int main(int argc, char **argv)
   14.13  		struct timeval tv = { 0, 500 };
   14.14  		select(0, NULL, NULL, NULL, &tv); /* pause briefly */
   14.15  
   14.16 -		str_pty = xs_read(xs, path, &len);
   14.17 +		str_pty = xs_read(xs, NULL, path, &len);
   14.18  	}
   14.19  
   14.20  	if (str_pty == NULL) {
    15.1 --- a/tools/console/daemon/io.c	Sun Oct 09 20:55:53 2005 +0100
    15.2 +++ b/tools/console/daemon/io.c	Sun Oct 09 21:29:10 2005 +0100
    15.3 @@ -179,7 +179,7 @@ static int domain_create_tty(struct doma
    15.4  		success = asprintf(&path, "%s/tty", dom->conspath) != -1;
    15.5  		if (!success)
    15.6  			goto out;
    15.7 -		success = xs_write(xs, path, slave, strlen(slave));
    15.8 +		success = xs_write(xs, NULL, path, slave, strlen(slave));
    15.9  		free(path);
   15.10  		if (!success)
   15.11  			goto out;
   15.12 @@ -187,7 +187,7 @@ static int domain_create_tty(struct doma
   15.13  		success = asprintf(&path, "%s/limit", dom->conspath) != -1;
   15.14  		if (!success)
   15.15  			goto out;
   15.16 -		data = xs_read(xs, path, &len);
   15.17 +		data = xs_read(xs, NULL, path, &len);
   15.18  		if (data) {
   15.19  			dom->buffer.max_capacity = strtoul(data, 0, 0);
   15.20  			free(data);
   15.21 @@ -216,7 +216,7 @@ int xs_gather(struct xs_handle *xs, cons
   15.22  		char *p;
   15.23  
   15.24  		asprintf(&path, "%s/%s", dir, name);
   15.25 -		p = xs_read(xs, path, NULL);
   15.26 +		p = xs_read(xs, NULL, path, NULL);
   15.27  		free(path);
   15.28  		if (p == NULL) {
   15.29  			ret = ENOENT;
    16.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Sun Oct 09 20:55:53 2005 +0100
    16.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Sun Oct 09 21:29:10 2005 +0100
    16.3 @@ -80,8 +80,8 @@ static inline PyObject *pyvalue_str(char
    16.4  
    16.5  static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
    16.6  {
    16.7 -    static char *kwd_spec[] = { "path", NULL };
    16.8 -    static char *arg_spec = "s|";
    16.9 +    static char *kwd_spec[] = { "transaction", "path", NULL };
   16.10 +    static char *arg_spec = "ss";
   16.11      char *path = NULL;
   16.12  
   16.13      struct xs_handle *xh = xshandle(self);
   16.14 @@ -89,13 +89,19 @@ static PyObject *xspy_read(PyObject *sel
   16.15      unsigned int xsval_n = 0;
   16.16      PyObject *val = NULL;
   16.17  
   16.18 +    struct xs_transaction_handle *th;
   16.19 +    char *thstr;
   16.20 +
   16.21      if (!xh)
   16.22          goto exit;
   16.23      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
   16.24 -                                     &path))
   16.25 +                                     &thstr, &path))
   16.26          goto exit;
   16.27 +
   16.28 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   16.29 +
   16.30      Py_BEGIN_ALLOW_THREADS
   16.31 -    xsval = xs_read(xh, path, &xsval_n);
   16.32 +    xsval = xs_read(xh, th, path, &xsval_n);
   16.33      Py_END_ALLOW_THREADS
   16.34      if (!xsval) {
   16.35          if (errno == ENOENT) {
   16.36 @@ -123,8 +129,8 @@ static PyObject *xspy_read(PyObject *sel
   16.37  
   16.38  static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
   16.39  {
   16.40 -    static char *kwd_spec[] = { "path", "data", NULL };
   16.41 -    static char *arg_spec = "ss#";
   16.42 +    static char *kwd_spec[] = { "transaction", "path", "data", NULL };
   16.43 +    static char *arg_spec = "sss#";
   16.44      char *path = NULL;
   16.45      char *data = NULL;
   16.46      int data_n = 0;
   16.47 @@ -133,13 +139,19 @@ static PyObject *xspy_write(PyObject *se
   16.48      PyObject *val = NULL;
   16.49      int xsval = 0;
   16.50  
   16.51 +    struct xs_transaction_handle *th;
   16.52 +    char *thstr;
   16.53 +
   16.54      if (!xh)
   16.55          goto exit;
   16.56      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
   16.57 -                                     &path, &data, &data_n))
   16.58 +                                     &thstr, &path, &data, &data_n))
   16.59          goto exit;
   16.60 +
   16.61 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   16.62 +
   16.63      Py_BEGIN_ALLOW_THREADS
   16.64 -    xsval = xs_write(xh, path, data, data_n);
   16.65 +    xsval = xs_write(xh, th, path, data, data_n);
   16.66      Py_END_ALLOW_THREADS
   16.67      if (!xsval) {
   16.68          PyErr_SetFromErrno(PyExc_RuntimeError);
   16.69 @@ -162,8 +174,8 @@ static PyObject *xspy_write(PyObject *se
   16.70  
   16.71  static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
   16.72  {
   16.73 -    static char *kwd_spec[] = { "path", NULL };
   16.74 -    static char *arg_spec = "s|";
   16.75 +    static char *kwd_spec[] = { "transaction", "path", NULL };
   16.76 +    static char *arg_spec = "ss";
   16.77      char *path = NULL;
   16.78  
   16.79      struct xs_handle *xh = xshandle(self);
   16.80 @@ -172,12 +184,20 @@ static PyObject *xspy_ls(PyObject *self,
   16.81      unsigned int xsval_n = 0;
   16.82      int i;
   16.83  
   16.84 +    struct xs_transaction_handle *th;
   16.85 +    char *thstr;
   16.86 +
   16.87      if (!xh)
   16.88          goto exit;
   16.89 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
   16.90 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
   16.91 +                                     &thstr, &path))
   16.92          goto exit;
   16.93 +
   16.94 +
   16.95 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   16.96 +
   16.97      Py_BEGIN_ALLOW_THREADS
   16.98 -    xsval = xs_directory(xh, path, &xsval_n);
   16.99 +    xsval = xs_directory(xh, th, path, &xsval_n);
  16.100      Py_END_ALLOW_THREADS
  16.101      if (!xsval) {
  16.102          if (errno == ENOENT) {
  16.103 @@ -205,20 +225,27 @@ static PyObject *xspy_ls(PyObject *self,
  16.104  
  16.105  static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
  16.106  {
  16.107 -    static char *kwd_spec[] = { "path", NULL };
  16.108 -    static char *arg_spec = "s|";
  16.109 +    static char *kwd_spec[] = { "transaction", "path", NULL };
  16.110 +    static char *arg_spec = "ss";
  16.111      char *path = NULL;
  16.112  
  16.113      struct xs_handle *xh = xshandle(self);
  16.114      PyObject *val = NULL;
  16.115      int xsval = 0;
  16.116  
  16.117 +    struct xs_transaction_handle *th;
  16.118 +    char *thstr;
  16.119 +
  16.120      if (!xh)
  16.121          goto exit;
  16.122 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
  16.123 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  16.124 +                                     &thstr, &path))
  16.125          goto exit;
  16.126 +
  16.127 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  16.128 +
  16.129      Py_BEGIN_ALLOW_THREADS
  16.130 -    xsval = xs_mkdir(xh, path);
  16.131 +    xsval = xs_mkdir(xh, th, path);
  16.132      Py_END_ALLOW_THREADS
  16.133      if (!xsval) {
  16.134          PyErr_SetFromErrno(PyExc_RuntimeError);
  16.135 @@ -240,20 +267,27 @@ static PyObject *xspy_mkdir(PyObject *se
  16.136  
  16.137  static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
  16.138  {
  16.139 -    static char *kwd_spec[] = { "path", NULL };
  16.140 -    static char *arg_spec = "s|";
  16.141 +    static char *kwd_spec[] = { "transaction", "path", NULL };
  16.142 +    static char *arg_spec = "ss";
  16.143      char *path = NULL;
  16.144  
  16.145      struct xs_handle *xh = xshandle(self);
  16.146      PyObject *val = NULL;
  16.147      int xsval = 0;
  16.148  
  16.149 +    struct xs_transaction_handle *th;
  16.150 +    char *thstr;
  16.151 +
  16.152      if (!xh)
  16.153          goto exit;
  16.154 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
  16.155 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  16.156 +                                     &thstr, &path))
  16.157          goto exit;
  16.158 +
  16.159 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  16.160 +
  16.161      Py_BEGIN_ALLOW_THREADS
  16.162 -    xsval = xs_rm(xh, path);
  16.163 +    xsval = xs_rm(xh, th, path);
  16.164      Py_END_ALLOW_THREADS
  16.165      if (!xsval && errno != ENOENT) {
  16.166          PyErr_SetFromErrno(PyExc_RuntimeError);
  16.167 @@ -276,8 +310,8 @@ static PyObject *xspy_rm(PyObject *self,
  16.168  static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
  16.169                                        PyObject *kwds)
  16.170  {
  16.171 -    static char *kwd_spec[] = { "path", NULL };
  16.172 -    static char *arg_spec = "s|";
  16.173 +    static char *kwd_spec[] = { "transaction", "path", NULL };
  16.174 +    static char *arg_spec = "ss";
  16.175      char *path = NULL;
  16.176  
  16.177      struct xs_handle *xh = xshandle(self);
  16.178 @@ -286,12 +320,19 @@ static PyObject *xspy_get_permissions(Py
  16.179      unsigned int perms_n = 0;
  16.180      int i;
  16.181  
  16.182 +    struct xs_transaction_handle *th;
  16.183 +    char *thstr;
  16.184 +
  16.185      if (!xh)
  16.186          goto exit;
  16.187 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
  16.188 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  16.189 +                                     &thstr, &path))
  16.190          goto exit;
  16.191 +
  16.192 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  16.193 +
  16.194      Py_BEGIN_ALLOW_THREADS
  16.195 -    perms = xs_get_permissions(xh, path, &perms_n);
  16.196 +    perms = xs_get_permissions(xh, th, path, &perms_n);
  16.197      Py_END_ALLOW_THREADS
  16.198      if (!perms) {
  16.199          PyErr_SetFromErrno(PyExc_RuntimeError);
  16.200 @@ -321,8 +362,8 @@ static PyObject *xspy_get_permissions(Py
  16.201  static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
  16.202                                        PyObject *kwds)
  16.203  {
  16.204 -    static char *kwd_spec[] = { "path", "perms", NULL };
  16.205 -    static char *arg_spec = "sO";
  16.206 +    static char *kwd_spec[] = { "transaction", "path", "perms", NULL };
  16.207 +    static char *arg_spec = "ssO";
  16.208      char *path = NULL;
  16.209      PyObject *perms = NULL;
  16.210      static char *perm_names[] = { "dom", "read", "write", NULL };
  16.211 @@ -335,11 +376,17 @@ static PyObject *xspy_set_permissions(Py
  16.212      PyObject *tuple0 = NULL;
  16.213      PyObject *val = NULL;
  16.214  
  16.215 +    struct xs_transaction_handle *th;
  16.216 +    char *thstr;
  16.217 +
  16.218      if (!xh)
  16.219          goto exit;
  16.220      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  16.221 -                                     &path, &perms))
  16.222 +                                     &thstr, &path, &perms))
  16.223          goto exit;
  16.224 +
  16.225 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  16.226 +
  16.227      if (!PyList_Check(perms)) {
  16.228          PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
  16.229          goto exit;
  16.230 @@ -369,7 +416,7 @@ static PyObject *xspy_set_permissions(Py
  16.231              xsperms[i].perms |= XS_PERM_WRITE;
  16.232      }
  16.233      Py_BEGIN_ALLOW_THREADS
  16.234 -    xsval = xs_set_permissions(xh, path, xsperms, xsperms_n);
  16.235 +    xsval = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
  16.236      Py_END_ALLOW_THREADS
  16.237      if (!xsval) {
  16.238          PyErr_SetFromErrno(PyExc_RuntimeError);
  16.239 @@ -543,9 +590,8 @@ static PyObject *xspy_unwatch(PyObject *
  16.240  
  16.241  #define xspy_transaction_start_doc "\n"				\
  16.242  	"Start a transaction.\n"				\
  16.243 -	"Only one transaction can be active at a time.\n"	\
  16.244  	"\n"							\
  16.245 -	"Returns None on success.\n"				\
  16.246 +	"Returns transaction handle on success.\n"		\
  16.247  	"Raises RuntimeError on error.\n"			\
  16.248  	"\n"
  16.249  
  16.250 @@ -558,21 +604,23 @@ static PyObject *xspy_transaction_start(
  16.251  
  16.252      struct xs_handle *xh = xshandle(self);
  16.253      PyObject *val = NULL;
  16.254 -    int xsval = 0;
  16.255 +    struct xs_transaction_handle *th;
  16.256 +    char thstr[20];
  16.257  
  16.258      if (!xh)
  16.259          goto exit;
  16.260      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
  16.261          goto exit;
  16.262      Py_BEGIN_ALLOW_THREADS
  16.263 -    xsval = xs_transaction_start(xh);
  16.264 +    th = xs_transaction_start(xh);
  16.265      Py_END_ALLOW_THREADS
  16.266 -    if (!xsval) {
  16.267 +    if (th == NULL) {
  16.268          PyErr_SetFromErrno(PyExc_RuntimeError);
  16.269          goto exit;
  16.270      }
  16.271 -    Py_INCREF(Py_None);
  16.272 -    val = Py_None;
  16.273 +
  16.274 +    sprintf(thstr, "%lX", (unsigned long)th);
  16.275 +    val = PyString_FromString(thstr);
  16.276   exit:
  16.277      return val;
  16.278  }
  16.279 @@ -589,20 +637,27 @@ static PyObject *xspy_transaction_start(
  16.280  static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
  16.281                                        PyObject *kwds)
  16.282  {
  16.283 -    static char *kwd_spec[] = { "abort", NULL };
  16.284 -    static char *arg_spec = "|i";
  16.285 +    static char *kwd_spec[] = { "transaction", "abort", NULL };
  16.286 +    static char *arg_spec = "s|i";
  16.287      int abort = 0;
  16.288  
  16.289      struct xs_handle *xh = xshandle(self);
  16.290      PyObject *val = NULL;
  16.291      int xsval = 0;
  16.292  
  16.293 +    struct xs_transaction_handle *th;
  16.294 +    char *thstr;
  16.295 +
  16.296      if (!xh)
  16.297          goto exit;
  16.298 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
  16.299 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  16.300 +                                     &thstr, &abort))
  16.301          goto exit;
  16.302 +
  16.303 +    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  16.304 +
  16.305      Py_BEGIN_ALLOW_THREADS
  16.306 -    xsval = xs_transaction_end(xh, abort);
  16.307 +    xsval = xs_transaction_end(xh, th, abort);
  16.308      Py_END_ALLOW_THREADS
  16.309      if (!xsval) {
  16.310  	if (errno == EAGAIN) {
    17.1 --- a/tools/python/xen/xend/xenstore/xstransact.py	Sun Oct 09 20:55:53 2005 +0100
    17.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py	Sun Oct 09 21:29:10 2005 +0100
    17.3 @@ -14,29 +14,34 @@ from xen.xend.xenstore.xsutil import xsh
    17.4  class xstransact:
    17.5  
    17.6      def __init__(self, path):
    17.7 -        self.in_transaction = False
    17.8          self.path = path.rstrip("/")
    17.9 -        xshandle().transaction_start()
   17.10 +        self.transaction = xshandle().transaction_start()
   17.11          self.in_transaction = True
   17.12  
   17.13      def __del__(self):
   17.14          if self.in_transaction:
   17.15 -            xshandle().transaction_end(True)
   17.16 +            xshandle().transaction_end(self.transaction, True)
   17.17  
   17.18      def commit(self):
   17.19          if not self.in_transaction:
   17.20              raise RuntimeError
   17.21          self.in_transaction = False
   17.22 -        return xshandle().transaction_end(False)
   17.23 +        rc = xshandle().transaction_end(self.transaction, False)
   17.24 +        self.transaction = "0"
   17.25 +        return rc
   17.26  
   17.27      def abort(self):
   17.28 +        if not self.in_transaction:
   17.29 +            return True
   17.30          self.in_transaction = False
   17.31 -        return xshandle().transaction_end(True)
   17.32 +        rc = xshandle().transaction_end(self.transaction, True)
   17.33 +        self.transaction = "0"
   17.34 +        return rc
   17.35  
   17.36      def _read(self, key):
   17.37          path = "%s/%s" % (self.path, key)
   17.38          try:
   17.39 -            return xshandle().read(path)
   17.40 +            return xshandle().read(self.transaction, path)
   17.41          except RuntimeError, ex:
   17.42              raise RuntimeError(ex.args[0],
   17.43                                 '%s, while reading %s' % (ex.args[1], path))
   17.44 @@ -50,7 +55,7 @@ class xstransact:
   17.45          instead.
   17.46          """
   17.47          if len(args) == 0:
   17.48 -            return xshandle().read(self.path)
   17.49 +            return xshandle().read(self.transaction, self.path)
   17.50          if len(args) == 1:
   17.51              return self._read(args[0])
   17.52          ret = []
   17.53 @@ -61,7 +66,7 @@ class xstransact:
   17.54      def _write(self, key, data):
   17.55          path = "%s/%s" % (self.path, key)
   17.56          try:
   17.57 -            xshandle().write(path, data)
   17.58 +            xshandle().write(self.transaction, path, data)
   17.59          except RuntimeError, ex:
   17.60              raise RuntimeError(ex.args[0],
   17.61                                 ('%s, while writing %s : %s' %
   17.62 @@ -93,7 +98,7 @@ class xstransact:
   17.63  
   17.64      def _remove(self, key):
   17.65          path = "%s/%s" % (self.path, key)
   17.66 -        return xshandle().rm(path)
   17.67 +        return xshandle().rm(self.transaction, path)
   17.68  
   17.69      def remove(self, *args):
   17.70          """If no arguments are given, remove this transaction's path.
   17.71 @@ -101,14 +106,14 @@ class xstransact:
   17.72          path, and remove each of those instead.
   17.73          """
   17.74          if len(args) == 0:
   17.75 -            xshandle().rm(self.path)
   17.76 +            xshandle().rm(self.transaction, self.path)
   17.77          else:
   17.78              for key in args:
   17.79                  self._remove(key)
   17.80  
   17.81      def _list(self, key):
   17.82          path = "%s/%s" % (self.path, key)
   17.83 -        l = xshandle().ls(path)
   17.84 +        l = xshandle().ls(self.transaction, path)
   17.85          if l:
   17.86              return map(lambda x: key + "/" + x, l)
   17.87          return []
   17.88 @@ -120,7 +125,7 @@ class xstransact:
   17.89          path, and return the cumulative listing of each of those instead.
   17.90          """
   17.91          if len(args) == 0:
   17.92 -            ret = xshandle().ls(self.path)
   17.93 +            ret = xshandle().ls(self.transaction, self.path)
   17.94              if ret is None:
   17.95                  return []
   17.96              else:
   17.97 @@ -136,11 +141,11 @@ class xstransact:
   17.98          ret = []
   17.99          for key in keys:
  17.100              new_subdir = subdir + "/" + key
  17.101 -            l = xshandle().ls(new_subdir)
  17.102 +            l = xshandle().ls(self.transaction, new_subdir)
  17.103              if l:
  17.104                  ret.append([key, self.list_recursive_(new_subdir, l)])
  17.105              else:
  17.106 -                ret.append([key, xshandle().read(new_subdir)])
  17.107 +                ret.append([key, xshandle().read(self.transaction, new_subdir)])
  17.108          return ret
  17.109  
  17.110  
    18.1 --- a/tools/xenstore/Makefile	Sun Oct 09 20:55:53 2005 +0100
    18.2 +++ b/tools/xenstore/Makefile	Sun Oct 09 21:29:10 2005 +0100
    18.3 @@ -8,7 +8,7 @@ INSTALL_PROG    = $(INSTALL) -m0755
    18.4  INSTALL_DIR     = $(INSTALL) -d -m0755
    18.5  
    18.6  PROFILE=#-pg
    18.7 -BASECFLAGS=-Wall -W -g -Werror
    18.8 +BASECFLAGS=-Wall -g -Werror
    18.9  # Make gcc generate dependencies.
   18.10  BASECFLAGS += -Wp,-MD,.$(@F).d
   18.11  PROG_DEP = .*.d
    19.1 --- a/tools/xenstore/xenstore_client.c	Sun Oct 09 20:55:53 2005 +0100
    19.2 +++ b/tools/xenstore/xenstore_client.c	Sun Oct 09 21:29:10 2005 +0100
    19.3 @@ -32,6 +32,7 @@ int
    19.4  main(int argc, char **argv)
    19.5  {
    19.6      struct xs_handle *xsh;
    19.7 +    struct xs_transaction_handle *xth;
    19.8      bool success;
    19.9      int ret = 0;
   19.10  #if defined(CLIENT_read) || defined(CLIENT_list)
   19.11 @@ -84,13 +85,13 @@ main(int argc, char **argv)
   19.12  #endif
   19.13  
   19.14    again:
   19.15 -    success = xs_transaction_start(xsh);
   19.16 -    if (!success)
   19.17 +    xth = xs_transaction_start(xsh);
   19.18 +    if (xth == NULL)
   19.19  	errx(1, "couldn't start transaction");
   19.20  
   19.21      while (optind < argc) {
   19.22  #if defined(CLIENT_read)
   19.23 -	char *val = xs_read(xsh, argv[optind], NULL);
   19.24 +	char *val = xs_read(xsh, xth, argv[optind], NULL);
   19.25  	if (val == NULL) {
   19.26  	    warnx("couldn't read path %s", argv[optind]);
   19.27  	    ret = 1;
   19.28 @@ -102,7 +103,7 @@ main(int argc, char **argv)
   19.29  	free(val);
   19.30  	optind++;
   19.31  #elif defined(CLIENT_write)
   19.32 -	success = xs_write(xsh, argv[optind], argv[optind + 1],
   19.33 +	success = xs_write(xsh, xth, argv[optind], argv[optind + 1],
   19.34  			   strlen(argv[optind + 1]));
   19.35  	if (!success) {
   19.36  	    warnx("could not write path %s", argv[optind]);
   19.37 @@ -111,7 +112,7 @@ main(int argc, char **argv)
   19.38  	}
   19.39  	optind += 2;
   19.40  #elif defined(CLIENT_rm)
   19.41 -	success = xs_rm(xsh, argv[optind]);
   19.42 +	success = xs_rm(xsh, xth, argv[optind]);
   19.43  	if (!success) {
   19.44  	    warnx("could not remove path %s", argv[optind]);
   19.45  	    ret = 1;
   19.46 @@ -119,7 +120,7 @@ main(int argc, char **argv)
   19.47  	}
   19.48  	optind++;
   19.49  #elif defined(CLIENT_exists)
   19.50 -	char *val = xs_read(xsh, argv[optind], NULL);
   19.51 +	char *val = xs_read(xsh, xth, argv[optind], NULL);
   19.52  	if (val == NULL) {
   19.53  	    ret = 1;
   19.54  	    goto out;
   19.55 @@ -128,7 +129,7 @@ main(int argc, char **argv)
   19.56  	optind++;
   19.57  #elif defined(CLIENT_list)
   19.58  	unsigned int i, num;
   19.59 -	char **list = xs_directory(xsh, argv[optind], &num);
   19.60 +	char **list = xs_directory(xsh, xth, argv[optind], &num);
   19.61  	if (list == NULL) {
   19.62  	    warnx("could not list path %s", argv[optind]);
   19.63  	    ret = 1;
   19.64 @@ -145,7 +146,7 @@ main(int argc, char **argv)
   19.65      }
   19.66  
   19.67   out:
   19.68 -    success = xs_transaction_end(xsh, ret ? true : false);
   19.69 +    success = xs_transaction_end(xsh, xth, ret ? true : false);
   19.70      if (!success) {
   19.71  	if (ret == 0 && errno == EAGAIN)
   19.72  	    goto again;
    20.1 --- a/tools/xenstore/xs.c	Sun Oct 09 20:55:53 2005 +0100
    20.2 +++ b/tools/xenstore/xs.c	Sun Oct 09 21:29:10 2005 +0100
    20.3 @@ -81,6 +81,10 @@ struct xs_handle {
    20.4  	pthread_t transaction_pthread;
    20.5  };
    20.6  
    20.7 +struct xs_transaction_handle {
    20.8 +	int id;
    20.9 +};
   20.10 +
   20.11  static void *read_thread(void *arg);
   20.12  
   20.13  static void request_mutex_acquire(struct xs_handle *h)
   20.14 @@ -407,7 +411,8 @@ static bool xs_bool(char *reply)
   20.15  	return true;
   20.16  }
   20.17  
   20.18 -char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num)
   20.19 +char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
   20.20 +		    const char *path, unsigned int *num)
   20.21  {
   20.22  	char *strings, *p, **ret;
   20.23  	unsigned int len;
   20.24 @@ -438,7 +443,8 @@ char **xs_directory(struct xs_handle *h,
   20.25   * Returns a malloced value: call free() on it after use.
   20.26   * len indicates length in bytes, not including the nul.
   20.27   */
   20.28 -void *xs_read(struct xs_handle *h, const char *path, unsigned int *len)
   20.29 +void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
   20.30 +	      const char *path, unsigned int *len)
   20.31  {
   20.32  	return xs_single(h, XS_READ, path, len);
   20.33  }
   20.34 @@ -446,8 +452,8 @@ void *xs_read(struct xs_handle *h, const
   20.35  /* Write the value of a single file.
   20.36   * Returns false on failure.
   20.37   */
   20.38 -bool xs_write(struct xs_handle *h, const char *path,
   20.39 -	      const void *data, unsigned int len)
   20.40 +bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
   20.41 +	      const char *path, const void *data, unsigned int len)
   20.42  {
   20.43  	struct iovec iovec[2];
   20.44  
   20.45 @@ -462,7 +468,8 @@ bool xs_write(struct xs_handle *h, const
   20.46  /* Create a new directory.
   20.47   * Returns false on failure, or success if it already exists.
   20.48   */
   20.49 -bool xs_mkdir(struct xs_handle *h, const char *path)
   20.50 +bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
   20.51 +	      const char *path)
   20.52  {
   20.53  	return xs_bool(xs_single(h, XS_MKDIR, path, NULL));
   20.54  }
   20.55 @@ -470,7 +477,8 @@ bool xs_mkdir(struct xs_handle *h, const
   20.56  /* Destroy a file or directory (directories must be empty).
   20.57   * Returns false on failure, or success if it doesn't exist.
   20.58   */
   20.59 -bool xs_rm(struct xs_handle *h, const char *path)
   20.60 +bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
   20.61 +	   const char *path)
   20.62  {
   20.63  	return xs_bool(xs_single(h, XS_RM, path, NULL));
   20.64  }
   20.65 @@ -479,6 +487,7 @@ bool xs_rm(struct xs_handle *h, const ch
   20.66   * Returns malloced array, or NULL: call free() after use.
   20.67   */
   20.68  struct xs_permissions *xs_get_permissions(struct xs_handle *h,
   20.69 +					  struct xs_transaction_handle *t,
   20.70  					  const char *path, unsigned int *num)
   20.71  {
   20.72  	char *strings;
   20.73 @@ -511,7 +520,9 @@ struct xs_permissions *xs_get_permission
   20.74  /* Set permissions of node (must be owner).
   20.75   * Returns false on failure.
   20.76   */
   20.77 -bool xs_set_permissions(struct xs_handle *h, const char *path,
   20.78 +bool xs_set_permissions(struct xs_handle *h,
   20.79 +			struct xs_transaction_handle *t,
   20.80 +			const char *path,
   20.81  			struct xs_permissions *perms,
   20.82  			unsigned int num_perms)
   20.83  {
   20.84 @@ -632,9 +643,9 @@ bool xs_unwatch(struct xs_handle *h, con
   20.85  /* Start a transaction: changes by others will not be seen during this
   20.86   * transaction, and changes will not be visible to others until end.
   20.87   * You can only have one transaction at any time.
   20.88 - * Returns false on failure.
   20.89 + * Returns NULL on failure.
   20.90   */
   20.91 -bool xs_transaction_start(struct xs_handle *h)
   20.92 +struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
   20.93  {
   20.94  	bool rc;
   20.95  
   20.96 @@ -647,7 +658,7 @@ bool xs_transaction_start(struct xs_hand
   20.97  		pthread_mutex_unlock(&h->transaction_mutex);
   20.98  	}
   20.99  
  20.100 -	return rc;
  20.101 +	return (struct xs_transaction_handle *)rc;
  20.102  }
  20.103  
  20.104  /* End a transaction.
  20.105 @@ -655,11 +666,15 @@ bool xs_transaction_start(struct xs_hand
  20.106   * Returns false on failure, which indicates an error: transactions will
  20.107   * not fail spuriously.
  20.108   */
  20.109 -bool xs_transaction_end(struct xs_handle *h, bool abort)
  20.110 +bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
  20.111 +			bool abort)
  20.112  {
  20.113  	char abortstr[2];
  20.114  	bool rc;
  20.115  
  20.116 +	if (t == NULL)
  20.117 +		return -EINVAL;
  20.118 +
  20.119  	if (abort)
  20.120  		strcpy(abortstr, "F");
  20.121  	else
    21.1 --- a/tools/xenstore/xs.h	Sun Oct 09 20:55:53 2005 +0100
    21.2 +++ b/tools/xenstore/xs.h	Sun Oct 09 21:29:10 2005 +0100
    21.3 @@ -23,6 +23,7 @@
    21.4  #include <xs_lib.h>
    21.5  
    21.6  struct xs_handle;
    21.7 +struct xs_transaction_handle;
    21.8  
    21.9  /* On failure, these routines set errno. */
   21.10  
   21.11 @@ -44,41 +45,47 @@ void xs_daemon_close(struct xs_handle *)
   21.12   * Returns a malloced array: call free() on it after use.
   21.13   * Num indicates size.
   21.14   */
   21.15 -char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num);
   21.16 +char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
   21.17 +		    const char *path, unsigned int *num);
   21.18  
   21.19  /* Get the value of a single file, nul terminated.
   21.20   * Returns a malloced value: call free() on it after use.
   21.21   * len indicates length in bytes, not including terminator.
   21.22   */
   21.23 -void *xs_read(struct xs_handle *h, const char *path, unsigned int *len);
   21.24 +void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
   21.25 +	      const char *path, unsigned int *len);
   21.26  
   21.27  /* Write the value of a single file.
   21.28   * Returns false on failure.
   21.29   */
   21.30 -bool xs_write(struct xs_handle *h, const char *path, const void *data,
   21.31 -	      unsigned int len);
   21.32 +bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
   21.33 +	      const char *path, const void *data, unsigned int len);
   21.34  
   21.35  /* Create a new directory.
   21.36   * Returns false on failure, or success if it already exists.
   21.37   */
   21.38 -bool xs_mkdir(struct xs_handle *h, const char *path);
   21.39 +bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
   21.40 +	      const char *path);
   21.41  
   21.42  /* Destroy a file or directory (and children).
   21.43   * Returns false on failure, or success if it doesn't exist.
   21.44   */
   21.45 -bool xs_rm(struct xs_handle *h, const char *path);
   21.46 +bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
   21.47 +	   const char *path);
   21.48  
   21.49  /* Get permissions of node (first element is owner, first perms is "other").
   21.50   * Returns malloced array, or NULL: call free() after use.
   21.51   */
   21.52  struct xs_permissions *xs_get_permissions(struct xs_handle *h,
   21.53 +					  struct xs_transaction_handle *t,
   21.54  					  const char *path, unsigned int *num);
   21.55  
   21.56  /* Set permissions of node (must be owner).
   21.57   * Returns false on failure.
   21.58   */
   21.59 -bool xs_set_permissions(struct xs_handle *h, const char *path,
   21.60 -			struct xs_permissions *perms, unsigned int num_perms);
   21.61 +bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
   21.62 +			const char *path, struct xs_permissions *perms,
   21.63 +			unsigned int num_perms);
   21.64  
   21.65  /* Watch a node for changes (poll on fd to detect, or call read_watch()).
   21.66   * When the node (or any child) changes, fd will become readable.
   21.67 @@ -104,16 +111,17 @@ bool xs_unwatch(struct xs_handle *h, con
   21.68  /* Start a transaction: changes by others will not be seen during this
   21.69   * transaction, and changes will not be visible to others until end.
   21.70   * You can only have one transaction at any time.
   21.71 - * Returns false on failure.
   21.72 + * Returns NULL on failure.
   21.73   */
   21.74 -bool xs_transaction_start(struct xs_handle *h);
   21.75 +struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
   21.76  
   21.77  /* End a transaction.
   21.78   * If abandon is true, transaction is discarded instead of committed.
   21.79   * Returns false on failure: if errno == EAGAIN, you have to restart
   21.80   * transaction.
   21.81   */
   21.82 -bool xs_transaction_end(struct xs_handle *h, bool abort);
   21.83 +bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
   21.84 +			bool abort);
   21.85  
   21.86  /* Introduce a new domain.
   21.87   * This tells the store daemon about a shared memory page, event channel
   21.88 @@ -136,3 +144,13 @@ char *xs_debug_command(struct xs_handle 
   21.89  		       void *data, unsigned int len);
   21.90  
   21.91  #endif /* _XS_H */
   21.92 +
   21.93 +/*
   21.94 + * Local variables:
   21.95 + *  c-file-style: "linux"
   21.96 + *  indent-tabs-mode: t
   21.97 + *  c-indent-level: 8
   21.98 + *  c-basic-offset: 8
   21.99 + *  tab-width: 8
  21.100 + * End:
  21.101 + */
    22.1 --- a/tools/xenstore/xs_test.c	Sun Oct 09 20:55:53 2005 +0100
    22.2 +++ b/tools/xenstore/xs_test.c	Sun Oct 09 21:29:10 2005 +0100
    22.3 @@ -42,6 +42,7 @@
    22.4  #define XSTEST
    22.5  
    22.6  static struct xs_handle *handles[10] = { NULL };
    22.7 +static struct xs_transaction_handle *txh[10] = { NULL };
    22.8  
    22.9  static unsigned int timeout_ms = 500;
   22.10  static bool timeout_suppressed = true;
   22.11 @@ -312,7 +313,7 @@ static void do_dir(unsigned int handle, 
   22.12  	char **entries;
   22.13  	unsigned int i, num;
   22.14  
   22.15 -	entries = xs_directory(handles[handle], path, &num);
   22.16 +	entries = xs_directory(handles[handle], txh[handle], path, &num);
   22.17  	if (!entries) {
   22.18  		failed(handle);
   22.19  		return;
   22.20 @@ -331,7 +332,7 @@ static void do_read(unsigned int handle,
   22.21  	char *value;
   22.22  	unsigned int len;
   22.23  
   22.24 -	value = xs_read(handles[handle], path, &len);
   22.25 +	value = xs_read(handles[handle], txh[handle], path, &len);
   22.26  	if (!value) {
   22.27  		failed(handle);
   22.28  		return;
   22.29 @@ -347,7 +348,7 @@ static void do_read(unsigned int handle,
   22.30  
   22.31  static void do_write(unsigned int handle, char *path, char *data)
   22.32  {
   22.33 -	if (!xs_write(handles[handle], path, data, strlen(data)))
   22.34 +	if (!xs_write(handles[handle], txh[handle], path, data, strlen(data)))
   22.35  		failed(handle);
   22.36  }
   22.37  
   22.38 @@ -360,13 +361,13 @@ static void do_setid(unsigned int handle
   22.39  
   22.40  static void do_mkdir(unsigned int handle, char *path)
   22.41  {
   22.42 -	if (!xs_mkdir(handles[handle], path))
   22.43 +	if (!xs_mkdir(handles[handle], txh[handle], path))
   22.44  		failed(handle);
   22.45  }
   22.46  
   22.47  static void do_rm(unsigned int handle, char *path)
   22.48  {
   22.49 -	if (!xs_rm(handles[handle], path))
   22.50 +	if (!xs_rm(handles[handle], txh[handle], path))
   22.51  		failed(handle);
   22.52  }
   22.53  
   22.54 @@ -375,7 +376,7 @@ static void do_getperm(unsigned int hand
   22.55  	unsigned int i, num;
   22.56  	struct xs_permissions *perms;
   22.57  
   22.58 -	perms = xs_get_permissions(handles[handle], path, &num);
   22.59 +	perms = xs_get_permissions(handles[handle], txh[handle], path, &num);
   22.60  	if (!perms) {
   22.61  		failed(handle);
   22.62  		return;
   22.63 @@ -436,7 +437,7 @@ static void do_setperm(unsigned int hand
   22.64  			barf("bad flags %s\n", arg);
   22.65  	}
   22.66  
   22.67 -	if (!xs_set_permissions(handles[handle], path, perms, i))
   22.68 +	if (!xs_set_permissions(handles[handle], txh[handle], path, perms, i))
   22.69  		failed(handle);
   22.70  }
   22.71  
   22.72 @@ -520,14 +521,16 @@ static void do_unwatch(unsigned int hand
   22.73  
   22.74  static void do_start(unsigned int handle)
   22.75  {
   22.76 -	if (!xs_transaction_start(handles[handle]))
   22.77 +	txh[handle] = xs_transaction_start(handles[handle]);
   22.78 +	if (txh[handle] == NULL)
   22.79  		failed(handle);
   22.80  }
   22.81  
   22.82  static void do_end(unsigned int handle, bool abort)
   22.83  {
   22.84 -	if (!xs_transaction_end(handles[handle], abort))
   22.85 +	if (!xs_transaction_end(handles[handle], txh[handle], abort))
   22.86  		failed(handle);
   22.87 +	txh[handle] = NULL;
   22.88  }
   22.89  
   22.90  static void do_introduce(unsigned int handle,
   22.91 @@ -617,7 +620,8 @@ static void dump_dir(unsigned int handle
   22.92  
   22.93  		sprintf(subnode, "%s/%s", node, dir[i]);
   22.94  
   22.95 -		perms = xs_get_permissions(handles[handle], subnode,&numperms);
   22.96 +		perms = xs_get_permissions(handles[handle], txh[handle],
   22.97 +					   subnode,&numperms);
   22.98  		if (!perms) {
   22.99  			failed(handle);
  22.100  			return;
  22.101 @@ -634,7 +638,8 @@ static void dump_dir(unsigned int handle
  22.102  		output("\n");
  22.103  
  22.104  		/* Even directories can have contents. */
  22.105 -		contents = xs_read(handles[handle], subnode, &len);
  22.106 +		contents = xs_read(handles[handle], txh[handle], 
  22.107 +				   subnode, &len);
  22.108  		if (!contents) {
  22.109  			if (errno != EISDIR)
  22.110  				failed(handle);
  22.111 @@ -644,7 +649,8 @@ static void dump_dir(unsigned int handle
  22.112  		}			
  22.113  
  22.114  		/* Every node is a directory. */
  22.115 -		subdirs = xs_directory(handles[handle], subnode, &subnum);
  22.116 +		subdirs = xs_directory(handles[handle], txh[handle], 
  22.117 +				       subnode, &subnum);
  22.118  		if (!subdirs) {
  22.119  			failed(handle);
  22.120  			return;
  22.121 @@ -659,7 +665,7 @@ static void dump(int handle)
  22.122  	char **subdirs;
  22.123  	unsigned int subnum;
  22.124  
  22.125 -	subdirs = xs_directory(handles[handle], "/", &subnum);
  22.126 +	subdirs = xs_directory(handles[handle], txh[handle], "/", &subnum);
  22.127  	if (!subdirs) {
  22.128  		failed(handle);
  22.129  		return;
  22.130 @@ -742,6 +748,7 @@ static void do_command(unsigned int defa
  22.131  	else if (streq(command, "close")) {
  22.132  		xs_daemon_close(handles[handle]);
  22.133  		handles[handle] = NULL;
  22.134 +		txh[handle] = NULL;
  22.135  	} else if (streq(command, "start"))
  22.136  		do_start(handle);
  22.137  	else if (streq(command, "commit"))
  22.138 @@ -825,3 +832,13 @@ int main(int argc, char *argv[])
  22.139  
  22.140  	return 0;
  22.141  }
  22.142 +
  22.143 +/*
  22.144 + * Local variables:
  22.145 + *  c-file-style: "linux"
  22.146 + *  indent-tabs-mode: t
  22.147 + *  c-indent-level: 8
  22.148 + *  c-basic-offset: 8
  22.149 + *  tab-width: 8
  22.150 + * End:
  22.151 + */