From: Marc-André Lureau <marcandre.lur...@redhat.com>

When starting qemu, a block driver isn't associated with a device, so
no notification is emitted when the media is loaded.

The Spice block driver loads the media during migration. But at
that time, the device is already associated, however, we want to
avoid notification to the guest. Checking the runstate seems the
simplest way.

Signed-off-by: Marc-André Lureau <marcandre.lur...@gmail.com>
---
 block.c               |  4 +++-
 hw/block/fdc.c        |  8 +++++---
 hw/ide/core.c         | 12 +++++++-----
 hw/scsi/scsi-disk.c   | 11 +++++++----
 hw/sd/sd.c            |  6 +++++-
 include/block/block.h |  2 +-
 stubs/vm-stop.c       |  5 +++++
 7 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/block.c b/block.c
index ce2427b..fdbc7f9 100644
--- a/block.c
+++ b/block.c
@@ -1864,9 +1864,11 @@ static void bdrv_emit_qmp_eject_event(BlockDriverState 
*bs, bool ejected)
 
 static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
 {
+    bool notify = !runstate_check(RUN_STATE_INMIGRATE);
+
     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
         bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
-        bs->dev_ops->change_media_cb(bs->dev_opaque, load);
+        bs->dev_ops->change_media_cb(bs->dev_opaque, load, notify);
         if (tray_was_closed) {
             /* tray open */
             bdrv_emit_qmp_eject_event(bs, true);
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index c5a6c21..bb8cffb 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1984,11 +1984,13 @@ static void fdctrl_result_timer(void *opaque)
     }
 }
 
-static void fdctrl_change_cb(void *opaque, bool load)
+static void fdctrl_change_cb(void *opaque, bool load, bool notify)
 {
     FDrive *drive = opaque;
 
-    drive->media_changed = 1;
+    if (notify) {
+        drive->media_changed = 1;
+    }
     fd_revalidate(drive);
 }
 
@@ -2018,7 +2020,7 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error 
**errp)
         }
 
         fd_init(drive);
-        fdctrl_change_cb(drive, 0);
+        fdctrl_change_cb(drive, 0, false);
         if (drive->bs) {
             bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
         }
diff --git a/hw/ide/core.c b/hw/ide/core.c
index e1f4c33..18b2f85 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -882,7 +882,7 @@ static void ide_cfata_metadata_write(IDEState *s)
 }
 
 /* called when the inserted state of the media has changed */
-static void ide_cd_change_cb(void *opaque, bool load)
+static void ide_cd_change_cb(void *opaque, bool load, bool notify)
 {
     IDEState *s = opaque;
     uint64_t nb_sectors;
@@ -898,10 +898,12 @@ static void ide_cd_change_cb(void *opaque, bool load)
      * Then we set UNIT_ATTENTION, by which the guest will
      * detect a new CD in the drive.  See ide_atapi_cmd() for details.
      */
-    s->cdrom_changed = 1;
-    s->events.new_media = true;
-    s->events.eject_request = false;
-    ide_set_irq(s->bus);
+    if (notify) {
+        s->cdrom_changed = 1;
+        s->events.new_media = true;
+        s->events.eject_request = false;
+        ide_set_irq(s->bus);
+    }
 }
 
 static void ide_cd_eject_request_cb(void *opaque, bool force)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 74e6a14..87f2299 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2010,7 +2010,7 @@ static void scsi_disk_resize_cb(void *opaque)
     }
 }
 
-static void scsi_cd_change_media_cb(void *opaque, bool load)
+static void scsi_cd_change_media_cb(void *opaque, bool load, bool notify)
 {
     SCSIDiskState *s = opaque;
 
@@ -2024,11 +2024,14 @@ static void scsi_cd_change_media_cb(void *opaque, bool 
load)
      * media_changed governs the state machine used for unit attention
      * report.  media_event is used by GET EVENT STATUS NOTIFICATION.
      */
-    s->media_changed = load;
     s->tray_open = !load;
-    scsi_device_set_ua(&s->qdev, SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM));
-    s->media_event = true;
     s->eject_request = false;
+
+    if (notify) {
+        s->media_changed = load;
+        scsi_device_set_ua(&s->qdev, SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM));
+        s->media_event = true;
+    }
 }
 
 static void scsi_cd_eject_request_cb(void *opaque, bool force)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4502ad1..09f37be 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -439,10 +439,14 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
     sd->expecting_acmd = false;
 }
 
-static void sd_cardchange(void *opaque, bool load)
+static void sd_cardchange(void *opaque, bool load, bool notify)
 {
     SDState *sd = opaque;
 
+    if (!notify) {
+        return;
+    }
+
     qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv));
     if (bdrv_is_inserted(sd->bdrv)) {
         sd_reset(sd, sd->bdrv);
diff --git a/include/block/block.h b/include/block/block.h
index 3560deb..a5ccbb5 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -36,7 +36,7 @@ typedef struct BlockDevOps {
      * changes.  Sure would be useful if it did.
      * Device models with removable media must implement this callback.
      */
-    void (*change_media_cb)(void *opaque, bool load);
+    void (*change_media_cb)(void *opaque, bool load, bool notify);
     /*
      * Runs when an eject request is issued from the monitor, the tray
      * is closed, and the medium is locked.
diff --git a/stubs/vm-stop.c b/stubs/vm-stop.c
index f82c897..9c66002 100644
--- a/stubs/vm-stop.c
+++ b/stubs/vm-stop.c
@@ -5,3 +5,8 @@ int vm_stop(RunState state)
 {
     abort();
 }
+
+bool runstate_check(RunState state)
+{
+    return FALSE;
+}
-- 
1.8.3.1


Reply via email to