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@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-10-09 21:29:10 +01:00
1 parent f2b39d8ae1
commit 25517fd2f2
22 files changed
+364 -223

No files matched your search

+94 -39
View File
@@ -80,8 +80,8 @@ static inline PyObject *pyvalue_str(char *val) {
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 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
unsigned int xsval_n = 0;
PyObject *val = NULL;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path))
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_read(xh, path, &xsval_n);
xsval = xs_read(xh, th, path, &xsval_n);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == ENOENT) {
@@ -123,8 +129,8 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
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 @@ static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path, &data, &data_n))
&thstr, &path, &data, &data_n))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_write(xh, path, data, data_n);
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_write(PyObject *self, PyObject *args, PyObject *kwds)
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 @@ static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
unsigned int xsval_n = 0;
int i;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
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, path, &xsval_n);
xsval = xs_directory(xh, th, path, &xsval_n);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == ENOENT) {
@@ -205,20 +225,27 @@ static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
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;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
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, path);
xsval = xs_mkdir(xh, th, path);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -240,20 +267,27 @@ static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
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;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
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, path);
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_rm(PyObject *self, PyObject *args, PyObject *kwds)
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 @@ static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
unsigned int perms_n = 0;
int i;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
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, path, &perms_n);
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_get_permissions(PyObject *self, PyObject *args,
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 @@ static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
PyObject *tuple0 = NULL;
PyObject *val = NULL;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path, &perms))
&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 @@ static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
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 @@ static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
#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 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
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);
th = xs_transaction_start(xh);
Py_END_ALLOW_THREADS
if (!xsval) {
if (th == NULL) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto exit;
}
Py_INCREF(Py_None);
val = Py_None;
sprintf(thstr, "%lX", (unsigned long)th);
val = PyString_FromString(thstr);
exit:
return val;
}
@@ -589,20 +637,27 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
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;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
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, abort);
xsval = xs_transaction_end(xh, th, abort);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == EAGAIN) {
+19 -14
View File
@@ -14,29 +14,34 @@ from xen.xend.xenstore.xsutil import xshandle
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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 @@ class xstransact:
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
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.