[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 08/12] xenstore: let command functions return error or success



Add a return value to all wire command functions of xenstored. If such
a function returns an error send the error message in
process_message().

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
 tools/xenstore/xenstored_core.c        | 213 +++++++++++++++------------------
 tools/xenstore/xenstored_domain.c      | 170 +++++++++++---------------
 tools/xenstore/xenstored_domain.h      |  14 +--
 tools/xenstore/xenstored_transaction.c |  50 ++++----
 tools/xenstore/xenstored_transaction.h |   4 +-
 tools/xenstore/xenstored_watch.c       |  46 +++----
 tools/xenstore/xenstored_watch.h       |   4 +-
 7 files changed, 212 insertions(+), 289 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f46ba6f..f5ec585 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -770,33 +770,31 @@ bool check_event_node(const char *node)
        return true;
 }
 
-static void send_directory(struct connection *conn, struct buffered_data *in)
+static int send_directory(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
        const char *name = onearg(in);
 
        name = canonicalize(conn, name);
        node = get_node(conn, in, name, XS_PERM_READ);
-       if (!node) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!node)
+               return errno;
 
        send_reply(conn, XS_DIRECTORY, node->children, node->childlen);
+
+       return 0;
 }
 
-static void send_directory_part(struct connection *conn,
-                               struct buffered_data *in)
+static int send_directory_part(struct connection *conn,
+                              struct buffered_data *in)
 {
        unsigned int off, len, maxlen, genlen;
        char *name, *child, *data;
        struct node *node;
        char gen[24];
 
-       if (xs_count_strings(in->buffer, in->used) != 2) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (xs_count_strings(in->buffer, in->used) != 2)
+               return EINVAL;
 
        /* First arg is node name. */
        name = canonicalize(conn, in->buffer);
@@ -805,10 +803,8 @@ static void send_directory_part(struct connection *conn,
        off = atoi(in->buffer + strlen(in->buffer) + 1);
 
        node = get_node(conn, in, name, XS_PERM_READ);
-       if (!node) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!node)
+               return errno;
 
        genlen = snprintf(gen, sizeof(gen), "%"PRIu64, node->generation) + 1;
 
@@ -816,7 +812,7 @@ static void send_directory_part(struct connection *conn,
        if (off >= node->childlen) {
                gen[genlen] = 0;
                send_reply(conn, XS_DIRECTORY_PART, gen, genlen + 1);
-               return;
+               return 0;
        }
 
        len = 0;
@@ -831,10 +827,8 @@ static void send_directory_part(struct connection *conn,
        }
 
        data = talloc_array(in, char, genlen + len + 1);
-       if (!data) {
-               send_error(conn, ENOMEM);
-               return;
-       }
+       if (!data)
+               return ENOMEM;
 
        memcpy(data, gen, genlen);
        memcpy(data + genlen, node->children + off, len);
@@ -844,21 +838,23 @@ static void send_directory_part(struct connection *conn,
        }
 
        send_reply(conn, XS_DIRECTORY_PART, data, genlen + len);
+
+       return 0;
 }
 
-static void do_read(struct connection *conn, struct buffered_data *in)
+static int do_read(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
        const char *name = onearg(in);
 
        name = canonicalize(conn, name);
        node = get_node(conn, in, name, XS_PERM_READ);
-       if (!node) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!node)
+               return errno;
 
        send_reply(conn, XS_READ, node->data, node->datalen);
+
+       return 0;
 }
 
 static void delete_node_single(struct connection *conn, struct node *node,
@@ -977,7 +973,7 @@ static struct node *create_node(struct connection *conn,
 }
 
 /* path, data... */
-static void do_write(struct connection *conn, struct buffered_data *in)
+static int do_write(struct connection *conn, struct buffered_data *in)
 {
        unsigned int offset, datalen;
        struct node *node;
@@ -985,10 +981,8 @@ static void do_write(struct connection *conn, struct 
buffered_data *in)
        char *name;
 
        /* Extra "strings" can be created by binary data. */
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
+               return EINVAL;
 
        offset = strlen(vec[0]) + 1;
        datalen = in->used - offset;
@@ -997,38 +991,31 @@ static void do_write(struct connection *conn, struct 
buffered_data *in)
        node = get_node(conn, in, name, XS_PERM_WRITE);
        if (!node) {
                /* No permissions, invalid input? */
-               if (errno != ENOENT) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (errno != ENOENT)
+                       return errno;
                node = create_node(conn, name, in->buffer + offset, datalen);
-               if (!node) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (!node)
+                       return errno;
        } else {
                node->data = in->buffer + offset;
                node->datalen = datalen;
-               if (!write_node(conn, node)){
-                       send_error(conn, errno);
-                       return;
-               }
+               if (!write_node(conn, node))
+                       return errno;
        }
 
        fire_watches(conn, in, name, false);
        send_ack(conn, XS_WRITE);
+
+       return 0;
 }
 
-static void do_mkdir(struct connection *conn, struct buffered_data *in)
+static int do_mkdir(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
        const char *name = onearg(in);
 
-       if (!name) {
-               errno = EINVAL;
-               send_error(conn, errno);
-               return;
-       }
+       if (!name)
+               return EINVAL;
 
        name = canonicalize(conn, name);
        node = get_node(conn, in, name, XS_PERM_WRITE);
@@ -1036,18 +1023,16 @@ static void do_mkdir(struct connection *conn, struct 
buffered_data *in)
        /* If it already exists, fine. */
        if (!node) {
                /* No permissions? */
-               if (errno != ENOENT) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (errno != ENOENT)
+                       return errno;
                node = create_node(conn, name, NULL, 0);
-               if (!node) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (!node)
+                       return errno;
                fire_watches(conn, in, name, false);
        }
        send_ack(conn, XS_MKDIR);
+
+       return 0;
 }
 
 static void delete_node(struct connection *conn, struct node *node,
@@ -1117,18 +1102,14 @@ static int _rm(struct connection *conn, struct node 
*node, const char *name)
           happen is the child will continue to take up space, but will
           otherwise be unreachable. */
        struct node *parent = read_node(conn, name, get_parent(name, name));
-       if (!parent) {
-               send_error(conn, EINVAL);
-               return 0;
-       }
+       if (!parent)
+               return EINVAL;
 
-       if (!delete_child(conn, parent, basename(name))) {
-               send_error(conn, EINVAL);
-               return 0;
-       }
+       if (!delete_child(conn, parent, basename(name)))
+               return EINVAL;
 
        delete_node(conn, node, true);
-       return 1;
+       return 0;
 }
 
 
@@ -1143,9 +1124,10 @@ static void internal_rm(const char *name)
 }
 
 
