LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Blogs > IsaacKuo
User Name
Password

Notices


Rate this Entry

RAMBOOT with continuous rsync synchronization

Posted 07-20-2017 at 11:55 AM by IsaacKuo

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:
Code:
cd /usr/share/initramfs-tools/scripts
cp -vax local local.NORMAL
cp -vax local local.RAMBACK
Edit local.RAMBACK by replacing the root mount line from this:
Code:
mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
to this:
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 ###
Step 3) INSTALL rsync, CREATE IMAGE

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
Step 4) PREPARE /ramback/etc/fstab

Edit /ramback/etc/fstab, changing the mount point of the current / and adding the following line:
Code:
none /   tmpfs size=95% 0 1
The resulting /ramback/etc/fstab will look something like:
Code:
UUID=5129efa8-fd32-58e4-83fd-2e3afdbcdef653 /mnt/sda1    ext4 error=remount-ro 0 1
none /   tmpfs size=95% 0 1
Step 5) CREATE CUSTOM BOOT FILES

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
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:

Code:
apt-get remove --purge 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:

Code:
rsync -vaxAX --delete /. /mnt/sda1/ramback/
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:
Code:
#!/bin/sh
while true; do
 rsync -vaxAX --delete /. /mnt/sda1/ramback/
 sleep 7
done
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.

Code:
apt-get install xorg xfce4 lightdm
apt-get clean
Posted in Uncategorized
Views 4271 Comments 8
« Prev     Main     Next »
Total Comments 8

Comments

  1. Old Comment
    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 towheedm is offline
  2. Old Comment
    Quote:
    Originally Posted by towheedm View Comment
    Does not work for me. Selecting the RAMBOOT option still boots normally.
    If it boots normally, then the initrd.img-ramboot somehow failed to get the custom code for /usr/share/initramfs-tools/scripts/local

    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.
    This requires a little adjusting, but it will still basically work fine. The important thing is to NOT mount /dev/md0 as /boot within /ramback/etc/fstab. IF YOU DO THIS, THEN YOU WILL EVENTUALLY BREAK YOUR NORMAL INSTALL. Why? Because at some point you'll boot up into your RAMBOOT system and do an apt update which updates initrd. This will overwrite your normal initrd and mess up your way to boot into your normal install!

    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.
    If the correct custom initrd code had been baked into initrd.img-ramboot, then it would have loaded up the file tree underneath /ramback into the tmpfs "/". This would have properly included /mnt/sda1 because of the instruction step:

    Code:
    ...
    mkdir /ramback/mnt/sda1
    ...
    As for the broken symlinks - it is important to NOT fix any broken symlinks underneath /ramback. Those symlinks need to be exactly the way they are after the rsync in order to load up properly into the tmpfs "/".
    Posted 08-29-2017 at 09:37 AM by IsaacKuo IsaacKuo is offline
  3. Old Comment
    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 towheedm is offline
    Updated 08-29-2017 at 08:01 PM by towheedm
  4. Old Comment
    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 IsaacKuo is offline
  5. Old Comment
    Quote:
    To determine whether the thing is working properly, use "df" to see that your "/" file system is indeed a tmpfs file system.
    OK, that explains why it reported tmpfs on / as 30G with 17G in use.

    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)
    This is where my additional boot time is spent. All 200s or so.
    Posted 08-29-2017 at 09:13 PM by towheedm towheedm is offline
    Updated 08-29-2017 at 09:19 PM by towheedm
  6. Old Comment
    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 IsaacKuo is offline
  7. Old Comment
    BTW, this still works in Debian 10 Buster.
    Posted 07-19-2019 at 05:16 PM by IsaacKuo IsaacKuo is offline
  8. Old Comment
    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 IsaacKuo is offline
 

  



All times are GMT -5. The time now is 09:42 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration