From: Ian Campbell <ian.campbell@citrix.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Ross Lagerwall <ross.lagerwall@citrix.com>,
Ian Jackson <Ian.Jackson@eu.citrix.com>,
Wei Liu <wei.liu2@citrix.com>,
Xen-devel <xen-devel@lists.xen.org>
Subject: Re: [PATCH 5/6] tools/libxl: Extend datacopier to support reading into a buffer
Date: Fri, 20 Feb 2015 10:34:23 +0000 [thread overview]
Message-ID: <1424428463.30924.176.camel@citrix.com> (raw)
In-Reply-To: <1424277263-27745-6-git-send-email-andrew.cooper3@citrix.com>
On Wed, 2015-02-18 at 16:34 +0000, Andrew Cooper wrote:
> From: Ross Lagerwall <ross.lagerwall@citrix.com>
>
> Implement a read-only mode for libxl__datacopier. The mode is invoked
> when readbuf is set and writefd is < 0. On success, the callback passes
> the number of bytes read.
http://lists.xen.org/archives/html/xen-devel/2014-09/msg01803.html
>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl_aoutils.c | 58 +++++++++++++++++++++++++-----------------
> tools/libxl/libxl_internal.h | 4 ++-
> 2 files changed, 38 insertions(+), 24 deletions(-)
>
> diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c
> index 037244e..a402e5c 100644
> --- a/tools/libxl/libxl_aoutils.c
> +++ b/tools/libxl/libxl_aoutils.c
> @@ -134,7 +134,7 @@ static void datacopier_check_state(libxl__egc *egc, libxl__datacopier_state *dc)
> STATE_AO_GC(dc->ao);
> int rc;
>
> - if (dc->used) {
> + if (dc->used && !dc->readbuf) {
> if (!libxl__ev_fd_isregistered(&dc->towrite)) {
> rc = libxl__ev_fd_register(gc, &dc->towrite, datacopier_writable,
> dc->writefd, POLLOUT);
> @@ -147,7 +147,7 @@ static void datacopier_check_state(libxl__egc *egc, libxl__datacopier_state *dc)
> }
> } else if (!libxl__ev_fd_isregistered(&dc->toread) || dc->maxread == 0) {
> /* we have had eof */
> - datacopier_callback(egc, dc, 0, 0);
> + datacopier_callback(egc, dc, 0, dc->readbuf ? dc->used : 0);
> return;
> } else {
> /* nothing buffered, but still reading */
> @@ -215,24 +215,30 @@ static void datacopier_readable(libxl__egc *egc, libxl__ev_fd *ev,
> }
> assert(revents & POLLIN);
> for (;;) {
> - while (dc->used >= dc->maxsz) {
> - libxl__datacopier_buf *rm = LIBXL_TAILQ_FIRST(&dc->bufs);
> - dc->used -= rm->used;
> - assert(dc->used >= 0);
> - LIBXL_TAILQ_REMOVE(&dc->bufs, rm, entry);
> - free(rm);
> - }
> + libxl__datacopier_buf *buf = NULL;
> + int r;
> +
> + if (dc->readbuf) {
> + r = read(ev->fd, dc->readbuf + dc->used, dc->maxread);
> + } else {
> + while (dc->used >= dc->maxsz) {
> + libxl__datacopier_buf *rm = LIBXL_TAILQ_FIRST(&dc->bufs);
> + dc->used -= rm->used;
> + assert(dc->used >= 0);
> + LIBXL_TAILQ_REMOVE(&dc->bufs, rm, entry);
> + free(rm);
> + }
>
> - libxl__datacopier_buf *buf =
> - LIBXL_TAILQ_LAST(&dc->bufs, libxl__datacopier_bufs);
> - if (!buf || buf->used >= sizeof(buf->buf)) {
> - buf = malloc(sizeof(*buf));
> - if (!buf) libxl__alloc_failed(CTX, __func__, 1, sizeof(*buf));
> - buf->used = 0;
> - LIBXL_TAILQ_INSERT_TAIL(&dc->bufs, buf, entry);
> - }
> - int r = read(ev->fd, buf->buf + buf->used,
> + buf = LIBXL_TAILQ_LAST(&dc->bufs, libxl__datacopier_bufs);
> + if (!buf || buf->used >= sizeof(buf->buf)) {
> + buf = malloc(sizeof(*buf));
> + if (!buf) libxl__alloc_failed(CTX, __func__, 1, sizeof(*buf));
> + buf->used = 0;
> + LIBXL_TAILQ_INSERT_TAIL(&dc->bufs, buf, entry);
> + }
> + r = read(ev->fd, buf->buf + buf->used,
> min_t(size_t, sizeof(buf->buf) - buf->used, dc->maxread));
> + }
> if (r < 0) {
> if (errno == EINTR) continue;
> if (errno == EWOULDBLOCK) break;
> @@ -255,10 +261,12 @@ static void datacopier_readable(libxl__egc *egc, libxl__ev_fd *ev,
> return;
> }
> }
> - buf->used += r;
> + if (!dc->readbuf) {
> + buf->used += r;
> + assert(buf->used <= sizeof(buf->buf));
> + }
> dc->used += r;
> dc->maxread -= r;
> - assert(buf->used <= sizeof(buf->buf));
> assert(dc->maxread >= 0);
> if (dc->maxread == 0)
> break;
> @@ -316,15 +324,19 @@ int libxl__datacopier_start(libxl__datacopier_state *dc)
>
> libxl__datacopier_init(dc);
>
> + assert(dc->readfd >= 0 || dc->writefd >= 0);
> +
> if (dc->readfd >= 0) {
> rc = libxl__ev_fd_register(gc, &dc->toread, datacopier_readable,
> dc->readfd, POLLIN);
> if (rc) goto out;
> }
>
> - rc = libxl__ev_fd_register(gc, &dc->towrite, datacopier_writable,
> - dc->writefd, POLLOUT);
> - if (rc) goto out;
> + if (dc->writefd >= 0) {
> + rc = libxl__ev_fd_register(gc, &dc->towrite, datacopier_writable,
> + dc->writefd, POLLOUT);
> + if (rc) goto out;
> + }
>
> return 0;
>
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index b7fd13d..c2e7aa4 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -2524,7 +2524,8 @@ _hidden void libxl__device_disk_local_initiate_detach(libxl__egc *egc,
>
> /* onwrite==1 means failure happened when writing, logged, errnoval is valid
> * onwrite==0 means failure happened when reading
> - * errnoval==0 means we got eof and all data was written
> + * errnoval>=0 means we got eof and all data was written or number of bytes
> + * written when in read mode
> * errnoval!=0 means we had a read error, logged
> * onwrite==-1 means some other internal failure, errnoval not valid, logged
> * If we get POLLHUP, we call callback_pollhup(..., onwrite, -1);
> @@ -2553,6 +2554,7 @@ struct libxl__datacopier_state {
> /* remaining fields are private to datacopier */
> libxl__ev_fd toread, towrite;
> ssize_t used;
> + void *readbuf;
> LIBXL_TAILQ_HEAD(libxl__datacopier_bufs, libxl__datacopier_buf) bufs;
> };
>
next prev parent reply other threads:[~2015-02-20 10:34 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-18 16:34 [PATCH 0/6] tools/libxl: Improvements to libxl__datacopier Andrew Cooper
2015-02-18 16:34 ` [PATCH 1/6] tools/libxl: Introduce min and max macros Andrew Cooper
2015-02-20 10:24 ` Ian Campbell
2015-02-20 10:42 ` Frediano Ziglio
2015-02-20 11:08 ` Andrew Cooper
2015-02-18 16:34 ` [PATCH 2/6] tools/libxl: Update datacopier to support sending data only Andrew Cooper
2015-02-20 10:27 ` Ian Campbell
2015-02-20 11:10 ` Andrew Cooper
2015-02-20 11:13 ` Ian Campbell
2015-02-18 16:34 ` [PATCH 3/6] tools/libxl: Allow adding larger amounts of prefixdata to datacopier Andrew Cooper
2015-02-20 10:32 ` Ian Campbell
2015-02-18 16:34 ` [PATCH 4/6] tools/libxl: Allow limiting amount copied by datacopier Andrew Cooper
2015-02-20 10:33 ` Ian Campbell
2015-02-18 16:34 ` [PATCH 5/6] tools/libxl: Extend datacopier to support reading into a buffer Andrew Cooper
2015-02-20 10:34 ` Ian Campbell [this message]
2015-02-18 16:34 ` [PATCH 6/6] tools/libxl: Fix datacopier POLLHUP handling to not always be fatal Andrew Cooper
2015-02-20 10:43 ` Ian Campbell
2015-02-20 13:55 ` Andrew Cooper
2015-02-20 14:05 ` Ian Campbell
2015-03-03 18:10 ` Ian Jackson
2015-03-03 18:38 ` Andrew Cooper
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=1424428463.30924.176.camel@citrix.com \
--to=ian.campbell@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=ross.lagerwall@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 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.