qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v7 12/13] Add the vhost-user netdev backend to c


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH v7 12/13] Add the vhost-user netdev backend to command line
Date: Mon, 10 Feb 2014 10:49:23 +0200

On Fri, Jan 31, 2014 at 06:34:41PM +0100, Antonios Motakis wrote:
> The supplied chardev id will be inspected for supported options. Only
> a socket backend, with a set path (i.e. a unix socket) and optionally
> the server parameter set, will be allowed. Other options (nowait, telnet)
> will make the chardev unusable and the netdev will not be initialised.
> 
> Signed-off-by: Antonios Motakis <address@hidden>
> Signed-off-by: Nikolay Nikolaev <address@hidden>
> ---
>  hmp-commands.hx     |  4 +--
>  hw/net/vhost_net.c  |  4 +++
>  hw/net/virtio-net.c |  3 ++
>  net/hub.c           |  1 +
>  net/net.c           |  2 ++
>  net/vhost-user.c    | 91 
> +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  qapi-schema.json    | 18 ++++++++++-
>  qemu-options.hx     | 16 ++++++++++
>  8 files changed, 134 insertions(+), 5 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index f3fc514..68128c1 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1195,7 +1195,7 @@ ETEXI
>      {
>          .name       = "host_net_add",
>          .args_type  = "device:s,opts:s?",
> -        .params     = "tap|user|socket|vde|netmap|dump [options]",
> +        .params     = "tap|user|socket|vde|netmap|vhost-user|dump [options]",
>          .help       = "add host VLAN client",
>          .mhandler.cmd = net_host_device_add,
>      },
> @@ -1223,7 +1223,7 @@ ETEXI
>      {
>          .name       = "netdev_add",
>          .args_type  = "netdev:O",
> -        .params     = 
> "[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
> +        .params     = 
> "[user|tap|socket|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
>          .help       = "add host network device",
>          .mhandler.cmd = hmp_netdev_add,
>      },
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 6b6268b..e630407 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -15,6 +15,7 @@
>  
>  #include "net/net.h"
>  #include "net/tap.h"
> +#include "net/vhost-user.h"
>  
>  #include "hw/virtio/virtio-net.h"
>  #include "net/vhost_net.h"
> @@ -322,6 +323,9 @@ VHostNetState *get_vhost_net(NetClientState *nc)
>      case NET_CLIENT_OPTIONS_KIND_TAP:
>          vhost_net = tap_get_vhost_net(nc);
>          break;
> +    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> +        vhost_net = vhost_user_get_vhost_net(nc);
> +        break;
>      default:
>          break;
>      }
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 72acd15..d49ee82 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -322,6 +322,9 @@ static void peer_test_vnet_hdr(VirtIONet *n)
>      case NET_CLIENT_OPTIONS_KIND_TAP:
>          n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer);
>          break;
> +    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> +        n->has_vnet_hdr = 0;
> +        break;
>      default:
>          break;
>      }
> diff --git a/net/hub.c b/net/hub.c
> index 33a99c9..7e0f2d6 100644
> --- a/net/hub.c
> +++ b/net/hub.c
> @@ -322,6 +322,7 @@ void net_hub_check_clients(void)
>              case NET_CLIENT_OPTIONS_KIND_TAP:
>              case NET_CLIENT_OPTIONS_KIND_SOCKET:
>              case NET_CLIENT_OPTIONS_KIND_VDE:
> +            case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
>                  has_host_dev = 1;
>                  break;
>              default:
> diff --git a/net/net.c b/net/net.c
> index 2c3af20..30f1273 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -731,6 +731,7 @@ static int (* const 
> net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
>          [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
>  #endif
>          [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
> +        [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
>  };
>  
>  

Please align other options at =.

> @@ -764,6 +765,7 @@ static int net_client_init1(const void *object, int 
> is_netdev, Error **errp)
>          case NET_CLIENT_OPTIONS_KIND_BRIDGE:
>  #endif
>          case NET_CLIENT_OPTIONS_KIND_HUBPORT:
> +        case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
>              break;
>  
>          default:
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index b25722c..f5bd211 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -12,6 +12,7 @@
>  #include "net/vhost_net.h"
>  #include "net/vhost-user.h"
>  #include "sysemu/char.h"
> +#include "qemu/config-file.h"
>  #include "qemu/error-report.h"
>  
>  typedef struct VhostUserState {
> @@ -20,9 +21,17 @@ typedef struct VhostUserState {
>      VHostNetState *vhost_net;
>  } VhostUserState;
>  
> +typedef struct VhostUserChardevProps {
> +    bool is_socket;
> +    bool is_unix;
> +    bool is_server;
> +    bool has_unsupported;
> +} VhostUserChardevProps;
> +
>  VHostNetState *vhost_user_get_vhost_net(NetClientState *nc)
>  {
>      VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
> +    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
>      return s->vhost_net;
>  }
>  
> @@ -67,7 +76,7 @@ static void vhost_user_cleanup(NetClientState *nc)
>  }
>  
>  static NetClientInfo net_vhost_user_info = {
> -        .type = 0,
> +        .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
>          .size = sizeof(VhostUserState),
>          .cleanup = vhost_user_cleanup,
>  };
> @@ -123,8 +132,86 @@ static int net_vhost_user_init(NetClientState *peer, 
> const char *device,
>      return 0;
>  }
>  
> +static int net_vhost_chardev_opts(const char *name, const char *value,
> +        void *opaque)
> +{
> +    VhostUserChardevProps *props = opaque;
> +
> +    if (strcmp(name, "backend") == 0 && strcmp(value, "socket") == 0) {
> +        props->is_socket = 1;
> +    } else if (strcmp(name, "path") == 0) {
> +        props->is_unix = 1;
> +    } else if (strcmp(name, "server") == 0) {
> +        props->is_server = 1;
> +    } else {
> +        error_report("vhost-user does not support a chardev"
> +                     " with the following option:\n %s = %s",
> +                     name, value);
> +        props->has_unsupported = 1;
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +static CharDriverState *net_vhost_parse_chardev(
> +        const NetdevVhostUserOptions *opts)
> +{
> +    CharDriverState *chr = qemu_chr_find(opts->chardev);
> +    VhostUserChardevProps props;
> +
> +    if (chr == NULL) {
> +        error_report("chardev \"%s\" not found\n", opts->chardev);
> +        return 0;
> +    }
> +
> +    /* inspect chardev opts */
> +    memset(&props, 0, sizeof(props));
> +    qemu_opt_foreach(chr->opts, net_vhost_chardev_opts, &props, false);
> +
> +    if (!props.is_socket || !props.is_unix) {
> +        error_report("chardev \"%s\" is not a unix socket\n",
> +                     opts->chardev);
> +        return 0;
> +    }
> +
> +    if (props.has_unsupported) {
> +        error_report("chardev \"%s\" has an unsupported option\n",
> +                opts->chardev);
> +        return 0;
> +    }
> +
> +    qemu_chr_fe_claim_no_fail(chr);
> +
> +    return chr;
> +}
> +
>  int net_init_vhost_user(const NetClientOptions *opts, const char *name,
>                     NetClientState *peer)
>  {
> -    return net_vhost_user_init(peer, "vhost_user", 0, 0);
> +    const NetdevVhostUserOptions *vhost_user_opts;
> +    CharDriverState *chr;
> +    QemuOpts *mem_opts;
> +    unsigned int mem_share = 0;
> +
> +    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
> +    vhost_user_opts = opts->vhost_user;
> +
> +    chr = net_vhost_parse_chardev(vhost_user_opts);
> +    if (!chr) {
> +        error_report("No suitable chardev found\n");
> +        return -1;
> +    }
> +
> +    /* verify mem-path is set and shared */
> +    mem_opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL);
> +    if (mem_opts) {
> +        mem_share = qemu_opt_get_bool(mem_opts, "share", 0);
> +    }
> +
> +    if (!mem_share) {
> +        error_report("vhost-user requires -mem-path /path,share=on");
> +        return -1;
> +    }
> +
> +    return net_vhost_user_init(peer, "vhost_user", name, chr);
>  }
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 05ced9d..51609a4 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3104,6 +3104,21 @@
>      '*devname':    'str' } }
>  
>  ##
> +# @NetdevVhostUserOptions
> +#
> +# Vhost-user network backend
> +#
> +# @path: control socket path
> +#
> +# Since 2.0
> +##
> +{ 'type': 'NetdevVhostUserOptions',
> +  'data': {
> +    'chardev': 'str' } }
> +
> +##
> +
> +##
>  # @NetClientOptions
>  #
>  # A discriminated record of network device traits.
> @@ -3121,7 +3136,8 @@
>      'dump':     'NetdevDumpOptions',
>      'bridge':   'NetdevBridgeOptions',
>      'hubport':  'NetdevHubPortOptions',
> -    'netmap':   'NetdevNetmapOptions' } }
> +    'netmap':   'NetdevNetmapOptions',
> +    'vhost-user': 'NetdevVhostUserOptions' } }
>  
>  ##
>  # @NetLegacy
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 60ecc95..2c59164 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1435,6 +1435,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>  #ifdef CONFIG_NETMAP
>      "netmap|"
>  #endif
> +    "vhost-user|"
>      "socket|"
>      "hubport],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL)
>  STEXI
> @@ -1766,6 +1767,21 @@ The hubport netdev lets you connect a NIC to a QEMU 
> "vlan" instead of a single
>  netdev.  @code{-net} and @code{-device} with parameter @option{vlan} create 
> the
>  required hub automatically.
>  
> address@hidden -netdev vhost-user,address@hidden
> +
> +Establish a vhost-user netdev, backedb by a chardev @var{id}. The chardev 
> should

typo

> +be a unix domain socket backed one. The vhost-user uses a specifically 
> defined
> +protocol to pass vhost ioctl replacement messages to an application on the 
> other
> +end of the socket.
> +
> +Example:
> address@hidden
> +qemu -m 1024 -mem-path /hugetlbfs,prealloc=on,share=on \
> +     -chardev socket,path=/path/to/socket \
> +     -netdev type=vhost-user,id=net0,chardev=chr0 \
> +     -device virtio-net-pci,netdev=net0
> address@hidden example
> +
>  @item -net dump[,address@hidden,address@hidden,address@hidden
>  Dump network traffic on VLAN @var{n} to file @var{file} 
> (@file{qemu-vlan0.pcap} by default).
>  At most @var{len} bytes (64k by default) per packet are stored. The file 
> format is
> -- 
> 1.8.3.2
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]