diff mbox series

blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom

Message ID 20221201134227.1983-1-luzhipeng@cestc.cn
State New
Headers show
Series blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom | expand

Commit Message

Zhipeng Lu Dec. 1, 2022, 1:42 p.m. UTC
From: zhipeng Lu <luzhipeng@cestc.cn>

The drive interface supports media=cdrom so that the usb cdrom
can be emulated as cdrom in qemu, but libvirt deprived the drive
interface, so media=cdrom is added to the blockdev interface to
support usb cdrom emulated as cdrom

Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>
---
 block.c                                     | 11 ++++++++++-
 block/block-backend.c                       | 18 ++++++++++++++++++
 hw/core/qdev-properties-system.c            |  3 +++
 hw/scsi/scsi-bus.c                          |  4 +++-
 include/block/block_int-common.h            |  1 +
 include/sysemu/block-backend-global-state.h |  2 ++
 6 files changed, 37 insertions(+), 2 deletions(-)

Comments

Markus Armbruster Dec. 1, 2022, 3:35 p.m. UTC | #1
luzhipeng <luzhipeng@cestc.cn> writes:

> From: zhipeng Lu <luzhipeng@cestc.cn>
>
> The drive interface supports media=cdrom so that the usb cdrom
> can be emulated as cdrom in qemu, but libvirt deprived the drive
> interface, so media=cdrom is added to the blockdev interface to
> support usb cdrom emulated as cdrom
>
> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>

What problem are you trying to solve?
Zhipeng Lu Dec. 2, 2022, 2:26 a.m. UTC | #2
libvirt issue: https://gitlab.com/libvirt/libvirt/-/issues/261

1、start vm with usb cdrom
<disk type="file" device="cdrom">
   <driver name="qemu" type="raw" discard="unmap"/>
   <source file="/tmp/cdrom"/>
   <target dev="sda" bus="usb"/>
   <readonly/>
   <address type="usb" bus="0" port="1"/>
</disk>

2、 get qemu cmdline


