Bug 1828252
| Summary: | auto-read-only doesn't work with read-only logical volumes | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux Advanced Virtualization | Reporter: | Peter Krempa <pkrempa> |
| Component: | qemu-kvm | Assignee: | Kevin Wolf <kwolf> |
| qemu-kvm sub component: | Storage | QA Contact: | qing.wang <qinwang> |
| Status: | CLOSED ERRATA | Docs Contact: | |
| Severity: | medium | ||
| Priority: | medium | CC: | aliang, coli, ddepaula, jinzhao, juzhang, qinwang, virt-maint |
| Version: | 8.2 | Keywords: | Regression, Triaged |
| Target Milestone: | rc | Flags: | pm-rhel:
mirror+
|
| Target Release: | 8.3 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | qemu-kvm-5.1.0-2.module+el8.3.0+7652+b30e6901 | Doc Type: | If docs needed, set a value |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2020-11-17 17:48:27 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
Reproduce on
4.18.0-193.el8.x86_64
qemu-kvm-core-4.2.0-17.module+el8.2.0+6141+0f540f16.x86_64
1.create lvm
lvname=/dev/vg_scsi_debug/ro-test
lvremove -f ${lvname}
vgremove -f vg_scsi_debug
modprobe -r scsi_debug; modprobe scsi_debug lbpu=1 lbpws=1 lbprz=0 dev_size_mb=512
devname=`lsscsi |grep scsi|awk '{ print $6 }'`
echo "${devname}"
pvcreate ${devname}
vgcreate vg_scsi_debug ${devname}
lvcreate --size 128M --name ro-test --permission r vg_scsi_debug
2.boot vm:
/usr/libexec/qemu-kvm \
-name 'avocado-vt-vm1' \
-sandbox on \
-machine q35 \
-device pcie-root-port,id=pcie-root-port-0,multifunction=on,bus=pcie.0,addr=0x1,chassis=1 \
-device pcie-pci-bridge,id=pcie-pci-bridge-0,addr=0x0,bus=pcie-root-port-0 \
-nodefaults \
-device VGA,bus=pcie.0,addr=0x2 \
-m 2048 \
-device pcie-root-port,id=pcie-root-port-1,port=0x1,addr=0x1.0x1,bus=pcie.0,chassis=2 \
-device qemu-xhci,id=usb1,bus=pcie-root-port-1,addr=0x0 \
-device usb-tablet,id=usb-tablet1,bus=usb1.0,port=1 \
-device pcie-root-port,id=pcie-root-port-2,port=0x2,addr=0x1.0x2,bus=pcie.0,chassis=3 \
-device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pcie-root-port-2,addr=0x0 \
-blockdev node-name=file_image1,driver=file,aio=threads,filename=/home/kvm_autotest_root/images/rhel821-64-virtio-scsi.qcow2,cache.direct=on,cache.no-flush=off \
-blockdev node-name=drive_image1,driver=qcow2,cache.direct=on,cache.no-flush=off,file=file_image1 \
-device scsi-hd,id=image1,drive=drive_image1,write-cache=on \
\
-blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=${lvname},cache.direct=on,cache.no-flush=off,auto-read-only=on,discard=unmap \
-blockdev node-name=drive_stg1,driver=raw,cache.direct=on,cache.no-flush=off,file=file_stg1,discard=unmap,auto-read-only=on \
-device scsi-hd,id=stg1,drive=drive_stg1,scsi-id=12 \
\
-device pcie-root-port,id=pcie-root-port-3,port=0x3,addr=0x1.0x3,bus=pcie.0,chassis=4 \
-device virtio-net-pci,mac=9a:5b:4f:9b:c3:b0,id=idg2bFqS,netdev=ida2LQKm,bus=pcie-root-port-3,addr=0x0 \
-netdev tap,id=ida2LQKm,vhost=on \
-vnc :6 \
-qmp tcp:0:5956,server,nowait \
-rtc base=utc,clock=host,driftfix=slew \
-boot menu=off,order=cdn,once=c,strict=off \
-enable-kvm -monitor stdio \
-device pcie-root-port,id=pcie_extra_root_port_0,multifunction=on,bus=pcie.0,addr=0x3,chassis=5 \
-device virtio-serial-pci,disable-legacy=on,disable-modern=off,id=virtio-serial0 \
-chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=qga0,id=channel1,name=org.qemu.guest_agent.0 \
result:
qemu-kvm: -blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=/dev/vg_scsi_debug/ro-test,cache.direct=on,cache.no-flush=off,auto-read-only=on,discard=unmap: The device is not writable: Permission denied
BTW, it works with on with read-only command
/usr/libexec/qemu-kvm -blockdev '{"driver":"host_device","filename":"/dev/vg_scsi_debug/ro-test","node-name":"libvirt-3-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"read-only":true,"discard":"unmap"}'
Yes, read-only works, but unfortunately that will prevent libvirt from using blockjobs. hdev_open() has an explicit check whether the block device is read-only and this will fail. As commit da888d37 explains, this is because the file permissions of the device node and whether the block device is read-only are two independent properties. I guess we could move the check to whenever we first try to reopen the file-posix node read-write, though by that point it would be too late for a good error message without auto-read-only. Anyway, does this really affect the libvirt use case? I thought libvirt was more concerned with permissions than whether the device is read-only per se. If I test a writable LV for which I only have read permissions, QEMU correctly opens the file with auto-read-only (and I assume the same is true for SELinux permission, though I didn't test it). On the other hand, opening a read-only LV fails with auto-read-only, no matter whether or not I have the right file permissions. Not trying to discuss the problem away, it clearly seems that file-posix doesn't fully implement auto-read-only for all cases yet even though it should. Test Failed on
4.18.0-227.el8.x86_64
qemu-kvm-core-5.1.0-2.module+el8.3.0+7652+b30e6901.x86_64
seabios-1.14.0-1.module+el8.3.0+7638+07cf13d2.x86_64
Test step
1.create read only lvm
lvname=/dev/vg_scsi_debug/ro-test
lvremove -f ${lvname}
vgremove -f vg_scsi_debug
modprobe -r scsi_debug; modprobe scsi_debug lbpu=1 lbpws=1 lbprz=0 dev_size_mb=512
devname=`lsscsi |grep scsi|awk '{ print $6 }'`
echo "${devname}"
pvcreate ${devname}
vgcreate vg_scsi_debug ${devname}
lvcreate --size 128M --name ro-test --permission r vg_scsi_debug
2.boot vm with read-only lvm
/usr/libexec/qemu-kvm \
-name 'avocado-vt-vm1' \
-sandbox on \
-machine q35 \
-device pcie-root-port,id=pcie-root-port-0,multifunction=on,bus=pcie.0,addr=0x1,chassis=1 \
-device pcie-pci-bridge,id=pcie-pci-bridge-0,addr=0x0,bus=pcie-root-port-0 \
-nodefaults \
-device VGA,bus=pcie.0,addr=0x2 \
-m 2048 \
-device pcie-root-port,id=pcie-root-port-1,port=0x1,addr=0x1.0x1,bus=pcie.0,chassis=2 \
-device qemu-xhci,id=usb1,bus=pcie-root-port-1,addr=0x0 \
-device usb-tablet,id=usb-tablet1,bus=usb1.0,port=1 \
-device pcie-root-port,id=pcie-root-port-2,port=0x2,addr=0x1.0x2,bus=pcie.0,chassis=3 \
-device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pcie-root-port-2,addr=0x0 \
-blockdev node-name=file_image1,driver=file,aio=threads,filename=/home/kvm_autotest_root/images/rhel830-64-virtio-scsi.qcow2,cache.direct=on,cache.no-flush=off \
-blockdev node-name=drive_image1,driver=qcow2,cache.direct=on,cache.no-flush=off,file=file_image1 \
-device scsi-hd,id=image1,drive=drive_image1,write-cache=on \
\
-blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=${lvname},cache.direct=on,cache.no-flush=off,auto-read-only=on,discard=unmap \
-blockdev node-name=drive_stg1,driver=raw,cache.direct=on,cache.no-flush=off,file=file_stg1,discard=unmap,auto-read-only=on \
-device scsi-hd,id=stg1,drive=drive_stg1 \
\
-device pcie-root-port,id=pcie-root-port-3,port=0x3,addr=0x1.0x3,bus=pcie.0,chassis=4 \
-device virtio-net-pci,mac=9a:5b:4f:9b:c3:b0,id=idg2bFqS,netdev=ida2LQKm,bus=pcie-root-port-3,addr=0x0 \
-netdev tap,id=ida2LQKm,vhost=on \
-vnc :6 \
-qmp tcp:0:5956,server,nowait \
-rtc base=utc,clock=host,driftfix=slew \
-boot menu=off,order=cdn,once=c,strict=off \
-enable-kvm -monitor stdio \
-device pcie-root-port,id=pcie_extra_root_port_0,multifunction=on,bus=pcie.0,addr=0x3,chassis=5 \
-device virtio-serial-pci,disable-legacy=on,disable-modern=off,id=virtio-serial0 \
-chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=qga0,id=channel1,name=org.qemu.guest_agent.0 \
Actual result:
qemu-kvm: -device scsi-hd,id=stg1,drive=drive_stg1: The device is not writable: Permission denied
(In reply to qing.wang from comment #12) > Actual result: > qemu-kvm: -device scsi-hd,id=stg1,drive=drive_stg1: The device is not > writable: Permission denied This is expected. If auto-read-only makes QEMU fall back to read-only for the volume, you can't attach this volume to a read-write guest device. Compare the original error message in comment 0 with this one: Previously, -blockdev would fail, now it is only using the block device in -device for a read-write scsi-hd. If you don't use the block node in -device, or only for a read-only device (e.g. scsi-cd), you would get a failure previously and it should succeed now. It works on "auto-read-only=on,read-only=on" and for the device.
-blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=${lvname},cache.direct=on,cache.no-flush=off,auto-read-only=on,read-only=on,discard=unmap \
-blockdev node-name=drive_stg1,driver=raw,cache.direct=on,cache.no-flush=off,file=file_stg1,discard=unmap,auto-read-only=on,read-only=on \
-device scsi-hd,id=stg1,drive=drive_stg1 \
or delete device scs-hd
-blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=${lvname},cache.direct=on,cache.no-flush=off,auto-read-only=on,discard=unmap \
-blockdev node-name=drive_stg1,driver=raw,cache.direct=on,cache.no-flush=off,file=file_stg1,discard=unmap,auto-read-only=on \
/usr/libexec/qemu-kvm \
-name 'avocado-vt-vm1' \
-sandbox on \
-machine q35 \
-device pcie-root-port,id=pcie-root-port-0,multifunction=on,bus=pcie.0,addr=0x1,chassis=1 \
-device pcie-pci-bridge,id=pcie-pci-bridge-0,addr=0x0,bus=pcie-root-port-0 \
-nodefaults \
-device VGA,bus=pcie.0,addr=0x2 \
-m 2048 \
-device pcie-root-port,id=pcie-root-port-1,port=0x1,addr=0x1.0x1,bus=pcie.0,chassis=2 \
-device qemu-xhci,id=usb1,bus=pcie-root-port-1,addr=0x0 \
-device usb-tablet,id=usb-tablet1,bus=usb1.0,port=1 \
-device pcie-root-port,id=pcie-root-port-2,port=0x2,addr=0x1.0x2,bus=pcie.0,chassis=3 \
-device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pcie-root-port-2,addr=0x0 \
-blockdev node-name=file_image1,driver=file,aio=threads,filename=/home/kvm_autotest_root/images/rhel830-64-virtio-scsi.qcow2,cache.direct=on,cache.no-flush=off \
-blockdev node-name=drive_image1,driver=qcow2,cache.direct=on,cache.no-flush=off,file=file_image1 \
-device scsi-hd,id=image1,drive=drive_image1,write-cache=on \
\
-blockdev node-name=file_stg1,driver=host_device,aio=threads,filename=${lvname},cache.direct=on,cache.no-flush=off,auto-read-only=on,read-only=on,discard=unmap \
-blockdev node-name=drive_stg1,driver=raw,cache.direct=on,cache.no-flush=off,file=file_stg1,discard=unmap,auto-read-only=on,read-only=on \
-device scsi-hd,id=stg1,drive=drive_stg1 \
\
-device pcie-root-port,id=pcie-root-port-3,port=0x3,addr=0x1.0x3,bus=pcie.0,chassis=4 \
-device virtio-net-pci,mac=9a:5b:4f:9b:c3:b0,id=idg2bFqS,netdev=ida2LQKm,bus=pcie-root-port-3,addr=0x0 \
-netdev tap,id=ida2LQKm,vhost=on \
-vnc :6 \
-qmp tcp:0:5956,server,nowait \
-rtc base=utc,clock=host,driftfix=slew \
-boot menu=off,order=cdn,once=c,strict=off \
-enable-kvm -monitor stdio \
-device pcie-root-port,id=pcie_extra_root_port_0,multifunction=on,bus=pcie.0,addr=0x3,chassis=5 \
-device virtio-serial-pci,disable-legacy=on,disable-modern=off,id=virtio-serial0 \
-chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=qga0,id=channel1,name=org.qemu.guest_agent.0 \
or remove
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (virt:8.3 bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:5137 |
Description of problem: 'auto-read-only' used on a 'host_device' backend doesn't properly set the node to read-only if the logical-volume itself is read-only. VM start then fails with the following error: qemu-system-x86_64: -blockdev {"driver":"host_device","filename":"/dev/angien/ro-test","node-name":"libvirt-3-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}: The device is not writable: Permission denied Version-Release number of selected component (if applicable): observed on current upstream How reproducible: always Steps to Reproduce: 1. Create read-only logical volume lvcreate --size 10M --name ro-test --permission r $VG 2. start qemu: qemu-system-x86_64 -blockdev '{"driver":"host_device","filename":"/dev/angien/ro-test","node-name":"libvirt-3-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}' Actual results: qemu-system-x86_64: -blockdev {"driver":"host_device","filename":"/dev/angien/ro-test","node-name":"libvirt-3-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}: The device is not writable: Permission denied Expected results: qemu starts Additional info: Note that while it may seem that in the above situation 'read-only' should be used but note that the logical volume may be a backing image for a qcow2 image and the user may turn the logical volume to read-write using lvchange. Using read-only would then prevent libvirt from doing blockjobs. See also: https://bugs.launchpad.net/qemu/+bug/1875139