qcow2 image corruption on non-extent filesystems (ext3)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
High
|
Chris J Arges | ||
Trusty |
Fix Released
|
High
|
Chris J Arges | ||
Vivid |
Fix Released
|
High
|
Unassigned | ||
linux-lts-utopic (Ubuntu) |
Invalid
|
Undecided
|
Unassigned | ||
Trusty |
Fix Released
|
High
|
Unassigned |
Bug Description
[Impact]
Users of non-extent ext4 filesystems (ext4 ^extents, or ext3 w/ CONFIG_
[Test Case]
1) Setup ext4 ^extents, or ext3 filesystem with CONFIG_
2) Create and install a VM using a qcow2 image and store the file on the filesystem
3) Snapshot the image with qemu-img
4) Boot the image and do some disk operations (fio,etc)
5) Shutdown image and delete snapshot
6) Repeat 3-5 until VM no longer boots due to image corruption, generally this takes a few iterations depending on disk operations.
[Fix]
commit 6f30b7e37a8239f
This has been discussed upstream here:
http://
A temporary fix would be to disable punch_hole for non-extent filesystem. This is how the normal ext3 module handles this and it is up to userspace to handle the failure. I've run this with the test case and was able to run for 600 iterations over 3 days where most failures occur within the first 2-20 iterations.
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5653fa4..e14cdfe 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3367,6 +3367,10 @@ int ext4_punch_
offset, loff_t length)
unsigned int credits;
int ret = 0;
+ /* EXTENTS required */
+ if (!(ext4_
+ return -EOPNOTSUPP;
+
if (!S_ISREG(
return -EOPNOTSUPP;
--
The security team uses a tool (http://
qemu-kvm 2.0~git-
$ cat /proc/version_
Ubuntu 3.13.0-
$ qemu-img info ./forhallyn-
image: ./forhallyn-
file format: qcow2
virtual size: 8.0G (8589934592 bytes)
disk size: 4.0G
cluster_size: 65536
Format specific information:
compat: 0.10
Steps to reproduce:
1. create a virtual machine. For a simplified reproducer, I used virt-manager with:
OS type: Linux
Version: Ubuntu 14.04
Memory: 768
CPUs: 1
Select managed or existing (Browse, new volume)
Create a new storage volume:
qcow2
Max capacity: 8192
Allocation: 0
Advanced:
NAT
kvm
x86_64
firmware: default
2. install a VM. I used trusty-
3. Backup the image file somewhere since steps 1 and 2 take a while :)
4. Execute the following commands which are based on what our uvt tool does:
$ virsh snapshot-create-as forhallyn-
$ virsh snapshot-current --name forhallyn-
pristine
$ virsh start forhallyn-
$ virsh snapshot-list forhallyn-
in guest:
sudo apt-get update
sudo apt-get dist-upgrade
780 upgraded...
shutdown -h now
$ virsh snapshot-delete forhallyn-
$ virsh snapshot-create-as forhallyn-
$ virsh start forhallyn-
The idea behind the above is to create a new VM with a pristine snapshot that we could revert later if we wanted. Instead, we boot the VM, run apt-get dist-upgrade, cleanly shutdown and then remove the old 'pristine' snapshot and create a new 'pristine' snapshot. The intention is to update the VM and the pristine snapshot so that when we boot the next time, we boot from the updated VM and can revert back to the updated VM.
After running 'virsh start' after doing snapshot-
This does not seem to be related to the machine type used. Ie, pc-i440fx-1.5, pc-i440fx-1.7 and pc-i440fx-2.0 all fail with qemu 2.0, pc-i440fx-1.5 and pc-i440fx-1.7 fail with qemu 1.7 and pc-i440fx-1.5 works fine with qemu 1.5.
Only workaround I know if is to downgrade qemu to 1.5.0+dfsg-
summary: |
- qcow2 image corruption in trusty (qemu 1.7) + qcow2 image corruption in trusty (qemu 1.7 and 2.0 candidate) |
Changed in qemu (Ubuntu): | |
importance: | Undecided → High |
Changed in qemu (Ubuntu): | |
assignee: | nobody → Serge Hallyn (serge-hallyn) |
tags: | added: qcow2 |
Changed in qemu (Ubuntu): | |
assignee: | Serge Hallyn (serge-hallyn) → Chris J Arges (arges) |
Changed in qemu (Ubuntu): | |
status: | Confirmed → In Progress |
summary: |
- qcow2 image corruption in trusty (qemu 1.7 and 2.0 candidate) + qcow2 image corruption on non-extent filesystems (ext3) |
no longer affects: | qemu |
Changed in linux (Ubuntu): | |
assignee: | nobody → Chris J Arges (arges) |
importance: | Undecided → High |
status: | New → In Progress |
Changed in qemu (Ubuntu): | |
status: | In Progress → Invalid |
assignee: | Chris J Arges (arges) → nobody |
importance: | High → Undecided |
description: | updated |
description: | updated |
description: | updated |
description: | updated |
description: | updated |
Changed in linux (Ubuntu): | |
status: | Fix Released → Confirmed |
Changed in linux (Ubuntu): | |
status: | Confirmed → Fix Committed |
no longer affects: | qemu (Ubuntu) |
no longer affects: | qemu (Ubuntu Trusty) |
no longer affects: | qemu (Ubuntu Vivid) |
Changed in linux-lts-utopic (Ubuntu): | |
status: | New → Invalid |
Changed in linux (Ubuntu Trusty): | |
assignee: | nobody → Chris J Arges (arges) |
Changed in linux (Ubuntu Vivid): | |
assignee: | nobody → Chris J Arges (arges) |
Changed in linux-lts-utopic (Ubuntu Trusty): | |
assignee: | nobody → Chris J Arges (arges) |
Changed in linux (Ubuntu Trusty): | |
importance: | Undecided → High |
Changed in linux (Ubuntu Vivid): | |
importance: | Undecided → High |
Changed in linux-lts-utopic (Ubuntu Trusty): | |
importance: | Undecided → High |
Changed in linux (Ubuntu Trusty): | |
status: | New → In Progress |
Changed in linux (Ubuntu Vivid): | |
status: | New → In Progress |
Changed in linux-lts-utopic (Ubuntu Trusty): | |
status: | New → In Progress |
Changed in linux (Ubuntu Vivid): | |
assignee: | Chris J Arges (arges) → nobody |
Changed in linux-lts-utopic (Ubuntu Trusty): | |
assignee: | Chris J Arges (arges) → nobody |
Changed in linux (Ubuntu Trusty): | |
status: | In Progress → Fix Committed |
tags: |
added: verification-failed removed: verification-needed-trusty |
tags: |
added: verification-failed-trusty removed: verification-failed |
Have not yet been able to reproduce this. I'm considering adding an upstart job to your image which updates and shuts down, so I can test this in a loop.
Do you know whether (a) the --children option to snapshot delete or (b) using the same name for the new snapshot as the one you just delete are crucial to reproducing this?