Red Hat Bugzilla – Bug 879234
[RFE] qemu-img: Add/improve support for VHDX format
Last modified: 2014-06-17 23:19:05 EDT
Description of problem:
Currently the 'qemu-img -O vpc' does not produce a valid vhd file that could be used in Hyper-V. It would be nice if we could integrate at least the functionality of the vhdtool here:
so that we can convert to valid VHD files
Should note that what we really want for virt-v2v is the
capability to convert *from* vhd/vhdx to a native qemu
Currently adding the vhdx file format, using the MS specification for VHDX from here: https://www.microsoft.com/en-us/download/details.aspx?id=29681
My github repo for the work in progress is
(this is just an informational update, it is not functional or ready to be committed upstream yet)
(In reply to comment #5)
> Currently adding the vhdx file format, using the MS specification for VHDX
> from here: https://www.microsoft.com/en-us/download/details.aspx?id=29681
> My github repo for the work in progress is
> branch jtc-vhdx-work
> (this is just an informational update, it is not functional or ready to be
> committed upstream yet)
If we support vhdx on rhel7, Does QE need to test vpc format? Thanks.
VHDX is completely independent of VPC. So testing VPC is more of a question if RHEL7 is going to support VPC, rather than if VHDX will require us to test VPC. But there is nothing with regards to VHDX that will cause VPC to need to be tested.
(In reply to comment #7)
> Hi Junyi,
> VHDX is completely independent of VPC. So testing VPC is more of a question
> if RHEL7 is going to support VPC, rather than if VHDX will require us to
> test VPC. But there is nothing with regards to VHDX that will cause VPC to
> need to be tested.
Thanks for the confirmation.
VHDX read-only patches are in upstream 1.5.0-rc0:
VHDX (MS Hyper-V) image format has initial read-only support. Dynamic and fixed sized disks are supported, but not differencing images (e.g. VHDX images with a backing file). Read-only is strictly enforced, and the 'readonly=on' option must be used for any VHDX images.
I tried upstream qemu from git with two vhdx disk images. One
was a blank disk, the other was a Fedora 18 guest, both were
created on Windows 2012 Server Hyper-V.
The blank disk image works fine.
The real guest disk image is suspicious. It doesn't give I/O
errors, but it doesn't entirely work properly either. I see
odd errors which seem to indicate that the virtual disk is
[ 0.520259] sd 2:0:0:0: [sda] 9838592 512-byte logical blocks: (5.03 GB/4.69 GiB)
[ 0.526631] sda: sda1 sda2
[ 0.526961] sda: p2 size 40916992 extends beyond EOD, enabling native capacity
[ 0.529179] sda: sda1 sda2
[ 0.530624] sda: p2 size 40916992 extends beyond EOD, truncated
Reading all physical volumes. This may take a while...
Found volume group "fedora" using metadata type lvm2
[ 1.384526] bio: create slab <bio-1> at 1
[ 1.389517] device-mapper: table: 253:1: sda2 too small for target: start=4065280, len=36847616, dev_size=8812544
device-mapper: resume ioctl on failed: Invalid argument
Unable to resume fedora-root (253:1)
2 logical volume(s) in volume group "fedora" now active
The real virtual disk size is 20 GB.
That error of course stops the guest from working. I can supply
the .vhdx file if that would help.
Created attachment 746176 [details]
libguestfs appliance boot logs
/dev/sda is the .vhdx file (or more precisely, is a qcow2
file with the .vhdx file as backing).
/dev/sdb is the libguestfs appliance root disk.
Comments 10-12 are a false alarm. This turns out to be
a libvirt bug (or missing feature). libvirt needs to be
extended with support for vhdx.
v5 posted upstream:
Closing this as a dupe of BZ 1007176 - it wasn't a dupe when written, but we've consolidated the BZs for adding vpc and vhdx formats to the whitelist.
*** This bug has been marked as a duplicate of bug 1007176 ***
Sorry - wrong bug closed as dupe. Meant to close BZ 1006662 instead.
Fix included in qemu-kvm-1.5.3-33.el7
Verified this issue with qemu-kvm-rhev-1.5.3-39.el7.x86_64.
# uname -r && rpm -q qemu-kvm-rhev
#### scenarios 1.
Use qemu-img to create and read the vpc/vhdx image correctly, and then attach it in KVM as a second disk specified readonly=on.
1.Use qemu-img to create and read the vpc/vhdx image.
# qemu-img create -f vpc my-data-disk.vpc 10G
Formatting 'my-data-disk.vpc', fmt=vpc size=10737418240
# qemu-img info my-data-disk.vpc
file format: vpc
virtual size: 10G (10737893376 bytes)
disk size: 24K
# qemu-img create -f vhdx my-data-disk.vhdx 10G
Formatting 'my-data-disk.vhdx', fmt=vhdx size=10737418240 log_size=1048576 block_size=0 block_state_zero=off
# qemu-img info my-data-disk.vhdx
file format: vhdx
virtual size: 10G (10737418240 bytes)
disk size: 328K
2.using QEMU, launch a guest with the VHDX data disk as a secondary disk.
e.g:...-drive file=/home/my-data-disk.vhdx,if=none,format=vhdx,id=drive-data-disk,cache=none,werror=stop,rerror=stop,readonly=on -device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-data-disk,id=data-disk
after step 1, use qemu-img to create and read the vpc/vhdx image successfully.
after step 2, using QEMU to launch a guest with the VHDX data disk as a secondary disk successfully.
#### scenarios 2.
Use Hyper-V to install OS and generate an image(clean dynamic & fixed image files), then convert it to qcow2/raw format via qemu-img and boot it in KVM environment.
1.Use Hyper-V to install OS and generate an image(clean dynamic & fixed image files).
2.convert it to qcow2/raw format via qemu-img.
# qemu-img convert -p -f vhdx sluo-rhel7.0-64bit-disk1.vhdx -O qcow2 sluo-rhel7.0-64bit-disk1.qcow2
3.boot it in KVM with simulate driver.
e.g:/usr/libexec/qemu-kvm -M pc -cpu host -enable-kvm -m 2048 -smp 2,sockets=2,cores=1,threads=1 -no-kvm-pit-reinjection -usb -device usb-tablet,id=input0 -name sluo -uuid 990ea161-6b67-47b2-b803-19fb01d30d30 -rtc base=localtime,clock=host,driftfix=slew -drive file=/home/sluo-rhel7.0-64bit-disk1.qcow2,if=none,id=drive-system-disk,format=qcow2,cache=none,aio=native -device ide-hd,drive=drive-system-disk,id=system-disk,bus=ide.0,unit=0 -k en-us -boot menu=on -qmp tcp:0:4444,server,nowait -serial unix:/tmp/ttyS0,server,nowait -vnc :1 -spice disable-ticketing,port=5931 -monitor stdio
after step 2, it convert successfully.
after step 3, boot up in KVM successfully.
after step 4, reboot/shutdown/poweroff VM successfully.
Base on above, this issue has been fixed correctly, move to VERIFIED status, please correct me if any mistake.
Unfortunately, it does not convert vhdx image created with disk2vhd (http://technet.microsoft.com/en-us/sysinternals/ee656415.aspx):
qemu-img convert -p -f vhdx ../SERVERIS.VHDX -O qcow2 serveris.qcow2
qemu-img: No valid VHDX header found
qemu-img: Could not open '../SERVERIS.VHDX': Could not open '../SERVERIS.VHDX': Invalid argument
qemu-img: Could not open '../SERVERIS.VHDX'
I made a small test partition and created vhdx image (22 MB) from it with disk2vhd - http://sat.lt/SERVERIS.VHDX - which shows the above problem.
(In reply to Nerijus Baliūnas from comment #24)
> Unfortunately, it does not convert vhdx image created with disk2vhd
> qemu-img convert -p -f vhdx ../SERVERIS.VHDX -O qcow2 serveris.qcow2
> qemu-img: No valid VHDX header found
> qemu-img: Could not open '../SERVERIS.VHDX': Could not open
> '../SERVERIS.VHDX': Invalid argument
> qemu-img: Could not open '../SERVERIS.VHDX'
(In reply to Nerijus Baliūnas from comment #25)
> I made a small test partition and created vhdx image (22 MB) from it with
> disk2vhd - http://sat.lt/SERVERIS.VHDX - which shows the above problem.
Thank you for this report! The VHDX file in your URL was very helpful.
Every VHDX image file has two 64kB headers. One header is an active header, and the other header is an inactive header. Each header has a sequence number; assuming the data and checksums in the headers are valid, the header with the highest sequence number is the active header, and the header to be used when opening the file.
Per the VHDX Format Specification v1.00 from Microsoft, Section 3.1.2:
"A header is valid if Signature and Checksum both validate correctly. A header is current if it is the only
valid header or if it is valid and its SequenceNumber field is greater than the other header’s
SequenceNumber field. The parser must only use data from the current header. If there is no current
header, then the VHDX file is corrupt."
In the sample image you provided, both of the header sections have valid checksums, valid signatures, and identical sequence numbers. As matter of fact, the checksum values are identical - my guess is the Disk2VHD tool takes a shortcut, and during creation creates active and inactive headers as identical, without bumping the sequence number of one of them.
That creates what the spec defines as a corrupt VHDX file. However, we can create an exception for this case, if the headers are both identical.
I made a small patch, that checks for these identical headers and doesn't flag the file as invalid in this case. That allowed me to read your VHDX file, both with qemu-img info, and also to mount it in a guest.
Once I've tried the Disk2VHD tool, and created multiple sample VHDX files (to make sure they are all behaving the same), I will submit a patch upstream. Until then, the patch can be seen at my github account:
Thanks again Nerijus for providing the sample image and the bug information. Since this deals with workarounds for Disk2VHD, I will open separate bug(s) for this issue.
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.