From 5b6716cee8bb69c5f309ce19e7e47da1f74992d9 Mon Sep 17 00:00:00 2001 From: SamYaple Date: Wed, 9 Mar 2016 22:43:27 +0000 Subject: [PATCH] Use fstrim to prep the block device This cuts the image size down alot, esspecially if there were lots of small file deletes. The fstrim utility is in the util-linux package and should be on most all systems. fstrim also works with XFS, ext4, btrfs, etc prodiving the kernel is new enough. A reduction of 25% or more in size is common. Change-Id: I269b4416be450369616f9b8e030f84c30e329804 --- bin/disk-image-create | 11 +++++++++++ doc/source/developer/design.rst | 7 +++++++ lib/img-functions | 11 +++++++++++ 3 files changed, 29 insertions(+) diff --git a/bin/disk-image-create b/bin/disk-image-create index 455ebda8..f6288975 100755 --- a/bin/disk-image-create +++ b/bin/disk-image-create @@ -264,6 +264,14 @@ for X in ${!IMAGE_TYPES[@]}; do esac done +# NOTE: fstrim is on most all recent systems. It is provided by the util-linux +# package. +if [[ -z "$(which fstrim)" ]]; then + echo "fstrim utility is not found. This is provided by util-linux package" + echo "Please check your PATH variable is set correctly" + exit 1 +fi + # NOTE: Tuning the rootfs uuid works only for ext filesystems. # Rely on the below environment variable only for ext filesystems. export DIB_IMAGE_ROOT_FS_UUID=$(uuidgen -r) @@ -387,6 +395,9 @@ for X in ${!IMAGE_TYPES[@]} ; do fi done +# Prep filesystem by discarding all unused space +fstrim_image + # Unmount and cleanup the /mnt and /build subdirectories, to save # space before converting the image to some other format. unmount_image diff --git a/doc/source/developer/design.rst b/doc/source/developer/design.rst index e767eadc..df0cecf1 100644 --- a/doc/source/developer/design.rst +++ b/doc/source/developer/design.rst @@ -12,6 +12,13 @@ and file system) is created and the tree copied into it. The file system created is an ext4 filesystem just large enough to hold the file system tree and can be resized up to 1PB in size. +To produce the smallest image the utility fstrim is used. When deleting a file +the space is simply marked as free on the disk, the file is still there until +it is overwritten. fstrim informs the underlying disk to drop those bytes the +end result of which is like writting zeros over those sectors. The same effect +could be achieved by creating a large file full of zeros and removing that +file, however that method is far more IO intensive. + An element is a particular set of code that alters how the image is built, or runs within the chroot to prepare the image. E.g. the local-config element copies in the http proxy and ssh keys of the user running the image build diff --git a/lib/img-functions b/lib/img-functions index cf817ae8..908123ce 100644 --- a/lib/img-functions +++ b/lib/img-functions @@ -29,6 +29,17 @@ function unmount_image () { fi } +function fstrim_image () { + # A race condition can occur when trying to fstrim immediately after + # deleting a file resulting in that free space not being reclaimed. + # Calling sync before fstrim is a workaround for this behaviour. + # https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02978.html + sync + + # Discard all unused bytes + sudo fstrim "${TMP_BUILD_DIR}/mnt" +} + function trap_cleanup() { exitval=$? cleanup