Bug 2168247

Summary: discard_granularity must be a multiple of logical_block_size
Product: Red Hat Enterprise Linux 9 Reporter: Jiri Kortus <jikortus>
Component: libvirtAssignee: Virtualization Maintenance <virt-maint>
libvirt sub component: Storage QA Contact: Virtualization Bugs <virt-bugs>
Status: CLOSED NOTABUG Docs Contact:
Severity: unspecified    
Priority: unspecified CC: pkrempa, vgoyal, virt-maint
Version: 9.1   
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-02-08 22:20:15 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:

Description Jiri Kortus 2023-02-08 15:00:47 UTC
Description of problem:
After changing logical and physical sector size of a disk in a libvirt VM to 4096 bytes, the VM start failed with the following error:

libvirtd[25346]: internal error: qemu unexpectedly closed the monitor: 2023-02-08T10:39:41.704580Z qemu-kvm: -device {"driver":"ide-hd","bus":"ide.1","drive":"libvirt-1-format","id":"sata0-0-1","logical_block_size":4096,"physical_block_size":4096}: discard_granularity must be a multiple of logical_block_size

According to bug 2154127, the default value should be 4096, so a physical block of 4096 bytes is a multiple of discard_granularity value (*1).

Interestingly this didn't happen right after the first change of the value, but after a few additions/removals of a disk with a change of the physical sector value (related to investigation of bug 2168245), with some RHEL installations in between, so unfortunately I don't have a 100% reproducer.

The whole qemu-kvm command used by libvirt was:
/usr/libexec/qemu-kvm -name guest=rhel9,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-37-rhel9/master-key.aes"} -machine pc-q35-rhel9.0.0,usb=off,vmport=off,dump-guest-core=off,memory-backend=pc.ram -accel kvm -cpu Cascadelake-Server,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,umip=on,pku=on,md-clear=on,stibp=on,arch-capabilities=on,xsaves=on,ibpb=on,ibrs=on,amd-stibp=on,amd-ssbd=on,rdctl-no=on,ibrs-all=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,tsx-ctrl=on,hle=off,rtm=off -m 4096 -object {"qom-type":"memory-backend-ram","id":"pc.ram","size":4294967296} -overcommit mem-lock=off -smp 8,sockets=8,cores=1,threads=1 -uuid 75805295-fa49-477c-8aed-b99926d3c4b1 -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=33,server=on,wait=off -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot menu=on,strict=on -device {"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"} -device {"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"} -device {"driver":"pcie-root-port","port":18,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x2"} -device {"driver":"pcie-root-port","port":19,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x2.0x3"} -device {"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"} -device {"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"} -device {"driver":"pcie-root-port","port":22,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x2.0x6"} -device {"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"} -device {"driver":"virtio-scsi-pci","id":"scsi0","bus":"pci.4","addr":"0x0"} -device {"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"} -blockdev {"driver":"file","filename":"/var/lib/libvirt/images/RHEL-9.2.0-20230119.t.4-x86_64-boot.iso","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-2-format","read-only":true,"driver":"raw","file":"libvirt-2-storage"} -device {"driver":"ide-cd","bus":"ide.0","drive":"libvirt-2-format","id":"sata0-0-0","bootindex":1} -blockdev {"driver":"file","filename":"/var/lib/libvirt/images/rhel9.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage","backing":null} -device {"driver":"ide-hd","bus":"ide.1","drive":"libvirt-1-format","id":"sata0-0-1","logical_block_size":4096,"physical_block_size":4096} -netdev tap,fd=34,vhost=on,vhostfd=36,id=hostnet0 -device {"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:1e:e7:e3","bus":"pci.1","addr":"0x0"} -chardev pty,id=charserial0 -device {"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0} -chardev socket,id=charchannel0,fd=32,server=on,wait=off -device {"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel0","id":"channel0","name":"org.qemu.guest_agent.0"} -device {"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"} -audiodev {"id":"audio1","driver":"none"} -vnc 127.0.0.1:0,audiodev=audio1 -device {"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pcie.0","addr":"0x1"} -device {"driver":"ich9-intel-hda","id":"sound0","bus":"pcie.0","addr":"0x1b"} -device {"driver":"hda-duplex","id":"sound0-codec0","bus":"sound0.0","cad":0,"audiodev":"audio1"} -device {"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"} -object {"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"} -device {"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"} -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on

Version-Release number of selected component (if applicable):
qemu-kvm-7.0.0-13.el9.x86_64

How reproducible:
Always?

Steps to Reproduce:
1. Prepare a VM with one disk (I just used virt-manager to do so) and a CD-ROM drive containing a RHEL ISO.
2. Change physical and logical sector size of the disk to 4096 (virsh edit --domain <vm_name>, insert <blockio logical_block_size='4096' physical_block_size='4096'/> into <disk>).
3. Complete system installation.
4. Power-cycle the VM and if it starts fine, power it off and repeat the steps again.

Actual results:
Start of the VM fails due to disk's physical_block_size value allegedly not being a multiple of discard_granularity value.

Expected results:
The VM starts fine.

Additional info:
When this error occurred, I wasn't able to use the machine again with a disk with 4K sector size. Removing the disk altogether (including the image) and recreating a new one with 4K sector size didn't work for me and the VM couldn't still start. The only solution was to remove the whole machine and create a new one with the same configuration. Restarting libvirtd didn't help either.

Comment 1 Peter Krempa 2023-02-08 15:15:15 UTC
You didn't attach your VM xml which is what we usually want for bugs reported against libvirt, as that is our primary configuration.

Luckily based on the generated commandline I see that your configuration uses an emulated 'IDE' disk, which has a default discard granularity of '512'. In fact I'm not even sure whether IDE disk even supports 4k sector sizes in the first place. I'm fairly sure that you don't want to actually use emulated IDE disks as your main storage device but want to switch to something like virtio.

Comment 2 Peter Krempa 2023-02-08 15:24:24 UTC
So for IDE disks it will not be possible:

Instantiation of a ide disks has the following logic:

    if (dev->conf.discard_granularity == -1) {
        dev->conf.discard_granularity = 512;
    } else if (dev->conf.discard_granularity &&
               dev->conf.discard_granularity != 512) {
        error_setg(errp, "discard_granularity must be 512 for ide");
        return;
    }


Later on when a block backend is created the following logic is applied:

    if (conf->discard_granularity != -1 &&
        !QEMU_IS_ALIGNED(conf->discard_granularity,
                         conf->logical_block_size)) {
        error_setg(errp, "discard_granularity must be "
                   "a multiple of logical_block_size");
        return false;

So this implies that 4k blocks can't be used in qemu. 

We can either move this bug to qemu, but I don't think there will be much to do.

Or you can use a different and more performat disk frontend which you most likely intended to do in the first place, just that virt-manager picks IDE as default.

Comment 3 Jiri Kortus 2023-02-08 15:46:04 UTC
Thank you for a quick response. That makes sense and most probably I just didn't pay attention to the type of the new disk device created when adding storage to the VM.

I had a look at the configuration again and the disk reports as SATA (but I can't tell for sure if this couldn't change due to some fiddling with the machine since I collected the data for the bug report); the VM start fails in the same way. In a different VM (RHEL-8), a new storage device defaults to VirtIO, which seems to not suffer from this issue (i. e. apparently uses bigger discard_granularity value).

In such a case I think there isn't anything that could be solved here, so I reckon we may close the bug.

Comment 4 Vivek Goyal 2023-02-08 22:20:15 UTC
Based on comment #3 closing this bug.