-static void do_rm(struct connection *conn, struct buffered_data *in)
+static int do_rm(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
+       int ret;
        const char *name = onearg(in);
 
        name = canonicalize(conn, name);
@@ -1156,28 +1138,29 @@ static void do_rm(struct connection *conn, struct 
buffered_data *in)
                        node = read_node(conn, in, get_parent(in, name));
                        if (node) {
                                send_ack(conn, XS_RM);
-                               return;
+                               return 0;
                        }
                        /* Restore errno, just in case. */
                        errno = ENOENT;
                }
-               send_error(conn, errno);
-               return;
+               return errno;
        }
 
-       if (streq(name, "/")) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (streq(name, "/"))
+               return EINVAL;
 
-       if (_rm(conn, node, name)) {
-               fire_watches(conn, in, name, true);
-               send_ack(conn, XS_RM);
-       }
+       ret = _rm(conn, node, name);
+       if (ret)
+               return ret;
+
+       fire_watches(conn, in, name, true);
+       send_ack(conn, XS_RM);
+
+       return 0;
 }
 
 
-static void do_get_perms(struct connection *conn, struct buffered_data *in)
+static int do_get_perms(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
        const char *name = onearg(in);
@@ -1186,19 +1169,19 @@ static void do_get_perms(struct connection *conn, 
struct buffered_data *in)
 
        name = canonicalize(conn, name);
        node = get_node(conn, in, name, XS_PERM_READ);
-       if (!node) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!node)
+               return errno;
 
        strings = perms_to_strings(node, node->perms, node->num_perms, &len);
        if (!strings)
