LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   LinuxQuestions.org Member Success Stories (https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/)
-   -   A readonly rootfs with a writeable overlay...without an initramfs (https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/a-readonly-rootfs-with-a-writeable-overlay-without-an-initramfs-4175639487/)

marler8997 09-30-2018 11:19 PM

A readonly rootfs with a writeable overlay...without an initramfs
 
Thought I should share and discuss a solution I came up with for having a readonly rootfs without having to have an initramfs. What I wanted was a readonly rootfs in its own block along with a writeable block for storing persistent changes (an overlay works great for this). My first thought was to create an initramfs to set this up but I think I came up with a better solution. The problem with an initramfs is that pretty much everything in it is just a copy of what's already in the rootfs. So the more you put into your initramfs (maybe you want it to more tools in case it fails and you want to recover) the more duplication you create (NOTE: bootloaders have the same conundrum with the kernel).

So the solution I came up with was to boot directly to the readonly rootfs and setup the overlay from there before starting systemd/sysv or whatever init program is installed. I created a small BASH script that sets up the rootfs overlay and then "exec"s to the real init process and you're done, no need for an initramfs. Since the rootfs is readonly, you can use a squashfs and you just put it in its own partition on the disk. I call the script "reinit" and it's also configurable via the kernel command line. Here's an example of what it might look like:

NOTE: in this example, I'm creating two disks, one that contains the bootloader/kernel/rootfs, and the second which is meant to hold all the changes to the rootfs. This allows you to 1) see all the changes by looking at the contents of the second disk and/or 2) swap out disks to update the rootfs and/or revert back to the stock rootfs

sda1: contains the rootfs (can be squashfs because it's readonly!)
sdb: a whole disk formatted with some filesystem that contains the upper/work dirs for the rootfs overlay

root=/dev/sda1 init=/sbin/reinit reinit.mountsrc=/dev/sdb

I thought it was a pretty neat idea. Now I don't have to bother with an initramfs, what should I have in it, should I sign it, how do I duplicate error handling with what the rootfs does etc. But I'm new to linux so there might be better ways to do what I've done here. Let me know if anyone knows of better solutions.

The reinit bash script is included below:
Code:

#!/bin/bash
#
# Support parameters (via command line or kernel parameter):
# ------------------------------------------------------------------------------
# reinit.mountsrc=<source_device>
# todo: maybe support reinit.dir (use a sub-directory in the mounted filesystem)
# todo: maybe support mounttype when an explicit mountsrc is supplied
# todo: add support for reinit.init=...

onfail() {
    echo Error occurred, dropping to bash
    /bin/bash
    exit 1
}
trap onfail ERR

echorun() {
    echo "$@"
    "$@"
}
echorun mount -t proc none /proc

# process kernel and passed in command-line parameters
set -- $(cat /proc/cmdline) "$@"
for arg in "$@"; do
  case "$arg" in
    reinit.mountsrc=*)
      mountsrc="${arg#reinit.mountsrc=}"
      ;;
    reinit.dir=*)
      dir="${arg#reinit.dir=}"
      echo Error: reinit.dir not supported yet
      onfail
      ;;
  esac
done

echo "reinit.mountsrc='$mountsrc'"
#echo "reinit.dir='$dir'"

if [[ -z "$mountsrc" ]]; then
  echorun mount -t tmpfs none /reinit_dir
else
  # todo: maybe support an explicit mount type
  echorun mount $mountsrc /reinit_dir
fi

echorun mkdir -p /reinit_dir/rootfs /reinit_dir/rootfs_upper /reinit_dir/rootfs_work
echorun mount -t overlay overlay /reinit_dir/rootfs -o lowerdir=/,upperdir=/reinit_dir/rootfs_upper,workdir=/reinit_dir/rootfs_work

echorun mkdir -p /reinit_dir/rootfs/oldroot
echorun cd /reinit_dir/rootfs
echorun pivot_root . oldroot
echorun exec /sbin/init
echo Error: reinit: exec /sbin/init failed
onfail


MCon 04-20-2020 05:09 AM

News?
 
Hi,
I stumbled on this and it looks interesting.
Do You have newer versions of this?
TiA!

ondoho 04-21-2020 01:39 AM

Quote:

Originally Posted by MCon (Post 6113713)
Hi,
I stumbled on this and it looks interesting.
Do You have newer versions of this?
TiA!

Why do you think it requires an update?
Have you tried it?

MCon 04-21-2020 01:49 AM

Hi,
I asked for a new revision, if available, because it has several issues marked "TODO" and one such thing (reinit.dir) would be useful to me.
Since it is "old code" I also wanted to avoid starting from something somewhat obsolete.
Code is simple enough I went ahead and modified to suit my needs.

Thanks
Mauro

ondoho 04-22-2020 05:57 AM

Quote:

Originally Posted by MCon (Post 6114016)
Code is simple enough I went ahead and modified to suit my needs.

You might want to share that; others might benefit. That's how FOSS works, even if it's only small things.


All times are GMT -5. The time now is 03:22 AM.