WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Extend xenbus/xenstore client interface to include a tra

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Extend xenbus/xenstore client interface to include a transaction
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 09 Oct 2005 20:32:10 +0000
Delivery-date: Sun, 09 Oct 2005 20:29:42 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID f1e8d5f641057018677e7282c3358835a749bec8
# Parent  5df423407700ae4ef9e9020501b24eb659febc8c
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@xxxxxxxxxxxxx>

diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Sun Oct  9 
20:29:10 2005
@@ -1364,7 +1364,7 @@
                        return;
 
                /* get the state value */
-               err = xenbus_scanf(dir, "availability", "%s", state);
+               err = xenbus_scanf(NULL, dir, "availability", "%s", state);
 
                if (err != 1) {
                        printk(KERN_ERR
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Sun Oct  9 19:55:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Sun Oct  9 20:29:10 2005
@@ -275,22 +275,23 @@
 {
        static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
        char *str;
+       struct xenbus_transaction *xbt;
        int err;
 
  again:
-       err = xenbus_transaction_start();
-       if (err)
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt))
                return;
-       str = (char *)xenbus_read("control", "shutdown", NULL);
+       str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
        /* Ignore read errors and empty reads. */
        if (XENBUS_IS_ERR_READ(str)) {
-               xenbus_transaction_end(1);
+               xenbus_transaction_end(xbt, 1);
                return;
        }
 
-       xenbus_write("control", "shutdown", "");
-
-       err = xenbus_transaction_end(0);
+       xenbus_write(xbt, "control", "shutdown", "");
+
+       err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN) {
                kfree(str);
                goto again;
@@ -320,23 +321,24 @@
                          unsigned int len)
 {
        char sysrq_key = '\0';
+       struct xenbus_transaction *xbt;
        int err;
 
  again:
-       err = xenbus_transaction_start();
-       if (err)
+       xbt  = xenbus_transaction_start();
+       if (IS_ERR(xbt))
                return;
-       if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
+       if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
                printk(KERN_ERR "Unable to read sysrq code in "
                       "control/sysrq\n");
-               xenbus_transaction_end(1);
+               xenbus_transaction_end(xbt, 1);
                return;
        }
 
        if (sysrq_key != '\0')
-               xenbus_printf("control", "sysrq", "%c", '\0');
-
-       err = xenbus_transaction_end(0);
+               xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
+
+       err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
 
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sun Oct  9 
20:29:10 2005
@@ -357,7 +357,7 @@
        unsigned long long new_target;
        int err;
 