-               send_error(conn, errno);
-       else
-               send_reply(conn, XS_GET_PERMS, strings, len);
+               return errno;
+
+       send_reply(conn, XS_GET_PERMS, strings, len);
+
+       return 0;
 }
 
-static void do_set_perms(struct connection *conn, struct buffered_data *in)
+static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
        unsigned int num;
        struct xs_permissions *perms;
@@ -1206,10 +1189,8 @@ static void do_set_perms(struct connection *conn, struct 
buffered_data *in)
        struct node *node;
 
        num = xs_count_strings(in->buffer, in->used);
-       if (num < 2) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (num < 2)
+               return EINVAL;
 
        /* First arg is node name. */
        name = canonicalize(conn, in->buffer);
@@ -1218,54 +1199,43 @@ static void do_set_perms(struct connection *conn, 
struct buffered_data *in)
 
        /* We must own node to do this (tools can do this too). */
        node = get_node(conn, in, name, XS_PERM_WRITE|XS_PERM_OWNER);
-       if (!node) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!node)
+               return errno;
 
        perms = talloc_array(node, struct xs_permissions, num);
-       if (!xs_strings_to_perms(perms, num, permstr)) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!xs_strings_to_perms(perms, num, permstr))
+               return errno;
 
        /* Unprivileged domains may not change the owner. */
-       if (domain_is_unprivileged(conn) &&
-           perms[0].id != node->perms[0].id) {
-               send_error(conn, EPERM);
-               return;
-       }
+       if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+               return EPERM;
 
        domain_entry_dec(conn, node);
        node->perms = perms;
        node->num_perms = num;
        domain_entry_inc(conn, node);
 
-       if (!write_node(conn, node)) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!write_node(conn, node))
+               return errno;
 
        fire_watches(conn, in, name, false);
        send_ack(conn, XS_SET_PERMS);
+
+       return 0;
 }
 
-static void do_debug(struct connection *conn, struct buffered_data *in)
+static int do_debug(struct connection *conn, struct buffered_data *in)
 {
        int num;
 
-       if (conn->id != 0) {
-               send_error(conn, EACCES);
-               return;
-       }
+       if (conn->id != 0)
+               return EACCES;
 
        num = xs_count_strings(in->buffer, in->used);
 
        if (streq(in->buffer, "print")) {
-               if (num < 2) {
-                       send_error(conn, EINVAL);
-                       return;
-               }
+               if (num < 2)
+                       return EINVAL;
                xprintf("debug: %s", in->buffer + get_string(in, 0));
        }
 
@@ -1273,11 +1243,13 @@ static void do_debug(struct connection *conn, struct 
buffered_data *in)
                check_store();
 
        send_ack(conn, XS_DEBUG);
+
+       return 0;
 }
 
 static struct {
        char *str;
-       void (*func)(struct connection *conn, struct buffered_data *in);
+       int (*func)(struct connection *conn, struct buffered_data *in);
 } wire_funcs[XS_NEXT_ENTRY] = {
        [XS_DEBUG]             = { "DEBUG",             do_debug },
        [XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
@@ -1320,6 +1292,7 @@ static void process_message(struct connection *conn, 
struct buffered_data *in)
 {
        struct transaction *trans;
        enum xsd_sockmsg_type type = in->hdr.msg.type;
+       int ret;
 
        trans = transaction_lookup(conn, in->hdr.msg.tx_id);
        if (IS_ERR(trans)) {
@@ -1331,11 +1304,13 @@ static void process_message(struct connection *conn, 
struct buffered_data *in)
        conn->transaction = trans;
 
        if ((unsigned)type < XS_NEXT_ENTRY && wire_funcs[type].func)
-               wire_funcs[type].func(conn, in);
+               ret = wire_funcs[type].func(conn, in);
        else {
                eprintf("Client unknown operation %i", type);
-               send_error(conn, ENOSYS);
+               ret = ENOSYS;
        }
+       if (ret)
+               send_error(conn, ret);
 
        conn->transaction = NULL;
 }
diff --git a/tools/xenstore/xenstored_domain.c 
b/tools/xenstore/xenstored_domain.c
index 5de93d4..0b2af13 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -338,7 +338,7 @@ static void domain_conn_reset(struct domain *domain)
 }
 
 /* domid, mfn, evtchn, path */
-void do_introduce(struct connection *conn, struct buffered_data *in)
+int do_introduce(struct connection *conn, struct buffered_data *in)
 {
        struct domain *domain;
        char *vec[3];
@@ -348,40 +348,32 @@ void do_introduce(struct connection *conn, struct 
buffered_data *in)
        int rc;
        struct xenstore_domain_interface *interface;
 
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
+               return EINVAL;
 
-       if (domain_is_unprivileged(conn) || !conn->can_write) {
-               send_error(conn, EACCES);
-               return;
-       }
+       if (domain_is_unprivileged(conn) || !conn->can_write)
+               return EACCES;
 
        domid = atoi(vec[0]);
        mfn = atol(vec[1]);
        port = atoi(vec[2]);
 
        /* Sanity check args. */
-       if (port <= 0) { 
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (port <= 0)
+               return EINVAL;
 
        domain = find_domain_by_domid(domid);
 
        if (domain == NULL) {
                interface = map_interface(domid, mfn);
-               if (!interface) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (!interface)
+                       return errno;
                /* Hang domain off "in" until we're finished. */
                domain = new_domain(in, domid, port);
                if (!domain) {
+                       rc = errno;
                        unmap_interface(interface);
-                       send_error(conn, errno);
-                       return;
+                       return rc;
                }
                domain->interface = interface;
                domain->mfn = mfn;
@@ -397,165 +389,137 @@ void do_introduce(struct connection *conn, struct 
buffered_data *in)
                rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
                domain->port = (rc == -1) ? 0 : rc;
                domain->remote_port = port;
-       } else {
-               send_error(conn, EINVAL);
-               return;
-       }
+       } else
+               return EINVAL;
 
        domain_conn_reset(domain);
 
        send_ack(conn, XS_INTRODUCE);
+
+       return 0;
 }
 
-void do_set_target(struct connection *conn, struct buffered_data *in)
+int do_set_target(struct connection *conn, struct buffered_data *in)
 {
        char *vec[2];
        unsigned int domid, tdomid;
         struct domain *domain, *tdomain;
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
+               return EINVAL;
 
-       if (domain_is_unprivileged(conn) || !conn->can_write) {
-               send_error(conn, EACCES);
-               return;
-       }
+       if (domain_is_unprivileged(conn) || !conn->can_write)
+               return EACCES;
 
        domid = atoi(vec[0]);
        tdomid = atoi(vec[1]);
 
         domain = find_domain_by_domid(domid);
-       if (!domain) {
-               send_error(conn, ENOENT);
-               return;
-       }
-        if (!domain->conn) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domain)
+               return ENOENT;
+        if (!domain->conn)
+               return EINVAL;
 
         tdomain = find_domain_by_domid(tdomid);
-       if (!tdomain) {
-               send_error(conn, ENOENT);
-               return;
-       }
+       if (!tdomain)
+               return ENOENT;
 
-        if (!tdomain->conn) {
-               send_error(conn, EINVAL);
-               return;
-       }
+        if (!tdomain->conn)
+               return EINVAL;
 
         talloc_reference(domain->conn, tdomain->conn);
         domain->conn->target = tdomain->conn;
 
        send_ack(conn, XS_SET_TARGET);
+
+       return 0;
 }
 
 /* domid */
-void do_release(struct connection *conn, struct buffered_data *in)
+int do_release(struct connection *conn, struct buffered_data *in)
 {
        const char *domid_str = onearg(in);
        struct domain *domain;
        unsigned int domid;
 
-       if (!domid_str) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid_str)
+               return EINVAL;
 
        domid = atoi(domid_str);
-       if (!domid) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid)
+               return EINVAL;
 
