|
|
@ -107,57 +107,6 @@ lb_chroot_includes () {
|
|
|
|
cd "${OLDPWD}"
|
|
|
|
cd "${OLDPWD}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
reduce_pass_size () {
|
|
|
|
|
|
|
|
# Remove duplicated files between parent and current pass
|
|
|
|
|
|
|
|
# Note the empty directories created in a child pass are not removed
|
|
|
|
|
|
|
|
local pass=$1
|
|
|
|
|
|
|
|
local parent="$(get_parent_pass $pass)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$(is_root_layer $pass) && return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pass_dir="overlay.${pass}"
|
|
|
|
|
|
|
|
parent_pass_dir="overlay.${parent}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local list_pass=$(mktemp)
|
|
|
|
|
|
|
|
local list_parent=$(mktemp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(cd $pass_dir && find . ! -type d -printf "%h/%f|%s|%y|%U|%G|%m\n"|sort > $list_pass)
|
|
|
|
|
|
|
|
(cd $parent_pass_dir && find . ! -type d -printf "%h/%f|%s|%y|%U|%G|%m\n"|sort > $list_parent)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Only iterate on common files with same type, owner, permission and size
|
|
|
|
|
|
|
|
comm -12 $list_pass $list_parent|cut -d'|' -f1|while read f; do
|
|
|
|
|
|
|
|
# If file contents are different, keep it
|
|
|
|
|
|
|
|
if ! diff --brief --no-dereference "$pass_dir/$f" "$parent_pass_dir/$f" >/dev/null; then
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
p="$(dirname "$f")"
|
|
|
|
|
|
|
|
while [ "$p" != . ]; do
|
|
|
|
|
|
|
|
# As explained in the overlayfs documentation
|
|
|
|
|
|
|
|
# https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#whiteouts-and-opaque-directories
|
|
|
|
|
|
|
|
# an xattr of trusted.overlay.opaque indicates an 'opaque' directory
|
|
|
|
|
|
|
|
# that was deleted from the overlay. Removing files from within the
|
|
|
|
|
|
|
|
# directory, even if identical with one in the lower layer, will result
|
|
|
|
|
|
|
|
# in it going missing from the combined filesystem.
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# It would be possible to be more clever, e.g. if the two directories
|
|
|
|
|
|
|
|
# are still similar, we could the delete the attribute and convert any
|
|
|
|
|
|
|
|
# still-needed deletions to whiteouts but it doesn't seem worth it in
|
|
|
|
|
|
|
|
# the cases seen so far.
|
|
|
|
|
|
|
|
if [ -n "$(getfattr -n trusted.overlay.opaque -h --only-values -- "$pass_dir/$p" 2>/dev/null)" ]; then
|
|
|
|
|
|
|
|
Echo_message "reduce_pass_size: '%s' would be removed from overlay but for trusted.overlay.opaque on '%s'" "$f" "$p"
|
|
|
|
|
|
|
|
continue 2
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
p="$(dirname "$p")"
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
# Files are strictly identical between the 2 passes (only mod or access times differs). No need for unused delta.
|
|
|
|
|
|
|
|
Echo_message "reduce_pass_size: '%s' is strictly identical between %s and %s. Removing." "$f" "$pass" "$parent"
|
|
|
|
|
|
|
|
rm "$pass_dir/$f"
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rm $list_pass
|
|
|
|
|
|
|
|
rm $list_parent
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
create_chroot_pass () {
|
|
|
|
create_chroot_pass () {
|
|
|
|
local pass=$1
|
|
|
|
local pass=$1
|
|
|
|
shift 1 # restore ${*}
|
|
|
|
shift 1 # restore ${*}
|
|
|
@ -182,8 +131,8 @@ create_chroot_pass () {
|
|
|
|
mkdir -p "$overlay_dir/"
|
|
|
|
mkdir -p "$overlay_dir/"
|
|
|
|
lowerdirs=$(get_lowerdirs_for_pass $pass)
|
|
|
|
lowerdirs=$(get_lowerdirs_for_pass $pass)
|
|
|
|
if [ -n "$lowerdirs" ]; then
|
|
|
|
if [ -n "$lowerdirs" ]; then
|
|
|
|
mkdir -p chroot/
|
|
|
|
mkdir -p chroot "${overlay_dir}-initial"
|
|
|
|
mount_overlay "$lowerdirs" "$overlay_dir" chroot/
|
|
|
|
mount_overlay "$lowerdirs" "${overlay_dir}-initial" chroot/
|
|
|
|
else
|
|
|
|
else
|
|
|
|
ln -s "$overlay_dir/" chroot
|
|
|
|
ln -s "$overlay_dir/" chroot
|
|
|
|
fi
|
|
|
|
fi
|
|
|
@ -319,13 +268,22 @@ create_chroot_pass () {
|
|
|
|
lb chroot_devpts remove ${*}
|
|
|
|
lb chroot_devpts remove ${*}
|
|
|
|
|
|
|
|
|
|
|
|
if [ -n "$lowerdirs" ]; then
|
|
|
|
if [ -n "$lowerdirs" ]; then
|
|
|
|
umount chroot
|
|
|
|
# Although the current chroot was created as an overlay over
|
|
|
|
rmdir chroot
|
|
|
|
# the previous layer, many operations can result in redundant
|
|
|
|
|
|
|
|
# files in the upperdir. Rather than trying to minimize the
|
|
|
|
|
|
|
|
# overlay by hand, we rsync the chroot into a fresh overlay,
|
|
|
|
|
|
|
|
# rely on rsyncs ability to avoid redundant file operations,
|
|
|
|
|
|
|
|
# and take _that_ overlay's upperdir as the content of the
|
|
|
|
|
|
|
|
# layer.
|
|
|
|
|
|
|
|
mkdir chroot-2
|
|
|
|
|
|
|
|
mount_overlay "$lowerdirs" "$overlay_dir" chroot-2/
|
|
|
|
|
|
|
|
rsync -aXHAS --del chroot/ chroot-2/
|
|
|
|
|
|
|
|
umount chroot chroot-2
|
|
|
|
|
|
|
|
rmdir chroot chroot-2
|
|
|
|
|
|
|
|
rm -rf ${overlay_dir}-initial
|
|
|
|
else
|
|
|
|
else
|
|
|
|
rm chroot
|
|
|
|
rm chroot
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
reduce_pass_size $pass
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if [ ! -d chroot.bootstrap/ ]; then
|
|
|
|
if [ ! -d chroot.bootstrap/ ]; then
|
|
|
|