qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Adam Litke <agl@us.ibm.com>
To: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: abeekhof@redhat.com, agl@linux.vnet.ibm.com,
	qemu-devel@nongnu.org, aliguori@linux.vnet.ibm.com
Subject: [Qemu-devel] Re: [RFC][RESEND][PATCH v1 06/15] virtproxy: add read handler for communication channel
Date: Wed, 03 Nov 2010 18:38:01 -0500	[thread overview]
Message-ID: <1288827481.2846.65.camel@aglitke> (raw)
In-Reply-To: <1288798090-7127-7-git-send-email-mdroth@linux.vnet.ibm.com>

On Wed, 2010-11-03 at 10:28 -0500, Michael Roth wrote:
> Handle data coming in over the channel as VPPackets: Process control
> messages and forward data from remote client/server connections to the
> appropriate server/client FD on our end.
> 
> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> ---
>  virtproxy.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 83 insertions(+), 0 deletions(-)
> 
> diff --git a/virtproxy.c b/virtproxy.c
> index 20532c2..c9c3022 100644
> --- a/virtproxy.c
> +++ b/virtproxy.c
> @@ -33,6 +33,7 @@
>  #define VP_SERVICE_ID_LEN 32    /* max length of service id string */
>  #define VP_PKT_DATA_LEN 1024    /* max proxied bytes per VPPacket */
>  #define VP_CONN_DATA_LEN 1024   /* max bytes conns can send at a time */
> +#define VP_CHAN_DATA_LEN 4096   /* max bytes channel can send at a time */
>  #define VP_MAGIC 0x1F374059
> 
>  /* listening fd, one for each service we're forwarding to remote end */
> @@ -150,6 +151,8 @@ static QemuOptsList vp_socket_opts = {
>      },
>  };
> 
> +static void vp_channel_read(void *opaque);

Try to get rid of these forward declarations.  If you really need them,
consider adding a virtproxy-internal.h.