-       if (domain_is_unprivileged(conn)) {
-               send_error(conn, EACCES);
-               return;
-       }
+       if (domain_is_unprivileged(conn))
+               return EACCES;
 
        domain = find_domain_by_domid(domid);
-       if (!domain) {
-               send_error(conn, ENOENT);
-               return;
-       }
+       if (!domain)
+               return ENOENT;
 
-       if (!domain->conn) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domain->conn)
+               return EINVAL;
 
        talloc_free(domain->conn);
 
        send_ack(conn, XS_RELEASE);
+
+       return 0;
 }
 
-void do_resume(struct connection *conn, struct buffered_data *in)
+int do_resume(struct connection *conn, struct buffered_data *in)
 {
        struct domain *domain;
        unsigned int domid;
        const char *domid_str = onearg(in);
 
-       if (!domid_str) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid_str)
+               return EINVAL;
 
        domid = atoi(domid_str);
-       if (!domid) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid)
+               return EINVAL;
 
-       if (domain_is_unprivileged(conn)) {
-               send_error(conn, EACCES);
-               return;
-       }
+       if (domain_is_unprivileged(conn))
+               return EACCES;
 
        domain = find_domain_by_domid(domid);
-       if (!domain) {
-               send_error(conn, ENOENT);
-               return;
-       }
+       if (!domain)
+               return ENOENT;
 
-       if (!domain->conn) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domain->conn)
+               return EINVAL;
 
        domain->shutdown = 0;
        
        send_ack(conn, XS_RESUME);
+
+       return 0;
 }
 
-void do_get_domain_path(struct connection *conn, struct buffered_data *in)
+int do_get_domain_path(struct connection *conn, struct buffered_data *in)
 {
        char *path;
        const char *domid_str = onearg(in);
 
-       if (!domid_str) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid_str)
+               return EINVAL;
 
        path = talloc_domain_path(conn, atoi(domid_str));
 
        send_reply(conn, XS_GET_DOMAIN_PATH, path, strlen(path) + 1);
 
        talloc_free(path);
+
+       return 0;
 }
 
-void do_is_domain_introduced(struct connection *conn, struct buffered_data *in)
+int do_is_domain_introduced(struct connection *conn, struct buffered_data *in)
 {
        int result;
        unsigned int domid;
        const char *domid_str = onearg(in);
 
-       if (!domid_str) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!domid_str)
+               return EINVAL;
 
        domid = atoi(domid_str);
        if (domid == DOMID_SELF)
@@ -564,15 +528,19 @@ void do_is_domain_introduced(struct connection *conn, 
struct buffered_data *in)
                result = (find_domain_by_domid(domid) != NULL);
 
        send_reply(conn, XS_IS_DOMAIN_INTRODUCED, result ? "T" : "F", 2);
+
+       return 0;
 }
 
 /* Allow guest to reset all watches */
-void do_reset_watches(struct connection *conn, struct buffered_data *in)
+int do_reset_watches(struct connection *conn, struct buffered_data *in)
 {
        conn_delete_all_watches(conn);
        conn_delete_all_transactions(conn);
 
        send_ack(conn, XS_RESET_WATCHES);
+
+       return 0;
 }
 
 static int close_xc_handle(void *_handle)
diff --git a/tools/xenstore/xenstored_domain.h 
b/tools/xenstore/xenstored_domain.h
index 2554423..40e15d1 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -22,25 +22,25 @@
 void handle_event(void);
 
 /* domid, mfn, eventchn, path */
-void do_introduce(struct connection *conn, struct buffered_data *in);
+int do_introduce(struct connection *conn, struct buffered_data *in);
 
 /* domid */
-void do_is_domain_introduced(struct connection *conn, struct buffered_data 
*in);
+int do_is_domain_introduced(struct connection *conn, struct buffered_data *in);
 
 /* domid */
-void do_release(struct connection *conn, struct buffered_data *in);
+int do_release(struct connection *conn, struct buffered_data *in);
 
 /* domid */
-void do_resume(struct connection *conn, struct buffered_data *in);
+int do_resume(struct connection *conn, struct buffered_data *in);
 
 /* domid, target */
