diff --git a/board/myna-player-odyssey/rootfs_overlay/usr/sbin/pre-init b/board/myna-player-odyssey/rootfs_overlay/usr/sbin/pre-init index b2cd8fc..7cfaf9b 100755 --- a/board/myna-player-odyssey/rootfs_overlay/usr/sbin/pre-init +++ b/board/myna-player-odyssey/rootfs_overlay/usr/sbin/pre-init @@ -16,7 +16,7 @@ # Step 1: Set up a temporary root on a tmpfs on /run # Since root is read-only, we'll use /run for our tmpfs mount # This tmpfs will store all our temporary files used for OverlayFS operation -mount -t tmpfs none /run +mount -t tmpfs tmpfs /run # Step 2: Mount and initialize the data partition at /run/data # For OverlayFS we need a partition (/dev/mmcblk2p6 in our case) and two @@ -41,7 +41,7 @@ ln -s /old_root/$i /run/$i done -# Step 4: Pivot our current root +# Step 4: Move current root # When using OverlayFS we have to make sure both the lower directory (in our # case the read-only root) and upper directory (in our case the data # partition's overlay root) don't contain each other. @@ -50,17 +50,23 @@ # The solution to this is to move the current root mount to /run/old_root. # The util-linux provides a tool for this: pivot_root. # In our case the pivot_root utility will move our read-only root filesystem -# from / to /run/old_root and chroot all running processes to /run. -# In order for this new root to work we need to have /bin, /sbin and /lib in -# /run with working programs so we can continue execution by calling a shell. +# from / to /run/old_root. +# The current version of Linux (5.8 as of writing) will automatically chroot +# all running applications to the /run directory, but this is explicitly not +# guaranteed behaviour. So we will have to chroot to /run ourselves next. + +mkdir /run/old_root && pivot_root /run/ /run/old_root + +# Note: Bash doesn't natively support chrooting and continuing execution, so we +# have to do the previous steps in one long invocation. Apologies. + +# Step 5: Chroot to /run so we have a proper root after pivoting +# In order for this step to work we need to have /bin, /sbin and /lib in /run +# with working programs so we can continue execution by calling a shell. # In step 3 we set up links to the now pivoted old_root's bin, sbin and lib # directories so everything will work fine. -mkdir /run/old_root -cd /run/ # Set working directory for pivot_root -pivot_root . /run/old_root - -# Step 5: Mount OverlayFS on /new_root (previously /run/new_root) +# Step 6: Mount OverlayFS on /new_root (previously /run/new_root) # At this point we have the following directories of interest: # - /old_root containing our read-only root filesystem # - /data/overlay_root containing our writeable root filesystem @@ -69,13 +75,11 @@ # When making the OverlayFS root, we use the /old_root as the lowerdir, # /data/overlay_root as the upperdir, and /data/overlay_work as the workdir. -mkdir new_root -mount -t overlay overlay -o lowerdir=/old_root,upperdir=/data/overlay_root,workdir=/data/overlay_work /new_root - -# Step 6: Chroot to /new_root and run /sbin/init within the root +# Step 7: Chroot to /new_root and run /sbin/init within the root # This finally boots the system from the overlay root. Yay! # Since we chroot instead of pivoting root, we leave our /run tmpfs in memory # but no longer accessible. This shouldn't take up much memory given it's just # a few mounts and symbolic links. -exec chroot /new_root /sbin/init +# Okay, finally do steps 5 to 7. +exec chroot . sh -c "mkdir new_root && mount -t overlay overlay -o lowerdir=/old_root,upperdir=/data/overlay_root,workdir=/data/overlay_work /new_root && exec chroot /new_root /sbin/init"