[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 |