-void do_set_target(struct connection *conn, struct buffered_data *in);
+int do_set_target(struct connection *conn, struct buffered_data *in);
 
 /* domid */
-void do_get_domain_path(struct connection *conn, struct buffered_data *in);
+int do_get_domain_path(struct connection *conn, struct buffered_data *in);
 
 /* Allow guest to reset all watches */
-void do_reset_watches(struct connection *conn, struct buffered_data *in);
+int do_reset_watches(struct connection *conn, struct buffered_data *in);
 
 void domain_init(void);
 
diff --git a/tools/xenstore/xenstored_transaction.c 
b/tools/xenstore/xenstored_transaction.c
index 6c65dc5..423fd3e 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -149,21 +149,17 @@ struct transaction *transaction_lookup(struct connection 
*conn, uint32_t id)
        return ERR_PTR(-ENOENT);
 }
 
-void do_transaction_start(struct connection *conn, struct buffered_data *in)
+int do_transaction_start(struct connection *conn, struct buffered_data *in)
 {
        struct transaction *trans, *exists;
        char id_str[20];
 
        /* We don't support nested transactions. */
-       if (conn->transaction) {
-               send_error(conn, EBUSY);
-               return;
-       }
+       if (conn->transaction)
+               return EBUSY;
 
-       if (conn->id && conn->transaction_started > quota_max_transaction) {
-               send_error(conn, ENOSPC);
-               return;
-       }
+       if (conn->id && conn->transaction_started > quota_max_transaction)
+               return ENOSPC;
 
        /* Attach transaction to input for autofree until it's complete */
        trans = talloc_zero(in, struct transaction);
@@ -173,10 +169,8 @@ void do_transaction_start(struct connection *conn, struct 
buffered_data *in)
        trans->tdb_name = talloc_asprintf(trans, "%s.%p",
                                          xs_daemon_tdb(), trans);
        trans->tdb = tdb_copy(tdb_context(conn), trans->tdb_name);
-       if (!trans->tdb) {
-               send_error(conn, errno);
-               return;
-       }
+       if (!trans->tdb)
+               return errno;
        /* Make it close if we go away. */
        talloc_steal(trans, trans->tdb);
 
@@ -194,24 +188,22 @@ void do_transaction_start(struct connection *conn, struct 
buffered_data *in)
 
        snprintf(id_str, sizeof(id_str), "%u", trans->id);
        send_reply(conn, XS_TRANSACTION_START, id_str, strlen(id_str)+1);
+
+       return 0;
 }
 
-void do_transaction_end(struct connection *conn, struct buffered_data *in)
+int do_transaction_end(struct connection *conn, struct buffered_data *in)
 {
        const char *arg = onearg(in);
        struct changed_node *i;
        struct changed_domain *d;
        struct transaction *trans;
 
-       if (!arg || (!streq(arg, "T") && !streq(arg, "F"))) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (!arg || (!streq(arg, "T") && !streq(arg, "F")))
+               return EINVAL;
 
-       if ((trans = conn->transaction) == NULL) {
-               send_error(conn, ENOENT);
-               return;
-       }
+       if ((trans = conn->transaction) == NULL)
+               return ENOENT;
 
        conn->transaction = NULL;
        list_del(&trans->list);
@@ -222,14 +214,10 @@ void do_transaction_end(struct connection *conn, struct 
buffered_data *in)
 
        if (streq(arg, "T")) {
                /* FIXME: Merge, rather failing on any change. */
-               if (trans->generation != generation) {
-                       send_error(conn, EAGAIN);
-                       return;
-               }
-               if (!replace_tdb(trans->tdb_name, trans->tdb)) {
-                       send_error(conn, errno);
-                       return;
-               }
+               if (trans->generation != generation)
+                       return EAGAIN;
+               if (!replace_tdb(trans->tdb_name, trans->tdb))
+                       return errno;
                /* Don't close this: we won! */
                trans->tdb = NULL;
 
@@ -243,6 +231,8 @@ void do_transaction_end(struct connection *conn, struct 
buffered_data *in)
                generation += trans->trans_gen;
        }
        send_ack(conn, XS_TRANSACTION_END);
+
+       return 0;
 }
 
 void transaction_entry_inc(struct transaction *trans, unsigned int domid)
