From: Juergen Gross <jgross@suse.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: ian.jackson@eu.citrix.com, andrew.cooper3@citrix.com,
wei.liu2@citrix.com, david.vrabel@citrix.com,
xen-devel@lists.xen.org
Subject: Re: [PATCH 1/2] xenstore: add support for reading directory with many children
Date: Tue, 25 Oct 2016 13:41:40 +0200 [thread overview]
Message-ID: <0a40bf5f-f8c6-0a51-721d-203351a1519d@suse.com> (raw)
In-Reply-To: <580F3CC902000078001195F3@suse.com>
On 25/10/16 11:06, Jan Beulich wrote:
>>>> On 25.10.16 at 07:52, <JGross@suse.com> wrote:
>> --- a/tools/xenstore/xenstored_transaction.c
>> +++ b/tools/xenstore/xenstored_transaction.c
>> @@ -79,6 +79,11 @@ struct transaction
>>
>> /* List of changed domains - to record the changed domain entry number */
>> struct list_head changed_domains;
>> +
>> + /* Temporary buffer for XS_DIRECTORY_PART. */
>> + char *dirpart_buf;
>> + unsigned buf_off;
>> + unsigned buf_len;
>> };
>
> The buffer you allocate for this can - by nature of this change - be
> huge, and there's one per transaction. Isn't this causing a resource
> utilization issue?
It will be allocated only when needed and its size is less than that of
the node to be read.
>> @@ -280,6 +285,58 @@ void conn_delete_all_transactions(struct connection *conn)
>> conn->transaction_started = 0;
>> }
>>
>> +void send_directory_part(struct connection *conn, struct buffered_data *in)
>> +{
>> + struct transaction *trans = conn->transaction;
>> + struct node *node;
>> + const char *name = onearg(in);
>> + unsigned len;
>> +
>> + if (name == NULL || trans == NULL) {
>> + send_error(conn, EINVAL);
>> + return;
>> + }
>> +
>> + if (name[0] == '@' && name[1] == 0) {
>> + if (trans->dirpart_buf == NULL) {
>> + send_error(conn, EINVAL);
>> + return;
>> + }
>> + } else {
>> + if (trans->dirpart_buf) {
>> + talloc_free(trans->dirpart_buf);
>> + trans->dirpart_buf = NULL;
>> + }
>> +
>> + name = canonicalize(conn, name);
>> + node = get_node(conn, in, name, XS_PERM_READ);
>> + if (!node) {
>> + send_error(conn, errno);
>> + return;
>> + }
>> + trans->dirpart_buf = talloc_array(trans, char,
>> + node->childlen + 1);
>
> Once again, especially considering the buffer possibly being huge,
> shouldn't you check for allocation failure here?
I followed coding style from xenstored. Modifying this style should be
another patch set IMHO (I'd be fine doing this).
>
>> + memcpy(trans->dirpart_buf, node->children, node->childlen);
>> + trans->dirpart_buf[node->childlen] = 0;
>> + trans->buf_off = 0;
>> + trans->buf_len = node->childlen + 1;
>> + }
>> +
>> + if (trans->buf_len - trans->buf_off > 1024)
>
> What has this 1024 been derived from? In particular, why is it not
> (close to) the 4096 limit mentioned in the description?
In theory a single entry could be up to 2048 bytes long. I wanted to
keep the logic simple by not trying to iterate until the limit is
reached. I can change that, of course.
>
>> + len = strlen(trans->dirpart_buf + trans->buf_off) + 1;
>
> Looking at construct_node() I'm getting the impression that there
> are embedded nul characters in the ->children array, in which case
> this strlen() would likely chop off values which could still fit, requiring
> needlessly many iterations. And the explicit nul termination after the
> allocation above would then also appear to be unnecessary.
Each children member is a nul terminated string, so I need to keep
the nul bytes in the result. And the final nul byte is the indicator
for the last entry being reached.
> And then - why did you put this function here instead of in
> xenstored_core.c, e.g. next to send_directory()?
It is using the xenstored_transaction.c private struct transaction.
Putting it in xenstored_core.c would have required to move the
struct definition into a header file.
Juergen
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2016-10-25 11:41 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-25 5:52 [PATCH 0/2] xenstore: support reading directory with many children Juergen Gross
2016-10-25 5:52 ` [PATCH 1/2] xenstore: add support for " Juergen Gross
2016-10-25 9:06 ` Jan Beulich
[not found] ` <580F3CC902000078001195F3@suse.com>
2016-10-25 11:41 ` Juergen Gross [this message]
2016-10-25 13:20 ` Jan Beulich
[not found] ` <580F785502000078001197C7@suse.com>
2016-10-25 13:47 ` Juergen Gross
2016-10-25 14:02 ` Jan Beulich
[not found] ` <580F820E0200007800119823@suse.com>
2016-10-25 14:48 ` Juergen Gross
2016-10-25 5:52 ` [PATCH 2/2] xenstore: support XS_DIRECTORY_PART in libxenstore Juergen Gross
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=0a40bf5f-f8c6-0a51-721d-203351a1519d@suse.com \
--to=jgross@suse.com \
--cc=JBeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=david.vrabel@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--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).