# HG changeset patch
# User emellor@ewan
# Node ID 10d6bda59ea4580b6138f73afcd7b5daca5d6332
# Parent 76af1a1df67cd8958fc40b1c574a8bd26d5026c2
Add check for speed (takes 33 minutes on my laptop, OUCH!)
Make xenstored use tdb, transactions can soft-fail (EAGAIN)
Transactions no longer take root dir, no longer lock & block: commit can fail
spuriously with EAGAIN, not ETIMEDOUT.
Speeds up transactions by over 1000 times, should be NFS safe.
New program: xs_tdb_dump to dump raw TDB contents.
Don't do failure testing: we are no longer robust against all ENOMEM 8(
Introduce "struct node" which contains perms, children and data.
Make struct xs_permissions unpadded, so we can write to tdb w/o valgrind
complaints.
Gently modify TDB to use talloc, not do alloc on tdb_delete.
Fix up transaction users for new semantics.
Don't need a transaction around a single read in xen/i386/kernel/smpboot.c.
Python: transaction_start() returns True/False rather than raising exception on
EAGAIN.
Fix usage comment on xs_transaction_end().
Include stdarg to xs_tdb_dump so it compiles.
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Sep 23
13:25:01 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Sep 23
13:28:16 2005
@@ -1394,9 +1394,7 @@
return;
/* get the state value */
- xenbus_transaction_start("cpu");
err = xenbus_scanf(dir, "availability", "%s", state);
- xenbus_transaction_end(0);
if (err != 1) {
printk(KERN_ERR
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Fri Sep 23 13:25:01 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Fri Sep 23 13:28:16 2005
@@ -324,7 +324,7 @@
int err;
again:
- err = xenbus_transaction_start("control");
+ err = xenbus_transaction_start();
if (err)
return;
str = (char *)xenbus_read("control", "shutdown", NULL);
@@ -337,7 +337,7 @@
xenbus_write("control", "shutdown", "");
err = xenbus_transaction_end(0);
- if (err == -ETIMEDOUT) {
+ if (err == -EAGAIN) {
kfree(str);
goto again;
}
@@ -366,7 +366,7 @@
int err;
again:
- err = xenbus_transaction_start("control");
+ err = xenbus_transaction_start();
if (err)
return;
if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
@@ -379,7 +379,7 @@
xenbus_printf("control", "sysrq", "%c", '\0');
err = xenbus_transaction_end(0);
- if (err == -ETIMEDOUT)
+ if (err == -EAGAIN)
goto again;
if (sysrq_key != '\0') {
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 23 13:25:01 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 23 13:28:16 2005
@@ -80,8 +80,9 @@
return;
}
+again:
/* Supply the information about the device the frontend needs */
- err = xenbus_transaction_start(be->dev->nodename);
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(be->dev, err, "starting transaction");
return;
@@ -119,7 +120,15 @@
goto abort;
}
- xenbus_transaction_end(0);
+ err = xenbus_transaction_end(0);
+ if (err == EAGAIN)
+ goto again;
+ if (err) {
+ xenbus_dev_error(be->dev, err, "ending transaction",
+ ring_ref, evtchn);
+ goto abort;
+ }
+
xenbus_dev_ok(be->dev);
return;
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 23
13:25:01 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 23
13:28:16 2005
@@ -572,7 +572,8 @@
goto out;
}
- err = xenbus_transaction_start(dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(dev, err, "starting transaction");
goto destroy_blkring;
@@ -603,6 +604,8 @@
err = xenbus_transaction_end(0);
if (err) {
+ if (err == EAGAIN)
+ goto again;
xenbus_dev_error(dev, err, "completing transaction");
goto destroy_blkring;
}
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 23
13:25:01 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 23
13:28:16 2005
@@ -1122,7 +1122,8 @@
goto out;
}
- err = xenbus_transaction_start(dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(dev, err, "starting transaction");
goto destroy_ring;
@@ -1160,6 +1161,8 @@
err = xenbus_transaction_end(0);
if (err) {
+ if (err == EAGAIN)
+ goto again;
xenbus_dev_error(dev, err, "completing transaction");
goto destroy_ring;
}
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Sep 23
13:25:01 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Sep 23
13:28:16 2005
@@ -287,12 +287,11 @@
/* Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
- * Transaction only applies to the given subtree.
* You can only have one transaction at any time.
*/
-int xenbus_transaction_start(const char *subtree)
-{
- return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
+int xenbus_transaction_start(void)
+{
+ return xs_error(xs_single(XS_TRANSACTION_START, "", NULL));
}
EXPORT_SYMBOL(xenbus_transaction_start);
diff -r 76af1a1df67c -r 10d6bda59ea4
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Fri Sep 23 13:25:01 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Fri Sep 23 13:28:16 2005
@@ -87,7 +87,7 @@
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(const char *subtree);
+int xenbus_transaction_start(void);
int xenbus_transaction_end(int abort);
/* Single read and scanf: returns -errno or num scanned if > 0. */
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Fri Sep 23 13:25:01 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Fri Sep 23 13:28:16 2005
@@ -582,9 +582,8 @@
}
#define xspy_transaction_start_doc "\n" \
- "Start a transaction on a path.\n" \
+ "Start a transaction.\n" \
"Only one transaction can be active at a time.\n" \
- " path [string]: xenstore path.\n" \
"\n" \
"Returns None on success.\n" \
"Raises RuntimeError on error.\n" \
@@ -593,8 +592,8 @@
static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
PyObject *kwds)
{
- static char *kwd_spec[] = { "path", NULL };
- static char *arg_spec = "s|";
+ static char *kwd_spec[] = { NULL };
+ static char *arg_spec = "";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
@@ -606,7 +605,7 @@
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
goto exit;
Py_BEGIN_ALLOW_THREADS
- xsval = xs_transaction_start(xh, path);
+ xsval = xs_transaction_start(xh);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -623,7 +622,7 @@
"Attempts to commit the transaction unless abort is true.\n" \
" abort [int]: abort flag (default 0).\n" \
"\n" \
- "Returns None on success.\n" \
+ "Returns True on success, False if you need to try again.\n" \
"Raises RuntimeError on error.\n" \
"\n"
@@ -646,11 +645,16 @@
xsval = xs_transaction_end(xh, abort);
Py_END_ALLOW_THREADS
if (!xsval) {
- PyErr_SetFromErrno(PyExc_RuntimeError);
- goto exit;
- }
- Py_INCREF(Py_None);
- val = Py_None;
+ if (errno == EAGAIN) {
+ Py_INCREF(Py_False);
+ val = Py_False;
+ goto exit;
+ }
+ PyErr_SetFromErrno(PyExc_RuntimeError);
+ goto exit;
+ }
+ Py_INCREF(Py_True);
+ val = Py_True;
exit:
return val;
}
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Sep 23 13:25:01 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Sep 23 13:28:16 2005
@@ -839,20 +839,20 @@
"""Release all vm devices.
"""
- t = xstransact("%s/device" % self.path)
-
- for n in controllerClasses.keys():
- for d in t.list(n):
- try:
- t.remove(d)
- except ex:
- # Log and swallow any exceptions in removal -- there's
- # nothing more we can do.
- log.exception(
- "Device release failed: %s; %s; %s; %s" %
- (self.info['name'], n, d, str(ex)))
- t.commit()
-
+ while True:
+ t = xstransact("%s/device" % self.path)
+ for n in controllerClasses.keys():
+ for d in t.list(n):
+ try:
+ t.remove(d)
+ except ex:
+ # Log and swallow any exceptions in removal --
+ # there's nothing more we can do.
+ log.exception(
+ "Device release failed: %s; %s; %s; %s" %
+ (self.info['name'], n, d, str(ex)))
+ if t.commit():
+ break
def eventChannel(self, path=None):
"""Create an event channel to the domain.
diff -r 76af1a1df67c -r 10d6bda59ea4
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Sep 23 13:25:01 2005
+++ b/tools/python/xen/xend/server/DevController.py Fri Sep 23 13:28:16 2005
@@ -126,20 +126,21 @@
compulsory to use it; subclasses may prefer to allocate IDs based upon
the device configuration instead.
"""
- path = self.frontendMiscPath()
- t = xstransact(path)
- try:
- result = t.read("nextDeviceID")
- if result:
- result = int(result)
- else:
- result = 1
- t.write("nextDeviceID", str(result + 1))
- t.commit()
- return result
- except:
- t.abort()
- raise
+ while True:
+ path = self.frontendMiscPath()
+ t = xstransact(path)
+ try:
+ result = t.read("nextDeviceID")
+ if result:
+ result = int(result)
+ else:
+ result = 1
+ t.write("nextDeviceID", str(result + 1))
+ if t.commit():
+ return result
+ except:
+ t.abort()
+ raise
## private:
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/python/xen/xend/xenstore/xsnode.py
--- a/tools/python/xen/xend/xenstore/xsnode.py Fri Sep 23 13:25:01 2005
+++ b/tools/python/xen/xend/xenstore/xsnode.py Fri Sep 23 13:28:16 2005
@@ -280,8 +280,8 @@
(', while writing %s : %s' % (str(path),
str(data))))
- def begin(self, path):
- self.getxs().transaction_start(path)
+ def begin(self):
+ self.getxs().transaction_start()
def commit(self, abandon=False):
self.getxs().transaction_end(abort=abandon)
diff -r 76af1a1df67c -r 10d6bda59ea4
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py Fri Sep 23 13:25:01 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py Fri Sep 23 13:28:16 2005
@@ -14,16 +14,8 @@
def __init__(self, path):
self.in_transaction = False
self.path = path.rstrip("/")
- while True:
- try:
- xshandle().transaction_start(path)
- self.in_transaction = True
- return
- except RuntimeError, ex:
- if ex.args[0] == errno.ENOENT and path != "/":
- path = "/".join(path.split("/")[0:-1]) or "/"
- else:
- raise
+ xshandle().transaction_start()
+ self.in_transaction = True
def __del__(self):
if self.in_transaction:
@@ -175,14 +167,8 @@
t = cls(path)
try:
v = t.read(*args)
- t.commit()
+ t.abort()
return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
except:
t.abort()
raise
@@ -194,14 +180,8 @@
t = cls(path)
try:
t.write(*args, **opts)
- t.commit()
- return
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return
except:
t.abort()
raise
@@ -217,14 +197,8 @@
t = cls(path)
try:
t.remove(*args)
- t.commit()
- return
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return
except:
t.abort()
raise
@@ -236,14 +210,8 @@
t = cls(path)
try:
v = t.list(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
@@ -255,14 +223,8 @@
t = cls(path)
try:
v = t.gather(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
@@ -274,14 +236,8 @@
t = cls(path)
try:
v = t.store(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c Fri Sep 23 13:25:01 2005
+++ b/tools/xenstore/xenstore_client.c Fri Sep 23 13:28:16 2005
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <xs.h>
+#include <errno.h>
static void
usage(const char *progname)
@@ -82,8 +83,8 @@
}
#endif
- /* XXX maybe find longest common prefix */
- success = xs_transaction_start(xsh, "/");
+ again:
+ success = xs_transaction_start(xsh);
if (!success)
errx(1, "couldn't start transaction");
@@ -145,8 +146,10 @@
out:
success = xs_transaction_end(xsh, ret ? true : false);
- if (!success)
+ if (!success) {
+ if (ret == 0 && errno == EAGAIN)
+ goto again;
errx(1, "couldn't end transaction");
-
+ }
return ret;
}
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h Fri Sep 23 13:25:01 2005
+++ b/tools/xenstore/xs.h Fri Sep 23 13:28:16 2005
@@ -116,8 +116,8 @@
/* End a transaction.
* If abandon is true, transaction is discarded instead of committed.
- * Returns false on failure, which indicates an error: transactions will
- * not fail spuriously.
+ * Returns false on failure: if errno == EAGAIN, you have to restart
+ * transaction.
*/
bool xs_transaction_end(struct xs_handle *h, bool abort);
diff -r 76af1a1df67c -r 10d6bda59ea4 tools/xenstore/xs_tdb_dump.c
--- a/tools/xenstore/xs_tdb_dump.c Fri Sep 23 13:25:01 2005
+++ b/tools/xenstore/xs_tdb_dump.c Fri Sep 23 13:28:16 2005
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdarg.h>
#include "xs_lib.h"
#include "tdb.h"
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|