aboutsummaryrefslogtreecommitdiff
path: root/hw/net
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2021-10-19 09:15:31 +0200
committerMichael S. Tsirkin <mst@redhat.com>2021-10-20 04:37:55 -0400
commit7fe7791e3f652ac31ef98dcc94a8f2a317ab846b (patch)
tree9cdf0a882ca893ff838048ff1f8e166ce6cc186b /hw/net
parenta1ed9ef1de87c3e86ff68589604298ec90875a14 (diff)
downloadqemu-7fe7791e3f652ac31ef98dcc94a8f2a317ab846b.zip
qemu-7fe7791e3f652ac31ef98dcc94a8f2a317ab846b.tar.gz
qemu-7fe7791e3f652ac31ef98dcc94a8f2a317ab846b.tar.bz2
failover: fix a regression introduced by JSON'ification of -device
The hide_device helper can be called several times for the same devices as it shouldn't change any state and should only return an information. But not to rely anymore on QemuOpts we have introduced a new field to store the parameters of the device and don't allow to update it once it is done. And as the function is called several times, we ends with: warning: Cannot attach more than one primary device to 'virtio0' That is not only a warning as it prevents to hide the device and breaks failover. Fix that by checking the device id. Now, we fail only if the virtio-net device is really used by two different devices, for instance: -device virtio-net-pci,id=virtio0,failover=on,... \ -device vfio-pci,id=hostdev0,failover_pair_id=virtio0,... \ -device e1000e,id=e1000e0,failover_pair_id=virtio0,... \ will exit with: Cannot attach more than one primary device to 'virtio0': 'hostdev0' and 'e1000e0' Fixes: 259a10dbcb4f ("virtio-net: Store failover primary opts pointer locally") Cc: kwolf@redhat.com Signed-off-by: Laurent Vivier <lvivier@redhat.com> Message-Id: <20211019071532.682717-2-lvivier@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/virtio-net.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 09e173a..83642c8 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3304,15 +3304,27 @@ static bool failover_hide_primary_device(DeviceListener *listener,
return false;
}
+ /*
+ * The hide helper can be called several times for a given device.
+ * Check there is only one primary for a virtio-net device but
+ * don't duplicate the qdict several times if it's called for the same
+ * device.
+ */
if (n->primary_opts) {
- error_setg(errp, "Cannot attach more than one primary device to '%s'",
- n->netclient_name);
- return false;
+ const char *old, *new;
+ /* devices with failover_pair_id always have an id */
+ old = qdict_get_str(n->primary_opts, "id");
+ new = qdict_get_str(device_opts, "id");
+ if (strcmp(old, new) != 0) {
+ error_setg(errp, "Cannot attach more than one primary device to "
+ "'%s': '%s' and '%s'", n->netclient_name, old, new);
+ return false;
+ }
+ } else {
+ n->primary_opts = qdict_clone_shallow(device_opts);
+ n->primary_opts_from_json = from_json;
}
- n->primary_opts = qdict_clone_shallow(device_opts);
- n->primary_opts_from_json = from_json;
-
/* failover_primary_hidden is set during feature negotiation */
return qatomic_read(&n->failover_primary_hidden);
}