Skip to content

Commit 259a10d

Browse files
committed
virtio-net: Store failover primary opts pointer locally
Instead of accessing the global QemuOptsList, which really belong to the command line parser and shouldn't be accessed from devices, store a pointer to the QemuOpts in a new VirtIONet field. This is not the final state, but just an intermediate step to get rid of QemuOpts in devices. It will later be replaced with an options QDict. Before this patch, two "primary" devices could be hidden for the same standby device, but only one of them would actually be enabled and the other one would be kept hidden forever, so this doesn't make sense. After this patch, configuring a second primary device is an error. Signed-off-by: Kevin Wolf <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Tested-by: Peter Krempa <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent 7d61808 commit 259a10d

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

hw/net/virtio-net.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -858,27 +858,24 @@ static DeviceState *failover_find_primary_device(VirtIONet *n)
858858
static void failover_add_primary(VirtIONet *n, Error **errp)
859859
{
860860
Error *err = NULL;
861-
QemuOpts *opts;
862-
char *id;
863861
DeviceState *dev = failover_find_primary_device(n);
864862

865863
if (dev) {
866864
return;
867865
}
868866

869-
id = failover_find_primary_device_id(n);
870-
if (!id) {
867+
if (!n->primary_opts) {
871868
error_setg(errp, "Primary device not found");
872869
error_append_hint(errp, "Virtio-net failover will not work. Make "
873870
"sure primary device has parameter"
874871
" failover_pair_id=%s\n", n->netclient_name);
875872
return;
876873
}
877-
opts = qemu_opts_find(qemu_find_opts("device"), id);
878-
g_assert(opts); /* cannot be NULL because id was found using opts list */
879-
dev = qdev_device_add(opts, &err);
874+
875+
dev = qdev_device_add(n->primary_opts, &err);
880876
if (err) {
881-
qemu_opts_del(opts);
877+
qemu_opts_del(n->primary_opts);
878+
n->primary_opts = NULL;
882879
} else {
883880
object_unref(OBJECT(dev));
884881
}
@@ -3317,6 +3314,19 @@ static bool failover_hide_primary_device(DeviceListener *listener,
33173314
return false;
33183315
}
33193316

3317+
if (n->primary_opts) {
3318+
error_setg(errp, "Cannot attach more than one primary device to '%s'",
3319+
n->netclient_name);
3320+
return false;
3321+
}
3322+
3323+
/*
3324+
* Having a weak reference here should be okay because a device can't be
3325+
* deleted while it's hidden. This will be replaced soon with a QDict that
3326+
* has a clearer ownership model.
3327+
*/
3328+
n->primary_opts = device_opts;
3329+
33203330
/* failover_primary_hidden is set during feature negotiation */
33213331
return qatomic_read(&n->failover_primary_hidden);
33223332
}

include/hw/virtio/virtio-net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct VirtIONet {
209209
bool failover_primary_hidden;
210210
bool failover;
211211
DeviceListener primary_listener;
212+
QemuOpts *primary_opts;
212213
Notifier migration_state;
213214
VirtioNetRssData rss_data;
214215
struct NetRxPkt *rx_pkt;

0 commit comments

Comments
 (0)