[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


 


Rackspace

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