-       err = xenbus_scanf("memory", "target", "%llu", &new_target);
+       err = xenbus_scanf(NULL, "memory", "target", "%llu", &new_target);
        if (err != 1) {
                printk(KERN_ERR "Unable to read memory/target\n");
                return;
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Sun Oct  9 19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Sun Oct  9 20:29:10 2005
@@ -61,18 +61,19 @@
        unsigned long ring_ref;
        unsigned int evtchn;
        int err;
+       struct xenbus_transaction *xbt;
        struct backend_info *be
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (vec && !xenbus_exists(be->frontpath, "")) {
+       if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
                device_unregister(&be->dev->dev);
                return;
        }
        if (be->blkif == NULL || be->blkif->status == CONNECTED)
                return;
 
-       err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
+       err = xenbus_gather(NULL, be->frontpath, "ring-ref", "%lu", &ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
                xenbus_dev_error(be->dev, err,
@@ -84,7 +85,8 @@
        /* Map the shared frame, irq etc. */
        err = blkif_map(be->blkif, ring_ref, evtchn);
        if (err) {
-               xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
+               xenbus_dev_error(be->dev, err,
+                                "mapping ring-ref %lu port %u",
                                 ring_ref, evtchn);
                return;
        }
@@ -92,13 +94,13 @@
 
 again:
        /* Supply the information about the device the frontend needs */
-       err = xenbus_transaction_start();
-       if (err) {
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
                xenbus_dev_error(be->dev, err, "starting transaction");
                return;
        }
 
-       err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
+       err = xenbus_printf(xbt, be->dev->nodename, "sectors", "%lu",
                            vbd_size(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/sectors",
@@ -107,14 +109,14 @@
        }
 
        /* FIXME: use a typename instead */
-       err = xenbus_printf(be->dev->nodename, "info", "%u",
+       err = xenbus_printf(xbt, be->dev->nodename, "info", "%u",
                            vbd_info(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/info",
                                 be->dev->nodename);
                goto abort;
        }
-       err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
+       err = xenbus_printf(xbt, be->dev->nodename, "sector-size", "%lu",
                            vbd_secsize(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/sector-size",
@@ -122,7 +124,7 @@
                goto abort;
        }
 
-       err = xenbus_transaction_end(0);
+       err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
@@ -136,7 +138,7 @@
        return;
 
  abort:
-       xenbus_transaction_end(1);
+       xenbus_transaction_end(xbt, 1);
 }
 
 /* 
@@ -154,7 +156,8 @@
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
+       err = xenbus_scanf(NULL, dev->nodename,
+                          "physical-device", "%li", &pdev);
        if (XENBUS_EXIST_ERR(err))
                return;
        if (err < 0) {
@@ -169,7 +172,7 @@
        be->pdev = pdev;
 
        /* If there's a read-only node, we're read only. */
-       p = xenbus_read(dev->nodename, "read-only", NULL);
+       p = xenbus_read(NULL, dev->nodename, "read-only", NULL);
        if (!IS_ERR(p)) {
                be->readonly = 1;
                kfree(p);
@@ -184,7 +187,8 @@
                if (IS_ERR(be->blkif)) {
                        err = PTR_ERR(be->blkif);
                        be->blkif = NULL;
-                       xenbus_dev_error(dev, err, "creating block interface");
+                       xenbus_dev_error(dev, err,
+                                        "creating block interface");
                        return;
                }
 
@@ -192,7 +196,8 @@
                if (err) {
                        blkif_put(be->blkif);
                        be->blkif = NULL;
-                       xenbus_dev_error(dev, err, "creating vbd structure");
+                       xenbus_dev_error(dev, err,
+                                        "creating vbd structure");
                        return;
                }
 
@@ -210,13 +215,14 @@
 
        be = kmalloc(sizeof(*be), GFP_KERNEL);
        if (!be) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
+               xenbus_dev_error(dev, -ENOMEM,
+                                "allocating backend structure");
                return -ENOMEM;
        }
        memset(be, 0, sizeof(*be));
 
        frontend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "frontend-id", "%li", &be->frontend_id,
                            "frontend", NULL, &frontend,
                            NULL);
@@ -228,7 +234,7 @@
                                 dev->nodename);
                goto free_be;
        }
-       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+       if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
                /* If we can't get a frontend path and a frontend-id,
                 * then our bus-id is no longer valid and we need to
                 * destroy the backend device.
@@ -244,7 +250,8 @@
        err = register_xenbus_watch(&be->backend_watch);
        if (err) {
                be->backend_watch.node = NULL;
-               xenbus_dev_error(dev, err, "adding backend watch on %s",
+               xenbus_dev_error(dev, err,
+                                "adding backend watch on %s",
                                 dev->nodename);
                goto free_be;
        }
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct  9 
20:29:10 2005
@@ -460,7 +460,7 @@
        if (info->connected == BLKIF_STATE_CONNECTED)
                return;
 
-       err = xenbus_gather(watch->node,
+       err = xenbus_gather(NULL, watch->node,
                            "sectors", "%lu", &sectors,
                            "info", "%u", &binfo,
                            "sector-size", "%lu", &sector_size,
@@ -532,10 +532,11 @@
 {
        char *backend;
        const char *message;
+       struct xenbus_transaction *xbt;
        int err;
 
        backend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "backend-id", "%i", &info->backend_id,
                            "backend", NULL, &backend,
                            NULL);
@@ -559,25 +560,26 @@
        }
 
 again:
-       err = xenbus_transaction_start();
-       if (err) {
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_blkring;
        }
 
-       err = xenbus_printf(dev->nodename, "ring-ref","%u", info->ring_ref);
+       err = xenbus_printf(xbt, dev->nodename,
+                           "ring-ref","%u", info->ring_ref);
        if (err) {
                message = "writing ring-ref";
                goto abort_transaction;
        }
-       err = xenbus_printf(dev->nodename,
+       err = xenbus_printf(xbt, dev->nodename,
                            "event-channel", "%u", info->evtchn);
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
        }
 
-       err = xenbus_transaction_end(0);
+       err = xenbus_transaction_end(xbt, 0);
        if (err) {
                if (err == -EAGAIN)
                        goto again;
@@ -598,8 +600,7 @@
        return 0;
 
  abort_transaction:
-       xenbus_transaction_end(1);
-       /* Have to do this *outside* transaction.  */
+       xenbus_transaction_end(xbt, 1);
        xenbus_dev_error(dev, err, "%s", message);
  destroy_blkring:
        blkif_free(info);
@@ -620,7 +621,8 @@
        struct blkfront_info *info;
 
        /* FIXME: Use dynamic device id if this is not set. */
-       err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
+       err = xenbus_scanf(NULL, dev->nodename,
+                          "virtual-device", "%i", &vdevice);
        if (XENBUS_EXIST_ERR(err))
                return err;
        if (err < 0) {
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sun Oct  9 19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sun Oct  9 20:29:10 2005
@@ -69,15 +69,15 @@
        int i;
 
        /* If other end is gone, delete ourself. */
-       if (vec && !xenbus_exists(be->frontpath, "")) {
-               xenbus_rm(be->dev->nodename, "");
+       if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
+               xenbus_rm(NULL, be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
        }
        if (be->netif == NULL || be->netif->status == CONNECTED)
                return;
 
-       mac = xenbus_read(be->frontpath, "mac", NULL);
+       mac = xenbus_read(NULL, be->frontpath, "mac", NULL);
        if (IS_ERR(mac)) {
                err = PTR_ERR(mac);
                xenbus_dev_error(be->dev, err, "reading %s/mac",
@@ -98,7 +98,8 @@
        }
        kfree(mac);
 
-       err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref,
+       err = xenbus_gather(NULL, be->frontpath,
+                           "tx-ring-ref", "%lu", &tx_ring_ref,
                            "rx-ring-ref", "%lu", &rx_ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
@@ -137,7 +138,7 @@
        struct xenbus_device *dev = be->dev;
        u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 
-       err = xenbus_scanf(dev->nodename, "handle", "%li", &handle);
+       err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle);
        if (XENBUS_EXIST_ERR(err))
                return;
        if (err < 0) {
@@ -188,7 +189,7 @@
 
        key = env_vars;
        while (*key != NULL) {
-               val = xenbus_read(xdev->nodename, *key, NULL);
+               val = xenbus_read(NULL, xdev->nodename, *key, NULL);
                if (!IS_ERR(val)) {
                        char buf[strlen(*key) + 4];
                        sprintf(buf, "%s=%%s", *key);
@@ -220,7 +221,7 @@
        memset(be, 0, sizeof(*be));
 
        frontend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "frontend-id", "%li", &be->frontend_id,
                            "frontend", NULL, &frontend,
                            NULL);
@@ -232,7 +233,7 @@
                                 dev->nodename);
                goto free_be;
        }
-       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+       if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
                /* If we can't get a frontend path and a frontend-id,
                 * then our bus-id is no longer valid and we need to
                 * destroy the backend device.
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sun Oct  9 
20:29:10 2005
@@ -1083,10 +1083,11 @@
 {
        char *backend, *mac, *e, *s;
        const char *message;
+       struct xenbus_transaction *xbt;
        int err, i;
 
        backend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "backend-id", "%i", &info->backend_id,
                            "backend", NULL, &backend,
                            NULL);
@@ -1102,7 +1103,7 @@
                goto out;
        }
 
-       mac = xenbus_read(dev->nodename, "mac", NULL);
+       mac = xenbus_read(NULL, dev->nodename, "mac", NULL);
        if (IS_ERR(mac)) {
                err = PTR_ERR(mac);
                xenbus_dev_error(dev, err, "reading %s/mac",
@@ -1131,32 +1132,32 @@
        }
 
 again:
-       err = xenbus_transaction_start();
-       if (err) {
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_ring;
        }
 
-       err = xenbus_printf(dev->nodename, "tx-ring-ref","%u",
+       err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
                            info->tx_ring_ref);
        if (err) {
                message = "writing tx ring-ref";
                goto abort_transaction;
        }
-       err = xenbus_printf(dev->nodename, "rx-ring-ref","%u",
+       err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
                            info->rx_ring_ref);
        if (err) {
                message = "writing rx ring-ref";
                goto abort_transaction;
        }
-       err = xenbus_printf(dev->nodename,
+       err = xenbus_printf(xbt, dev->nodename,
                            "event-channel", "%u", info->evtchn);
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
        }
 
-       err = xenbus_transaction_end(0);
+       err = xenbus_transaction_end(xbt, 0);
        if (err) {
                if (err == -EAGAIN)
                        goto again;
@@ -1177,8 +1178,7 @@
        return 0;
 
  abort_transaction:
-       xenbus_transaction_end(1);
-       /* Have to do this *outside* transaction.  */
+       xenbus_transaction_end(xbt, 1);
        xenbus_dev_error(dev, err, "%s", message);
  destroy_ring:
        shutdown_device(info);
@@ -1201,7 +1201,7 @@
        struct netfront_info *info;
        unsigned int handle;
 
-       err = xenbus_scanf(dev->nodename, "handle", "%u", &handle);
+       err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
        if (XENBUS_EXIST_ERR(err))
                return err;
        if (err < 0) {
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Sun Oct  9 19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Sun Oct  9 20:29:10 2005
@@ -66,12 +66,13 @@
        unsigned int evtchn;
        unsigned long ready = 1;
        int err;
+       struct xenbus_transaction *xbt;
        struct backend_info *be
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (vec && !xenbus_exists(be->frontpath, "")) {
-               xenbus_rm(be->dev->nodename, "");
+       if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
+               xenbus_rm(NULL, be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
        }
@@ -79,7 +80,7 @@
        if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
                return;
 
-       err = xenbus_gather(be->frontpath,
+       err = xenbus_gather(NULL, be->frontpath,
                            "ring-ref", "%lu", &ringref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
@@ -115,20 +116,20 @@
         * unless something bad happens
         */
 again:
-       err = xenbus_transaction_start();
-       if (err) {
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
                xenbus_dev_error(be->dev, err, "starting transaction");
                return;
        }
 
-       err = xenbus_printf(be->dev->nodename,
+       err = xenbus_printf(xbt, be->dev->nodename,
                            "ready", "%lu", ready);
        if (err) {
                xenbus_dev_error(be->dev, err, "writing 'ready'");
                goto abort;
        }
 
-       err = xenbus_transaction_end(0);
+       err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
@@ -139,7 +140,7 @@
        xenbus_dev_ok(be->dev);
        return;
 abort:
-       xenbus_transaction_end(1);
+       xenbus_transaction_end(xbt, 1);
 }
 
 
@@ -152,7 +153,7 @@
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
+       err = xenbus_scanf(NULL, dev->nodename, "instance", "%li", &instance);
        if (XENBUS_EXIST_ERR(err))
                return;
        if (err < 0) {
@@ -205,7 +206,7 @@
        memset(be, 0, sizeof(*be));
 
        frontend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "frontend-id", "%li", &be->frontend_id,
                            "frontend", NULL, &frontend,
                            NULL);
@@ -217,7 +218,7 @@
                                 dev->nodename);
                goto free_be;
        }
-       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+       if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
                /* If we can't get a frontend path and a frontend-id,
                 * then our bus-id is no longer valid and we need to
                 * destroy the backend device.
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sun Oct  9 
20:29:10 2005
@@ -226,7 +226,7 @@
        if (tp->connected)
                return;
 
-       err = xenbus_gather(watch->node,
+       err = xenbus_gather(NULL, watch->node,
                            "ready", "%lu", &ready,
                            NULL);
        if (err) {
@@ -311,9 +311,10 @@
        const char *message;
        int err;
        int backend_id;
+       struct xenbus_transaction *xbt;
 
        backend = NULL;
-       err = xenbus_gather(dev->nodename,
+       err = xenbus_gather(NULL, dev->nodename,
                            "backend-id", "%i", &backend_id,
                            "backend", NULL, &backend,
                            NULL);
@@ -339,27 +340,27 @@
        }
 
 again:
-       err = xenbus_transaction_start();
-       if (err) {
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_tpmring;
        }
 
-       err = xenbus_printf(dev->nodename,
+       err = xenbus_printf(xbt, dev->nodename,
                            "ring-ref","%u", info->ring_ref);
        if (err) {
                message = "writing ring-ref";
                goto abort_transaction;
        }
 
-       err = xenbus_printf(dev->nodename,
+       err = xenbus_printf(xbt, dev->nodename,
                            "event-channel", "%u", my_private.evtchn);
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
        }
 
-       err = xenbus_transaction_end(0);
+       err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
@@ -380,8 +381,7 @@
        return 0;
 
 abort_transaction:
-       xenbus_transaction_end(1);
-       /* Have to do this *outside* transaction.  */
+       xenbus_transaction_end(xbt, 1);
        xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
        destroy_tpmring(info, &my_private);
@@ -399,7 +399,7 @@
        struct tpmfront_info *info;
        int handle;
 
-       err = xenbus_scanf(dev->nodename,
+       err = xenbus_scanf(NULL, dev->nodename,
                           "handle", "%i", &handle);
        if (XENBUS_EXIST_ERR(err))
                return err;
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sun Oct  9 
20:29:10 2005
@@ -181,7 +181,7 @@
        struct xenbus_dev_data *u = filp->private_data;
 
        if (u->in_transaction)
-               xenbus_transaction_end(1);
+               xenbus_transaction_end((struct xenbus_transaction *)1, 1);
 
        kfree(u);
 
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sun Oct  9 
20:29:10 2005
@@ -128,7 +128,7 @@
 
        devid = strrchr(nodename, '/') + 1;
 
-       err = xenbus_gather(nodename, "frontend-id", "%i", &domid,
+       err = xenbus_gather(NULL, nodename, "frontend-id", "%i", &domid,
                            "frontend", NULL, &frontend,
                            NULL);
        if (err)
@@ -136,7 +136,7 @@
        if (strlen(frontend) == 0)
                err = -ERANGE;
 
-       if (!err && !xenbus_exists(frontend, ""))
+       if (!err && !xenbus_exists(NULL, frontend, ""))
                err = -ENOENT;
 
        if (err) {
@@ -450,7 +450,7 @@
        if (!nodename)
                return -ENOMEM;
 
-       dir = xenbus_directory(nodename, "", &dir_n);
+       dir = xenbus_directory(NULL, nodename, "", &dir_n);
        if (IS_ERR(dir)) {
                kfree(nodename);
                return PTR_ERR(dir);
@@ -473,7 +473,7 @@
        unsigned int dir_n = 0;
        int i;
 
-       dir = xenbus_directory(bus->root, type, &dir_n);
+       dir = xenbus_directory(NULL, bus->root, type, &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
@@ -492,7 +492,7 @@
        char **dir;
        unsigned int i, dir_n;
 
-       dir = xenbus_directory(bus->root, "", &dir_n);
+       dir = xenbus_directory(NULL, bus->root, "", &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
@@ -538,7 +538,7 @@
        if (char_count(node, '/') < 2)
                return;
 
-       exists = xenbus_exists(node, "");
+       exists = xenbus_exists(NULL, node, "");
        if (!exists) {
                xenbus_cleanup_devices(node, &bus->bus);
                return;
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sun Oct  9 
19:55:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sun Oct  9 
20:29:10 2005
@@ -316,7 +316,8 @@
        return ret;
 }
 
-char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
+char **xenbus_directory(struct xenbus_transaction *t,
+                       const char *dir, const char *node, unsigned int *num)
 {
        char *strings;
        unsigned int len;
@@ -330,12 +331,13 @@
 EXPORT_SYMBOL(xenbus_directory);
 
 /* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(const char *dir, const char *node)
+int xenbus_exists(struct xenbus_transaction *t,
+                 const char *dir, const char *node)
 {
        char **d;
        int dir_n;
 
-       d = xenbus_directory(dir, node, &dir_n);
+       d = xenbus_directory(t, dir, node, &dir_n);
        if (IS_ERR(d))
                return 0;
        kfree(d);
@@ -347,7 +349,8 @@
  * Returns a kmalloced value: call free() on it after use.
  * len indicates length in bytes.
  */
-void *xenbus_read(const char *dir, const char *node, unsigned int *len)
+void *xenbus_read(struct xenbus_transaction *t,
+                 const char *dir, const char *node, unsigned int *len)
 {
        return xs_single(XS_READ, join(dir, node), len);
 }
@@ -356,7 +359,8 @@
 /* Write the value of a single file.
  * Returns -err on failure.
  */
-int xenbus_write(const char *dir, const char *node, const char *string)
+int xenbus_write(struct xenbus_transaction *t,
+                const char *dir, const char *node, const char *string)
 {
        const char *path;
        struct kvec iovec[2];
@@ -373,14 +377,15 @@
 EXPORT_SYMBOL(xenbus_write);
 
 /* Create a new directory. */
-int xenbus_mkdir(const char *dir, const char *node)
+int xenbus_mkdir(struct xenbus_transaction *t,
+                const char *dir, const char *node)
 {
        return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL));
 }
 EXPORT_SYMBOL(xenbus_mkdir);
 
 /* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(const char *dir, const char *node)
+int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
 {
        return xs_error(xs_single(XS_RM, join(dir, node), NULL));
 }
@@ -388,9 +393,8 @@
 
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
- * You can only have one transaction at any time.
  */
-int xenbus_transaction_start(void)
+struct xenbus_transaction *xenbus_transaction_start(void)
 {
        int err;
 
@@ -403,17 +407,19 @@
                up(&xs_state.transaction_mutex);
        }
 
-       return err;
+       return err ? ERR_PTR(err) : (struct xenbus_transaction *)1;
 }
 EXPORT_SYMBOL(xenbus_transaction_start);
 
 /* End a transaction.
  * If abandon is true, transaction is discarded instead of committed.
  */
-int xenbus_transaction_end(int abort)
+int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
 {
        char abortstr[2];
        int err;
+
+       BUG_ON(t == NULL);
 
        if (abort)
                strcpy(abortstr, "F");
@@ -430,13 +436,14 @@
 EXPORT_SYMBOL(xenbus_transaction_end);
 
 /* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
+int xenbus_scanf(struct xenbus_transaction *t,
+                const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
        int ret;
        char *val;
 
-       val = xenbus_read(dir, node, NULL);
+       val = xenbus_read(t, dir, node, NULL);
        if (IS_ERR(val))
                return PTR_ERR(val);
 
@@ -452,7 +459,8 @@
 EXPORT_SYMBOL(xenbus_scanf);
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
+int xenbus_printf(struct xenbus_transaction *t,
+                 const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
        int ret;
@@ -468,7 +476,7 @@
        va_end(ap);
 
        BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
-       ret = xenbus_write(dir, node, printf_buffer);
+       ret = xenbus_write(t, dir, node, printf_buffer);
 
        kfree(printf_buffer);
 
@@ -495,7 +503,7 @@
 
        BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
        dev->has_error = 1;
-       if (xenbus_write(dev->nodename, "error", printf_buffer) != 0)
+       if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0)
                goto fail;
 
        kfree(printf_buffer);
@@ -511,7 +519,7 @@
 void xenbus_dev_ok(struct xenbus_device *dev)
 {
        if (dev->has_error) {
-               if (xenbus_rm(dev->nodename, "error") != 0)
+               if (xenbus_rm(NULL, dev->nodename, "error") != 0)
                        printk("xenbus: failed to clear error node for %s\n",
                               dev->nodename);
                else
@@ -521,7 +529,7 @@
 EXPORT_SYMBOL(xenbus_dev_ok);
        
 /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(const char *dir, ...)
+int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
 {
        va_list ap;
        const char *name;
@@ -533,7 +541,7 @@
                void *result = va_arg(ap, void *);
                char *p;
 
-               p = xenbus_read(dir, name, NULL);
+               p = xenbus_read(t, dir, name, NULL);
                if (IS_ERR(p)) {
                        ret = PTR_ERR(p);
                        break;
diff -r 5df423407700 -r f1e8d5f64105 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Sun Oct  9 19:55:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Sun Oct  9 20:29:10 2005
@@ -78,26 +78,35 @@
 int xenbus_register_backend(struct xenbus_driver *drv);
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
-char **xenbus_directory(const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(const char *dir, const char *node, unsigned int *len);
-int xenbus_write(const char *dir, const char *node, const char *string);
-int xenbus_mkdir(const char *dir, const char *node);
-int xenbus_exists(const char *dir, const char *node);
-int xenbus_rm(const char *dir, const char *node);
-int xenbus_transaction_start(void);
-int xenbus_transaction_end(int abort);
+struct xenbus_transaction;
+
+char **xenbus_directory(struct xenbus_transaction *t,
+                       const char *dir, const char *node, unsigned int *num);
+void *xenbus_read(struct xenbus_transaction *t,
+                 const char *dir, const char *node, unsigned int *len);
+int xenbus_write(struct xenbus_transaction *t,
+                const char *dir, const char *node, const char *string);
+int xenbus_mkdir(struct xenbus_transaction *t,
+                const char *dir, const char *node);
+int xenbus_exists(struct xenbus_transaction *t,
+                 const char *dir, const char *node);
+int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
+struct xenbus_transaction *xenbus_transaction_start(void);
+int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
-       __attribute__((format(scanf, 3, 4)));
+int xenbus_scanf(struct xenbus_transaction *t,
+                const char *dir, const char *node, const char *fmt, ...)
+       __attribute__((format(scanf, 4, 5)));
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
-       __attribute__((format(printf, 3, 4)));
+int xenbus_printf(struct xenbus_transaction *t,
+                 const char *dir, const char *node, const char *fmt, ...)
+       __attribute__((format(printf, 4, 5)));
 
 /* Generic read function: NULL-terminated triples of name,
  * sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(const char *dir, ...);
+int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
 
 /* Report a (negative) errno into the store, with explanation. */
 void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,...);
diff -r 5df423407700 -r f1e8d5f64105 tools/console/client/main.c
--- a/tools/console/client/main.c       Sun Oct  9 19:55:53 2005
+++ b/tools/console/client/main.c       Sun Oct  9 20:29:10 2005
@@ -220,7 +220,7 @@
        if (path == NULL)
                err(ENOMEM, "realloc");
        strcat(path, "/console/tty");
-       str_pty = xs_read(xs, path, &len);
+       str_pty = xs_read(xs, NULL, path, &len);
 
        /* FIXME consoled currently does not assume domain-0 doesn't have a
           console which is good when we break domain-0 up.  To keep us
@@ -245,7 +245,7 @@
                struct timeval tv = { 0, 500 };
                select(0, NULL, NULL, NULL, &tv); /* pause briefly */
 
-               str_pty = xs_read(xs, path, &len);
+               str_pty = xs_read(xs, NULL, path, &len);
        }
 
        if (str_pty == NULL) {
diff -r 5df423407700 -r f1e8d5f64105 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sun Oct  9 19:55:53 2005
+++ b/tools/console/daemon/io.c Sun Oct  9 20:29:10 2005
@@ -179,7 +179,7 @@
                success = asprintf(&path, "%s/tty", dom->conspath) != -1;
                if (!success)
                        goto out;
-               success = xs_write(xs, path, slave, strlen(slave));
+               success = xs_write(xs, NULL, path, slave, strlen(slave));
                free(path);
                if (!success)
                        goto out;
@@ -187,7 +187,7 @@
                success = asprintf(&path, "%s/limit", dom->conspath) != -1;
                if (!success)
                        goto out;
-               data = xs_read(xs, path, &len);
+               data = xs_read(xs, NULL, path, &len);
                if (data) {
                        dom->buffer.max_capacity = strtoul(data, 0, 0);
                        free(data);
@@ -216,7 +216,7 @@
                char *p;
 
                asprintf(&path, "%s/%s", dir, name);
-               p = xs_read(xs, path, NULL);
+               p = xs_read(xs, NULL, path, NULL);
                free(path);
                if (p == NULL) {
                        ret = ENOENT;
diff -r 5df423407700 -r f1e8d5f64105 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Sun Oct  9 19:55:53 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Sun Oct  9 20:29:10 2005
@@ -80,8 +80,8 @@
 
 static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { "transaction", "path", NULL };
+    static char *arg_spec = "ss";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
@@ -89,13 +89,19 @@
     unsigned int xsval_n = 0;
     PyObject *val = NULL;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_read(xh, path, &xsval_n);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_read(xh, th, path, &xsval_n);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         if (errno == ENOENT) {
@@ -123,8 +129,8 @@
 
 static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", "data", NULL };
-    static char *arg_spec = "ss#";
+    static char *kwd_spec[] = { "transaction", "path", "data", NULL };
+    static char *arg_spec = "sss#";
     char *path = NULL;
     char *data = NULL;
     int data_n = 0;
@@ -133,13 +139,19 @@
     PyObject *val = NULL;
     int xsval = 0;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &path, &data, &data_n))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_write(xh, path, data, data_n);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path, &data, &data_n))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_write(xh, th, path, data, data_n);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -162,8 +174,8 @@
 
 static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { "transaction", "path", NULL };
+    static char *arg_spec = "ss";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
@@ -172,12 +184,20 @@
     unsigned int xsval_n = 0;
     int i;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_directory(xh, path, &xsval_n);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path))
+        goto exit;
+
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_directory(xh, th, path, &xsval_n);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         if (errno == ENOENT) {
@@ -205,20 +225,27 @@
 
 static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { "transaction", "path", NULL };
+    static char *arg_spec = "ss";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
     int xsval = 0;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_mkdir(xh, path);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_mkdir(xh, th, path);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -240,20 +267,27 @@
 
 static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { "transaction", "path", NULL };
+    static char *arg_spec = "ss";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
     int xsval = 0;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_rm(xh, path);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_rm(xh, th, path);
     Py_END_ALLOW_THREADS
     if (!xsval && errno != ENOENT) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -276,8 +310,8 @@
 static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
                                       PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { "transaction", "path", NULL };
+    static char *arg_spec = "ss";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
@@ -286,12 +320,19 @@
     unsigned int perms_n = 0;
     int i;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    perms = xs_get_permissions(xh, path, &perms_n);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    perms = xs_get_permissions(xh, th, path, &perms_n);
     Py_END_ALLOW_THREADS
     if (!perms) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -321,8 +362,8 @@
 static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
                                       PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", "perms", NULL };
-    static char *arg_spec = "sO";
+    static char *kwd_spec[] = { "transaction", "path", "perms", NULL };
+    static char *arg_spec = "ssO";
     char *path = NULL;
     PyObject *perms = NULL;
     static char *perm_names[] = { "dom", "read", "write", NULL };
@@ -335,11 +376,17 @@
     PyObject *tuple0 = NULL;
     PyObject *val = NULL;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &path, &perms))
-        goto exit;
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &path, &perms))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
     if (!PyList_Check(perms)) {
         PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
         goto exit;
@@ -369,7 +416,7 @@
             xsperms[i].perms |= XS_PERM_WRITE;
     }
     Py_BEGIN_ALLOW_THREADS
-    xsval = xs_set_permissions(xh, path, xsperms, xsperms_n);
+    xsval = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -543,9 +590,8 @@
 
 #define xspy_transaction_start_doc "\n"                                \
        "Start a transaction.\n"                                \
-       "Only one transaction can be active at a time.\n"       \
        "\n"                                                    \
-       "Returns None on success.\n"                            \
+       "Returns transaction handle on success.\n"              \
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
@@ -558,21 +604,23 @@
 
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
-    int xsval = 0;
+    struct xs_transaction_handle *th;
+    char thstr[20];
 
     if (!xh)
         goto exit;
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
         goto exit;
     Py_BEGIN_ALLOW_THREADS
-    xsval = xs_transaction_start(xh);
-    Py_END_ALLOW_THREADS
-    if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    Py_INCREF(Py_None);
-    val = Py_None;
+    th = xs_transaction_start(xh);
+    Py_END_ALLOW_THREADS
+    if (th == NULL) {
+        PyErr_SetFromErrno(PyExc_RuntimeError);
+        goto exit;
+    }
+
+    sprintf(thstr, "%lX", (unsigned long)th);
+    val = PyString_FromString(thstr);
  exit:
     return val;
 }
@@ -589,20 +637,27 @@
 static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
                                       PyObject *kwds)
 {
-    static char *kwd_spec[] = { "abort", NULL };
-    static char *arg_spec = "|i";
+    static char *kwd_spec[] = { "transaction", "abort", NULL };
+    static char *arg_spec = "s|i";
     int abort = 0;
 
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
     int xsval = 0;
 
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_transaction_end(xh, abort);
+    struct xs_transaction_handle *th;
+    char *thstr;
+
+    if (!xh)
+        goto exit;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
+                                     &thstr, &abort))
+        goto exit;
+
+    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_transaction_end(xh, th, abort);
     Py_END_ALLOW_THREADS
     if (!xsval) {
        if (errno == EAGAIN) {
diff -r 5df423407700 -r f1e8d5f64105 
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py      Sun Oct  9 19:55:53 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py      Sun Oct  9 20:29:10 2005
@@ -14,29 +14,34 @@
 class xstransact:
 
     def __init__(self, path):
-        self.in_transaction = False
         self.path = path.rstrip("/")
-        xshandle().transaction_start()
+        self.transaction = xshandle().transaction_start()
         self.in_transaction = True
 
     def __del__(self):
         if self.in_transaction:
-            xshandle().transaction_end(True)
+            xshandle().transaction_end(self.transaction, True)
 
     def commit(self):
         if not self.in_transaction:
             raise RuntimeError
         self.in_transaction = False
-        return xshandle().transaction_end(False)
+        rc = xshandle().transaction_end(self.transaction, False)
+        self.transaction = "0"
+        return rc
 
     def abort(self):
+        if not self.in_transaction:
+            return True
         self.in_transaction = False
-        return xshandle().transaction_end(True)
+        rc = xshandle().transaction_end(self.transaction, True)
+        self.transaction = "0"
+        return rc
 
     def _read(self, key):
         path = "%s/%s" % (self.path, key)
         try:
-            return xshandle().read(path)
+            return xshandle().read(self.transaction, path)
         except RuntimeError, ex:
             raise RuntimeError(ex.args[0],
                                '%s, while reading %s' % (ex.args[1], path))
@@ -50,7 +55,7 @@
         instead.
         """
         if len(args) == 0:
-            return xshandle().read(self.path)
+            return xshandle().read(self.transaction, self.path)
         if len(args) == 1:
             return self._read(args[0])
         ret = []
@@ -61,7 +66,7 @@
     def _write(self, key, data):
         path = "%s/%s" % (self.path, key)
         try:
-            xshandle().write(path, data)
+            xshandle().write(self.transaction, path, data)
         except RuntimeError, ex:
             raise RuntimeError(ex.args[0],
                                ('%s, while writing %s : %s' %
@@ -93,7 +98,7 @@
 
     def _remove(self, key):
         path = "%s/%s" % (self.path, key)
-        return xshandle().rm(path)
+        return xshandle().rm(self.transaction, path)
 
     def remove(self, *args):
         """If no arguments are given, remove this transaction's path.
@@ -101,14 +106,14 @@
         path, and remove each of those instead.
         """
         if len(args) == 0:
-            xshandle().rm(self.path)
+            xshandle().rm(self.transaction, self.path)
         else:
             for key in args:
                 self._remove(key)
 
     def _list(self, key):
         path = "%s/%s" % (self.path, key)
-        l = xshandle().ls(path)
+        l = xshandle().ls(self.transaction, path)
         if l:
             return map(lambda x: key + "/" + x, l)
         return []
@@ -120,7 +125,7 @@
         path, and return the cumulative listing of each of those instead.
         """
         if len(args) == 0:
-            ret = xshandle().ls(self.path)
+            ret = xshandle().ls(self.transaction, self.path)
             if ret is None:
                 return []
             else:
@@ -136,11 +141,11 @@
         ret = []
         for key in keys:
             new_subdir = subdir + "/" + key
-            l = xshandle().ls(new_subdir)
+            l = xshandle().ls(self.transaction, new_subdir)
             if l:
                 ret.append([key, self.list_recursive_(new_subdir, l)])
             else:
-                ret.append([key, xshandle().read(new_subdir)])
+                ret.append([key, xshandle().read(self.transaction, 
new_subdir)])
         return ret
 
 
diff -r 5df423407700 -r f1e8d5f64105 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Sun Oct  9 19:55:53 2005
+++ b/tools/xenstore/Makefile   Sun Oct  9 20:29:10 2005
@@ -8,7 +8,7 @@
 INSTALL_DIR     = $(INSTALL) -d -m0755
 
 PROFILE=#-pg
-BASECFLAGS=-Wall -W -g -Werror
+BASECFLAGS=-Wall -g -Werror
 # Make gcc generate dependencies.
 BASECFLAGS += -Wp,-MD,.$(@F).d
 PROG_DEP = .*.d
diff -r 5df423407700 -r f1e8d5f64105 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c  Sun Oct  9 19:55:53 2005
+++ b/tools/xenstore/xenstore_client.c  Sun Oct  9 20:29:10 2005
@@ -32,6 +32,7 @@
 main(int argc, char **argv)
 {
     struct xs_handle *xsh;
+    struct xs_transaction_handle *xth;
     bool success;
     int ret = 0;
 #if defined(CLIENT_read) || defined(CLIENT_list)
@@ -84,13 +85,13 @@
 #endif
 
   again:
-    success = xs_transaction_start(xsh);
-    if (!success)
+    xth = xs_transaction_start(xsh);
+    if (xth == NULL)
        errx(1, "couldn't start transaction");
 
     while (optind < argc) {
 #if defined(CLIENT_read)
-       char *val = xs_read(xsh, argv[optind], NULL);
+       char *val = xs_read(xsh, xth, argv[optind], NULL);
        if (val == NULL) {
            warnx("couldn't read path %s", argv[optind]);
            ret = 1;
@@ -102,7 +103,7 @@
        free(val);
        optind++;
 #elif defined(CLIENT_write)
-       success = xs_write(xsh, argv[optind], argv[optind + 1],
+       success = xs_write(xsh, xth, argv[optind], argv[optind + 1],
                           strlen(argv[optind + 1]));
        if (!success) {
            warnx("could not write path %s", argv[optind]);
@@ -111,7 +112,7 @@
        }
        optind += 2;
 #elif defined(CLIENT_rm)
-       success = xs_rm(xsh, argv[optind]);
+       success = xs_rm(xsh, xth, argv[optind]);
        if (!success) {
            warnx("could not remove path %s", argv[optind]);
            ret = 1;
@@ -119,7 +120,7 @@
        }
        optind++;
 #elif defined(CLIENT_exists)
-       char *val = xs_read(xsh, argv[optind], NULL);
+       char *val = xs_read(xsh, xth, argv[optind], NULL);
        if (val == NULL) {
            ret = 1;
            goto out;
@@ -128,7 +129,7 @@
        optind++;
 #elif defined(CLIENT_list)
        unsigned int i, num;
-       char **list = xs_directory(xsh, argv[optind], &num);
+       char **list = xs_directory(xsh, xth, argv[optind], &num);
        if (list == NULL) {
            warnx("could not list path %s", argv[optind]);
            ret = 1;
@@ -145,7 +146,7 @@
     }
 
  out:
-    success = xs_transaction_end(xsh, ret ? true : false);
+    success = xs_transaction_end(xsh, xth, ret ? true : false);
     if (!success) {
        if (ret == 0 && errno == EAGAIN)
            goto again;
diff -r 5df423407700 -r f1e8d5f64105 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Sun Oct  9 19:55:53 2005
+++ b/tools/xenstore/xs.c       Sun Oct  9 20:29:10 2005
@@ -81,6 +81,10 @@
        pthread_t transaction_pthread;
 };
 
+struct xs_transaction_handle {
+       int id;
+};
+
 static void *read_thread(void *arg);
 
 static void request_mutex_acquire(struct xs_handle *h)
@@ -407,7 +411,8 @@
        return true;
 }
 
-char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num)
+char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+                   const char *path, unsigned int *num)
 {
        char *strings, *p, **ret;
        unsigned int len;
@@ -438,7 +443,8 @@
  * Returns a malloced value: call free() on it after use.
  * len indicates length in bytes, not including the nul.
  */
-void *xs_read(struct xs_handle *h, const char *path, unsigned int *len)
+void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path, unsigned int *len)
 {
        return xs_single(h, XS_READ, path, len);
 }
@@ -446,8 +452,8 @@
 /* Write the value of a single file.
  * Returns false on failure.
  */
-bool xs_write(struct xs_handle *h, const char *path,
-             const void *data, unsigned int len)
+bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path, const void *data, unsigned int len)
 {
        struct iovec iovec[2];
 
@@ -462,7 +468,8 @@
 /* Create a new directory.
  * Returns false on failure, or success if it already exists.
  */
-bool xs_mkdir(struct xs_handle *h, const char *path)
+bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path)
 {
        return xs_bool(xs_single(h, XS_MKDIR, path, NULL));
 }
@@ -470,7 +477,8 @@
 /* Destroy a file or directory (directories must be empty).
  * Returns false on failure, or success if it doesn't exist.
  */
-bool xs_rm(struct xs_handle *h, const char *path)
+bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+          const char *path)
 {
        return xs_bool(xs_single(h, XS_RM, path, NULL));
 }
@@ -479,6 +487,7 @@
  * Returns malloced array, or NULL: call free() after use.
  */
 struct xs_permissions *xs_get_permissions(struct xs_handle *h,
+                                         struct xs_transaction_handle *t,
                                          const char *path, unsigned int *num)
 {
        char *strings;
@@ -511,7 +520,9 @@
 /* Set permissions of node (must be owner).
  * Returns false on failure.
  */
-bool xs_set_permissions(struct xs_handle *h, const char *path,
+bool xs_set_permissions(struct xs_handle *h,
+                       struct xs_transaction_handle *t,
+                       const char *path,
                        struct xs_permissions *perms,
                        unsigned int num_perms)
 {
@@ -632,9 +643,9 @@
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
  * You can only have one transaction at any time.
- * Returns false on failure.
- */
-bool xs_transaction_start(struct xs_handle *h)
+ * Returns NULL on failure.
+ */
+struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
 {
        bool rc;
 
@@ -647,7 +658,7 @@
                pthread_mutex_unlock(&h->transaction_mutex);
        }
 
-       return rc;
+       return (struct xs_transaction_handle *)rc;
 }
 
 /* End a transaction.
@@ -655,10 +666,14 @@
  * Returns false on failure, which indicates an error: transactions will
  * not fail spuriously.
  */
-bool xs_transaction_end(struct xs_handle *h, bool abort)
+bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+                       bool abort)
 {
        char abortstr[2];
        bool rc;
+
+       if (t == NULL)
+               return -EINVAL;
 
        if (abort)
                strcpy(abortstr, "F");
diff -r 5df423407700 -r f1e8d5f64105 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Sun Oct  9 19:55:53 2005
+++ b/tools/xenstore/xs.h       Sun Oct  9 20:29:10 2005
@@ -23,6 +23,7 @@
 #include <xs_lib.h>
 
 struct xs_handle;
+struct xs_transaction_handle;
 
 /* On failure, these routines set errno. */
 
@@ -44,41 +45,47 @@
  * Returns a malloced array: call free() on it after use.
  * Num indicates size.
  */
-char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num);
+char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+                   const char *path, unsigned int *num);
 
 /* Get the value of a single file, nul terminated.
  * Returns a malloced value: call free() on it after use.
  * len indicates length in bytes, not including terminator.
  */
-void *xs_read(struct xs_handle *h, const char *path, unsigned int *len);
+void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path, unsigned int *len);
 
 /* Write the value of a single file.
  * Returns false on failure.
  */
-bool xs_write(struct xs_handle *h, const char *path, const void *data,
-             unsigned int len);
+bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path, const void *data, unsigned int len);
 
 /* Create a new directory.
  * Returns false on failure, or success if it already exists.
  */
-bool xs_mkdir(struct xs_handle *h, const char *path);
+bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+             const char *path);
 
 /* Destroy a file or directory (and children).
  * Returns false on failure, or success if it doesn't exist.
  */
-bool xs_rm(struct xs_handle *h, const char *path);
+bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+          const char *path);
 
 /* Get permissions of node (first element is owner, first perms is "other").
  * Returns malloced array, or NULL: call free() after use.
  */
 struct xs_permissions *xs_get_permissions(struct xs_handle *h,
+                                         struct xs_transaction_handle *t,
                                          const char *path, unsigned int *num);
 
 /* Set permissions of node (must be owner).
  * Returns false on failure.
  */
-bool xs_set_permissions(struct xs_handle *h, const char *path,
-                       struct xs_permissions *perms, unsigned int num_perms);
+bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
+                       const char *path, struct xs_permissions *perms,
+                       unsigned int num_perms);
 
 /* Watch a node for changes (poll on fd to detect, or call read_watch()).
  * When the node (or any child) changes, fd will become readable.
@@ -104,16 +111,17 @@
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
  * You can only have one transaction at any time.
- * Returns false on failure.
+ * Returns NULL on failure.
  */
-bool xs_transaction_start(struct xs_handle *h);
+struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
 
 /* End a transaction.
  * If abandon is true, transaction is discarded instead of committed.
  * Returns false on failure: if errno == EAGAIN, you have to restart
  * transaction.
  */
-bool xs_transaction_end(struct xs_handle *h, bool abort);
+bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+                       bool abort);
 
 /* Introduce a new domain.
  * This tells the store daemon about a shared memory page, event channel
@@ -136,3 +144,13 @@
                       void *data, unsigned int len);
 
 #endif /* _XS_H */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 5df423407700 -r f1e8d5f64105 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Sun Oct  9 19:55:53 2005
+++ b/tools/xenstore/xs_test.c  Sun Oct  9 20:29:10 2005
@@ -42,6 +42,7 @@
 #define XSTEST
 
 static struct xs_handle *handles[10] = { NULL };
+static struct xs_transaction_handle *txh[10] = { NULL };
 
 static unsigned int timeout_ms = 500;
 static bool timeout_suppressed = true;
@@ -312,7 +313,7 @@
        char **entries;
        unsigned int i, num;
 
-       entries = xs_directory(handles[handle], path, &num);
+       entries = xs_directory(handles[handle], txh[handle], path, &num);
        if (!entries) {
                failed(handle);
                return;
@@ -331,7 +332,7 @@
        char *value;
        unsigned int len;
 
-       value = xs_read(handles[handle], path, &len);
+       value = xs_read(handles[handle], txh[handle], path, &len);
        if (!value) {
                failed(handle);
                return;
@@ -347,7 +348,7 @@
 
 static void do_write(unsigned int handle, char *path, char *data)
 {
-       if (!xs_write(handles[handle], path, data, strlen(data)))
+       if (!xs_write(handles[handle], txh[handle], path, data, strlen(data)))
                failed(handle);
 }
 
@@ -360,13 +361,13 @@
 
 static void do_mkdir(unsigned int handle, char *path)
 {
-       if (!xs_mkdir(handles[handle], path))
+       if (!xs_mkdir(handles[handle], txh[handle], path))
                failed(handle);
 }
 
 static void do_rm(unsigned int handle, char *path)
 {
-       if (!xs_rm(handles[handle], path))
+       if (!xs_rm(handles[handle], txh[handle], path))
                failed(handle);
 }
 
@@ -375,7 +376,7 @@
        unsigned int i, num;
        struct xs_permissions *perms;
 
-       perms = xs_get_permissions(handles[handle], path, &num);
+       perms = xs_get_permissions(handles[handle], txh[handle], path, &num);
        if (!perms) {
                failed(handle);
                return;
@@ -436,7 +437,7 @@
                        barf("bad flags %s\n", arg);
        }
 
-       if (!xs_set_permissions(handles[handle], path, perms, i))
+       if (!xs_set_permissions(handles[handle], txh[handle], path, perms, i))
                failed(handle);
 }
 
@@ -520,14 +521,16 @@
 
 static void do_start(unsigned int handle)
 {
-       if (!xs_transaction_start(handles[handle]))
+       txh[handle] = xs_transaction_start(handles[handle]);
+       if (txh[handle] == NULL)
                failed(handle);
 }
 
 static void do_end(unsigned int handle, bool abort)
 {
-       if (!xs_transaction_end(handles[handle], abort))
-               failed(handle);
+       if (!xs_transaction_end(handles[handle], txh[handle], abort))
+               failed(handle);
+       txh[handle] = NULL;
 }
 
 static void do_introduce(unsigned int handle,
@@ -617,7 +620,8 @@
 
                sprintf(subnode, "%s/%s", node, dir[i]);
 
-               perms = xs_get_permissions(handles[handle], subnode,&numperms);
+               perms = xs_get_permissions(handles[handle], txh[handle],
+                                          subnode,&numperms);
                if (!perms) {
                        failed(handle);
                        return;
@@ -634,7 +638,8 @@
                output("\n");
 
                /* Even directories can have contents. */
-               contents = xs_read(handles[handle], subnode, &len);
+               contents = xs_read(handles[handle], txh[handle], 
+                                  subnode, &len);
                if (!contents) {
                        if (errno != EISDIR)
                                failed(handle);
@@ -644,7 +649,8 @@
                }                       
 
                /* Every node is a directory. */
-               subdirs = xs_directory(handles[handle], subnode, &subnum);
+               subdirs = xs_directory(handles[handle], txh[handle], 
+                                      subnode, &subnum);
                if (!subdirs) {
                        failed(handle);
                        return;
@@ -659,7 +665,7 @@
        char **subdirs;
        unsigned int subnum;
 
-       subdirs = xs_directory(handles[handle], "/", &subnum);
+       subdirs = xs_directory(handles[handle], txh[handle], "/", &subnum);
        if (!subdirs) {
                failed(handle);
                return;
@@ -742,6 +748,7 @@
        else if (streq(command, "close")) {
                xs_daemon_close(handles[handle]);
                handles[handle] = NULL;
+               txh[handle] = NULL;
        } else if (streq(command, "start"))
                do_start(handle);
        else if (streq(command, "commit"))
@@ -825,3 +832,13 @@
 
        return 0;
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Extend xenbus/xenstore client interface to include a transaction, Xen patchbot -unstable <=