Bug 1007815

Summary: fix WRITE SAME support
Product: Red Hat Enterprise Linux 7 Reporter: Paolo Bonzini <pbonzini>
Component: qemu-kvmAssignee: Paolo Bonzini <pbonzini>
Status: CLOSED CURRENTRELEASE QA Contact: Virtualization Bugs <virt-bugs>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.0CC: acathrow, hhuang, juzhang, pbonzini, sluo, virt-maint
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: qemu-kvm-1.5.3-31.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-13 10:09:23 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:
Bug Depends On:    
Bug Blocks: 1039557    

Description Paolo Bonzini 2013-09-13 11:29:53 UTC
WRITE SAME with the UNMAP bit set should _not_ unmap the sectors unless the written data matches the payload of the WRITE SAME command.

Testing:

1. Create a raw image back.raw and fill it with random data (dd if=/dev/urandom of=/dev/sda).
2. Create a qcow2 image test.qcow2, with back.raw as backing file, and fill it with zeros (dd if=/dev/zero of=/dev/sda).
3. Start a VM with test.qcow2 as a virtio-scsi disk, using the discard=on option for -drive.
4. Do "sg_write_same --unmap --num=16 --in=/dev/zero --xferlen=512 /dev/sdb".  Check that test.qcow2 still has zeroes at the beginning.
5. Do "sg_write_same --unmap --num=16 --in=/dev/urandom --xferlen=512 /dev/sdb".  Check that test.qcow2 does not have zeroes at the beginning.
6. Do "sg_write_same --unmap --num=16 --in=/dev/zero --xferlen=512 /dev/sdb".  Check that test.qcow2 still has zeroes at the beginning.
7. Start a VM with back.raw as a virtio-scsi disk, using the discard=on option for -drive, and repeat steps 4-6.

The disk image for testing can be very small (16 MB is enough).

Comment 3 Paolo Bonzini 2013-12-09 12:39:08 UTC
Testing steps:

1. Create a 1G raw image on an XFS file system

2. Start qemu with a command-line like the following:

x86_64-softmmu/qemu-system-x86_64 RHEL-6.4.img \
  -device virtio-scsi-pci \
  -drive if=none,id=data,file=/mnt/xfs/pbonzini/test.img,cache=none,format=raw,discard=on \
  -device scsi-hd,drive=data,logical_block_size=4096 -m 512

I used a RHEL6.4 guest, and installed sg3_utils in it.

3. Execute the following commands in guest:

# yes | head -n2048 > buf
# sg_write_same --in buf --num=32 --lba=80 /dev/sdb
# sg_write_same --in /dev/zero --num=96 --lba=0 /dev/sdb
# sg_write_same -U --in /dev/zero --num=16 --lba=0 /dev/sdb
# sg_write_same --in buf --num=65536 --lba=131074 /dev/sdb
# sg_write_same --in /dev/zero --num=65534 --lba=196608 /dev/sdb
# sg_write_same --in /dev/zero --num=0 --lba=128 /dev/sdb

The fifth sg_write_same command should be much faster than the fourth.

The sixth command should give an error.

4. Also in guest:

# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /mnt/xfs/pbonzini/test.img

5. In host (xfs-test.img is the path to the test image):

# qemu-img map --output=json xfs-test.img
[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": 0},
{ "start": 65536, "length": 327680, "depth": 0, "zero": true, "data": true, "offset": 65536},
{ "start": 393216, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 393216},
{ "start": 458752, "length": 536420352, "depth": 0, "zero": true, "data": false, "offset": 458752},
{ "start": 536879104, "length": 268427264, "depth": 0, "zero": false, "data": true, "offset": 536879104},
{ "start": 805306368, "length": 268427264, "depth": 0, "zero": true, "data": true, "offset": 805306368},
{ "start": 1073733632, "length": 8192, "depth": 0, "zero": true, "data": false, "offset": 1073733632}]

6. Also in host:

# sha1sum /mnt/xfs/pbonzini/test.img
03a8c894d614ef68ec2013b3420157bd2d4843db  /mnt/xfs/pbonzini/test.img

7. Repeat with scsi_debug disk after
"modprobe scsi_debug lbprz=1 lbpu=1 dev_size_mb=1024".
Replace step 5 with:

# cat /sys/bus/pseudo/drivers/scsi_debug/map
128-895,1048592-2097135

8. Repeat with scsi_debug disk after
"modprobe scsi_debug lbprz=0 lbpu=1 dev_size_mb=1024".
Replace step 5 with:

# cat /sys/bus/pseudo/drivers/scsi_debug/map
0-895,1048592-2097135

Comment 7 Sibiao Luo 2014-01-21 07:29:50 UTC
verified this issue on qemu-kvm-1.5.3-38.el7.x86_64 with the instruction steps as comment #3.

host info:
# uname -r && rpm -q qemu-kvm
3.10.0-76.el7.x86_64
qemu-kvm-1.5.3-38.el7.x86_64
guest info:
# uname -r
3.10.0-76.el7.x86_64

Steps and results:
1. Create a 1G raw image on an XFS file system
# df -T | awk '{print $1,$2,$NF}' | grep "^/dev"
/dev/mapper/rhel_dhcp--11--229-root xfs /
/dev/sda1 xfs /boot
/dev/mapper/rhel_dhcp--11--229-home xfs /home
# qemu-img create -f raw test.img 1G
Formatting 'test.img', fmt=raw size=1073741824 
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 0

