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@rustcorp.com.au>
This commit is contained in:
emellor@ewan committed 2005-09-23 14:28:16 +01:00
1 parent f11f68cd11
commit bdd477ad34
15 files changed
+92 -115

No files matched your search

+12 -8
View File
@@ -582,9 +582,8 @@ static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
}
#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_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
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 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
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 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
"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 @@ static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
xsval = xs_transaction_end(xh, abort);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == EAGAIN) {
Py_INCREF(Py_False);
val = Py_False;
goto exit;
}
PyErr_SetFromErrno(PyExc_RuntimeError);
goto exit;
}
Py_INCREF(Py_None);
val = Py_None;
Py_INCREF(Py_True);
val = Py_True;
exit:
return val;
}
+14 -14
View File
@@ -839,20 +839,20 @@ class XendDomainInfo:
"""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.
+15 -14
View File
@@ -126,20 +126,21 @@ class DevController:
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:
+2 -2
View File
@@ -280,8 +280,8 @@ class XenStore:
(', 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)
+13 -57
View File
@@ -14,16 +14,8 @@ class xstransact:
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 @@ class xstransact:
t = cls(path)
try:
v = t.read(*args)
t.commit()
return v
except RuntimeError, ex:
t.abort()
if ex.args[0] == errno.ETIMEDOUT:
pass
else:
raise
return v
except:
t.abort()
raise
@@ -194,14 +180,8 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.