xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xen.org
Cc: Juergen Gross <jgross@suse.com>,
	sstabellini@kernel.org, wei.liu2@citrix.com,
	George.Dunlap@eu.citrix.com, andrew.cooper3@citrix.com,
	ian.jackson@eu.citrix.com, tim@xen.org, jbeulich@suse.com
Subject: [PATCH v3 05/12] xenstore: add support for reading directory with many children
Date: Fri, 11 Nov 2016 09:00:03 +0100	[thread overview]
Message-ID: <1478851210-6251-6-git-send-email-jgross@suse.com> (raw)
In-Reply-To: <1478851210-6251-1-git-send-email-jgross@suse.com>

As the payload size for one xenstore wire command is limited to 4096
bytes it is impossible to read the children names of a node with a
large number of children (e.g. /local/domain in case of a host with
more than about 2000 domains). This effectively limits the maximum
number of domains a host can support.

In order to support such long directory outputs add a new wire command
XS_DIRECTORY_PART which will return only some entries in each call and
can be called in a loop to get all entries.

Input data are the path of the node and the byte offset into the child
list where returned data should start.

Output is the generation count of the node (which will change each time
the node is being modified) and a list of child names starting with
the specified index. The end of the list is indicated by an empty
child name. It is the responsibility of the caller to check for data
consistency by comparing the generation counts of all returned data
sets to be the same for one node.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V3: use genlen, memcpy instead of strcpy as requested by Jan Beulich
    add XS_NEXT_ENTRY to xs_wire.h
    add XS_DIRECTORY_PART to sockmsg_string()

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstore/xenstored_core.c | 67 +++++++++++++++++++++++++++++++++++++++++
 xen/include/public/io/xs_wire.h |  3 ++
 2 files changed, 70 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 95d6d7d..e4e09fa 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -16,6 +16,7 @@
     along with this program; If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <poll.h>
@@ -147,6 +148,7 @@ static char *sockmsg_string(enum xsd_sockmsg_type type)
 	case XS_RESUME: return "RESUME";
 	case XS_SET_TARGET: return "SET_TARGET";
 	case XS_RESET_WATCHES: return "RESET_WATCHES";
+	case XS_DIRECTORY_PART: return "DIRECTORY_PART";
 	default:
 		return "**UNKNOWN**";
 	}
@@ -812,6 +814,67 @@ static void send_directory(struct connection *conn, struct buffered_data *in)
 	send_reply(conn, XS_DIRECTORY, node->children, node->childlen);
 }
 
+static void 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;
+	}
+
+	/* First arg is node name. */
+	name = canonicalize(conn, in->buffer);
+
+	/* Second arg is childlist offset. */
+	off = atoi(in->buffer + strlen(in->buffer) + 1);
+
+	node = get_node(conn, in, name, XS_PERM_READ);
+	if (!node) {
+		send_error(conn, errno);
+		return;
+	}
+
+	genlen = snprintf(gen, sizeof(gen), "%"PRIu64, node->generation) + 1;
+
+	/* Offset behind list: just return a list with an empty string. */
+	if (off >= node->childlen) {
+		gen[genlen] = 0;
+		send_reply(conn, XS_DIRECTORY_PART, gen, genlen + 1);
+		return;
+	}
+
+	len = 0;
+	maxlen = XENSTORE_PAYLOAD_MAX - genlen - 1;
+	child = node->children + off;
+
+	while (len + strlen(child) < maxlen) {
+		len += strlen(child) + 1;
+		child += strlen(child) + 1;
+		if (off + len == node->childlen)
+			break;
+	}
+
+	data = talloc_array(in, char, genlen + len + 1);
+	if (!data) {
+		send_error(conn, ENOMEM);
+		return;
+	}
+
+	memcpy(data, gen, genlen);
+	memcpy(data + genlen, node->children + off, len);
+	if (off + len == node->childlen) {
+		data[genlen + len] = 0;
+		len++;
+	}
+
+	send_reply(conn, XS_DIRECTORY_PART, data, genlen + len);
+}
+
 static void do_read(struct connection *conn, struct buffered_data *in)
 {
 	struct node *node;
@@ -1334,6 +1397,10 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		do_reset_watches(conn, in);
 		break;
 
+	case XS_DIRECTORY_PART:
+		send_directory_part(conn, in);
+		break;
+
 	default:
 		eprintf("Client unknown operation %i", in->hdr.msg.type);
 		send_error(conn, ENOSYS);
diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h
index 0a0cdbc..9a6f8eb 100644
--- a/xen/include/public/io/xs_wire.h
+++ b/xen/include/public/io/xs_wire.h
@@ -50,6 +50,9 @@ enum xsd_sockmsg_type
     XS_SET_TARGET,
     XS_RESTRICT,
     XS_RESET_WATCHES,
+    XS_DIRECTORY_PART,
+
+    XS_NEXT_ENTRY,      /* First unused type. */
 
     XS_INVALID = 0xffff /* Guaranteed to remain an invalid type */
 };
-- 
2.6.6


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

  parent reply	other threads:[~2016-11-11  8:00 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-11  7:59 [PATCH v3 00/12] xenstore: support reading directory with many children Juergen Gross
2016-11-11  7:59 ` [PATCH v3 01/12] xenstore: modify add_change_node() parameter types Juergen Gross
2016-11-12 15:09   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 02/12] xenstore: call add_change_node() directly when writing node Juergen Gross
2016-11-12 15:10   ` Wei Liu
2016-11-13 10:50     ` Juergen Gross
2016-11-14  8:46       ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 03/12] xenstore: use common tdb record header in xenstore Juergen Gross
2016-11-12 15:10   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 04/12] xenstore: add per-node generation counter Juergen Gross
2016-11-12 15:10   ` Wei Liu
2016-11-11  8:00 ` Juergen Gross [this message]
2016-11-11 10:09   ` [PATCH v3 05/12] xenstore: add support for reading directory with many children Jan Beulich
     [not found]   ` <5825A6D6020000780011DEA4@suse.com>
2016-11-11 10:43     ` Juergen Gross
2016-11-11 11:12       ` Jan Beulich
     [not found]       ` <5825B59B020000780011DF28@suse.com>
2016-11-11 11:15         ` Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 06/12] xenstore: support XS_DIRECTORY_PART in libxenstore Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 07/12] xenstore: use array for xenstore wire command handling Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 08/12] xenstore: let command functions return error or success Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-13 11:05     ` Juergen Gross
2016-11-11  8:00 ` [PATCH v3 09/12] xenstore: make functions static Juergen Gross
2016-11-11 13:02   ` Andrew Cooper
2016-11-11 13:19     ` Juergen Gross
2016-11-11  8:00 ` [PATCH v3 10/12] xenstore: add helper functions for wire argument parsing Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 11/12] xenstore: add small default data buffer to internal struct Juergen Gross
2016-11-12 15:11   ` Wei Liu
2016-11-11  8:00 ` [PATCH v3 12/12] xenstore: handle memory allocation failures in xenstored Juergen Gross
2016-11-11 11:07   ` Juergen Gross
2016-11-12 15:11     ` Wei Liu

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=1478851210-6251-6-git-send-email-jgross@suse.com \
    --to=jgross@suse.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).