diff --git a/tools/xenstore/xenstored_transaction.h 
b/tools/xenstore/xenstored_transaction.h
index 7f0a781..aeeac3d 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -21,8 +21,8 @@
 
 struct transaction;
 
-void do_transaction_start(struct connection *conn, struct buffered_data *node);
-void do_transaction_end(struct connection *conn, struct buffered_data *in);
+int do_transaction_start(struct connection *conn, struct buffered_data *node);
+int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
 struct transaction *transaction_lookup(struct connection *conn, uint32_t id);
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 856750e..8cfc5b0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -121,46 +121,36 @@ static int destroy_watch(void *_watch)
        return 0;
 }
 
-void do_watch(struct connection *conn, struct buffered_data *in)
+int do_watch(struct connection *conn, struct buffered_data *in)
 {
        struct watch *watch;
        char *vec[2];
        bool relative;
 
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec))
+               return EINVAL;
 
        if (strstarts(vec[0], "@")) {
                relative = false;
-               if (strlen(vec[0]) > XENSTORE_REL_PATH_MAX) {
-                       send_error(conn, EINVAL);
-                       return;
-               }
+               if (strlen(vec[0]) > XENSTORE_REL_PATH_MAX)
+                       return EINVAL;
                /* check if valid event */
        } else {
                relative = !strstarts(vec[0], "/");
                vec[0] = canonicalize(conn, vec[0]);
-               if (!is_valid_nodename(vec[0])) {
-                       send_error(conn, EINVAL);
-                       return;
-               }
+               if (!is_valid_nodename(vec[0]))
+                       return EINVAL;
        }
 
        /* Check for duplicates. */
        list_for_each_entry(watch, &conn->watches, list) {
                if (streq(watch->node, vec[0]) &&
-                   streq(watch->token, vec[1])) {
-                       send_error(conn, EEXIST);
-                       return;
-               }
+                   streq(watch->token, vec[1]))
+                       return EEXIST;
        }
 
-       if (domain_watch(conn) > quota_nb_watch_per_domain) {
-               send_error(conn, E2BIG);
-               return;
-       }
+       if (domain_watch(conn) > quota_nb_watch_per_domain)
+               return E2BIG;
 
        watch = talloc(conn, struct watch);
        watch->node = talloc_strdup(watch, vec[0]);
@@ -180,17 +170,17 @@ void do_watch(struct connection *conn, struct 
buffered_data *in)
 
        /* We fire once up front: simplifies clients and restart. */
        add_event(conn, in, watch, watch->node);
+
+       return 0;
 }
 
-void do_unwatch(struct connection *conn, struct buffered_data *in)
+int do_unwatch(struct connection *conn, struct buffered_data *in)
 {
        struct watch *watch;
        char *node, *vec[2];
 
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) {
-               send_error(conn, EINVAL);
-               return;
-       }
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec))
+               return EINVAL;
 
        node = canonicalize(conn, vec[0]);
        list_for_each_entry(watch, &conn->watches, list) {
@@ -199,10 +189,10 @@ void do_unwatch(struct connection *conn, struct 
buffered_data *in)
                        talloc_free(watch);
                        domain_watch_dec(conn);
                        send_ack(conn, XS_UNWATCH);
-                       return;
+                       return 0;
                }
        }
-       send_error(conn, ENOENT);
+       return ENOENT;
 }
 
 void conn_delete_all_watches(struct connection *conn)
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 8ed1dde..546a5c3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -21,8 +21,8 @@
 
 #include "xenstored_core.h"
 
-void do_watch(struct connection *conn, struct buffered_data *in);
-void do_unwatch(struct connection *conn, struct buffered_data *in);
+int do_watch(struct connection *conn, struct buffered_data *in);
+int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, void *tmp, const char *name,
-- 
2.6.6


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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