diff --git a/dracut-initramfs-restore.sh b/dracut-initramfs-restore.sh index ff6c3869..1feec108 100644 --- a/dracut-initramfs-restore.sh +++ b/dracut-initramfs-restore.sh @@ -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 diff --git a/dracut.sh b/dracut.sh index 184e4769..421fc1b1 100755 --- a/dracut.sh +++ b/dracut.sh @@ -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 diff --git a/lsinitrd.sh b/lsinitrd.sh index ffdb4a4f..66cfa9bc 100755 --- a/lsinitrd.sh +++ b/lsinitrd.sh @@ -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 -- \ diff --git a/modules.d/99squash/clear-squash.sh b/modules.d/99squash/clear-squash.sh deleted file mode 100755 index 4f357817..00000000 --- a/modules.d/99squash/clear-squash.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -mnt="/squash/root" -for dir in jsquash/root/*; do - mnt="$mnt ${dir#$SQUASH_MNT}" -done -umount --lazy -- $mnt diff --git a/modules.d/99squash/init-squash.sh b/modules.d/99squash/init-squash.sh index fee0105e..3de6f819 100755 --- a/modules.d/99squash/init-squash.sh +++ b/modules.d/99squash/init-squash.sh @@ -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 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 the squashfs image -mount -t squashfs -o ro,loop $SQUASH_IMG $SQUASH_MNT +# Setup new root overlay +mkdir /newroot +mount -t overlay overlay -o lowerdir=/squash/root,upperdir=/squash/overlay/upper,workdir=/squash/overlay/work/ /newroot/ -if [ $? != 0 ]; then - echo "Unable to mount squashed initramfs image" -fi +# Move all mount points to new root to prepare chroot +mount --move /squash /newroot/squash -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 -t overlay overlay -o\ - lowerdir=$lowerdir,upperdir=$upperdir,workdir=$workdir $mntdir -done - -exec /init.orig - -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 diff --git a/modules.d/99squash/module-setup.sh b/modules.d/99squash/module-setup.sh index 59933447..50c92c31 100644 --- a/modules.d/99squash/module-setup.sh +++ b/modules.d/99squash/module-setup.sh @@ -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 } diff --git a/modules.d/99squash/squash-mnt-clear.service b/modules.d/99squash/squash-mnt-clear.service deleted file mode 100644 index 9d94c524..00000000 --- a/modules.d/99squash/squash-mnt-clear.service +++ /dev/null @@ -1,17 +0,0 @@ -# This file is part of dracut. -# - -[Unit] -Description=Cleanup squashfs mounts when switch root -DefaultDependencies=no -Before=initrd-switch-root.service -After=initrd-switch-root.target -ConditionPathExists=/squash/root - -[Service] -Type=oneshot -RemainAfterExit=no -StandardInput=null -StandardOutput=journal+console -StandardError=journal+console -ExecStart=/squash/clear-squash.sh