qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@redhat.com>
To: "Samuel Thibault" <samuel.thibault@ens-lyon.org>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Daniel P. Berrange" <berrange@redhat.com>
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org,
	stefanha@redhat.com, jan.kiszka@siemens.com
Subject: Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback
Date: Thu, 7 Feb 2019 19:31:49 +0100	[thread overview]
Message-ID: <df0735c3-cab0-085f-f8ea-db820055b221@redhat.com> (raw)
In-Reply-To: <20190207140316.16103-28-samuel.thibault@ens-lyon.org>

Hi Samuel,

On 2/7/19 3:03 PM, Samuel Thibault wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Use a more descriptive name for the callback.
> 
> Reuse the SlirpWriteCb type. Wrap it to check that all data has been written.
> 
> Return a ssize_t for potential error handling and data-loss reporting.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> ---
>  include/net/net.h |  2 +-
>  net/net.c         |  4 ++--
>  net/slirp.c       |  9 +++++----
>  slirp/libslirp.h  | 11 +++++++----
>  slirp/ncsi.c      |  2 +-
>  slirp/slirp.c     | 18 +++++++++++++++---
>  slirp/slirp.h     |  2 ++
>  7 files changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/include/net/net.h b/include/net/net.h
> index 643295d163..075cc01267 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
>                            int iovcnt);
>  ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
>                                  int iovcnt, NetPacketSent *sent_cb);
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
> +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
>  ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
>  ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
>                                 int size, NetPacketSent *sent_cb);
> diff --git a/net/net.c b/net/net.c
> index 3acbdccd61..5dcff7fe2a 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender,
>                                               buf, size, sent_cb);
>  }
>  
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
> +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
>  {
> -    qemu_send_packet_async(nc, buf, size, NULL);
> +    return qemu_send_packet_async(nc, buf, size, NULL);
>  }
>  
>  ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
> diff --git a/net/slirp.c b/net/slirp.c
> index 7b4f9f5c5e..664ff1c002 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s);
>  static inline void slirp_smb_cleanup(SlirpState *s) { }
>  #endif
>  
> -static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
> +static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len,
> +                                     void *opaque)
>  {
>      SlirpState *s = opaque;
>  
> -    qemu_send_packet(&s->nc, pkt, pkt_len);
> +    return qemu_send_packet(&s->nc, pkt, pkt_len);
>  }
>  
>  static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t size)
> @@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd)
>  }
>  
>  static const SlirpCb slirp_cb = {
> -    .output = net_slirp_output,
> +    .send_packet = net_slirp_send_packet,
>      .guest_error = net_slirp_guest_error,
>      .clock_get_ns = net_slirp_clock_get_ns,
>      .timer_new = net_slirp_timer_new,
> @@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
>      slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
>  }
>  
> -static int guestfwd_write(const void *buf, size_t len, void *chr)
> +static ssize_t guestfwd_write(const void *buf, size_t len, void *chr)
>  {
>      return qemu_chr_fe_write_all(chr, buf, len);
>  }
> diff --git a/slirp/libslirp.h b/slirp/libslirp.h
> index 02cbec9f8b..8e5d4ed11b 100644
> --- a/slirp/libslirp.h
> +++ b/slirp/libslirp.h
> @@ -15,7 +15,7 @@
>  
>  typedef struct Slirp Slirp;
>  
> -typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
> +typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
>  typedef void (*SlirpTimerCb)(void *opaque);
>  
>  /*
> @@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque);
>   */
>  typedef struct SlirpCb {
>      /*
> -     * Send an ethernet frame to the guest network. The opaque parameter
> -     * is the one given to slirp_init().
> +     * Send an ethernet frame to the guest network. The opaque
> +     * parameter is the one given to slirp_init(). The function
> +     * doesn't need to send all the data and may return <len (no
> +     * buffering is done on libslirp side, so the data will be dropped
> +     * in this case). <0 reports an IO error.
>       */
> -    void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
> +    SlirpWriteCb send_packet;
>      /* Print a message for an error due to guest misbehavior.  */
>      void (*guest_error)(const char *msg);
>      /* Return the virtual clock value in nanoseconds */
> diff --git a/slirp/ncsi.c b/slirp/ncsi.c
> index 327f17543c..359f52c284 100644
> --- a/slirp/ncsi.c
> +++ b/slirp/ncsi.c
> @@ -162,5 +162,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
>      *pchecksum = htonl(checksum);
>      ncsi_rsp_len += 4;
>  
> -    slirp->cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
> +    slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
>  }
> diff --git a/slirp/slirp.c b/slirp/slirp.c
> index 3304c83001..2bc53e3e12 100644
> --- a/slirp/slirp.c
> +++ b/slirp/slirp.c
> @@ -800,7 +800,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
>              rah->ar_sip = ah->ar_tip;
>              memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
>              rah->ar_tip = ah->ar_sip;
> -            slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
> +            slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply));
>          }
>          break;
>      case ARPOP_REPLY:
> @@ -900,7 +900,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
>              /* target IP */
>              rah->ar_tip = iph->ip_dst.s_addr;
>              slirp->client_ipaddr = iph->ip_dst;
> -            slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
> +            slirp_send_packet_all(slirp, arp_req, sizeof(arp_req));
>              ifm->resolution_requested = true;
>  
>              /* Expire request and drop outgoing packet after 1 second */
> @@ -985,7 +985,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
>                eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
>                eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
>      memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
> -    slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
> +    slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN);
>      return 1;
>  }
>  
> @@ -1152,3 +1152,15 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
>      if (ret > 0)
>          tcp_output(sototcpcb(so));
>  }
> +
> +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len)
> +{
> +    ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque);
> +
> +    if (ret < 0) {
> +        g_critical("Failed to send packet, ret: %ld", (long) ret);

>From the v3 discussion [*] I thought send_packet() would return a
gssize, then we'd use G_GSSIZE_FORMAT here (and similarly use gssize
instead ssize_t in this series).
Anyway your fix is simpler. And we can still do this on top of this PR.

[*] https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg01841.html

> +    } else if (ret < len) {
> +        DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu",
> +                (long) ret, (unsigned long) len);
> +    }
> +}
> diff --git a/slirp/slirp.h b/slirp/slirp.h
> index 05b8364c07..752a4cd8c8 100644
> --- a/slirp/slirp.h
> +++ b/slirp/slirp.h
> @@ -269,4 +269,6 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
>  struct socket *
>  slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port);
>  
> +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len);
> +
>  #endif
> 

  reply	other threads:[~2019-02-07 18:31 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock() Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/ Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback Samuel Thibault
2019-02-07 18:31   ` Philippe Mathieu-Daudé [this message]
2019-02-07 19:04     ` Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 32/32] slirp: API is extern C Samuel Thibault
2019-02-07 14:59 ` [Qemu-devel] [PULLv4 00/32] More work towards libslirp no-reply
2019-02-08 10:58 ` Peter Maydell

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=df0735c3-cab0-085f-f8ea-db820055b221@redhat.com \
    --to=philmd@redhat.com \
    --cc=berrange@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=samuel.thibault@ens-lyon.org \
    --cc=stefanha@redhat.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).