Skip to content

Commit

Permalink
refactor(squash): structure in a cleaner way
Browse files Browse the repository at this point in the history
Simplify the squash mount layout. Instead of overlay on each top
directory (/etc, /usr), just mount and switch_root into the squash
image, with a overlay on top of it.

Also install the binaries and setup scripts separately, so the squash
setup code and the squash image content is independent of each other,
all squash setup script and binaries can be deleted safely upon
switch_root.

With this change, previous squash clean up service and other tricky
implementations are all gone.

This commit depends on systemd commits from:
systemd/systemd#18124

Previouly systemd doesn't recognize non-ramfs initramfs, now this is
doable with SYSTEMD_IN_INITRD=lenient

Signed-off-by: Kairui Song <kasong@redhat.com>
  • Loading branch information
ryncsn authored and johannbg committed Mar 9, 2021
1 parent bdd194b commit 8f7c332
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 117 deletions.
4 changes: 2 additions & 2 deletions dracut-initramfs-restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ else
fi

if [[ -d squash ]]; then
unsquashfs -no-xattrs -f -d . squash/root.img >/dev/null
unsquashfs -no-xattrs -f -d . squash-root.img >/dev/null
if [ $? -ne 0 ]; then
echo "Squash module is enabled for this initramfs but failed to unpack squash/root.img" >&2
echo "Squash module is enabled for this initramfs but failed to unpack squash-root.img" >&2
rm -f -- /run/initramfs/shutdown
exit 1
fi
Expand Down
4 changes: 2 additions & 2 deletions dracut.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2057,8 +2057,8 @@ fi
if dracut_module_included "squash"; then
readonly squash_dir="$initdir/squash/root"
readonly squash_img="$initdir/squash/root.img"
readonly squash_img="$initdir/squash-root.img"
mkdir -p "$squash_dir"
dinfo "*** Install squash loader ***"
DRACUT_SQUASH_POST_INST=1 module_install "squash"
fi
Expand Down
2 changes: 1 addition & 1 deletion lsinitrd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ list_files()

list_squash_content()
{
SQUASH_IMG="squash/root.img"
SQUASH_IMG="squash-root.img"
SQUASH_TMPFILE="$TMPDIR/initrd.root.sqsh"

$CAT "$image" 2>/dev/null | cpio --extract --verbose --quiet --to-stdout -- \
Expand Down
6 changes: 0 additions & 6 deletions modules.d/99squash/clear-squash.sh

This file was deleted.

70 changes: 19 additions & 51 deletions modules.d/99squash/init-squash.sh
Original file line number Diff line number Diff line change
@@ -1,61 +1,29 @@
#!/bin/bash
#!/bin/sh
PATH=/bin:/sbin

SQUASH_IMG=/squash/root.img
SQUASH_MNT=/squash/root
# Basic mounts for mounting a squash image
mkdir /proc /sys /dev /run
mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sysfs /sys
mount -t devtmpfs -o mode=755,noexec,nosuid,strictatime devtmpfs /dev
mount -t tmpfs -o mode=755,nodev,nosuid,strictatime tmpfs /run

# Following mount points are neccessary for mounting a squash image

[ ! -d /proc/self ] && \
mount -t proc -o nosuid,noexec,nodev proc /proc

[ ! -d /sys/kernel ] && \
mount -t sysfs -o nosuid,noexec,nodev sysfs /sys

[ ! -e /dev/loop-control ] && \
mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev

# Need a loop device backend, overlayfs, and squashfs module
# Load required modules
modprobe loop
if [ $? != 0 ]; then
echo "Unable to setup loop module"
fi

modprobe squashfs
if [ $? != 0 ]; then
echo "Unable to setup squashfs module"
fi

modprobe overlay
if [ $? != 0 ]; then
echo "Unable to setup overlay module"
fi

[ ! -d "$SQUASH_MNT" ] && \
mkdir -m 0755 -p $SQUASH_MNT

# Mount the squashfs image
mount -t squashfs -o ro,loop $SQUASH_IMG $SQUASH_MNT

if [ $? != 0 ]; then
echo "Unable to mount squashed initramfs image"
fi

for file in $SQUASH_MNT/*; do
file=${file#$SQUASH_MNT/}
lowerdir=$SQUASH_MNT/$file
workdir=/squash/overlay-work/$file
upperdir=/$file
mntdir=/$file

mkdir -m 0755 -p $workdir
mkdir -m 0755 -p $mntdir
# Mount the squash image
mount -t ramfs ramfs /squash
mkdir -p /squash/root /squash/overlay/upper /squash/overlay/work
mount -t squashfs -o ro,loop /squash-root.img /squash/root

mount -t overlay overlay -o\
lowerdir=$lowerdir,upperdir=$upperdir,workdir=$workdir $mntdir
done
# Setup new root overlay
mkdir /newroot
mount -t overlay overlay -o lowerdir=/squash/root,upperdir=/squash/overlay/upper,workdir=/squash/overlay/work/ /newroot/

exec /init.orig
# Move all mount points to new root to prepare chroot
mount --move /squash /newroot/squash

echo "Something went wrong when trying to exec original init!"
exit 1
# Jump to new root and clean setup files
SYSTEMD_IN_INITRD=lenient exec switch_root /newroot /init
56 changes: 18 additions & 38 deletions modules.d/99squash/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,36 @@ depends() {
}

installpost() {
local squash_candidate=( "usr" "etc" )

# shellcheck disable=SC2174
mkdir -m 0755 -p "$squash_dir"
for folder in "${squash_candidate[@]}"; do
mv "$initdir/$folder" "$squash_dir/$folder"
# Move everything under $initdir except $squash_dir
# itself into squash image
for i in "$initdir"/*; do
[[ "$squash_dir" == "$i"/* ]] || mv "$i" "$squash_dir"/
done

# Move some files out side of the squash image, including:
# - Files required to boot and mount the squashfs image
# - Files need to be accessible without mounting the squash image
# - Initramfs marker
for file in \
"$squash_dir"/usr/lib/dracut/* \
"$squash_dir"/etc/initrd-release
do
# Create mount points for squash loader
mkdir -p "$initdir"/squash/
mkdir -p "$squash_dir"/squash/

# Copy dracut spec files out side of the squash image
# so dracut rebuild and lsinitrd can work
for file in "$squash_dir"/usr/lib/dracut/*; do
[[ -f $file ]] || continue
DRACUT_RESOLVE_DEPS=1 dracutsysrootdir="$squash_dir" inst "${file#$squash_dir}"
rm "$file"
done

# Install required files for the squash image setup script.
inst_multiple modprobe mount mkdir ln echo rm

mv "$initdir"/init "$initdir"/init.orig
inst "$moddir"/init-squash.sh /init
inst "$moddir"/clear-squash.sh /squash/clear-squash.sh

# Keep systemctl outsite if we need switch root
if [[ ! -f "$initdir/lib/dracut/no-switch-root" ]]; then
inst "systemctl"
fi

# Remove duplicated files
for folder in "${squash_candidate[@]}"; do
find "$initdir/$folder/" -not -type d \
-exec bash -c 'mv -f "$squash_dir${1#$initdir}" "$1"' -- "{}" \;
done

# Install required modules for the squash image init script.
# Install required modules and binaries for the squash image init script.
DRACUT_RESOLVE_DEPS=1 inst_multiple sh mount modprobe mkdir switch_root
hostonly="" instmods "loop" "squashfs" "overlay"
dracut_kernel_post

# Install squash image init script.
ln -sfn /usr/bin "$initdir/bin"
ln -sfn /usr/sbin "$initdir/sbin"
inst_simple "$moddir"/init-squash.sh /init
}

install() {
if [[ $DRACUT_SQUASH_POST_INST ]]; then
installpost
return
fi

inst "$moddir/squash-mnt-clear.service" "$systemdsystemunitdir/squash-mnt-clear.service"
$SYSTEMCTL -q --root "$initdir" add-wants initrd-switch-root.target squash-mnt-clear.service
}
17 changes: 0 additions & 17 deletions modules.d/99squash/squash-mnt-clear.service

This file was deleted.

0 comments on commit 8f7c332

Please sign in to comment.