All of lore.kernel.org
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>, Wei Liu <wl@xen.org>,
	Julien Grall <julien@xen.org>,
	Anthony PERARD <anthony.perard@citrix.com>
Subject: [PATCH v4 13/19] tools/xenstore: introduce read_node_const()
Date: Mon, 14 Aug 2023 09:47:01 +0200	[thread overview]
Message-ID: <20230814074707.27696-14-jgross@suse.com> (raw)
In-Reply-To: <20230814074707.27696-1-jgross@suse.com>

Introduce a read_node() variant returning a pointer to const struct
node, which doesn't do a copy of the node data after retrieval from
the data base.

Call this variant where appropriate.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V3:
- new approach (Julien Grall)
V4:
- fix patch subject (Julien Grall)
- let read_node_helper() return a bool (Julien Grall)
---
 tools/xenstore/xenstored_core.c   | 105 ++++++++++++++++++++++--------
 tools/xenstore/xenstored_core.h   |   2 +
 tools/xenstore/xenstored_domain.c |   4 +-
 tools/xenstore/xenstored_watch.c  |  10 +--
 tools/xenstore/xenstored_watch.h  |   3 +-
 5 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8c8c4b8f4..f8e5e7b697 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -706,11 +706,11 @@ void db_delete(struct connection *conn, const char *name,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-struct node *read_node(struct connection *conn, const void *ctx,
-		       const char *name)
+static struct node *read_node_alloc(struct connection *conn, const void *ctx,
+				    const char *name,
+				    const struct node_hdr **hdr)
 {
 	size_t size;
-	const struct node_hdr *hdr;
 	struct node *node;
 	const char *db_name;
 	int err;
@@ -720,17 +720,16 @@ struct node *read_node(struct connection *conn, const void *ctx,
 		errno = ENOMEM;
 		return NULL;
 	}
+
 	node->name = talloc_strdup(node, name);
 	if (!node->name) {
-		talloc_free(node);
 		errno = ENOMEM;
-		return NULL;
+		goto error;
 	}
 
 	db_name = transaction_prepend(conn, name);
-	hdr = db_fetch(db_name, &size);
-
-	if (hdr == NULL) {
+	*hdr = db_fetch(db_name, &size);
+	if (*hdr == NULL) {
 		node->hdr.generation = NO_GENERATION;
 		err = access_node(conn, node, NODE_ACCESS_READ, NULL);
 		errno = err ? : ENOENT;
@@ -740,31 +739,80 @@ struct node *read_node(struct connection *conn, const void *ctx,
 	node->parent = NULL;
 
 	/* Datalen, childlen, number of permissions */
-	node->hdr = *hdr;
-	node->acc.domid = perms_from_node_hdr(hdr)->id;
+	node->hdr = **hdr;
+	node->acc.domid = perms_from_node_hdr(*hdr)->id;
 	node->acc.memory = size;
 
-	/* Copy node data to new memory area, starting with permissions. */
-	size -= sizeof(*hdr);
-	node->perms = talloc_memdup(node, perms_from_node_hdr(hdr), size);
-	if (node->perms == NULL) {
-		errno = ENOMEM;
-		goto error;
-	}
+	return node;
+
+ error:
+	talloc_free(node);
+	return NULL;
+}
 
+static bool read_node_helper(struct connection *conn, struct node *node)
+{
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + hdr->num_perms;
+	node->data = node->perms + node->hdr.num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->hdr.datalen;
 
 	if (domain_adjust_node_perms(node))
-		goto error;
+		return false;
 
 	/* If owner is gone reset currently accounted memory size. */
 	if (node->acc.domid != get_node_owner(node))
 		node->acc.memory = 0;
 
 	if (access_node(conn, node, NODE_ACCESS_READ, NULL))
+		return false;
+
+	return true;
+}
+
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
+{
+	size_t size;
+	const struct node_hdr *hdr;
+	struct node *node;
+
+	node = read_node_alloc(conn, ctx, name, &hdr);
+	if (!node)
+		return NULL;
+
+	/* Copy node data to new memory area, starting with permissions. */
+	size = node->acc.memory - sizeof(*hdr);
+	node->perms = talloc_memdup(node, perms_from_node_hdr(hdr), size);
+	if (node->perms == NULL) {
+		errno = ENOMEM;
+		goto error;
+	}
+
+	if (!read_node_helper(conn, node))
+		goto error;
+
+	return node;
+
+ error:
+	talloc_free(node);
+	return NULL;
+}
+
+const struct node *read_node_const(struct connection *conn, const void *ctx,
+				   const char *name)
+{
+	const struct node_hdr *hdr;
+	struct node *node;
+
+	node = read_node_alloc(conn, ctx, name, &hdr);
+	if (!node)
+		return NULL;
+
+	/* Unfortunately node->perms isn't const. */
+	node->perms = (void *)perms_from_node_hdr(hdr);
+
+	if (!read_node_helper(conn, node))
 		goto error;
 
 	return node;
@@ -900,13 +948,13 @@ char *get_parent(const void *ctx, const char *node)
 static int ask_parents(struct connection *conn, const void *ctx,
 		       const char *name, unsigned int *perm)
 {
-	struct node *node;
+	const struct node *node;
 
 	do {
 		name = get_parent(ctx, name);
 		if (!name)
 			return errno;
-		node = read_node(conn, ctx, name);
+		node = read_node_const(conn, ctx, name);
 		if (node)
 			break;
 		if (read_node_can_propagate_errno())
@@ -3197,9 +3245,8 @@ static int dump_state_node_err(struct dump_node_data *data, const char *err)
 }
 
 static int dump_state_node(const void *ctx, struct connection *conn,
-			   struct node *node, void *arg)
+			   const struct node *node, struct dump_node_data *data)
 {
-	struct dump_node_data *data = arg;
 	FILE *fp = data->fp;
 	unsigned int pathlen;
 	struct xs_state_record_header head;
@@ -3244,14 +3291,20 @@ static int dump_state_node(const void *ctx, struct connection *conn,
 	return WALK_TREE_OK;
 }
 
+static int dump_state_node_enter(const void *ctx, struct connection *conn,
+				 struct node *node, void *arg)
+{
+	return dump_state_node(ctx, conn, node, arg);
+}
+
 static int dump_state_special_node(FILE *fp, const void *ctx,
 				   struct dump_node_data *data,
 				   const char *name)
 {
-	struct node *node;
+	const struct node *node;
 	int ret;
 
-	node = read_node(NULL, ctx, name);
+	node = read_node_const(NULL, ctx, name);
 	if (!node)
 		return dump_state_node_err(data, "Dump node read node error");
 
@@ -3267,7 +3320,7 @@ const char *dump_state_nodes(FILE *fp, const void *ctx)
 		.fp = fp,
 		.err = "Dump node walk error"
 	};
-	struct walk_funcs walkfuncs = { .enter = dump_state_node };
+	struct walk_funcs walkfuncs = { .enter = dump_state_node_enter };
 
 	if (walk_node_tree(ctx, NULL, "/", &walkfuncs, &data))
 		return data.err;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index cbed412a86..07c59c07b7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -292,6 +292,8 @@ int write_node_raw(struct connection *conn, const char *db_name,
 /* Get a node from the data base. */
 struct node *read_node(struct connection *conn, const void *ctx,
 		       const char *name);
+const struct node *read_node_const(struct connection *conn, const void *ctx,
+				   const char *name);
 
 /* Remove a node and its children. */
 int rm_node(struct connection *conn, const void *ctx, const char *name);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index c00ea397cf..1bf138c8b1 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -563,12 +563,12 @@ static void domain_tree_remove(struct domain *domain)
 static void fire_special_watches(const char *name)
 {
 	void *ctx = talloc_new(NULL);
-	struct node *node;
+	const struct node *node;
 
 	if (!ctx)
 		return;
 
-	node = read_node(NULL, ctx, name);
+	node = read_node_const(NULL, ctx, name);
 
 	if (node)
 		fire_watches(NULL, ctx, name, node, true, NULL);
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 5767675e04..d6e5a4be1e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -73,11 +73,11 @@ static const char *get_watch_path(const struct watch *watch, const char *name)
  * changed permissions we need to take the old permissions into account, too.
  */
 static bool watch_permitted(struct connection *conn, const void *ctx,
-			    const char *name, struct node *node,
+			    const char *name, const struct node *node,
 			    struct node_perms *perms)
 {
 	unsigned int perm;
-	struct node *parent;
+	const struct node *parent;
 	char *parent_name;
 
 	if (perms) {
@@ -87,7 +87,7 @@ static bool watch_permitted(struct connection *conn, const void *ctx,
 	}
 
 	if (!node) {
-		node = read_node(conn, ctx, name);
+		node = read_node_const(conn, ctx, name);
 		if (!node)
 			return false;
 	}
@@ -101,7 +101,7 @@ static bool watch_permitted(struct connection *conn, const void *ctx,
 		parent_name = get_parent(ctx, node->name);
 		if (!parent_name)
 			return false;
-		parent = read_node(conn, ctx, parent_name);
+		parent = read_node_const(conn, ctx, parent_name);
 		if (!parent)
 			return false;
 	}
@@ -119,7 +119,7 @@ static bool watch_permitted(struct connection *conn, const void *ctx,
  * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  struct node *node, bool exact, struct node_perms *perms)
+		  const struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct buffered_data *req;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 091890edca..ea247997ad 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -28,7 +28,8 @@ int do_unwatch(const void *ctx, struct connection *conn,
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  struct node *node, bool exact, struct node_perms *perms);
+		  const struct node *node, bool exact,
+		  struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
-- 
2.35.3



  parent reply	other threads:[~2023-08-14  8:02 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-14  7:46 [PATCH v4 00/19] tools/xenstore: drop TDB Juergen Gross
2023-08-14  7:46 ` [PATCH v4 01/19] tools/xenstore: make hashtable key parameter const Juergen Gross
2023-08-14 17:51   ` Julien Grall
2023-08-14  7:46 ` [PATCH v4 02/19] tools/xenstore: let hashtable_add() fail in case of existing entry Juergen Gross
2023-08-14  7:46 ` [PATCH v4 03/19] tools/xenstore: add hashtable_replace() function Juergen Gross
2023-08-14  7:46 ` [PATCH v4 04/19] tools/xenstore: drop use of tdb Juergen Gross
2023-08-14  7:46 ` [PATCH v4 05/19] tools/xenstore: remove tdb code Juergen Gross
2023-08-14  7:46 ` [PATCH v4 06/19] tools/xenstore: let db_delete() return void Juergen Gross
2023-08-14  7:46 ` [PATCH v4 07/19] tools/xenstore: change talloc_free() to take a const pointer Juergen Gross
2023-08-14 17:53   ` Julien Grall
2023-08-14  7:46 ` [PATCH v4 08/19] tools/xenstore: move copying of node data out of db_fetch() Juergen Gross
2023-08-14 17:55   ` Julien Grall
2023-08-14  7:46 ` [PATCH v4 09/19] tools/xenstore: rework struct xs_tdb_record_hdr Juergen Gross
2023-08-14 18:04   ` Julien Grall
2023-08-14  7:46 ` [PATCH v4 10/19] tools/xenstore: don't use struct node_perms in struct node Juergen Gross
2023-08-14 18:09   ` Julien Grall
2023-08-14  7:46 ` [PATCH v4 11/19] tools/xenstore: use struct node_hdr " Juergen Gross
2023-08-18 10:57   ` Julien Grall
2023-08-14  7:47 ` [PATCH v4 12/19] tools/xenstore: alloc new memory in domain_adjust_node_perms() Juergen Gross
2023-08-18 10:59   ` [PATCH v4 12/19]tools/xenstore: " Julien Grall
2023-08-14  7:47 ` Juergen Gross [this message]
2023-08-18 11:06   ` [PATCH v4 13/19] tools/xenstore: introduce read_node_const() Julien Grall
2023-08-14  7:47 ` [PATCH v4 14/19] tools/xenstore: merge get_spec_node() into get_node_canonicalized() Juergen Gross
2023-08-18 11:07   ` Julien Grall
2023-08-14  7:47 ` [PATCH v4 15/19] tools/xenstore: merge is_valid_nodename() into canonicalize() Juergen Gross
2023-08-18 11:12   ` Julien Grall
2023-08-14  7:47 ` [PATCH v4 16/19] tools/xenstore: rework get_node() Juergen Gross
2023-08-18 11:14   ` Julien Grall
2023-08-14  7:47 ` [PATCH v4 17/19] tools/xenstore: introduce get_node_const() Juergen Gross
2023-08-18 11:16   ` Julien Grall
2023-08-14  7:47 ` [PATCH v4 18/19] tools/config: add XEN_RUN_STORED to config.h Juergen Gross
2023-08-14 10:34   ` Anthony PERARD
2023-08-14 11:07     ` Juergen Gross
2023-08-14 11:30   ` [PATCH v4.1 " Juergen Gross
2023-08-14  7:47 ` [PATCH v4 19/19] tools/xenstore: move xenstored sources into dedicated directory Juergen Gross
2023-08-18 11:22   ` Julien Grall
2023-08-18 12:14     ` Juergen Gross
2023-08-18 12:42       ` Julien Grall
2023-08-18 12:46         ` Juergen Gross
2023-08-18 12:54 ` [PATCH v4 00/19] tools/xenstore: drop TDB Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230814074707.27696-14-jgross@suse.com \
    --to=jgross@suse.com \
    --cc=anthony.perard@citrix.com \
    --cc=julien@xen.org \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.