return s->acked_features;
}
-static void vhost_user_stop(int queues, NetClientState *ncs[])
+void vhost_user_save_acked_features(NetClientState *nc)
{
NetVhostUserState *s;
+
+ s = DO_UPCAST(NetVhostUserState, nc, nc);
+ if (s->vhost_net) {
+ uint64_t features = vhost_net_get_acked_features(s->vhost_net);
+ if (features) {
+ s->acked_features = features;
+ }
+ }
+}
+
+static void vhost_user_stop(int queues, NetClientState *ncs[])
+{
int i;
+ NetVhostUserState *s;
for (i = 0; i < queues; i++) {
assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
s = DO_UPCAST(NetVhostUserState, nc, ncs[i]);
if (s->vhost_net) {
- /* save acked features */
- uint64_t features = vhost_net_get_acked_features(s->vhost_net);
- if (features) {
- s->acked_features = features;
- }
+ vhost_user_save_acked_features(ncs[i]);
vhost_net_cleanup(s->vhost_net);
}
}
options.net_backend = ncs[i];
options.opaque = be;
options.busyloop_timeout = 0;
+ options.nvqs = 2;
net = vhost_net_init(&options);
if (!net) {
error_report("failed to init vhost_net for queue %d", i);
return true;
}
+static bool vhost_user_check_peer_type(NetClientState *nc, ObjectClass *oc,
+ Error **errp)
+{
+ const char *driver = object_class_get_name(oc);
+
+ if (!g_str_has_prefix(driver, "virtio-net-")) {
+ error_setg(errp, "vhost-user requires frontend driver virtio-net-*");
+ return false;
+ }
+
+ return true;
+}
+
static NetClientInfo net_vhost_user_info = {
.type = NET_CLIENT_DRIVER_VHOST_USER,
.size = sizeof(NetVhostUserState),
.has_ufo = vhost_user_has_ufo,
.set_vnet_be = vhost_user_set_vnet_endianness,
.set_vnet_le = vhost_user_set_vnet_endianness,
+ .check_peer_type = vhost_user_check_peer_type,
};
-static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond,
- void *opaque)
+static gboolean net_vhost_user_watch(void *do_not_use, GIOCondition cond,
+ void *opaque)
{
NetVhostUserState *s = opaque;
qemu_chr_fe_disconnect(&s->chr);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
static void net_vhost_user_event(void *opaque, QEMUChrEvent event);
s = DO_UPCAST(NetVhostUserState, nc, ncs[0]);
for (i = queues -1; i >= 0; i--) {
- s = DO_UPCAST(NetVhostUserState, nc, ncs[i]);
-
- if (s->vhost_net) {
- s->acked_features = vhost_net_get_acked_features(s->vhost_net);
- }
+ vhost_user_save_acked_features(ncs[i]);
}
qmp_set_link(name, false, &err);
}
static int net_vhost_user_init(NetClientState *peer, const char *device,
- const char *name, const char *chardev,
- Chardev *chr, int queues)
+ const char *name, Chardev *chr,
+ int queues)
{
Error *err = NULL;
NetClientState *nc, *nc0 = NULL;
NetVhostUserState *s = NULL;
VhostUserState *user;
int i;
- NetdevVhostUserOptions *stored;
assert(name);
assert(queues > 0);
user = g_new0(struct VhostUserState, 1);
for (i = 0; i < queues; i++) {
nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
+ qemu_set_info_str(nc, "vhost-user%d to %s", i, chr->label);
nc->queue_index = i;
if (!nc0) {
nc0 = nc;
assert(s->vhost_net);
- /* Store startup parameters */
- nc0->stored_config = g_new0(NetdevInfo, 1);
- nc0->stored_config->type = NET_BACKEND_VHOST_USER;
- stored = &nc0->stored_config->u.vhost_user;
-
- stored->chardev = g_strdup(chardev);
-
- stored->has_queues = true;
- stored->queues = queues;
-
return 0;
err:
return chr;
}
-static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
-{
- const char *name = opaque;
- const char *driver, *netdev;
-
- driver = qemu_opt_get(opts, "driver");
- netdev = qemu_opt_get(opts, "netdev");
-
- if (!driver || !netdev) {
- return 0;
- }
-
- if (strcmp(netdev, name) == 0 &&
- !g_str_has_prefix(driver, "virtio-net-")) {
- error_setg(errp, "vhost-user requires frontend driver virtio-net-*");
- return -1;
- }
-
- return 0;
-}
-
int net_init_vhost_user(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
return -1;
}
- /* verify net frontend */
- if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net,
- (char *)name, errp)) {
- return -1;
- }
-
queues = vhost_user_opts->has_queues ? vhost_user_opts->queues : 1;
if (queues < 1 || queues > MAX_QUEUE_NUM) {
error_setg(errp,
return -1;
}
- return net_vhost_user_init(peer, "vhost_user", name,
- vhost_user_opts->chardev, chr, queues);
+ return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
}