puppylinux-woof-CE / woof-CE

woof - the Puppy builder
GNU General Public License v2.0
389 stars 277 forks source link

Overlayfs in "testing", init and rc.shutdown #3456

Open gyrog opened 1 year ago

gyrog commented 1 year ago

The patches mentioned in this message reside in github.

I started testing the new overlayfs feature in JammyPup32 a few weeks ago. I inserted the current 'init' script into a 'local-initrd.gz', the utilities into a 'ydrv_upupjj+d_22.04.sfs', and appended " punionfs=overlay" to it's 'linux' line in 'grub.cfg' This seemed to work Ok, a savefolder on ext4 running pupmode=12.

I then tried pupmode=13, and was surprised when it seemed stable. I remember reading the "overlayfs" documentation and it saying that directly changing the contents of a "read-only" layer produced an "undetermined" result. I won't be using overlayfs pupmode=13, but then I never use aufs pupmode=13.

There were a few things I noticed;

1) I kept getting "Recovering journal" messages from the fsck of the ext4 partition during the next boot. After applying 'rc.shutdown-overlay.diff' to the 'rc.shutdown' in the ydrv, shutdowns are clean. (This is a bit of a "quick and dirty", there may be a "better" way of implementing the same thing.)

2) I noticed that in 'init', mount "move"'s have been replaced with mount "bind"'s. I don't know what the reasoninng is behind this, but the one in the 'ensure_save_mounted()' function causes a problem for the 'umount_unneeded()' function so I produced 'init-move.diff' to re-establish mount "move" in this case. (It really is just a re-name of the mount-point.)

3) The save "upgrade" code seems to process aufs whiteout files(.wh.), but not overlayfs whiteout files(character device files, use "find / -type c" to list them). The other thing about the save "upgrade" code is that it requires access to the actual RW directory, for overlayfs this means the '/upper' directory.

4) There is an inconsistency between the naming of the overlayfs top layer directories between pupmode=5 and other pupmodes. I would suggest that a consistent naming scheme be implemented, e.g. there should be a primary save directory and the 2 directories "rw" (or "upper" if you will) and "work" would be it's top level. So this could be implemented for pupmode=5 with '/mnt/tmpfs' as the primary directory with '/mnt/tmpfs/rw' and '/mnt/tmpfs/work', then '/pup_rw' is a symbolic link to '/mnt/tmpfs/rw'. Or go the other way and always call them 'pup_rw' and 'pup_work', e.g. a zram mounted as '/mnt/top' with '/mnt/top/pup_rw' and '/mnt/top/pup_work', '/pup_rw' is a symbolic link to '/mnt/top/pup_rw'. This could be done for all saving methods even when aufs is being used. This would provide consistency for all new Puppies, but a small issue for backporting the 'init' script. Hmmm..., there would be an issue with swaping a save-folder from aufs to overlayfs and back, each unionfs would ignore the others whiteout files.

BUT, I would suggest that consideration be given to the 'init-singly.diff' patch. This rather large patch against the 'init' script in the woof-CE "testing" branch, "merges" the "do one thing at a time" algorithm from the 'init-experiment' branch with the current 'init'. This is now the 'init' in the 'init-experiment' branch, and the 'init' I've neen running in my overlayfs JammyPup32 for a while now. It's also contained in 'local-initrd.gz' which can be downloaded from mediafire.

To minimise the dependence on a particular unionfs, the processing of the ".sfs" files, and the save method, produces a stack-layer list, a ":" delimited list of directories in stack order, top to bottom. Then an appropriate stack is mounted, using this stack-layer list.

This 'init' processes the ".sfs" files one by one, from being just an identifying character to being a directory in the stack-layer list. This includes checking for all means of specifying an alternate file, decoding any UUID's etc... What sfs files are processed is defined by 2 ' ' delimited lists, here is the default definitions:

APPEND_DRVS="f z" PREPEND_DRVS="y b a k"

The puppy...sfs is not included in the definitions, since it must be present, and it's directory(mount-point) becomes the core of the stack-layer list. When each item in $APPEND_DRVS is being processed it's resultant directory(mount-point) is added to the end of the stack-layer list. When each item in $PREPEND_DRVS is being processed it's resultant directory(mount-point) is added to the begining of the stack-layer list.

The "save" processing code then adds an RW directory to the front of the stack-layer list, except for pupmode=13, which adds a 'pup_r01' to the front of the stack-layer list before adding the RW directory.

This version of 'init' logs a lot more information about each processed ".sfs" file in '/initrd/tmp/bootinit.log'. It represents a much more "straight-forward" algorithm, because it doesn't decode all the boot parameters in one place, or all the UUID's in one place, etc..., thus avoiding a significant number of global variables for each drv.

There is also the added feature of the 'DRV_SPECS' text file, that allows the user to define which drv's to load and their location. Here is my 'DRV_SPECS' file for my test JammyPup32:

DRV_AP="f z s x" DRV_PRE="y b k" DRV_f=':/pups/aadesk_firmware.sfs' DRV_s=':/pups/aadesk_setup.sfs' DRV_x=':devx_upupjj+d_22.04+6.sfs'

The first 2 lines override APPEND_DRVS and PREPEND_DRVS respectively. Note that 'adrv_upupjj+d_22.04.sfs' is ommitted, and therefore ignored. The last 3 lines define the files to be used instead of 'fdrv_upupjj+d_22.04.sfs', 'sdrv_upupjj+d_22.04.sfs', and 'xdrv_upupjj+d_22.04.sfs'

Note: This 'init' does not attempt to resolve my issues 3) or 4) above.

It might also be noticed that a temporary read-only overlayfs stack is mounted at '/pup_sfs' for 'initmodules' support, agnostic of the $UNIONFS setting. Hmmm..., this could be retained and used as a lower-dir for the real overlayfs stack, but more generally a facility for easily checking if a file exists in any Puppy system ".sfs" file.

gyrog commented 1 year ago

i've updated 'init-singly.diff' to account for the changed 'init' in "testing".

I can now remove 'init-move.diff'.

I have not updated the "init-experiment" branch, and I will not. It can be deleted.