@@ -46,6 +46,7 @@
#include "qmp-commands.h"
#include "trace.h"
#include "sysemu/arch_init.h"
+#include "monitor/qdev.h"
static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none",
@@ -231,6 +232,15 @@ static void create_implicit_virtio_device(const char *driveid,
if (devaddr) {
qemu_opt_set(devopts, "addr", devaddr, &error_abort);
}
+
+ /* We're called after vl.c has processed the -device options,
+ * so we need to create the device ourselves now.
+ */
+ DeviceState *dev = qdev_device_add(devopts);
+ if (!dev) {
+ exit(1);
+ }
+ object_unref(OBJECT(dev));
}
bool drive_check_orphaned(void)
@@ -245,6 +255,14 @@ bool drive_check_orphaned(void)
/* Unless this is a default drive, this may be an oversight. */
if (!blk_get_attached_dev(blk) && !dinfo->is_default &&
dinfo->type != IF_NONE) {
+ if (dinfo->type == IF_VIRTIO) {
+ /* An orphaned virtio drive might be waiting for us to
+ * create the implicit device for it.
+ */
+ create_implicit_virtio_device(blk_name(blk), dinfo->devaddr);
+ continue;
+ }
+
fprintf(stderr, "Warning: Orphaned drive without device: "
"id=%s,file=%s,if=%s,bus=%d,unit=%d\n",
blk_name(blk), blk_bs(blk)->filename, if_name[dinfo->type],
@@ -949,10 +967,6 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
goto fail;
}
- if (type == IF_VIRTIO) {
- create_implicit_virtio_device(qdict_get_str(bs_opts, "id"), devaddr);
- }
-
filename = qemu_opt_get(legacy_opts, "file");
/* Check werror/rerror compatibility with if=... */
If a user requests an IF_VIRTIO drive on the command line, don't create the implicit PCI virtio device immediately, but wait until the rest of the command line has been processed and only create the device if the drive would otherwise be orphaned. This means that if the user said drive,id=something,... -device drive=something,..,. we'll allow the drive to be connected to the user's specified device rather than stealing it to connect to the implicit virtio device. This change does reorder device creation (which will mean a migration break, and guest visible changes like which PCI slot implicitly created devices appear in). We can do this because no machine currently specifies a block_default_type of IF_VIRTIO except for the S390 machines, and those machines do not currently support cross-version migration anyway. Although at first glance it looks like this commit is changing the behaviour for hotplugged devices, it is not: although hotplugged devices used to call the code to create an implicit virtio device, this had no effect because the code in vl.c to create devices from the devopts list had already run once and would not be run again. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- blockdev.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)