Description of problem: When running the mirror job, nearly all permissions on the source blockdev node are lifted (except for the WRITE permission). Depending on the image format used, this may lead to the image file becoming accessible to concurrent qemu instances, even though it should not be. Specifically for raw images, all locks (but the WRITE permission lock) are lifted. Furthermore, if the mirror job is canceled, it assumes it can just take back the permissions it lifted before, which may not be possible. Then, qemu will crash. Version-Release number of selected component (if applicable): qemu-kvm-5.2.0-14.module+el8.4.0+10425+ad586fa5 How reproducible: Always Steps to Reproduce: $ qemu-img create -f raw src.img 64M Formatting 'src.img', fmt=raw size=67108864 $ qemu-img create -f raw tgt.img 64M Formatting 'tgt.img', fmt=raw size=67108864 $ qemu-system-x86_64 \ -blockdev file,node-name=source,filename=src.img \ -blockdev file,node-name=target,filename=tgt.img \ -device virtio-blk,drive=source \ -qmp stdio {"QMP": {"version": {"qemu": {"micro": 0, "minor": 2, "major": 5}, "package": "qemu-foo-bar"}, "capabilities": ["oob"]}} {"execute":"qmp_capabilities"} {"return": {}} {"execute":"blockdev-mirror","arguments":{"job-id":"mirror","device":"source","target":"target","sync":"full","filter-node-name":"mirror-top"}} {"timestamp": {"seconds": 1617956960, "microseconds": 810076}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}} {"timestamp": {"seconds": 1617956960, "microseconds": 810338}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}} {"return": {}} {"timestamp": {"seconds": 1617956960, "microseconds": 820371}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}} {"timestamp": {"seconds": 1617956960, "microseconds": 820490}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}} Then, in another shell: $ qemu-io -f raw src.img > Back to the QMP prompt: {"execute":"block-job-cancel","arguments":{"device":"mirror"}} {"return": {}} {"timestamp": {"seconds": 1617956981, "microseconds": 956370}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}} {"timestamp": {"seconds": 1617956981, "microseconds": 956463}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}} Unexpected error in raw_check_lock_bytes() at ../block/file-posix.c:908: qemu-system-x86_64: Failed to get shared "write" lock [1] 13754 IOT instruction (core dumped) x86_64-softmmu/qemu-system-x86_64 -blockdev -blockdev -device -qmp stdio Actual results: qemu-io can successfully open the image file while it is in use by the VM, and when canceling the mirror job, qemu crashes. Expected results: qemu-io should be prevented from opening the image file, and so canceling the mirror job should not crash qemu. I.e., the qemu-io invocation should return this: $ qemu-io -f raw src.img qemu-io: can't open device src.img: Failed to get "write" lock Is another process using the image [src.img]? Additional info: Fixed upstream in commit 53431b9086b2832ca1aeff0c55e186e9ed79bd11 (which is going to be part of qemu 6.0).
Test on qemu-kvm-6.0.0-25.module+el8.5.0+11890+8e7c3f51, don't hit this issue any more. Test Steps: 1.Create 20G src image #qemu-img create -f raw /home/src.img 20G 2.Start guest with qemu cmds: /usr/libexec/qemu-kvm \ -name 'avocado-vt-vm1' \ -sandbox on \ -machine q35,memory-backend=mem-machine_mem \ -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 30720 \ -object memory-backend-ram,size=30720M,id=mem-machine_mem \ -smp 10,maxcpus=10,cores=5,threads=1,dies=1,sockets=2 \ -cpu 'Cascadelake-Server-noTSX',+kvm_pv_unhalt \ -chardev socket,path=/tmp/monitor-qmpmonitor1-20210726-224623-wKtTHYii,server=on,wait=off,id=qmp_id_qmpmonitor1 \ -mon chardev=qmp_id_qmpmonitor1,mode=control \ -chardev socket,path=/tmp/monitor-catch_monitor-20210726-224623-wKtTHYii,server=on,wait=off,id=qmp_id_catch_monitor \ -mon chardev=qmp_id_catch_monitor,mode=control \ -device pvpanic,ioport=0x505,id=idrUTreX \ -chardev socket,path=/tmp/serial-serial0-20210726-224623-wKtTHYii,server=on,wait=off,id=chardev_serial0 \ -device isa-serial,id=serial0,chardev=chardev_serial0 \ -chardev socket,id=seabioslog_id_20210726-224623-wKtTHYii,path=/tmp/seabios-20210726-224623-wKtTHYii,server=on,wait=off \ -device isa-debugcon,chardev=seabioslog_id_20210726-224623-wKtTHYii,iobase=0x402 \ -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,auto-read-only=on,discard=unmap,aio=threads,filename=/home/src.img,cache.direct=on,cache.no-flush=off \ -blockdev node-name=drive_image1,driver=raw,read-only=off,cache.direct=on,cache.no-flush=off,file=file_image1 \ -device scsi-hd,id=image1,drive=drive_image1,write-cache=on \ -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:6b:6a:ee:c1:06,id=idL1rFoB,netdev=idW45Tup,bus=pcie-root-port-3,addr=0x0 \ -netdev tap,id=idW45Tup,vhost=on \ -vnc :0 \ -rtc base=utc,clock=host,driftfix=slew \ -boot menu=off,order=cdn,once=c,strict=off \ -enable-kvm \ -device pcie-root-port,id=pcie_extra_root_port_0,multifunction=on,bus=pcie.0,addr=0x3,chassis=5 \ -monitor stdio \ 3.Create target node. {'execute':'blockdev-create','arguments':{'options': {'driver':'file','filename':'/root/sn1','size':21474836480},'job-id':'job1'}} {"timestamp": {"seconds": 1627442242, "microseconds": 347370}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} {"timestamp": {"seconds": 1627442242, "microseconds": 347435}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} {"return": {}} {"timestamp": {"seconds": 1627442242, "microseconds": 348295}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} {"timestamp": {"seconds": 1627442242, "microseconds": 348337}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} {"timestamp": {"seconds": 1627442242, "microseconds": 348362}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} {'execute':'blockdev-add','arguments':{'driver':'file','node-name':'drive_sn1','filename':'/root/sn1'}} {"return": {}} 4.Do mirror from src to target {"execute": "blockdev-mirror", "arguments": {"sync": "full", "device": "drive_image1", "target": "drive_sn1", "job-id": "j1"}} {"timestamp": {"seconds": 1627442316, "microseconds": 565203}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "j1"}} {"timestamp": {"seconds": 1627442316, "microseconds": 565280}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "j1"}} {"return": {}} {"timestamp": {"seconds": 1627442316, "microseconds": 585744}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "j1"}} {"timestamp": {"seconds": 1627442316, "microseconds": 585787}, "event": "BLOCK_JOB_READY", "data": {"device": "j1", "len": 21474836480, "offset": 21474836480, "speed": 0, "type": "mirror"}} 5.Qemu-io src image #qemu-io -f raw /home/src.img qemu-io: can't open device /home/src.img: Failed to get "write" lock Is another process using the image [/home/src.img]? Hi, Max Please help to check the test result. If ok, I will move it to AV and set bug's status to "Closed->CURRENTRELEASE". Thanks, Aliang
Hi, I’m a bit confused myself. Well, we definitely need an AV BZ, and what I wrote (also the “going to be part of qemu 6.0” part) clearly seems to indicate that I intended this as an AV BZ. However, the bug exists in non-AV 8.5.0, too... So I guess we should move this BZ here to AV and then clone it for non-AV. Max
(In reply to aihua liang from comment #3) > Hi, Max > Please help to check the test result. If ok, I will move it to AV and set > bug's status to "Closed->CURRENTRELEASE". Sorry, forgot to say: Yes, the test result looks good, thanks. Max
(In reply to Max Reitz from comment #4) > Hi, > > I’m a bit confused myself. Well, we definitely need an AV BZ, and what I > wrote (also the “going to be part of qemu 6.0” part) clearly seems to > indicate that I intended this as an AV BZ. > > However, the bug exists in non-AV 8.5.0, too... So I guess we should move > this BZ here to AV and then clone it for non-AV. > > Max Hi, Max Block jobs only be tested on AV. And in non-AV, block jobs are in black list. So we don't need to clone it for non-AV. BR, Aliang
(In reply to aihua liang from comment #6) > Hi, Max > > Block jobs only be tested on AV. > And in non-AV, block jobs are in black list. > So we don't need to clone it for non-AV. Oh, what a nice surprise. :) Thanks for the info! Max
As comment3, set bug's status to "Verified".
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:av 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-2021:4684