mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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:
1 parent
f11f68cd11
commit
bdd477ad34
15 files changed
+92
-115
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||