RAMBOOT with continuous rsync synchronization
Posted 07-20-2017 at 11:55 AM by IsaacKuo
Tags ramboot ssd tmpfs
RAMBOOT is an initrd hack that loads the entire OS partition in RAM, making it run like an extremely fast SSD, at the expense of perhaps 1.5+GB of RAM.
Previously I described RAMBOOT using a compressed OS tarball. This is good for boot time, but it takes time to create a new tarball. This new How-To takes a different approach - simply copying an entire directory tree using piped tar commands (cp won't work because of the limited initrd environment). This increases boot time, but allows fast incremental updates to keep the hard drive copy synced up.
This how-to is for Debian 9, but it'll work for other versions of Debian (including ones before systemd) and also similar distributions.
- - - - - 8< - - - - - cute here - - - - - 8< - - - - -
Step 1) MINIMAL DEBIAN INSTALL
Do a minimal Debian install on /dev/sda1 (either a hard drive or USB, typically) and boot to it. Deselect all software suites, unless you're sure you want them.
Step 2) PREPARE CUSTOMIZED local.RAMBACK
Make a couple copies of the local initramfs script with:
Edit local.RAMBACK by replacing the root mount line from this:
to this:
Step 3) INSTALL rsync, CREATE IMAGE
Log in as root. Install rsync, and create image with:
Step 4) PREPARE /ramback/etc/fstab
Edit /ramback/etc/fstab, changing the mount point of the current / and adding the following line:
The resulting /ramback/etc/fstab will look something like:
Step 5) CREATE CUSTOM BOOT FILES
Reboot, and see if it works! Choose "advanced options" to choose between ramboot and normal mode.
Step 6) Uninstall grub-pc
After you have booted into the RAMBOOT option, use the following command to uninstall grub-pc:
If you don't do this, then attempts to install an update which includes kernel updates will fail when it tries to run "update-grub". The cleanest way to prevent this problem is to simply uninstall grub-pc. Updates will still update initrd and vmlinuz. However, you will have to manually copy them from /boot (in ram) to /mnt/sda1/boot/initrd.img-ramboot and /mnt/sda1/boot/vmlinuz-ramboot.
MAINTENANCE
When you want to rsync the current OS state to disk, use the following command:
Note that this command is very fast. It only copies over the changed files, and it's pretty efficient at skipping all the unchanged files. If you want, you can even use a bash script which continuously loops to keep it synced up often:
If you use a script like this, I recommend manually initiating it and running it in an open window. That way, you will see it churning away and you can confirm that it's operating just by looking at the window. If you run it in a background process, there's a risk that something has gone wrong with it and you didn't realize. Then later, oops! You get a rude shock when there's a power cut and it turns out you have lost a lot of work. Also, having its activity visible in a window makes it easy to stop it for when you want to install updates or other maintenance tasks.
INSTALLING XFCE4 GUI
Here's an example for installing a GUI. It's not the most stripped down option, but it's easy to specify without being too heavyweight.
Previously I described RAMBOOT using a compressed OS tarball. This is good for boot time, but it takes time to create a new tarball. This new How-To takes a different approach - simply copying an entire directory tree using piped tar commands (cp won't work because of the limited initrd environment). This increases boot time, but allows fast incremental updates to keep the hard drive copy synced up.
This how-to is for Debian 9, but it'll work for other versions of Debian (including ones before systemd) and also similar distributions.
- - - - - 8< - - - - - cute here - - - - - 8< - - - - -
Step 1) MINIMAL DEBIAN INSTALL
Do a minimal Debian install on /dev/sda1 (either a hard drive or USB, typically) and boot to it. Deselect all software suites, unless you're sure you want them.
Step 2) PREPARE CUSTOMIZED local.RAMBACK
Make a couple copies of the local initramfs script with:
Code:
cd /usr/share/initramfs-tools/scripts cp -vax local local.NORMAL cp -vax local local.RAMBACK
Code:
mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
Code:
### MODIFIED FOR RAMBACK ### mkdir /ijkijk ###mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ijkijk mount -t tmpfs -o size=95% none ${rootmnt} cd /ijkijk/ramback tar cv . | (cd ${rootmnt} ; tar x) cd / umount /ijkijk ### MODIFIED FOR RAMBACK ###
Log in as root. Install rsync, and create image with:
Code:
apt-get install rsync apt-get clean mkdir /ramback rsync -vaxAX --delete --exclude ramback /. /ramback/ mkdir /ramback/mnt/sda1 cd /ramback/usr/share/initramfs-tools/scripts cp -vax local.RAMBACK local
Edit /ramback/etc/fstab, changing the mount point of the current / and adding the following line:
Code:
none / tmpfs size=95% 0 1
Code:
UUID=5129efa8-fd32-58e4-83fd-2e3afdbcdef653 /mnt/sda1 ext4 error=remount-ro 0 1 none / tmpfs size=95% 0 1
Code:
cd /usr/share/initramfs-tools/scripts/ cp -vax local.RAMBACK local mkinitramfs -o /boot/initrd.img-ramboot cp -vax local.NORMAL local cp -vax /boot/vmlinuz-4.9.0-3-amd64 /boot/vmlinuz-ramboot update-grub
Step 6) Uninstall grub-pc
After you have booted into the RAMBOOT option, use the following command to uninstall grub-pc:
Code:
apt-get remove --purge grub-pc
MAINTENANCE
When you want to rsync the current OS state to disk, use the following command:
Code:
rsync -vaxAX --delete /. /mnt/sda1/ramback/
Code:
#!/bin/sh while true; do rsync -vaxAX --delete /. /mnt/sda1/ramback/ sleep 7 done
INSTALLING XFCE4 GUI
Here's an example for installing a GUI. It's not the most stripped down option, but it's easy to specify without being too heavyweight.
Code:
apt-get install xorg xfce4 lightdm apt-get clean
Total Comments 8
Comments
-
Does not work for me. Selecting the RAMBOOT option still boots normally.
I did not do a minimal install. I used my live system for the ramback dir. I have a separate /boot fs on /dev/md0 and / on /dev/md1.
On the first boot of the RAMBOOT option, firstly the /mnt dir was empty and /ramback/{vmlinux,initrd.img} were broken symlinks to /ramback/boot/vmlinuz-4.9.... and initrd.img-4.9......respectively. This was easily corrected but a reboot still rebooted normally.Posted 08-29-2017 at 12:51 AM by towheedm -
Quote:
Be very careful when doing "mkinitramfs -o /boot/initrd.img-ramboot" that the custom code is present in /usr/share/initramfs-tools/scripts/local at that time.
I would recommend you repeat the instructions very carefully. You don't need to scrap the contents of /ramback first, because the rsync command will scrap any differences for you. Pay very close attention to the custom local.RAMBACK code and make sure to copy local.RAMBACK to local before the mkinitramfs step.
Note that there are two branches to the "if" statement for mounting the root file system. My instructions only modify the branch where the root file system's type is known (which I think should really always be the case). But if for some reason you're still not getting it to work, maybe modify both branches of the "if" statement.
Quote:I did not do a minimal install. I used my live system for the ramback dir. I have a separate /boot fs on /dev/md0 and / on /dev/md1.
Instead, mount /dev/md0 to "/bootMD0" instead of "/boot". That way, apt will simply ignore the contents and never write anything to it. You can then manually copy whatever updated initrd/vmlinuz pair apt updates from /boot to /bootMD0/initrd.img-ramboot and /bootMD0/vmlinuz-ramboot
Quote:On the first boot of the RAMBOOT option, firstly the /mnt dir was empty and /ramback/{vmlinux,initrd.img} were broken symlinks to /ramback/boot/vmlinuz-4.9.... and initrd.img-4.9......respectively. This was easily corrected but a reboot still rebooted normally.
Code:... mkdir /ramback/mnt/sda1 ...
Posted 08-29-2017 at 09:37 AM by IsaacKuo -
The problem for me is the -x option in the rsync command used for copying / to /ramback. Because /boot was on a different fs, it did not get copied over to /ramback. This was corrected.
However, now once I booted, it added about 200s to my boot time and I did not see any decrease in RAM usage to account for the ramboot image in RAM. From your code, it appears that the tarball is built on every boot. According to df, I'm using 17G on my / fs.
I should get about 1G/s read out of the RAID10 that / is on. I'm gonna re-benchmark and see the actual results. I can't recall the results from about 2 yrs ago.
I'll return to this after my ZFS endeavours.Posted 08-29-2017 at 07:59 PM by towheedm
Updated 08-29-2017 at 08:01 PM by towheedm -
The code in this How-To does not create any tarball. It uses a piped pair of tar commands instead of "cp -vax" because "cp" just doesn't have enough juice to do the job in the limited initrd environment.
As for your RAM usage - if you use "free" to determine your ram usage, you will not see tmpfs usage correctly reflected in it. Unfortunately, "free" thinks that anything in tmpfs is file system buffers. Truthfully, tmpfs is in fact implemented as file system buffers, but they have no backing file system so it's impossible for tmpfs "buffers" to get flushed to the non-existent backing file system.
To determine whether the thing is working properly, use "df" to see that your "/" file system is indeed a tmpfs file system. You can also use a different tool to see your true RAM usage, including all tmpfs file systems. For example, gnome-system-monitor shows the correct RAM and swap usage.
Note that even though there is no backing file system for tmpfs, tmpfs blocks CAN be swapped out to swap. This is useful because there is a lot of stuff in "/" which is rarely if ever accessed. This stuff will eventually get swapped out to swap if necessary.Posted 08-29-2017 at 08:16 PM by IsaacKuo -
Quote:To determine whether the thing is working properly, use "df" to see that your "/" file system is indeed a tmpfs file system.
That being said, I did not see any improvement in the loading speed of apps:
GIMP - ~2sec from SSD and ramboot
LibreOffice ~3 sec from SSD and ramboot
KDE took about the same time to reach the desktop. I did not check the actual ~ time.
Code:tar cv . | (cd ${rootmnt} ; tar x)
Posted 08-29-2017 at 09:13 PM by towheedm
Updated 08-29-2017 at 09:19 PM by towheedm -
If you experienced no significant speed up in loading time, then that means that the applications you're loading are already heavily CPU limited rather than disk speed limited.
Loading 17GB in 200s means a read speed of about 85MB/sec. Honestly, that's not very good. It may be the result of your RAID and file system not being very efficient at reading many small files. Web browser caches are particularly bad for this (which is why I tend to put /home/kuo/.cache on its own separate tmpfs or on an SSD). You'd probably find a huge improvement in boot time by using a compressed tarball instead of this rsync synchronization, but ... really, what's the point? The real life performance gain in your use case is practically nonexistent.Posted 08-30-2017 at 02:31 AM by IsaacKuo -
BTW, this still works in Debian 10 Buster.
Posted 07-19-2019 at 05:16 PM by IsaacKuo -
Just a minor update - for a long time, my RAMBOOT init scripts failed to work in Debian 10 Buster. I do not know why.
I decided to give it a whirl for Debian 11 Bullseye, and ... it works again! The mount statement is a bit different from the above - it's now part of an "if" statement. But you make basically the same modification, just put the mkdir above the IF and the rest of the statements after the FI. So it looks like this:
Code:# Mount root # shellcheck disable=SC2086 # if ! mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"; then # panic "Failed to mount ${ROOT} as root file system." # fi mkdir /ijkijk if ! mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" /ijkijk ; then panic "Failed to mount ${ROOT} as root file system." fi mount -t tmpfs -o size=95% none "${rootmnt?}" cd /ijkijk/ramback tar cv . | (cd "${rootmnt?}" ; tar x) cd / umount /ijkijk
Posted 08-18-2021 at 03:09 PM by IsaacKuo