[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Add check for speed (takes 33 minutes on my laptop, OUCH!)



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.