Skip to content

Instantly share code, notes, and snippets.

@emsi
Forked from paul-ridgway/ro-root.sh
Last active July 25, 2021 08:39
Show Gist options
  • Select an option

  • Save emsi/3c7143f0583566aad14bad182297a104 to your computer and use it in GitHub Desktop.

Select an option

Save emsi/3c7143f0583566aad14bad182297a104 to your computer and use it in GitHub Desktop.

Revisions

  1. emsi revised this gist Jan 10, 2021. 1 changed file with 1 addition and 11 deletions.
    12 changes: 1 addition & 11 deletions ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -97,17 +97,7 @@ mount --move /proc /mnt/newroot/proc
    cd /mnt/newroot
    pivot_root . mnt
    exec chroot . sh -c "$(cat <<END
    # # move ro and rw mounts to the new root
    # mount --move /mnt/mnt/lower/ /ro
    # if [ $? -ne 0 ]; then
    # echo "ERROR: could not move ro-root into newroot"
    # /bin/bash
    # fi
    # mount --move /mnt/mnt/rw /rw
    # if [ $? -ne 0 ]; then
    # echo "ERROR: could not move tempfs rw mount into newroot"
    # /bin/bash
    # fi
    # unmount unneeded mounts so we can unmout the old readonly root
    umount -l -f /mnt
    umount -l -f /dev
  2. emsi revised this gist Jan 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -109,9 +109,9 @@ exec chroot . sh -c "$(cat <<END
    # /bin/bash
    # fi
    # unmount unneeded mounts so we can unmout the old readonly root
    umount -l -f /mnt
    umount -l -f /dev
    umount -l -f /proc
    umount -l -f /mnt
    # continue with regular init
    exec /sbin/init
    END
  3. emsi revised this gist Jan 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    # Version 1.2:
    # Don't mount ro/rw root inside newroot
    # Don't remove root from ftab
    # Move dev to newroot and redirect execed chrooted subshell console to newroot's dev
    # Move dev & proc to newroot and redirect execed chrooted subshell console to newroot's dev
    # Version 1.1:
    # Changed to use /proc/mounts rathern than /etc/fstab for deriving the root filesystem.
    #
  4. emsi revised this gist Jan 10, 2021. 1 changed file with 11 additions and 14 deletions.
    25 changes: 11 additions & 14 deletions ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,10 @@
    #!/bin/sh

    # Read-only Root-FS for Raspian using overlayfs
    # Version 1.2:
    # Don't mount ro/rw root inside newroot
    # Don't remove root from ftab
    # Move dev to newroot and redirect execed chrooted subshell console to newroot's dev
    # Version 1.1:
    # Changed to use /proc/mounts rathern than /etc/fstab for deriving the root filesystem.
    #
    @@ -56,7 +60,6 @@ modprobe overlay
    if [ $? -ne 0 ]; then
    fail "ERROR: missing overlay kernel module"
    fi
    # mount /proc
    mount -t proc proc /proc

    # create a writable fs to then create our mountpoints
    @@ -86,16 +89,11 @@ mount -t overlay -o lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/w
    if [ $? -ne 0 ]; then
    fail "ERROR: could not mount overlayFS"
    fi
    # # create mountpoints inside the new root filesystem-overlay
    # mkdir /mnt/newroot/ro
    # mkdir /mnt/newroot/rw

    # # remove root mount from fstab (this is already a non-permanent modification)
    # grep -v "$rootDev" /mnt/lower/etc/fstab > /mnt/newroot/etc/fstab
    # echo "#the original root mount has been removed by overlayRoot.sh" >> /mnt/newroot/etc/fstab
    # echo "#this is only a temporary modification, the original fstab" >> /mnt/newroot/etc/fstab
    # echo "#stored on the disk can be found in /ro/etc/fstab" >> /mnt/newroot/etc/fstab
    # change to the new overlay root
    # move dev&proc to newroot
    mount --move /dev /mnt/newroot/dev
    mount --move /proc /mnt/newroot/proc

    cd /mnt/newroot
    pivot_root . mnt
    exec chroot . sh -c "$(cat <<END
    @@ -111,11 +109,10 @@ exec chroot . sh -c "$(cat <<END
    # /bin/bash
    # fi
    # unmount unneeded mounts so we can unmout the old readonly root
    # umount /mnt/mnt
    umount /mnt/proc
    umount -l -f /mnt/dev
    umount -l -f /dev
    umount -l -f /proc
    umount -l -f /mnt
    # continue with regular init
    exec /sbin/init
    END
    )"
    )" <dev/console >dev/console 2>&1
  5. emsi revised this gist Jan 10, 2021. 1 changed file with 21 additions and 20 deletions.
    41 changes: 21 additions & 20 deletions ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -86,31 +86,32 @@ mount -t overlay -o lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/w
    if [ $? -ne 0 ]; then
    fail "ERROR: could not mount overlayFS"
    fi
    # create mountpoints inside the new root filesystem-overlay
    mkdir /mnt/newroot/ro
    mkdir /mnt/newroot/rw
    # remove root mount from fstab (this is already a non-permanent modification)
    grep -v "$rootDev" /mnt/lower/etc/fstab > /mnt/newroot/etc/fstab
    echo "#the original root mount has been removed by overlayRoot.sh" >> /mnt/newroot/etc/fstab
    echo "#this is only a temporary modification, the original fstab" >> /mnt/newroot/etc/fstab
    echo "#stored on the disk can be found in /ro/etc/fstab" >> /mnt/newroot/etc/fstab
    # # create mountpoints inside the new root filesystem-overlay
    # mkdir /mnt/newroot/ro
    # mkdir /mnt/newroot/rw

    # # remove root mount from fstab (this is already a non-permanent modification)
    # grep -v "$rootDev" /mnt/lower/etc/fstab > /mnt/newroot/etc/fstab
    # echo "#the original root mount has been removed by overlayRoot.sh" >> /mnt/newroot/etc/fstab
    # echo "#this is only a temporary modification, the original fstab" >> /mnt/newroot/etc/fstab
    # echo "#stored on the disk can be found in /ro/etc/fstab" >> /mnt/newroot/etc/fstab
    # change to the new overlay root
    cd /mnt/newroot
    pivot_root . mnt
    exec chroot . sh -c "$(cat <<END
    # move ro and rw mounts to the new root
    mount --move /mnt/mnt/lower/ /ro
    if [ $? -ne 0 ]; then
    echo "ERROR: could not move ro-root into newroot"
    /bin/bash
    fi
    mount --move /mnt/mnt/rw /rw
    if [ $? -ne 0 ]; then
    echo "ERROR: could not move tempfs rw mount into newroot"
    /bin/bash
    fi
    # # move ro and rw mounts to the new root
    # mount --move /mnt/mnt/lower/ /ro
    # if [ $? -ne 0 ]; then
    # echo "ERROR: could not move ro-root into newroot"
    # /bin/bash
    # fi
    # mount --move /mnt/mnt/rw /rw
    # if [ $? -ne 0 ]; then
    # echo "ERROR: could not move tempfs rw mount into newroot"
    # /bin/bash
    # fi
    # unmount unneeded mounts so we can unmout the old readonly root
    umount /mnt/mnt
    # umount /mnt/mnt
    umount /mnt/proc
    umount -l -f /mnt/dev
    umount -l -f /mnt
  6. Paul Ridgway revised this gist Mar 24, 2018. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,10 @@
    #!/bin/sh

    # Read-only Root-FS for Raspian using overlayfs
    # Version 1.0
    # Version 1.1:
    # Changed to use /proc/mounts rathern than /etc/fstab for deriving the root filesystem.
    #
    # Version 1:
    # Created 2017 by Pascal Suter @ DALCO AG, Switzerland to work on Raspian as custom init script
    # (raspbian does not use an initramfs on boot)
    #
  7. Paul Ridgway created this gist Mar 24, 2018.
    118 changes: 118 additions & 0 deletions ro-root.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,118 @@
    #!/bin/sh

    # Read-only Root-FS for Raspian using overlayfs
    # Version 1.0
    #
    # Created 2017 by Pascal Suter @ DALCO AG, Switzerland to work on Raspian as custom init script
    # (raspbian does not use an initramfs on boot)
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program. If not, see
    # <http://www.gnu.org/licenses/>.
    #
    #
    # Tested with Raspbian mini, 2017-01-11
    #
    # This script will mount the root filesystem read-only and overlay it with a temporary tempfs
    # which is read-write mounted. This is done using the overlayFS which is part of the linux kernel
    # since version 3.18.
    # when this script is in use, all changes made to anywhere in the root filesystem mount will be lost
    # upon reboot of the system. The SD card will only be accessed as read-only drive, which significantly
    # helps to prolong its life and prevent filesystem coruption in environments where the system is usually
    # not shut down properly
    #
    # Install:
    # copy this script to /sbin/overlayRoot.sh and add "init=/sbin/overlayRoot.sh" to the cmdline.txt
    # file in the raspbian image's boot partition.
    # I strongly recommend to disable swapping before using this. it will work with swap but that just does
    # not make sens as the swap file will be stored in the tempfs which again resides in the ram.
    # run these commands on the booted raspberry pi BEFORE you set the init=/sbin/overlayRoot.sh boot option:
    # sudo dphys-swapfile swapoff
    # sudo dphys-swapfile uninstall
    # sudo update-rc.d dphys-swapfile remove
    #
    # To install software, run upgrades and do other changes to the raspberry setup, simply remove the init=
    # entry from the cmdline.txt file and reboot, make the changes, add the init= entry and reboot once more.

    fail(){
    echo -e "$1"
    /bin/bash
    }

    # load module
    modprobe overlay
    if [ $? -ne 0 ]; then
    fail "ERROR: missing overlay kernel module"
    fi
    # mount /proc
    mount -t proc proc /proc

    # create a writable fs to then create our mountpoints
    mount -t tmpfs inittemp /mnt
    if [ $? -ne 0 ]; then
    fail "ERROR: could not create a temporary filesystem to mount the base filesystems for overlayfs"
    fi
    mkdir /mnt/lower
    mkdir /mnt/rw
    mount -t tmpfs root-rw /mnt/rw
    if [ $? -ne 0 ]; then
    fail "ERROR: could not create tempfs for upper filesystem"
    fi
    mkdir /mnt/rw/upper
    mkdir /mnt/rw/work
    mkdir /mnt/newroot

    # mount root filesystem readonly
    rootDev=`awk '$2 == "/" {print $1}' /proc/mounts`
    rootMountOpt=`awk '$2 == "/" {print $4}' /proc/mounts`
    rootFsType=`awk '$2 == "/" {print $3}' /proc/mounts`
    mount -t ${rootFsType} -o ${rootMountOpt},ro ${rootDev} /mnt/lower
    if [ $? -ne 0 ]; then
    fail "ERROR: could not ro-mount original root partition"
    fi
    mount -t overlay -o lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work overlayfs-root /mnt/newroot
    if [ $? -ne 0 ]; then
    fail "ERROR: could not mount overlayFS"
    fi
    # create mountpoints inside the new root filesystem-overlay
    mkdir /mnt/newroot/ro
    mkdir /mnt/newroot/rw
    # remove root mount from fstab (this is already a non-permanent modification)
    grep -v "$rootDev" /mnt/lower/etc/fstab > /mnt/newroot/etc/fstab
    echo "#the original root mount has been removed by overlayRoot.sh" >> /mnt/newroot/etc/fstab
    echo "#this is only a temporary modification, the original fstab" >> /mnt/newroot/etc/fstab
    echo "#stored on the disk can be found in /ro/etc/fstab" >> /mnt/newroot/etc/fstab
    # change to the new overlay root
    cd /mnt/newroot
    pivot_root . mnt
    exec chroot . sh -c "$(cat <<END
    # move ro and rw mounts to the new root
    mount --move /mnt/mnt/lower/ /ro
    if [ $? -ne 0 ]; then
    echo "ERROR: could not move ro-root into newroot"
    /bin/bash
    fi
    mount --move /mnt/mnt/rw /rw
    if [ $? -ne 0 ]; then
    echo "ERROR: could not move tempfs rw mount into newroot"
    /bin/bash
    fi
    # unmount unneeded mounts so we can unmout the old readonly root
    umount /mnt/mnt
    umount /mnt/proc
    umount -l -f /mnt/dev
    umount -l -f /mnt
    # continue with regular init
    exec /sbin/init
    END
    )"