2. Start qemu with a command-line like the following:
e.g:/usr/libexec/qemu-kvm...-drive file=/home/test.img,if=none,id=drive-data-disk,format=raw,cache=none,aio=native,werror=stop,rerror=stop,discard=on -device virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x7 -device scsi-hd,drive=drive-data-disk,id=data-disk,logical_block_size=4096,bus=scsi1.0

I used a RHEL7.0 guest, and installed sg3_utils in it.

3. Execute the following commands in guest:

# yes | head -n2048 > buf
# sg_write_same --in buf --num=32 --lba=80 /dev/sdb
# sg_write_same --in /dev/zero --num=96 --lba=0 /dev/sdb
# sg_write_same -U --in /dev/zero --num=16 --lba=0 /dev/sdb
# time sg_write_same --in buf --num=65536 --lba=131074 /dev/sdb

real	0m2.038s
user	0m0.000s
sys	0m0.003s
# time sg_write_same --in /dev/zero --num=65534 --lba=196608 /dev/sdb

real	0m1.995s
user	0m0.000s
sys	0m0.001s
# sg_write_same --in /dev/zero --num=0 --lba=128 /dev/sdb
bad field in Write same(10) cdb, option probably not supported

The fifth sg_write_same command should be much faster than the fourth.

The sixth command should give an error.

4. Also in guest:

guest ]# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /dev/sdb

5. In host (xfs-test.img is the path to the test image):

host ]# qemu-img map --output=json test.img
[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": 0},
{ "start": 65536, "length": 393216, "depth": 0, "zero": false, "data": true, "offset": 65536},
{ "start": 458752, "length": 536420352, "depth": 0, "zero": true, "data": false, "offset": 458752},
{ "start": 536879104, "length": 536854528, "depth": 0, "zero": false, "data": true, "offset": 536879104},
{ "start": 1073733632, "length": 8192, "depth": 0, "zero": true, "data": false, "offset": 1073733632}]

6. Also in host:

host ]# sha1sum test.img
03a8c894d614ef68ec2013b3420157bd2d4843db  test.img

7. Repeat with scsi_debug disk after
"modprobe scsi_debug lbprz=1 lbpu=1 dev_size_mb=1024".
Replace step 5 with:
# cat /sys/bus/pseudo/drivers/scsi_debug/map
------------------------------------------------------
Results:
e.g:...-drive file=/dev/sdb,if=none,id=drive-data-disk,format=raw,cache=none,aio=native,werror=stop,rerror=stop,discard=on -device virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x7 -device scsi-hd,drive=drive-data-disk,id=data-disk,logical_block_size=4096,bus=scsi1.0
guest]# yes | head -n2048 > buf
guest]# sg_write_same --in buf --num=32 --lba=80 /dev/sdb
guest]# sg_write_same --in /dev/zero --num=96 --lba=0 /dev/sdb
guest]# sg_write_same -U --in /dev/zero --num=16 --lba=0 /dev/sdb
guest]# time sg_write_same --in buf --num=65536 --lba=131074 /dev/sdb

real	0m0.513s
user	0m0.001s
sys	0m0.000s
guest]# time sg_write_same --in /dev/zero --num=65534 --lba=196608 /dev/sdb

real	0m0.050s
user	0m0.000s
sys	0m0.002s
guest]# sg_write_same --in /dev/zero --num=0 --lba=128 /dev/sdb
bad field in Write same(10) cdb, option probably not supported
guest]# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /dev/sdb

host]# cat /sys/bus/pseudo/drivers/scsi_debug/map
128-895,1048592-2097135
host]# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /dev/sdb

8. Repeat with scsi_debug disk after
"modprobe scsi_debug lbprz=0 lbpu=1 dev_size_mb=1024".
Replace step 5 with:
# cat /sys/bus/pseudo/drivers/scsi_debug/map
------------------------------------------------------
Results:
guest]# yes | head -n2048 > buf
guest]# sg_write_same --in buf --num=32 --lba=80 /dev/sdb
guest]# sg_write_same --in /dev/zero --num=96 --lba=0 /dev/sdb
guest]# sg_write_same -U --in /dev/zero --num=16 --lba=0 /dev/sdb
guest]# time sg_write_same --in buf --num=65536 --lba=131074 /dev/sdb

real	0m0.513s
user	0m0.000s
sys	0m0.001s
guest]# time sg_write_same --in /dev/zero --num=65534 --lba=196608 /dev/sdb

real	0m0.056s
user	0m0.000s
sys	0m0.001s
guest]# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /dev/sdb

host]# cat /sys/bus/pseudo/drivers/scsi_debug/map
0-895,1048592-2097135
host]# sha1sum /dev/sdb
03a8c894d614ef68ec2013b3420157bd2d4843db  /dev/sdb

Base on above, this issue has been fixed correctly, move to VERIFIED status. Please correctly me if any mistake.

Best Regards,
sluo

Comment 10 Sibiao Luo 2014-01-26 03:12:23 UTC
According comment #7 and comment #9, this bug has been fixed, move it to VERIFIED status. Please correct me if any mistake, thanks in advance.

Best Regards,
sluo

Comment 11 Ludek Smid 2014-06-13 10:09:23 UTC
This request was resolved in Red Hat Enterprise Linux 7.0.

Contact your manager or support representative in case you have further questions about the request.