xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Wei Liu <wei.liu2@citrix.com>
To: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Cc: Anthony PERARD <anthony.perard@citrix.com>,
	Xen devel <xen-devel@lists.xenproject.org>,
	Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Wei Liu <wei.liu2@citrix.com>
Subject: Re: [PATCH] libxl/libxl_qmp.c: Fix code style in qmp_next()
Date: Thu, 22 Dec 2016 10:47:35 +0000	[thread overview]
Message-ID: <20161222104734.GL28690@citrix.com> (raw)
In-Reply-To: <1482400387-18231-1-git-send-email-zhangchen.fnst@cn.fujitsu.com>

Also CC Anthony, who wrote the original code.

On Thu, Dec 22, 2016 at 05:53:07PM +0800, Zhang Chen wrote:
> Make select loop more readable.

The behaviour of this function is changed. The changes are not
necessarily wrong, but we need to have clear commit message for why the
change of behaviour is desirable.

Basically you break a big loop into two disjoint ones. I think the
original code handles short-read correctly while this patch doesn't.

See below.

> 
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> ---
>  tools/libxl/libxl_qmp.c | 123 ++++++++++++++++++++++++------------------------
>  1 file changed, 61 insertions(+), 62 deletions(-)
> 
> diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
> index ad22ad4..123a6bf 100644
> --- a/tools/libxl/libxl_qmp.c
> +++ b/tools/libxl/libxl_qmp.c
> @@ -427,79 +427,78 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
>      size_t incomplete_size = 0;
>      int rc = 0;
>  
> -    do {
> -        fd_set rfds;
> -        int ret = 0;
> -        struct timeval timeout = {
> -            .tv_sec = qmp->timeout,
> -            .tv_usec = 0,
> -        };
> +    fd_set rfds;
> +    int ret = 0;
> +    struct timeval timeout = {
> +        .tv_sec = qmp->timeout,
> +        .tv_usec = 0,
> +    };
>  
> -        FD_ZERO(&rfds);
> -        FD_SET(qmp->qmp_fd, &rfds);
> +    FD_ZERO(&rfds);
> +    FD_SET(qmp->qmp_fd, &rfds);
>  
> +    do {
>          ret = select(qmp->qmp_fd + 1, &rfds, NULL, NULL, &timeout);
> -        if (ret == 0) {
> -            LOGD(ERROR, qmp->domid, "timeout");
> -            return -1;
> -        } else if (ret < 0) {
> -            if (errno == EINTR)
> -                continue;
> -            LOGED(ERROR, qmp->domid, "Select error");
> -            return -1;
> -        }
> +    } while (ret == -1 && errno == EINTR);
>  

A side note.

Select may modify timeout, so I think we need to reset timeout at the
beginning of the loop.

> -        rd = read(qmp->qmp_fd, qmp->buffer, QMP_RECEIVE_BUFFER_SIZE);
> -        if (rd == 0) {
> -            LOGD(ERROR, qmp->domid, "Unexpected end of socket");
> -            return -1;
> -        } else if (rd < 0) {
> -            LOGED(ERROR, qmp->domid, "Socket read error");
> -            return rd;
> -        }
> -        qmp->buffer[rd] = '\0';
> -
> -        DEBUG_REPORT_RECEIVED(qmp->domid, qmp->buffer, rd);
> -
> -        do {
> -            char *end = NULL;
> -            if (incomplete) {
> -                size_t current_pos = s - incomplete;
> -                incomplete = libxl__realloc(gc, incomplete,
> -                                            incomplete_size + rd + 1);
> -                strncat(incomplete + incomplete_size, qmp->buffer, rd);
> -                s = incomplete + current_pos;
> -                incomplete_size += rd;
> -                s_end = incomplete + incomplete_size;
> -            } else {
> -                incomplete = libxl__strndup(gc, qmp->buffer, rd);
> -                incomplete_size = rd;
> -                s = incomplete;
> -                s_end = s + rd;
> -                rd = 0;
> -            }
> +    if (ret == 0) {
> +        LOGD(ERROR, qmp->domid, "timeout");
> +        return -1;
> +    } else if (ret < 0) {
> +        LOGED(ERROR, qmp->domid, "Select error");
> +        return -1;
> +    }
>  
> -            end = strstr(s, "\r\n");
> -            if (end) {
> -                libxl__json_object *o = NULL;
> +    rd = read(qmp->qmp_fd, qmp->buffer, QMP_RECEIVE_BUFFER_SIZE);
> +    if (rd == 0) {
> +        LOGD(ERROR, qmp->domid, "Unexpected end of socket");
> +        return -1;
> +    } else if (rd < 0) {
> +        LOGED(ERROR, qmp->domid, "Socket read error");
> +        return rd;
> +    }
> +    qmp->buffer[rd] = '\0';
> +

Here, as I understand it, read can return incomplete message. For
example, when the buffer is not big enough.

And the inner loop in original code handles that by checking if there is
"\r\n". If not, it will read from the socket again.

So I'm afraid this patch is not correct. Please point out if there is
anything I missed.

Wei.

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

  reply	other threads:[~2016-12-22 10:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-22  9:53 [PATCH] libxl/libxl_qmp.c: Fix code style in qmp_next() Zhang Chen
2016-12-22 10:47 ` Wei Liu [this message]
2016-12-23  3:16   ` Zhang Chen
2016-12-23 11:44     ` Wei Liu
2016-12-26  6:48       ` Zhang Chen
2017-01-04 17:56   ` Anthony PERARD

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=20161222104734.GL28690@citrix.com \
    --to=wei.liu2@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=anthony.perard@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    --cc=zhangchen.fnst@cn.fujitsu.com \
    /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).