|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 23/29] tools/libxl: Extend datacopier to support reading into a buffer
On 09/11/2014 01:11 AM, Andrew Cooper wrote:
> From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
>
> 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.
>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
> tools/libxl/libxl_aoutils.c | 59
> +++++++++++++++++++++++++-----------------
> tools/libxl/libxl_internal.h | 4 ++-
> 2 files changed, 38 insertions(+), 25 deletions(-)
>
> diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c
> index 6502325..9183716 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,26 +215,31 @@ 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,
> (sizeof(buf->buf) - buf->used) < dc->maxread ?
> (sizeof(buf->buf) - buf->used) : dc->maxread);
> + }
> if (r < 0) {
> if (errno == EINTR) continue;
> if (errno == EWOULDBLOCK) break;
> @@ -257,10 +262,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;
> @@ -324,9 +331,13 @@ int libxl__datacopier_start(libxl__datacopier_state *dc)
> 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;
> + }
> +
> + assert(dc->readfd >= 0 || dc->writefd >= 0);
If readfd and writefd are valid, and readbuf is not NULL, what it the behavior?
Thanks
Wen Congyang
>
> return 0;
>
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index d93a6ee..056843a 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -2404,7 +2404,8 @@ typedef struct libxl__datacopier_buf
> libxl__datacopier_buf;
>
> /* 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);
> @@ -2433,6 +2434,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;
> };
>
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |