-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importing a containerdisk onto a block volume loses sparseness #3614
Comments
@stefanha Is there a particular version of qemu-img that has this support, or has it been there a long time? We should make sure the version of qemu-img used in CDI supports this flag. |
It is available starting from RHEL 8, Ubuntu 22.04, OpenSUSE Leap 15.4, Debian 10 (backports) or 11. |
Super interesting, thanks for opening the issue! I am wondering how a certain test we have isn't catching this containerized-data-importer/tests/import_test.go Line 1643 in 41b96ed
#3213 |
This du(1) command-line probably isn't working as expected on a block device: |
This PR gets rid of the |
This explains it:
SizeOnDisk being |
There is no generic way in Linux to query a block device to find out how many blocks are allocated, so SizeOnDisk will not have a useful value. |
Maybe this trick will work: create a sparse file using truncate(1) and then create a corresponding loopback block device using losetup(8). The test would be able to look at the blocks allocated in the underlying sparse file to get an approximation of the number of block touched on the loopback block device, modulo file system effects like its block size. |
Can't we just use |
If I understand correctly, the test is attempting to verify that the block device was written sparsely (non-zero blocks were skipped). Simply using dd to copy the block device to a file won't show whether the block device was written sparsely, so I don't think that approach works. You could first populate the block device with a pattern, import the containerdisk, and then check to see whether the pattern is still visible in blocks where the containerdisk is zero. That last step could be a single checksum comparison of the contents of the whole disk. |
Looks like this issue is somehow hidden with ceph rbd (using same 10Gi image) # rook-ceph-toolbox pod
$ ceph df -f json | jq .pools[0].stats.bytes_used
2036678656 |
Ceph might be doing zero detection or deduplication? Even if this is the case, you should be able to see the issue by running the same qemu-img command-line as CDI under strace(1) and looking at the pattern of write syscalls. |
What happened:
Importing a containerdisk onto a block volume loses sparseness. When I imported the centos-stream:9 containerdisk, which only uses 2 GB of non-zero data onto an empty 10 GB block volume, all 10 GB were written by CDI. Preallocation was not enabled.
What you expected to happen:
Only the non-zero data should be written to the block volume. This saves space on the underlying storage.
How to reproduce it (as minimally and precisely as possible):
Create a DataVolume from the YAML below and observe the amount of storage allocated. I used KubeSAN as the CSI driver, so the LVM
lvs
command can be used to see the thin provisioned storage usage. If you don't have thin provisioned storage you could use I/O stats or tracing to determine how much data is being written.Additional context:
I discussed this with @aglitke and we looked at the qemu-img command that is invoked:
Adding the
--target-is-zero
option should avoid writing every block in the target block volume.If there are concerns that some new block volumes come uninitialized (blocks not zeroed), then it should be possible to run
blkdiscard --zeroout /path/to/block/device
before invoking qemu-img with--target-is-zero
. I have not tested this, but blkdiscard should zero the device efficiently and fall back to writing zero buffers on old hardware. On modern devices this would still be faster and preserve sparseness compared to writing all zeroes. On old devices it would be slower, depending on how many non-zero the input disk image has.Environment:
kubectl get deployments cdi-deployment -o yaml
): 4.17.3kubectl version
): v1.30.5uname -a
): N/AThe text was updated successfully, but these errors were encountered: