Repository navigation
Conversation
Provide a runtime configuration key to let the data sync that installs
the image payload turn sequences of null bytes in the source into holes
on the target:
sync:
sparse: true
The key is off by default. It adds the --sparse option to the rsync call. It
is skipped with a warning rather than failing the build if it cannot be used,
which is the case for rsync releases before 3.1.3 because they reject --sparse
together with --inplace, and for a caller that asked for --preallocate because
that allocates every file in full before writing it.
The option alone is not enough on a filesystem that performs speculative
preallocation. rsync only seeks forward across a null sequence, it does not
punch a hole, and on xfs the skipped range falls inside the preallocation
beyond the end of file and is recorded as an allocated but unwritten
extent. Such an extent reads as zero and is reported as a hole by SEEK_HOLE,
yet it still occupies space in the target image.
A filesystem implementation can therefore declare mount options that its
install time mount needs for a sparse sync to be effective, via the new
sparse_install_mount_options attribute. These apply to the mount the payload
is synced into and are not passed on to the fstab of the image, so they do not
become mount options of the running system. An explicit setting of the same
option in the fsmountoptions attribute of the image description takes
precedence.
The xfs implementation declares the minimum of allocsize=4k for maximal size
savings.
Measured with a payload of 64k aligned binaries carrying a zero tail per
segment, as produced for architectures with a 64k page size. The filesystem
accounts 244MB used and the image file occupies 581MB without the key. With
the key it is 119MB and 457MB, with no unwritten extents left. The extent
count drops at the same time, because the unwritten bridges are extents of
their own.
Signed-off-by: Martin Pohlack <mpohlack@amazon.de>
Assisted-by: Kiro:claude-opus-5
8a0ba60 to
11dab29
Compare
|
@martinp26 Thanks much, the idea is nice and the implementation looks good. I have a few questions prior merge though:
Your thoughts please. Thanks much |
|
Hi @schaefi, thanks for looking into this. A few quick answers:
Let me iterate a bit on the testing story. |
sorry my question was not very clear here. You already answered it. With "performance" I meant the disk usage on the storage backend. Thanks makes sense to me.
yes, it would be imho interesting what happens with sparse sync enabled on the following integration tests
You find the respective image descriptions in source below kiwi/build-tests. I believe the distro doesn't matter much so you should be able to rebuild this type of image also with Amazon Linux or another OS of your choice I believe sparse sync on encrypted will not have many null bytes to write as kiwi also randomize the target. For the others I agree with you that the storage backend will benefit in the same way as with less complex layouts. Don't get me wrong, I don't want to burn your time in testing. I just wanted to make sure enabling the sparse sync feature is not causing some sort of corruption at the end of the sync chain. The feature is great, let's merge when you believe we are good to go :) Thanks much |
|
Thanks :-). I understand this is a complex change and you need to protect kiwi's stability. Totally warranted!
Right, just saw that you enforce randomizing. Unless I am mixing things up here, rsync would still see the zero runs in the source files to be synced and would create sparse representations in the target. Only the outer image would not see a size reduction as the unwritten areas would not manifest as sparse holes or zero runs in it. The only benefit would be within the file system, where the user has a little bit more free space now from the sparse savings. There are no direct savings on the out image itself. |
Provide a runtime configuration key to let the data sync that installs the image payload turn sequences of null bytes in the source into holes on the target:
sync:
sparse: true
The key is off by default. It adds the --sparse option to the rsync call. It is skipped with a warning rather than failing the build if it cannot be used, which is the case for rsync releases before 3.1.3 because they reject --sparse together with --inplace, and for a caller that asked for --preallocate because that allocates every file in full before writing it.
The option alone is not enough on a filesystem that performs speculative preallocation. rsync only seeks forward across a null sequence, it does not punch a hole, and on xfs the skipped range falls inside the preallocation beyond the end of file and is recorded as an allocated but unwritten extent. Such an extent reads as zero and is reported as a hole by SEEK_HOLE, yet it still occupies space in the target image.
A filesystem implementation can therefore declare mount options that its install time mount needs for a sparse sync to be effective, via the new sparse_install_mount_options attribute. These apply to the mount the payload is synced into and are not passed on to the fstab of the image, so they do not become mount options of the running system. An explicit setting of the same option in the fsmountoptions attribute of the image description takes precedence.
The xfs implementation declares the minimum of allocsize=4k for maximal size savings.
Measured with a payload of 64k aligned binaries carrying a zero tail per segment, as produced for architectures with a 64k page size. The filesystem accounts 244MB used and the image file occupies 581MB without the key. With the key it is 119MB and 457MB, with no unwritten extents left. The extent count drops at the same time, because the unwritten bridges are extents of their own.
Assisted-by: Kiro:claude-opus-5