> @@ -230,3 +233,83 @@ static void vp_channel_accept(void *opaque)
>      /* dont accept anymore connections until channel_fd is closed */
>      vp_set_fd_handler(drv->listen_fd, NULL, NULL, NULL);
>  }
> +
> +/* read handler for communication channel
> + *
> + * de-multiplexes data coming in over the channel. for control messages
> + * we process them here, for data destined for a service or client we
> + * send it to the appropriate FD.
> + */
> +static void vp_channel_read(void *opaque)
> +{
> +    VPDriver *drv = opaque;
> +    VPPacket pkt;
> +    int count, ret, buf_offset;
> +    char buf[VP_CHAN_DATA_LEN];
> +    char *pkt_ptr, *buf_ptr;
> +
> +    TRACE("called with opaque: %p", drv);
> +
> +    count = read(drv->channel_fd, buf, sizeof(buf));
> +
> +    if (count == -1) {
> +        LOG("read() failed: %s", strerror(errno));
> +        return;
> +    } else if (count == 0) {
> +        /* TODO: channel closed, this probably shouldn't happen for guest-side
> +         * serial/virtio-serial connections, but need to confirm and consider
> +         * what should happen in this case. as it stands this virtproxy instance
> +         * is basically defunct at this point, same goes for "client" instances
> +         * of virtproxy where the remote end has hung-up.
> +         */
> +        LOG("channel connection closed");
> +        vp_set_fd_handler(drv->channel_fd, NULL, NULL, drv);
> +        drv->channel_fd = -1;
> +        if (drv->listen_fd) {
> +            vp_set_fd_handler(drv->listen_fd, vp_channel_accept, NULL, drv);
> +        }
> +        /* TODO: should close/remove/delete all existing VPConns here */

Looks like you have a little work TODO here still.  Perhaps you could
add some reset/init functions that would make handling this easier.  The
ability to reset state at both the channel and VPConn levels should give
you the ability to handle errors more gracefully in other places where
you currently just log them.

> +    }
> +
> +    if (drv->buflen + count >= sizeof(VPPacket)) {
> +        TRACE("initial packet, drv->buflen: %d", drv->buflen);
> +        pkt_ptr = (char *)&pkt;
> +        memcpy(pkt_ptr, drv->buf, drv->buflen);

Can drv->buflen ever be > sizeof(VPPacket) ?  You might consider adding
an assert(drv->buflen < sizeof(VPPacket)) unless it's mathematically
impossible.

> +        pkt_ptr += drv->buflen;
> +        memcpy(pkt_ptr, buf, sizeof(VPPacket) - drv->buflen);
> +        /* handle first packet */
> +        ret = vp_handle_packet(drv, &pkt);
> +        if (ret != 0) {
> +            LOG("error handling packet");
> +        }
> +        /* handle the rest of the buffer */
> +        buf_offset = sizeof(VPPacket) - drv->buflen;
> +        drv->buflen = 0;
> +        buf_ptr = buf + buf_offset;
> +        count -= buf_offset;
> +        while (count > 0) {
> +            if (count >= sizeof(VPPacket)) {
> +                /* handle full packet */
> +                TRACE("additional packet, drv->buflen: %d", drv->buflen);
> +                memcpy((void *)&pkt, buf_ptr, sizeof(VPPacket));
> +                ret = vp_handle_packet(drv, &pkt);
> +                if (ret != 0) {
> +                    LOG("error handling packet");
> +                }
> +                count -= sizeof(VPPacket);
> +                buf_ptr += sizeof(VPPacket);
> +            } else {
> +                /* buffer the remainder */
> +                TRACE("buffering packet");
> +                memcpy(drv->buf, buf_ptr, count);
> +                drv->buflen = count;
> +                break;
> +            }
> +        }
> +    } else {
> +        /* haven't got a full VPPacket yet, buffer for later */
> +        buf_ptr = drv->buf + drv->buflen;
> +        memcpy(buf_ptr, buf, count);
> +        drv->buflen += count;

With this algorithm you can hold some data hostage indefinitely.  You
either need to send out smaller packets of whatever data you receive or
maybe have a timer that periodically fires to flush drv->buf.  Any
thoughts on what you plan to do here?

-- 
Thanks,
Adam

  reply	other threads:[~2010-11-04  1:39 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-03 15:27 [Qemu-devel] [RFC][RESEND][PATCH v1 00/15] virtproxy: host/guest communication layer Michael Roth
2010-11-03 15:27 ` [Qemu-devel] [RFC][RESEND][PATCH v1 01/15] virtproxy: base data structures and constants Michael Roth
2010-11-03 22:33   ` [Qemu-devel] " Adam Litke
2010-11-03 15:27 ` [Qemu-devel] [RFC][RESEND][PATCH v1 02/15] virtproxy: qemu-vp, standalone daemon skeleton Michael Roth
2010-11-03 22:47   ` [Qemu-devel] " Adam Litke
2010-11-04 13:57     ` Michael Roth
2010-11-05 13:32       ` Adam Litke
2010-11-09 10:45         ` Amit Shah
2010-11-10  2:51           ` Michael Roth
2010-11-03 15:27 ` [Qemu-devel] [RFC][RESEND][PATCH v1 03/15] virtproxy: add debug functions for virtproxy core Michael Roth
2010-11-03 22:51   ` [Qemu-devel] " Adam Litke
2010-11-03 15:27 ` [Qemu-devel] [RFC][RESEND][PATCH v1 04/15] virtproxy: list look-up functions conns/oforwards/iforwards Michael Roth
2010-11-03 22:56   ` [Qemu-devel] " Adam Litke
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 05/15] virtproxy: add accept handler for communication channel Michael Roth
2010-11-03 23:02   ` [Qemu-devel] " Adam Litke
2010-11-04 16:17     ` Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 06/15] virtproxy: add read " Michael Roth
2010-11-03 23:38   ` Adam Litke [this message]
2010-11-04 17:00     ` [Qemu-devel] " Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 07/15] virtproxy: add vp_new() VPDriver constructor Michael Roth
2010-11-03 23:45   ` [Qemu-devel] " Adam Litke
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 08/15] virtproxy: interfaces to set/remove/handle VPOForwards Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 09/15] virtproxy: add handler for data packets Michael Roth
2010-11-04  0:46   ` [Qemu-devel] " Adam Litke
2010-11-04 18:23     ` Michael Roth
2010-11-04  1:48   ` Adam Litke
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 10/15] virtproxy: add handler for control packet Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 11/15] virtproxy: add vp_handle_packet() Michael Roth
2010-11-04  1:13   ` [Qemu-devel] " Adam Litke
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 12/15] virtproxy: interfaces to set/remove VPIForwards Michael Roth
2010-11-04  1:12   ` [Qemu-devel] " Adam Litke
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 13/15] virtproxy: add read handler for proxied connections Michael Roth
2010-11-04  1:21   ` [Qemu-devel] " Adam Litke
2010-11-04 18:26     ` Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 14/15] virtproxy: Makefile/configure changes to build qemu-vp Michael Roth
2010-11-03 15:28 ` [Qemu-devel] [RFC][RESEND][PATCH v1 15/15] virtproxy: qemu-vp, main logic Michael Roth
2010-11-03 23:44 ` [Qemu-devel] Re: [RFC][RESEND][PATCH v1 00/15] virtproxy: host/guest communication layer Adam Litke
2010-11-04 18:46   ` Michael Roth

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=1288827481.2846.65.camel@aglitke \
    --to=agl@us.ibm.com \
    --cc=abeekhof@redhat.com \
    --cc=agl@linux.vnet.ibm.com \
    --cc=aliguori@linux.vnet.ibm.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.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).