|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/7] minios: enhance xenstore available for stubdoms
Update xs*_{open,close} to match new API (mainly introduce xs_open and
xs_close).
Add xs_transaction_{start,end} and xs_{get,set}_permissions - mostly
based on tools/xenstore/xs.c.
Signed-off-by: Marek Marczykowski <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
extras/mini-os/lib/xs.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 192 insertions(+), 3 deletions(-)
diff --git a/extras/mini-os/lib/xs.c b/extras/mini-os/lib/xs.c
index a2a1220..ff524c3 100644
--- a/extras/mini-os/lib/xs.c
+++ b/extras/mini-os/lib/xs.c
@@ -18,14 +18,25 @@ static inline int _xs_fileno(struct xs_handle *h) {
return (intptr_t) h;
}
-struct xs_handle *xs_daemon_open()
-{
- int fd = alloc_fd(FTYPE_XENBUS);
+struct xs_handle *xs_open(unsigned long flags) {
+ int fd;
+ if (flags != 0)
+ return NULL;
+ fd = alloc_fd(FTYPE_XENBUS);
files[fd].xenbus.events = NULL;
printk("xs_daemon_open -> %d, %p\n", fd, &files[fd].xenbus.events);
return (void*)(intptr_t) fd;
}
+struct xs_handle *xs_daemon_open()
+{
+ return xs_open(0);
+}
+
+struct xs_handle *xs_domain_open() {
+ return xs_open(0);
+}
+
void xs_daemon_close(struct xs_handle *h)
{
int fd = _xs_fileno(h);
@@ -35,6 +46,12 @@ void xs_daemon_close(struct xs_handle *h)
files[fd].type = FTYPE_NONE;
}
+void xs_close(struct xs_handle *h)
+{
+ if (h)
+ xs_daemon_close(h);
+}
+
int xs_fileno(struct xs_handle *h)
{
return _xs_fileno(h);
@@ -186,4 +203,176 @@ bool xs_unwatch(struct xs_handle *h, const char *path,
const char *token)
printk("xs_unwatch(%s, %s)\n", path, token);
return xs_bool(xenbus_unwatch_path_token(XBT_NULL, path, token));
}
+
+xs_transaction_t xs_transaction_start(struct xs_handle *h)
+{
+ xenbus_transaction_t xbt;
+
+ if (!xs_bool(xenbus_transaction_start(&xbt)))
+ return XBT_NULL;
+ return xbt;
+}
+
+bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t, bool abort)
+{
+ int retry;
+
+ if (!xs_bool(xenbus_transaction_end(t, abort, &retry)))
+ return false;
+ if (retry) {
+ errno = EAGAIN;
+ return false;
+ }
+ return true;
+}
+
+/* Convert strings to permissions. False if a problem. */
+bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
+ const char *strings)
+{
+ const char *p;
+ char *end;
+ unsigned int i;
+
+ for (p = strings, i = 0; i < num; i++) {
+ /* "r", "w", or "b" for both. */
+ switch (*p) {
+ case 'r':
+ perms[i].perms = XS_PERM_READ;
+ break;
+ case 'w':
+ perms[i].perms = XS_PERM_WRITE;
+ break;
+ case 'b':
+ perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
+ break;
+ case 'n':
+ perms[i].perms = XS_PERM_NONE;
+ break;
+ default:
+ errno = EINVAL;
+ return false;
+ }
+ p++;
+ perms[i].id = strtol(p, &end, 0);
+ if (*end || !*p) {
+ errno = EINVAL;
+ return false;
+ }
+ p = end + 1;
+ }
+ return true;
+}
+
+/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
+bool xs_perm_to_string(const struct xs_permissions *perm,
+ char *buffer, size_t buf_len)
+{
+ switch ((int)perm->perms) {
+ case XS_PERM_WRITE:
+ *buffer = 'w';
+ break;
+ case XS_PERM_READ:
+ *buffer = 'r';
+ break;
+ case XS_PERM_READ|XS_PERM_WRITE:
+ *buffer = 'b';
+ break;
+ case XS_PERM_NONE:
+ *buffer = 'n';
+ break;
+ default:
+ errno = EINVAL;
+ return false;
+ }
+ snprintf(buffer+1, buf_len-1, "%i", (int)perm->id);
+ return true;
+}
+
+/* Given a string and a length, count how many strings (nul terms). */
+unsigned int xs_count_strings(const char *strings, unsigned int len)
+{
+ unsigned int num;
+ const char *p;
+
+ for (p = strings, num = 0; p < strings + len; p++)
+ if (*p == '\0')
+ num++;
+
+ return num;
+}
+
+/* Get permissions of node (first element is owner).
+ * Returns malloced array, or NULL: call free() after use.
+ */
+struct xs_permissions *xs_get_permissions(struct xs_handle *h,
+ xs_transaction_t t,
+ const char *path, unsigned int *num)
+{
+ char *strings;
+ unsigned int len;
+ struct xs_permissions *ret;
+
+ strings = xs_single(h, t, XS_GET_PERMS, path, &len);
+ if (!strings)
+ return NULL;
+
+ /* Count the strings: each one perms then domid. */
+ *num = xs_count_strings(strings, len);
+
+ /* Transfer to one big alloc for easy freeing. */
+ ret = malloc(*num * sizeof(struct xs_permissions));
+ if (!ret) {
+ free(strings);
+ return NULL;
+ }
+
+ if (!xs_strings_to_perms(ret, *num, strings)) {
+ free(ret);
+ ret = NULL;
+ }
+
+ free(strings);
+ return ret;
+}
+
+/* Set permissions of node (must be owner).
+ * Returns false on failure.
+ */
+bool xs_set_permissions(struct xs_handle *h,
+ xs_transaction_t t,
+ const char *path,
+ struct xs_permissions *perms,
+ unsigned int num_perms)
+{
+ unsigned int i;
+ struct write_req iov[1+num_perms];
+
+ iov[0].data = (void *)path;
+ iov[0].len = strlen(path) + 1;
+
+ for (i = 0; i < num_perms; i++) {
+ char buffer[MAX_STRLEN(unsigned int)+1];
+
+ if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+ goto unwind;
+
+ iov[i+1].data = strdup(buffer);
+ iov[i+1].len = strlen(buffer) + 1;
+ if (!iov[i+1].data)
+ goto unwind;
+ }
+
+ if (!xs_bool(xs_talkv(h, t, XS_SET_PERMS, iov, 1+num_perms, NULL)))
+ goto unwind;
+ for (i = 0; i < num_perms; i++)
+ free((void*)iov[i+1].data);
+ return true;
+
+unwind:
+ num_perms = i;
+ for (i = 0; i < num_perms; i++)
+ free((void*)iov[i+1].data);
+ return false;
+}
#endif
--
1.8.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |