diff mbox

[v3,10/12] xenstore: add helper functions for wire argument parsing

Message ID 1478851210-6251-11-git-send-email-jgross@suse.com (mailing list archive)
State New, archived
Headers show

Commit Message

Juergen Gross Nov. 11, 2016, 8 a.m. UTC
The xenstore wire command argument parsing of the different commands
is repeating some patterns multiple times. Add some helper functions
to avoid the duplicated code.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstore/xenstored_core.c   | 66 ++++++++++++++--------------
 tools/xenstore/xenstored_domain.c | 90 +++++++++++++++++++--------------------
 2 files changed, 77 insertions(+), 79 deletions(-)

Comments

Wei Liu Nov. 12, 2016, 3:11 p.m. UTC | #1
On Fri, Nov 11, 2016 at 09:00:08AM +0100, Juergen Gross wrote:
> The xenstore wire command argument parsing of the different commands
> is repeating some patterns multiple times. Add some helper functions
> to avoid the duplicated code.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>
diff mbox

Patch

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3faab6e..c7a7c45 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -745,13 +745,25 @@  char *canonicalize(struct connection *conn, const char *node)
 	return (char *)node;
 }
 
+static struct node *get_node_canonicalized(struct connection *conn,
+					   const void *ctx,
+					   const char *name,
+					   char **canonical_name,
+					   enum xs_perm_type perm)
+{
+	char *tmp_name;
+
+	if (!canonical_name)
+		canonical_name = &tmp_name;
+	*canonical_name = canonicalize(conn, name);
+	return get_node(conn, ctx, *canonical_name, perm);
+}
+
 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);
+	node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
 	if (!node)
 		return errno;
 
@@ -764,7 +776,7 @@  static int send_directory_part(struct connection *conn,
 			       struct buffered_data *in)
 {
 	unsigned int off, len, maxlen, genlen;
-	char *name, *child, *data;
+	char *child, *data;
 	struct node *node;
 	char gen[24];
 
@@ -772,15 +784,13 @@  static int send_directory_part(struct connection *conn,
 		return EINVAL;
 
 	/* First arg is node name. */
-	name = canonicalize(conn, in->buffer);
+	node = get_node_canonicalized(conn, in, in->buffer, NULL, XS_PERM_READ);
+	if (!node)
+		return errno;
 
 	/* Second arg is childlist offset. */
 	off = atoi(in->buffer + strlen(in->buffer) + 1);
 
-	node = get_node(conn, in, name, XS_PERM_READ);
-	if (!node)
-		return errno;
-
 	genlen = snprintf(gen, sizeof(gen), "%"PRIu64, node->generation) + 1;
 
 	/* Offset behind list: just return a list with an empty string. */
@@ -820,10 +830,8 @@  static int send_directory_part(struct connection *conn,
 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);
+	node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
 	if (!node)
 		return errno;
 
@@ -962,8 +970,7 @@  static int do_write(struct connection *conn, struct buffered_data *in)
 	offset = strlen(vec[0]) + 1;
 	datalen = in->used - offset;
 
-	name = canonicalize(conn, vec[0]);
-	node = get_node(conn, in, name, XS_PERM_WRITE);
+	node = get_node_canonicalized(conn, in, vec[0], &name, XS_PERM_WRITE);
 	if (!node) {
 		/* No permissions, invalid input? */
 		if (errno != ENOENT)
@@ -987,13 +994,10 @@  static int do_write(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);
+	char *name;
 
-	if (!name)
-		return EINVAL;
-
-	name = canonicalize(conn, name);
-	node = get_node(conn, in, name, XS_PERM_WRITE);
+	node = get_node_canonicalized(conn, in, onearg(in), &name,
+				      XS_PERM_WRITE);
 
 	/* If it already exists, fine. */
 	if (!node) {
@@ -1103,10 +1107,10 @@  static int do_rm(struct connection *conn, struct buffered_data *in)
 {
 	struct node *node;
 	int ret;
-	const char *name = onearg(in);
+	char *name;
 
-	name = canonicalize(conn, name);
-	node = get_node(conn, in, name, XS_PERM_WRITE);
+	node = get_node_canonicalized(conn, in, onearg(in), &name,
+				      XS_PERM_WRITE);
 	if (!node) {
 		/* Didn't exist already?  Fine, if parent exists. */
 		if (errno == ENOENT) {
@@ -1138,12 +1142,10 @@  static int do_rm(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);
 	char *strings;
 	unsigned int len;
 
-	name = canonicalize(conn, name);
-	node = get_node(conn, in, name, XS_PERM_READ);
+	node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
 	if (!node)
 		return errno;
 
@@ -1168,15 +1170,15 @@  static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return EINVAL;
 
 	/* First arg is node name. */
-	name = canonicalize(conn, in->buffer);
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	num--;
 
-	/* 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)
-		return errno;
-
 	perms = talloc_array(node, struct xs_permissions, num);
 	if (!xs_strings_to_perms(perms, num, permstr))
 		return errno;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2af13..2443b08 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -399,6 +399,18 @@  int do_introduce(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
+static struct domain *find_connected_domain(unsigned int domid)
+{
+	struct domain *domain;
+
+	domain = find_domain_by_domid(domid);
+	if (!domain)
+		return ERR_PTR(-ENOENT);
+	if (!domain->conn)
+		return ERR_PTR(-EINVAL);
+	return domain;
+}
+
 int do_set_target(struct connection *conn, struct buffered_data *in)
 {
 	char *vec[2];
@@ -413,18 +425,13 @@  int do_set_target(struct connection *conn, struct buffered_data *in)
 	domid = atoi(vec[0]);
 	tdomid = atoi(vec[1]);
 
-        domain = find_domain_by_domid(domid);
-	if (!domain)
-		return ENOENT;
-        if (!domain->conn)
-		return EINVAL;
+        domain = find_connected_domain(domid);
+	if (IS_ERR(domain))
+		return -PTR_ERR(domain);
 
-        tdomain = find_domain_by_domid(tdomid);
-	if (!tdomain)
-		return ENOENT;
-
-        if (!tdomain->conn)
-		return EINVAL;
+        tdomain = find_connected_domain(tdomid);
+	if (IS_ERR(tdomain))
+		return -PTR_ERR(tdomain);
 
         talloc_reference(domain->conn, tdomain->conn);
         domain->conn->target = tdomain->conn;
@@ -434,29 +441,33 @@  int do_set_target(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
+static struct domain *onearg_domain(struct connection *conn,
+				    struct buffered_data *in)
+{
+	const char *domid_str = onearg(in);
+	unsigned int domid;
+
+	if (!domid_str)
+		return ERR_PTR(-EINVAL);
+
+	domid = atoi(domid_str);
+	if (!domid)
+		return ERR_PTR(-EINVAL);
+
+	if (domain_is_unprivileged(conn))
+		return ERR_PTR(-EACCES);
+
+	return find_connected_domain(domid);
+}
+
 /* domid */
 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)
-		return EINVAL;
-
-	domid = atoi(domid_str);
-	if (!domid)
-		return EINVAL;
-
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
-	domain = find_domain_by_domid(domid);
-	if (!domain)
-		return ENOENT;
-
-	if (!domain->conn)
-		return EINVAL;
+	domain = onearg_domain(conn, in);
+	if (IS_ERR(domain))
+		return -PTR_ERR(domain);
 
 	talloc_free(domain->conn);
 
@@ -468,25 +479,10 @@  int do_release(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)
-		return EINVAL;
-
-	domid = atoi(domid_str);
-	if (!domid)
-		return EINVAL;
-
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
-	domain = find_domain_by_domid(domid);
-	if (!domain)
-		return ENOENT;
-
-	if (!domain->conn)
-		return EINVAL;
+	domain = onearg_domain(conn, in);
+	if (IS_ERR(domain))
+		return -PTR_ERR(domain);
 
 	domain->shutdown = 0;