site  contact  subhomenews

Save session by pivot_root for overlayfs

September 12, 2025 — BarryK

Yesterday, posted about problems with saving the session for overlayfs:

Which implemented saving at shutdown by an indirect method, where the session save is completed at next bootup.

However, I have figured out a direct save at shutdown, by pivot_root. What this involves is to pivot to a new filesystem, thus rendering the original overlay filesystem inoperable. Direct writes can then be done to the save-folders -- they are multiple, because the main desktop and containers each have their own save-folders, named ".session".

The sequence at shutdown is you choose poweroff or reboot from the menu on the main desktop. This runs scripts 'wmpoweroff' or 'wmreboot', which in turn call scripts 'poweroff' or 'reboot', which run /etc/rc.d/rc.shutdown and finally run 'busybox poweroff' or 'busybox reboot'. This may seem rather a lot of steps, but was worked out this way right back in the early Puppy days.

Latest change to rc.shutdown:

  if "${EOS_LAYERFS}" == "aufs" ];then #20250911
   /etc/rc.d/rw-merge 2>/dev/console
  else #overlay...
   #indirect method works, but trying pivot_root direct save...
   #mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.session-transit
   #/etc/rc.d/rw-merge '.session-transit'
   ##...initrd will complete saving the session (including containers).
   exec /etc/rc.d/shutdown-pivot-root ${PARAM1}
   #...will not return.
  fi

...where $PARAM1 is "reboot" or "poweroff'. Here is shutdown-pivot-root:

#!/bin/ash
#20250911 called from rc.shutdown
#passed in "reboot" or "poweroff"

. /etc/rc.d/PUPSTATE
. /etc/DISTRO_SPECS

#EXE1="$(cat /tmp/wmexitmode.txt)" #poweroff or reboot
EXE1="${1}"
-z "${EXE1}" ] && EXE1=poweroff

-d /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/rw1 ] && rm -rf /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/rw1
-d /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/wkg11 ] && rm -rf /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/wkg1
mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/rw1
mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/ro1
mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/wkg1
mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.shutdown/top1

cd /mnt/${WKG_DEV}/${WKG_DIR}.shutdown
busybox mount -t squashfs ../sfs/easyos/${DISTRO_BINARY_COMPAT}/${DISTRO_COMPAT_VERSION}/easy_${DISTRO_VERSION}_amd64.sfs ro1

busybox mount -t overlay -o xino=on,nfs_export=off,index=off,uuid=null,verity=off,redirect_dir=off,metacopy=off,lowerdir=ro1,upperdir=rw1,workdir=wkg1 overlay top1
#busybox mount -t aufs -o udba=none,br=rw1=rw:ro1=ro aufs top1

mkdir -p top1/old_root
cd top1
busybox pivot_root old_root

if [ ! -e /old_root/etc/DISTRO_SPECS ];then
 cd /
 echo -e "\\033[1;31m" >/dev/console #red
 echo "ERROR: unable to pivot_root" >/dev/console
 echo "Fallback to indrect save (completed at next bootup)..." >/dev/console
 echo -e "\\033[0;39m" >/dev/console #restore default color.
 busybox umount top1 2>/dev/null
 busybox umount ro1 2>/dev/null
 sleep 0.5
 mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}.session-transit
 /etc/rc.d/rw-merge '.session-transit'
else
 #busybox mount -t proc proc /proc
 #20250913 in rw-merge will write direct to ro layer of old overlayfs
 # this will upset it, docs say cause "undefined behaviour" but it won't crash.
 # the following line works, but just in case "undefined behaviour" causes changes
 # on the rw layer, copy it instead of symlink...
 #busybox ln -snf /old_root/mnt/.easy_rw /mnt/.easy_rw
 busybox cp -a /old_root/mnt/.easy_rw /mnt/
 busybox ln -snf /old_root/mnt/.easy_ro /mnt/.easy_ro
 busybox mkdir -p /mnt
 busybox ln -snf /old_root/mnt/${WKG_DEV} /mnt/${WKG_DEV}
 busybox ln -snf /old_root/mnt/${WKG_DEV}/${WKG_DIR} /mnt/wkg
 busybox cp -a -f /old_root/etc/rc.d/PUPSTATE /etc/rc.d/
 busybox cp -a -f /old_root/etc/rc.d/rw-merge /etc/rc.d/
 echo "Saving sessions (main desktop and containers)..." >/dev/console
 /etc/rc.d/rw-merge >/dev/console 2>&1
fi

sync
busybox umount /mnt/${WKG_DEV} 2>/dev/null
if $? -ne ];then
 busybox umount -r /mnt/${WKG_DEV} 2>/dev/null
fi

busybox umount -ar > /dev/null 2>&1

#poweroff or reboot...
busybox ${EXE1}
###end###

...it works!

What it does is create another overlay filesystem, with easy.sfs as the ro layer, then pivot_root into it. It is quite simple. I put in some just-in-case code, fallback to indirect-save in case the pivot_root fails. Note, 'pivot-root' is a busybox applet; it is also in util-linux package, but I have kept the busybox one in EasyOS.   

Tags: easy