Message ID | 1453314561-10486-3-git-send-email-mreitz@redhat.com |
---|---|
State | New |
Headers | show |
On 01/20/2016 11:29 AM, Max Reitz wrote: > 'change' and related operations did not work when used on guest devices > featuring removable media but no actual tray, because > blk_dev_is_tray_open() always returned false for them and the > blockdev-{insert,remove}-medium commands required it to return true. > > Fix this by making blockdev-{insert,remove}-medium work on tray-less > devices. Also, blockdev-{open,close}-tray are now explicitly no-ops when > invoked on such devices, and blk_dev_change_media_cb() is instead > called by blockdev-{insert,remove}-medium (for tray-less devices only). > > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Cc: qemu-stable <qemu-stable@nongnu.org> > Signed-off-by: Max Reitz <mreitz@redhat.com> > --- > blockdev.c | 31 +++++++++++++++++++++++++++++-- > qapi/block-core.json | 3 +-- > 2 files changed, 30 insertions(+), 4 deletions(-) > Reviewed-by: Eric Blake <eblake@redhat.com>
On Wed 20 Jan 2016 07:29:19 PM CET, Max Reitz wrote: > @@ -2424,6 +2442,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device, > > blk_insert_bs(blk, bs); > > + if (!blk_dev_has_tray(blk)) { > + /* For tray-less devices, blockdev-close-tray is a no-op (or may not be > + * called at all); therefore, the medium needs to be pushed into the > + * slot here. > + * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load > + * value passed here (i.e. true). */ > + blk_dev_change_media_cb(blk, true); > + } > + > QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list); > } Any reason why you do this before updating bdrv_states ? If the device has a tray this would happen afterwards, in qmp_blockdev_close_tray(). Berto
On 22.01.2016 10:58, Alberto Garcia wrote: > On Wed 20 Jan 2016 07:29:19 PM CET, Max Reitz wrote: >> @@ -2424,6 +2442,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device, >> >> blk_insert_bs(blk, bs); >> >> + if (!blk_dev_has_tray(blk)) { >> + /* For tray-less devices, blockdev-close-tray is a no-op (or may not be >> + * called at all); therefore, the medium needs to be pushed into the >> + * slot here. >> + * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load >> + * value passed here (i.e. true). */ >> + blk_dev_change_media_cb(blk, true); >> + } >> + >> QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list); >> } > > Any reason why you do this before updating bdrv_states ? The reason is that I just moved it after blk_insert_bs(). But that's wrong, QTAILQ_INSERT_TAIL() should be paired with blk_insert_bs() without anything in between, thanks! (I don't think it changes anything in practice, but it still is wrong.) > If the device has a tray this would happen afterwards, in > qmp_blockdev_close_tray(). Well, tray devices are no longer really a good comparison, because in the opposite case (ejecting a medium), for them we open the tray and then eject the medium; however, for trayless devices we now eject the medium and only then "open the tray" (invoke blk_dev_change_media_cb()). Anyway, will fix, thanks. Max
diff --git a/blockdev.c b/blockdev.c index 1392fff..33d01cd 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2303,6 +2303,11 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force, return; } + if (!blk_dev_has_tray(blk)) { + /* Ignore this command on tray-less devices */ + return; + } + if (blk_dev_is_tray_open(blk)) { return; } @@ -2333,6 +2338,11 @@ void qmp_blockdev_close_tray(const char *device, Error **errp) return; } + if (!blk_dev_has_tray(blk)) { + /* Ignore this command on tray-less devices */ + return; + } + if (!blk_dev_is_tray_open(blk)) { return; } @@ -2362,7 +2372,7 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp) return; } - if (has_device && !blk_dev_is_tray_open(blk)) { + if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) { error_setg(errp, "Tray of device '%s' is not open", device); return; } @@ -2387,6 +2397,14 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp) blk_remove_bs(blk); + if (!blk_dev_has_tray(blk)) { + /* For tray-less devices, blockdev-open-tray is a no-op (or may not be + * called at all); therefore, the medium needs to be ejected here. + * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load + * value passed here (i.e. false). */ + blk_dev_change_media_cb(blk, false); + } + out: aio_context_release(aio_context); } @@ -2412,7 +2430,7 @@ static void qmp_blockdev_insert_anon_medium(const char *device, return; } - if (has_device && !blk_dev_is_tray_open(blk)) { + if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) { error_setg(errp, "Tray of device '%s' is not open", device); return; } @@ -2424,6 +2442,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device, blk_insert_bs(blk, bs); + if (!blk_dev_has_tray(blk)) { + /* For tray-less devices, blockdev-close-tray is a no-op (or may not be + * called at all); therefore, the medium needs to be pushed into the + * slot here. + * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load + * value passed here (i.e. true). */ + blk_dev_change_media_cb(blk, true); + } + QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list); } diff --git a/qapi/block-core.json b/qapi/block-core.json index 0a915ed..40239bf 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2098,8 +2098,7 @@ # respond to the eject request # - if the BlockBackend denoted by @device does not have a guest device attached # to it -# - if the guest device does not have an actual tray and is empty, for instance -# for floppy disk drives +# - if the guest device does not have an actual tray # # @device: block device name #
'change' and related operations did not work when used on guest devices featuring removable media but no actual tray, because blk_dev_is_tray_open() always returned false for them and the blockdev-{insert,remove}-medium commands required it to return true. Fix this by making blockdev-{insert,remove}-medium work on tray-less devices. Also, blockdev-{open,close}-tray are now explicitly no-ops when invoked on such devices, and blk_dev_change_media_cb() is instead called by blockdev-{insert,remove}-medium (for tray-less devices only). Reported-by: Peter Maydell <peter.maydell@linaro.org> Cc: qemu-stable <qemu-stable@nongnu.org> Signed-off-by: Max Reitz <mreitz@redhat.com> --- blockdev.c | 31 +++++++++++++++++++++++++++++-- qapi/block-core.json | 3 +-- 2 files changed, 30 insertions(+), 4 deletions(-)