Browse Source
With all files stored in ramfs, and most of them are not compressed, the initramfs will take up a lot of memory. Besides, if the file number is large, each file will waste some memory due to page fragmetation. This is due to ramfs' design, at least one page will be allocated for one file however small the file is. On machine with large page size, this will become worse and waste too many memory. One approach to reducing the memory usage is to reduce the number of files that got directly loaded into the root ramfs, and compress files by put most files will into a read-only squash image and keep a minimum set of executable and libraries outside as the loader for the squash image. After the squash image is mounted, the real 'init' will be executed and then everything behaves as usual. This patch will introduce a '99squash' module which will never be included by default. User can force add it, and if it is included, dracut will perform some extra steps before creating the final image: For now, "/etc" and "/usr" will be moved into the squashfs image. "/init" will be renamed to "/init.stock" and replaced by "/init.squash". Files and folders need to be accessible before mounting the image will be still avaliable at their original place. And due to squashfs is readonly, an overlayfs layer will be created on top of squashfs mount point, as many dracut module require readwrite access to "/etc" and "/usr", "init.squash" will ultimately call "/init.stock". An extra systemd service will be installed. This service will umount all squashfs related mount points right before switch-root to release resources properly. This service will not actually do anything if switch-root is not used. This is very helpful when mem resource is very limited, like Kdump. According to my tests, this squash module can help save about 35MB of memory with 64K page size, or about 15MB with 4K page size on an ordinary kdump capture routine. This module could also help reduce memory usage for normal boot up process. Won't change any behavior if squash module is not enabled. Signed-off-by: Kairui Song <kasong@redhat.com>master


7 changed files with 246 additions and 0 deletions
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh |
||||
SQUASH_MNT_REC=/squash/mounts |
||||
SQUASH_MNTS=( ) |
||||
|
||||
while read mnt; do |
||||
SQUASH_MNTS+=( "$mnt" ) |
||||
done <<< "$(cat $SQUASH_MNT_REC)" |
||||
|
||||
umount --lazy -- ${SQUASH_MNTS[@]} |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh |
||||
/squash/setup-squash.sh |
||||
|
||||
exec /init.stock |
||||
|
||||
echo "Something went wrong when trying to start original init executable!" |
||||
exit 1 |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash |
||||
|
||||
check() { |
||||
return 255 |
||||
} |
||||
|
||||
depends() { |
||||
echo "bash systemd systemd-initrd" |
||||
return 0 |
||||
} |
||||
|
||||
installkernel() { |
||||
hostonly="" instmods squashfs loop overlay |
||||
} |
||||
|
||||
install() { |
||||
if ! type -P mksquashfs >/dev/null || ! type -P unsquashfs >/dev/null ; then |
||||
derror "squash module requires squashfs-tools to be installed." |
||||
return 1 |
||||
fi |
||||
|
||||
inst_multiple kmod modprobe mount mkdir ln echo |
||||
inst $moddir/setup-squash.sh /squash/setup-squash.sh |
||||
inst $moddir/clear-squash.sh /squash/clear-squash.sh |
||||
inst $moddir/init.sh /squash/init.sh |
||||
|
||||
inst "$moddir/squash-mnt-clear.service" "$systemdsystemunitdir/squash-mnt-clear.service" |
||||
ln_r "$systemdsystemunitdir/squash-mnt-clear.service" "$systemdsystemunitdir/initrd.target.wants/squash-mnt-clear.service" |
||||
} |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh |
||||
PATH=/bin:/sbin |
||||
|
||||
SQUASH_IMG=/squash/root.img |
||||
SQUASH_MNT=/squash/root |
||||
SQUASH_MNT_REC=/squash/mounts |
||||
SQUASHED_MNT="usr etc" |
||||
|
||||
echo $SQUASH_MNT > $SQUASH_MNT_REC |
||||
|
||||
# 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 |
||||
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 $SQUASHED_MNT; do |
||||
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 |
||||
|
||||
echo $mntdir >> $SQUASH_MNT_REC |
||||
done |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh |
||||
/squash/setup-squash.sh |
||||
|
||||
exec /shutdown.stock |
||||
|
||||
echo "Something went wrong when trying to start original shutdown executable!" |
||||
exit 1 |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
# This file is part of dracut. |
||||
# |
||||
|
||||
[Unit] |
||||
Description=Cleanup squashfs mounts when switch root |
||||
DefaultDependencies=no |
||||
After=initrd.target |
||||
After=dracut-initqueue.service dracut-pre-pivot.service |
||||
Before=initrd-cleanup.service |
||||
ConditionPathExists=/squash/root |
||||
Conflicts=initrd-switch-root.target |
||||
|
||||
[Service] |
||||
Type=oneshot |
||||
RemainAfterExit=yes |
||||
StandardInput=null |
||||
StandardOutput=syslog+console |
||||
StandardError=syslog+console |
||||
ExecStop=/squash/clear-squash.sh |
Loading…
Reference in new issue