Skip to content

Commit

Permalink
failover: fix a regression introduced by JSON'ification of -device
Browse files Browse the repository at this point in the history
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: 259a10d ("virtio-net: Store failover primary opts pointer locally")
Cc: [email protected]
Signed-off-by: Laurent Vivier <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
Reviewed-by: Kevin Wolf <[email protected]>
Reviewed-by: Kevin Wolf <[email protected]>
  • Loading branch information
vivier authored and mstsirkin committed Oct 20, 2021
1 parent a1ed9ef commit 7fe7791
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions hw/net/virtio-net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 7fe7791

Please sign in to comment.