dracut
dracut copied to clipboard
rd.live.ram=1 may fill up /run if tmpfs is too small
Describe the bug
Many distros now cap the total size of the /run
filesystem at a relatively small percentage of RAM. For example, Fedora Security Live F38 on a VM with 4 GB of RAM caps /run
at only 779.89 MB. This is not enough to contain the complete ISO when rd.live.ram=1
is requested. When dracut writes the rootfs image to /run/initramfs/squashed.img
, it fills up /run
and fails the boot.
Distribution used Fedora Security Live F38
Dracut version 059-2.fc38
Init system systemd-253.2-1.fc38
To Reproduce
- Obtain
Fedora-Security-Live-x86_64-38-1.6.iso
- Configure a VM in GNOME Boxes or libvirt with 4000 MB of RAM
- At the GRUB2 menu, choose a normal boot option like "Start Fedora-Security Live 38." Press
e
to edit the boot options. Addrd.live.ram=1 rd.break rd.shell
to the end of thelinux
options line. Pressctrl-x
to boot. - Observe that dracut fails to mount the rootfs because
mount
can't recognize the filesystem. - Run
and verify that aecho "something something something" >/run/initramfs/testfile
no space left on device
error occurs. Also verify that/run/initramfs/squashed.img
is smaller than it should be. - tmpfs size may be queried with
cat /proc/self/mountinfo
Expected behavior I believe that dracut dmsquash-live and livenet should either:
- Create a tmpfs just for
squashed.img
that is large enough to contain it; OR - Resize the existing tmpfs for
/run
so that it is large enough to containsquashed.img
.
Without changes to dracut, distros that want to support rd.live.ram
will need to ensure that /run/initramfs
is large enough.
Additional context
Requesting rd.live.ram=1
on a system with not enough memory may put the system under severe memory pressure. #2344 adds the capability to check for this, and we probably don't need to second-guess this check.
The tmpfs(5)
default size is 50% of memory. The default size should be large enough on most modern hardware to contain a live image of "reasonable" size. It is clear that some distos opt for a lower size
limit for /run
.
See also downstream bug RH-2035641
This is also a problem when you have rd.writable.fsimg=1
This option copies the rootfs.img into /run, this image can be very large.
It used to run fine on f38 but no longer works on f39. The /run should be resized automatically to fit the image when writable.fsimg is used otherwise you get "no space left on device"
If you are experiencing this issue and need to temporarily fix it until dracut has a more permanent solution, you can create a custom dracut module, that remounts /run at the size you need like this:
File: module-setup.sh, executable:
#!/bin/bash
check() {
return 0
}
depends() {
return 0
}
install() {
inst_hook pre-udev 10 "$moddir/run-remount.sh"
}
File run-remount.sh, executable:
#!/bin/sh
# Append emergency_shell to debug.
SIZE="16000M"
echo "Mounting /run with $SIZE" > /dev/kmsg
mount -t tmpfs -o remount,mode=755,rw,nosuid,nodev,size="$SIZE",nr_inodes=819200,inode64 tmpfs /run
mkdir /usr/lib/dracut/modules.d/90dmsquash-a
mv run-remount.sh /usr/lib/dracut/modules.d/90dmsquash-a
mv module-setup.sh /usr/lib/dracut/modules.d/90dmsquash-a
echo 'add_dracutmodules+=dmsquash-a' >> /etc/dracut.conf.d/remount.conf
Then when dracut runs it will pick up the new module and during boot remount /run with the size of 16GB.
Perhaps https://github.com/dracutdevs/dracut/pull/2551
I tested the https://github.com/dracutdevs/dracut/pull/2551 and it does not solve the problem with rd.writable.fsimg=1
In 90dmsquash-live module in dmsquash-live-root.sh The code that uses the new function is:
fi
if [ -e "$SQUASHED" ]; then
if [ -n "$live_ram" ]; then
imgsize=$(($(stat -c %s -- $SQUASHED) / (1024 * 1024)))
check_live_ram $imgsize
echo 'Copying live image to RAM...' > /dev/kmsg
echo ' (this may take a minute)' > /dev/kmsg
dd if=$SQUASHED of=/run/initramfs/squashed.img bs=512 2> /dev/null
echo 'Done copying live image to RAM.' > /dev/kmsg
SQUASHED="/run/initramfs/squashed.img"
fi
...
This only takes care of the squashfs.img
But writable.fsimg which is a little lower in the file does not use it and the cp command will fail:
if [ -n "$FSIMG" ]; then
if [ -n "$writable_fsimg" ]; then
# mount the provided filesystem read/write
echo "Unpacking live filesystem (may take some time)" > /dev/kmsg
mkdir -m 0755 -p /run/initramfs/fsimg/
if [ -n "$SQUASHED" ]; then
cp -v $FSIMG /run/initramfs/fsimg/rootfs.img
else
unpack_archive $FSIMG /run/initramfs/fsimg/
fi
FSIMG=/run/initramfs/fsimg/rootfs.img
fi
Thanks for helping. I misspoke earlier, this is the one I wanted to point out - https://github.com/dracutdevs/dracut/pull/2604
CC @FGrose