qemu     ... -blockdev 
{"driver":"file","filename":"/tmp/cdrom","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} 
-blockdev 
{"node-name":"libvirt-1-format","read-only":true,"discard":"unmap","driver":"raw","file":"libvirt-1-storage"} 
-device 
{"driver":"usb-storage","bus":"usb.0","port":"1","drive":"libvirt-1-format","id":"usb-disk0","removable":false}
3、 in vm

NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda             8:0    0  100M  1 disk
vda           252:0    0   10G  0 disk
├─vda1        252:1    0    1G  0 part /boot
└─vda2        252:2    0    9G  0 part
   ├─rhel-root 253:0    0    8G  0 lvm  /
   └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
lshw -short|grep cdrom -i
No cdrom.

My patch is to solve this problem, usb cdrom emulated as cdrom.



在 2022/12/1 23:35, Markus Armbruster 写道:
> luzhipeng <luzhipeng@cestc.cn> writes:
> 
>> From: zhipeng Lu <luzhipeng@cestc.cn>
>>
>> The drive interface supports media=cdrom so that the usb cdrom
>> can be emulated as cdrom in qemu, but libvirt deprived the drive
>> interface, so media=cdrom is added to the blockdev interface to
>> support usb cdrom emulated as cdrom
>>
>> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>
> 
> What problem are you trying to solve?
> 
> 
>
Paolo Bonzini Dec. 2, 2022, 9:40 a.m. UTC | #3
On 12/2/22 03:26, Zhipeng Lu wrote:
> NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
> sda             8:0    0  100M  1 disk
> vda           252:0    0   10G  0 disk
> ├─vda1        252:1    0    1G  0 part /boot
> └─vda2        252:2    0    9G  0 part
>    ├─rhel-root 253:0    0    8G  0 lvm  /
>    └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
> lshw -short|grep cdrom -i
> No cdrom.
> 
> My patch is to solve this problem, usb cdrom emulated as cdrom.

This is a libvirt bug, it should use usb-bot instead of usb-storage 
together with -blockdev.  Then it can add a scsi-cd device below usb-bot.

Paolo

> 
> 
> 在 2022/12/1 23:35, Markus Armbruster 写道:
>> luzhipeng <luzhipeng@cestc.cn> writes:
>>
>>> From: zhipeng Lu <luzhipeng@cestc.cn>
>>>
>>> The drive interface supports media=cdrom so that the usb cdrom
>>> can be emulated as cdrom in qemu, but libvirt deprived the drive
>>> interface, so media=cdrom is added to the blockdev interface to
>>> support usb cdrom emulated as cdrom
>>>
>>> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>
>>
>> What problem are you trying to solve?
>>
>>
>>
> 
> 
>
Zhipeng Lu Dec. 3, 2022, 12:51 p.m. UTC | #4
Could you give the detail qemu cmdline about usb-bot?

在 2022/12/2 17:40, Paolo Bonzini 写道:
> On 12/2/22 03:26, Zhipeng Lu wrote:
>> NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
>> sda             8:0    0  100M  1 disk
>> vda           252:0    0   10G  0 disk
>> ├─vda1        252:1    0    1G  0 part /boot
>> └─vda2        252:2    0    9G  0 part
>>    ├─rhel-root 253:0    0    8G  0 lvm  /
>>    └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
>> lshw -short|grep cdrom -i
>> No cdrom.
>>
>> My patch is to solve this problem, usb cdrom emulated as cdrom.
> 
> This is a libvirt bug, it should use usb-bot instead of usb-storage 
> together with -blockdev.  Then it can add a scsi-cd device below usb-bot.
> 
> Paolo
> 
>>
>>
>> 在 2022/12/1 23:35, Markus Armbruster 写道:
>>> luzhipeng <luzhipeng@cestc.cn> writes:
>>>
>>>> From: zhipeng Lu <luzhipeng@cestc.cn>
>>>>
>>>> The drive interface supports media=cdrom so that the usb cdrom
>>>> can be emulated as cdrom in qemu, but libvirt deprived the drive
>>>> interface, so media=cdrom is added to the blockdev interface to
>>>> support usb cdrom emulated as cdrom
>>>>
>>>> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>
>>>
>>> What problem are you trying to solve?
>>>
>>>
>>>
>>
>>
>>
> 
> 
>
Paolo Bonzini Dec. 7, 2022, 8:39 a.m. UTC | #5
It should be like this:

-device usb-bot,id=bot0
-device scsi-{cd,hd},bus=bot0.0,drive=drive0

Libvirt has the code to generate the options for SCSI controllers, but
usb-bot only allows one disk attached to it so it's easier to make it a
<drive> element.

Paolo

Il sab 3 dic 2022, 13:52 Zhipeng Lu <luzhipeng@cestc.cn> ha scritto:

> Could you give the detail qemu cmdline about usb-bot?
>
> 在 2022/12/2 17:40, Paolo Bonzini 写道:
> > On 12/2/22 03:26, Zhipeng Lu wrote:
> >> NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
> >> sda             8:0    0  100M  1 disk
> >> vda           252:0    0   10G  0 disk
> >> ├─vda1        252:1    0    1G  0 part /boot
> >> └─vda2        252:2    0    9G  0 part
> >>    ├─rhel-root 253:0    0    8G  0 lvm  /
> >>    └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
> >> lshw -short|grep cdrom -i
> >> No cdrom.
> >>
> >> My patch is to solve this problem, usb cdrom emulated as cdrom.
> >
> > This is a libvirt bug, it should use usb-bot instead of usb-storage
> > together with -blockdev.  Then it can add a scsi-cd device below usb-bot.
> >
> > Paolo
> >
> >>
> >>
> >> 在 2022/12/1 23:35, Markus Armbruster 写道:
> >>> luzhipeng <luzhipeng@cestc.cn> writes:
> >>>
> >>>> From: zhipeng Lu <luzhipeng@cestc.cn>
> >>>>
> >>>> The drive interface supports media=cdrom so that the usb cdrom
> >>>> can be emulated as cdrom in qemu, but libvirt deprived the drive
> >>>> interface, so media=cdrom is added to the blockdev interface to
> >>>> support usb cdrom emulated as cdrom
> >>>>
> >>>> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn>
> >>>
> >>> What problem are you trying to solve?
> >>>
> >>>
> >>>
> >>
> >>
> >>
> >
> >
> >
>
>
>
Zhipeng Lu Dec. 9, 2022, 2:28 a.m. UTC | #6
Thanks.

  -device usb-bot,id=bot0
  -device scsi-{cd,hd},bus=bot0.0,drive=drive0

Qemu implements virtio scsi to emulate scsi controller, but if the 
virtual machine(for example windows guest os) don't install the virtio 
scsi driver, it don't work
i need the function: emulate cdrom in guest, support hotplug and unplug, 
not  depend on virtio driver

have a better idea?

在 2022/12/7 16:39, Paolo Bonzini 写道:
> It should be like this:
> 
> -device usb-bot,id=bot0
> -device scsi-{cd,hd},bus=bot0.0,drive=drive0
> 
> Libvirt has the code to generate the options for SCSI controllers, but 
> usb-bot only allows one disk attached to it so it's easier to make it a 
> <drive> element.
> 
> Paolo
> 
> Il sab 3 dic 2022, 13:52 Zhipeng Lu <luzhipeng@cestc.cn 
> <mailto:luzhipeng@cestc.cn>> ha scritto:
> 
>     Could you give the detail qemu cmdline about usb-bot?
> 
>     在 2022/12/2 17:40, Paolo Bonzini 写道:
>      > On 12/2/22 03:26, Zhipeng Lu wrote:
>      >> NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
>      >> sda             8:0    0  100M  1 disk
>      >> vda           252:0    0   10G  0 disk
>      >> ├─vda1        252:1    0    1G  0 part /boot
>      >> └─vda2        252:2    0    9G  0 part
>      >>    ├─rhel-root 253:0    0    8G  0 lvm  /
>      >>    └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
>      >> lshw -short|grep cdrom -i
>      >> No cdrom.
>      >>
>      >> My patch is to solve this problem, usb cdrom emulated as cdrom.
>      >
>      > This is a libvirt bug, it should use usb-bot instead of usb-storage
>      > together with -blockdev.  Then it can add a scsi-cd device below
>     usb-bot.
>      >
>      > Paolo
>      >
>      >>
>      >>
>      >> 在 2022/12/1 23:35, Markus Armbruster 写道:
>      >>> luzhipeng <luzhipeng@cestc.cn <mailto:luzhipeng@cestc.cn>> writes:
>      >>>
>      >>>> From: zhipeng Lu <luzhipeng@cestc.cn <mailto:luzhipeng@cestc.cn>>
>      >>>>
>      >>>> The drive interface supports media=cdrom so that the usb cdrom
>      >>>> can be emulated as cdrom in qemu, but libvirt deprived the drive
>      >>>> interface, so media=cdrom is added to the blockdev interface to
>      >>>> support usb cdrom emulated as cdrom
>      >>>>
>      >>>> Signed-off-by: zhipeng Lu <luzhipeng@cestc.cn
>     <mailto:luzhipeng@cestc.cn>>
>      >>>
>      >>> What problem are you trying to solve?
>      >>>
>      >>>
>      >>>
>      >>
>      >>
>      >>
>      >
>      >
>      >
> 
>
Paolo Bonzini Dec. 9, 2022, 8:57 a.m. UTC | #7
On 12/9/22 03:28, Zhipeng Lu wrote:
> Thanks.
> 
>   -device usb-bot,id=bot0
>   -device scsi-{cd,hd},bus=bot0.0,drive=drive0
> 
> Qemu implements virtio scsi to emulate scsi controller, but if the 
> virtual machine(for example windows guest os) don't install the virtio 
> scsi driver, it don't work
> i need the function: emulate cdrom in guest, support hotplug and unplug, 
> not  depend on virtio driver

usb-bot *is* a SCSI controller and it does not require drivers in the 
guest.  It is not very high-performance, but as you say it has hotplug 
functionality via USB.

Paolo
diff mbox series

Patch

diff --git a/block.c b/block.c
index a18f052374..d194e3039e 100644
--- a/block.c
+++ b/block.c
@@ -3787,6 +3787,7 @@  static BlockDriverState *bdrv_open_inherit(const char *filename,
     Error *local_err = NULL;
     QDict *snapshot_options = NULL;
     int snapshot_flags = 0;
+    int media = 0;
 
     assert(!child_class || !flags);
     assert(!child_class == !parent);
@@ -3906,6 +3907,12 @@  static BlockDriverState *bdrv_open_inherit(const char *filename,
         qdict_del(bs->options, "backing");
         qdict_del(options, "backing");
     }
+    if (!g_strcmp0(qdict_get_try_str(options, "media"), "cdrom")) {
+        media = 1;
+        qdict_del(bs->explicit_options, "media");
+        qdict_del(bs->options, "media");
+        qdict_del(options, "media");
+    }
 
     /* Open image file without format layer. This BlockBackend is only used for
      * probing, the block drivers will do their own bdrv_open_child() for the
@@ -4033,7 +4040,9 @@  static BlockDriverState *bdrv_open_inherit(const char *filename,
         bdrv_unref(bs);
         bs = snapshot_bs;
     }
-
+    if (bs && media) {
+        bs->media_cd = true;
+    }
     return bs;
 
 fail:
diff --git a/block/block-backend.c b/block/block-backend.c
index d98a96ff37..1760079a67 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -72,6 +72,7 @@  struct BlockBackend {
     uint64_t perm;
     uint64_t shared_perm;
     bool disable_perm;
+    bool media_cd;
 
     bool allow_aio_context_change;
     bool allow_write_beyond_eof;
@@ -2634,3 +2635,20 @@  int blk_make_empty(BlockBackend *blk, Error **errp)
 
     return bdrv_make_empty(blk->root, errp);
 }
+
+bool blk_is_cdrom(BlockBackend *blk)
+{
+    if (!blk) {
+        return false;
+    }
+    return blk->media_cd;
+
+}
+
+void blk_set_cdrom(BlockBackend *blk)
+{
+    if (!blk) {
+        return ;
+    }
+    blk->media_cd = true;
+}
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index a91f60567a..99df29ccb8 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -149,6 +149,9 @@  static void set_drive_helper(Object *obj, Visitor *v, const char *name,
             if (ret < 0) {
                 goto fail;
             }
+            if (bs->media_cd) {
+                blk_set_cdrom(blk);
+            }
         }
     }
     if (!blk) {
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index ceceafb2cd..bc2bbdc823 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -321,7 +321,9 @@  SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
         driver = "scsi-generic";
     } else {
         dinfo = blk_legacy_dinfo(blk);
-        if (dinfo && dinfo->media_cd) {
+        if ((dinfo && dinfo->media_cd)) {
+            driver = "scsi-cd";
+        } else if (blk_is_cdrom(blk)) {
             driver = "scsi-cd";
         } else {
             driver = "scsi-hd";
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 31ae91e56e..04a814ab1b 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -1023,6 +1023,7 @@  struct BlockDriverState {
     bool probed;    /* if true, format was probed rather than specified */
     bool force_share; /* if true, always allow all shared permissions */
     bool implicit;  /* if true, this filter node was automatically inserted */
+    bool media_cd;
 
     BlockDriver *drv; /* NULL means no media */
     void *opaque;
diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
index 6858e39cb6..108dfad283 100644
--- a/include/sysemu/block-backend-global-state.h
+++ b/include/sysemu/block-backend-global-state.h
@@ -71,6 +71,8 @@  void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
                       BlockdevOnError on_write_error);
 bool blk_supports_write_perm(BlockBackend *blk);
 bool blk_is_sg(BlockBackend *blk);
+bool blk_is_cdrom(BlockBackend *blk);
+void blk_set_cdrom(BlockBackend *blk);
 void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
 int blk_get_flags(BlockBackend *blk);
 bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);