├── etc ├── revdep-rebuild │ ├── 66-squashmount-changes │ ├── 66-squashmount-workdir │ ├── 66-squashmount-readonly │ └── 66-squashmount ├── systemd │ └── system │ │ └── squashmount.service.d │ │ └── timeout.conf └── portage │ └── repo.postsync.d │ └── 10-squashmount-gentoo ├── lib ├── find_cruft │ └── find_cruft.d │ │ └── 50-squashmount.pl └── squashmount.pl ├── tmpfiles.d └── squashmount.conf ├── openrc └── init.d │ └── squashmount ├── systemd └── system │ └── squashmount.service ├── demo.svg ├── compress.txt ├── zsh └── _squashmount ├── README.md └── ChangeLog /etc/revdep-rebuild/66-squashmount-changes: -------------------------------------------------------------------------------- 1 | SEARCH_DIRS_MASK=*.mount/changes 2 | -------------------------------------------------------------------------------- /etc/revdep-rebuild/66-squashmount-workdir: -------------------------------------------------------------------------------- 1 | SEARCH_DIRS_MASK=*.mount/workdir 2 | -------------------------------------------------------------------------------- /etc/revdep-rebuild/66-squashmount-readonly: -------------------------------------------------------------------------------- 1 | SEARCH_DIRS_MASK=*.mount/readonly 2 | -------------------------------------------------------------------------------- /lib/find_cruft/find_cruft.d/50-squashmount.pl: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # find_cruft should ignore *.mount/{changes,readonly,workdir} 3 | push(@cutre, '[^/]\.mount/(?:changes|readonly|workdir)$'); 4 | 1; 5 | -------------------------------------------------------------------------------- /etc/systemd/system/squashmount.service.d/timeout.conf: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | [Service] 3 | # Replace the value by a generous upper bound for the maximally 4 | # expected compression time on your system: 5 | TimeoutStopSec=15m 6 | -------------------------------------------------------------------------------- /tmpfiles.d/squashmount.conf: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Use "d" or "D" depending on whether /run is on a ramdisk or not. 3 | # With "D" make sure to run tmpfiles.d only once and before starting squasmount 4 | d /run/squashmount 0755 root root - 5 | -------------------------------------------------------------------------------- /openrc/init.d/squashmount: -------------------------------------------------------------------------------- 1 | #!/sbin/openrc-run 2 | # (C) Martin V\"ath 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | 5 | depend() { 6 | need localmount tmpfiles.setup 7 | } 8 | 9 | description='start/stop all squashmount configured mount points' 10 | 11 | start() { 12 | ebegin 'mounting with squashmount' 13 | squashmount start 14 | eend $? 15 | } 16 | 17 | stop() { 18 | ebegin 'umounting/stopping squashmount' 19 | squashmount -f --lsof=0 --lsof-ro=0 stop 20 | eend $? 21 | } 22 | -------------------------------------------------------------------------------- /systemd/system/squashmount.service: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | [Unit] 3 | Description=mount/umount all squashmount configured mount points 4 | After=local-fs.target systemd-tmpfiles-setup.service 5 | 6 | [Service] 7 | # Squashing can take a long time. It is recommended to override the following 8 | # long timeout in /etc/systemd/system/squashmount.service.d/timeout.conf 9 | TimeoutStopSec=1800 10 | Type=oneshot 11 | MemoryDenyWriteExecute=true 12 | NoNewPrivileges=true 13 | PrivateMounts=false 14 | PrivateNetwork=true 15 | RemainAfterExit=true 16 | ExecStart=/usr/bin/squashmount start 17 | ExecStop=/usr/bin/squashmount -f --lsof=0 --lsof-ro=0 stop 18 | 19 | [Install] 20 | WantedBy=multi-user.target 21 | -------------------------------------------------------------------------------- /demo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | % squashmount list 12 |  * [db]:     overlay/squashfs    (0), will resquash modifications 13 |  * [fetch]:  overlay/squashfs   (1k), unmodified (kill-or-resquash) 14 |  * [tex]:    overlay/squashfs    (0), unmodified 15 |  * [kernel]: overlay/squashfs   (1m), will kill modifications 16 |  * [office]: overlay/squashfs   (1k), unmodified 17 |  * [games]:  overlay/squashfs    (0), will resquash modifications 18 |  * [repos]:  overlay/squashfs  (40m), modified, but will not resquash 19 | % 20 | 21 | -------------------------------------------------------------------------------- /etc/revdep-rebuild/66-squashmount: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # The python variant of revdep-rebuild requires full paths and " " 3 | # On the other hand, it accecpts several SEARCH_DIR_MASK entries in one file 4 | SEARCH_DIRS_MASK="/*/*.mount/readonly" 5 | SEARCH_DIRS_MASK="/*/*.mount/readonly/*" 6 | SEARCH_DIRS_MASK="/*/*.mount/readonly/*/*" 7 | SEARCH_DIRS_MASK="/*/*.mount/readonly/*/*/*" 8 | SEARCH_DIRS_MASK="/*/*.mount/readonly/*/*/*/*" 9 | SEARCH_DIRS_MASK="/*/*.mount/changes" 10 | SEARCH_DIRS_MASK="/*/*.mount/changes/*" 11 | SEARCH_DIRS_MASK="/*/*.mount/changes/*/*" 12 | SEARCH_DIRS_MASK="/*/*.mount/changes/*/*/*" 13 | SEARCH_DIRS_MASK="/*/*.mount/changes/*/*/*/*" 14 | SEARCH_DIRS_MASK="/*/*.mount/workdir" 15 | SEARCH_DIRS_MASK="/*/*.mount/workdir/*" 16 | SEARCH_DIRS_MASK="/*/*.mount/workdir/*/*" 17 | SEARCH_DIRS_MASK="/*/*.mount/workdir/*/*/*" 18 | SEARCH_DIRS_MASK="/*/*.mount/workdir/*/*/*/*" 19 | SEARCH_DIRS_MASK="/*/*/*.mount/readonly" 20 | SEARCH_DIRS_MASK="/*/*/*.mount/readonly/*" 21 | SEARCH_DIRS_MASK="/*/*/*.mount/readonly/*/*" 22 | SEARCH_DIRS_MASK="/*/*/*.mount/readonly/*/*/*" 23 | SEARCH_DIRS_MASK="/*/*/*.mount/readonly/*/*/*/*" 24 | SEARCH_DIRS_MASK="/*/*/*.mount/changes" 25 | SEARCH_DIRS_MASK="/*/*/*.mount/changes/*" 26 | SEARCH_DIRS_MASK="/*/*/*.mount/changes/*/*" 27 | SEARCH_DIRS_MASK="/*/*/*.mount/changes/*/*/*" 28 | SEARCH_DIRS_MASK="/*/*/*.mount/changes/*/*/*/*" 29 | SEARCH_DIRS_MASK="/*/*/*.mount/workdir" 30 | SEARCH_DIRS_MASK="/*/*/*.mount/workdir/*" 31 | SEARCH_DIRS_MASK="/*/*/*.mount/workdir/*/*" 32 | SEARCH_DIRS_MASK="/*/*/*.mount/workdir/*/*/*" 33 | SEARCH_DIRS_MASK="/*/*/*.mount/workdir/*/*/*/*" 34 | -------------------------------------------------------------------------------- /etc/portage/repo.postsync.d/10-squashmount-gentoo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # This file remounts the squashmount mount-point "gentoo" after each syncing 4 | # of the "gentoo" repository. 5 | # Do not use this file if you want to use a mount-point named "gentoo" with 6 | # squashmount without using sync-type = squashdelta 7 | set -u 8 | 9 | repository_name=$1 10 | sync_uri=$2 11 | repository_path=$3 12 | 13 | # Run only if the configured sync-uri contains the string "/squash" 14 | case $sync_uri in 15 | */squash*) 16 | false;; 17 | *) 18 | exit 0;; 19 | esac 20 | 21 | # Run only for repository gentoo: 22 | [ x"$repository_name" = x'gentoo' ] || exit 0 23 | 24 | # Run only if mount-point gentoo is configured 25 | [ x"`squashmount --quiet print-tag gentoo 2>/dev/null`" = x'gentoo' ] || exit 0 26 | 27 | yesno() { 28 | case ${1:-n} in 29 | [nNfF]*|[oO][fF]*|0|-) 30 | return 1;; 31 | esac 32 | : 33 | } 34 | 35 | if [ -n "${PORTAGE_QUIET:++}" ] || yesno "${EINFO_QUIET-}" 36 | then 37 | einfo() { 38 | : 39 | } 40 | else 41 | init_colors() { 42 | if yesno "${RC_NOCOLOR-}" 43 | then NORMAL= 44 | GOOD= 45 | elif tput color >/dev/null 2>&1 46 | then NORMAL=`tput sgr0` 47 | init_colors=$NORMAL`tput bold` 48 | GOOD=$init_colors`tput setaf 2` 49 | else NORMAL=`printf '\033[0m'` 50 | GOOD=`printf '\033[32;01m'` 51 | fi 52 | init_colors() { 53 | : 54 | } 55 | } 56 | einfo() { 57 | init_colors 58 | printf '%s%s\n' " ${GOOD}*$NORMAL " "$*" 59 | } 60 | fi 61 | 62 | einfo 'squashmount remount gentoo' 63 | exit 64 | 65 | # Suppress all output in the following commands: 66 | { 67 | # Forcibly umount, even if portage should have messed up our mount... 68 | squashmount --lazy=1 --lsof=0 --lsof-ro=0 --ignore --force \ 69 | ${PORTAGE_QUIET:+-qq} umount gentoo 70 | 71 | # If portage should still have mounted DIR, we umount it: 72 | umount ${PORTAGE_QUIET:---verbose} -- "$repository_path" || \ 73 | umount ${PORTAGE_QUIET:---verbose} --lazy -- "$repository_path" 74 | 75 | } >/dev/null 2>&1 76 | 77 | # Finally the main purpose of this script: Mount gentoo with squashmount: 78 | 79 | exec squashmount mount gentoo 80 | -------------------------------------------------------------------------------- /compress.txt: -------------------------------------------------------------------------------- 1 | Comparison of some size/time for compression of large directories. 2 | Sorting is by size, if size is equal by time 3 | 4 | MB Core2 I3 Athlon 5 | 6 | /usr/lib/libreoffice: 7 | 8 | uncompressed 292 9 | xz -Xbcj x86 92 3:02 10 | xz 97 1:29 11 | lzma 97 1:22 12 | gzip 114 38 13 | lzo -Xcompression-level 9 125 1:04 14 | lzo 125 52 15 | lz4 -Xhc 134 10 16 | lz4 157 2 17 | 18 | The gentoo repository (including some overlays): 19 | 20 | uncompressed 332 21 | xz 77 2:01 22 | xz -Xbcj x86 77 3:20 23 | lzma 77 1:45 24 | gzip 90 53 25 | lzo -Xcompression-level 9 105 1:03 26 | lzo 105 59 27 | lz4 -Xhc 112 53 28 | lz4 137 51 29 | 30 | Gentoo's database of installed packages (/var/db): 31 | 32 | uncompressed 78 33 | xz -Xbcj x86 44 2:51 1:46 6:46 34 | xz 44 3:50 1:48 4:44 35 | lzma 44 3:11 1:47 4:24 36 | gzip 46 18 9 55 37 | lzo -Xcompression-level 9 48 11 6 55 38 | lzo 48 11 6 54 39 | lz4 -Xhc 49 6 3 27 40 | lz4 51 4 3 22 41 | 42 | Kernel sources with some .o files: 43 | 44 | uncompressed 796 45 | xz -Xbcj x86 151 7:59 3:29 46 | xz 151 4:13 1:44 47 | lzma 153 5:39 1:25 48 | gzip 181 1:24 39 49 | lzo -Xcompression-level 9 203 2:15 1:06 50 | lzo 204 1:49 52 51 | lz4 -Xhc 214 34 13 52 | lz4 282 18 6 53 | 54 | /usr/share/texmf-dist: 55 | 56 | uncompressed 2053 57 | xz -Xbcj x86 1349 7:41 58 | xz 1349 4:11 59 | lzma 1351 3:20 60 | gzip 1397 49 61 | lzo -Xcompression-level 9 1425 1:37 62 | lzo 1425 1:33 63 | lz4 -Xhc 1443 31 64 | lz4 1506 11 65 | 66 | /usr/share/games: 67 | 68 | uncompressed 749 69 | xz -Xbcj x86 502 2:51 70 | xz 502 1:20 71 | lzma 502 1:11 72 | gzip 521 31 73 | lzo -Xcompression-level 9 536 54 74 | lzo 536 44 75 | lz4 -Xhc 543 16 76 | lz4 570 6 77 | -------------------------------------------------------------------------------- /zsh/_squashmount: -------------------------------------------------------------------------------- 1 | #compdef squashmount 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | local curcontext="$curcontext" state state_descr line 4 | typeset -A opt_args 5 | _arguments -C -s -S : \ 6 | '(* -)'{'--help','-h'}'[print a brief help]' \ 7 | '(* -)'{'--man','-\\?'}'[show extended help as a manpage]' \ 8 | '(* -)'{'--version','-V'}'[print version and exit]' \ 9 | '*'{'-v','--verbose'}'[be more verbose (accumulative)]' \ 10 | '*'{'-q','--quiet'}'[be more quiet (accumulative)]' \ 11 | {'*-a+','*--arg='}'[add specified arg for user]:user arg:_files' \ 12 | {'*-c+','*--config='}'[add specified configfile to list]:configfile:_files' \ 13 | '*--system-config=[add specified configfile to fallbacks]:configfile:_files' \ 14 | {'*-u+','*--umount='}'[add specified option to umount DIR]:umount option:("-r")' \ 15 | {'*-U+','*--umount-ro='}'[add specified option to umount READONLY]:umount option:("-r")' \ 16 | '*--fumount=[add specified option to fusermount -u DIR)]:umount option:()' \ 17 | '*--fumount-ro=[add specified option to fusermount -u READONLY]:umount option:()' \ 18 | '*'{'--bind=','-2+'}'[replace directory in stored data]:directory path to replace:_files -P/ -W "(/)":directory path to replace with:_files -P/ -W "(/)"' \ 19 | {'(-/)--root=','(--root)-/'}'[use specified dir as original root]:original root directory:_files -P/ -W "(/)" -/' \ 20 | '--rundir=[use specified dir instead of /run/squashmount)]:runtime config dir:_files -/' \ 21 | '(--no-backup --nobackup -B '{'--backup)-b+','-b)--backup='}'[override BACKUP with specified file or appendix]:file or appendix:_files' \ 22 | '(--backup -b '{'--no-backup --nobackup)-B','--nobackup -B)--no-backup','--no-backup -B)--nobackup'}'[do not make a backup]' \ 23 | {'(--tempdir)-D+','(-D)--tempdir='}'[override TEMPDIR with specified dir]:tempdir:_files -/' \ 24 | {'(--compression --comp)-x','(--comp -x)--compression','(--compression -x)--comp'}'[override COMPRESSION with specified mode]:compression mode:(zstd xz lzma gzip lzo lz4)' \ 25 | '(--force-squash --squash-force --squash --no-squash --nosquash -s -n '{'--threshold)-t+','-t)--threshold='}'[set THRESHOLD to specified size]:threshold size:(0 1m 10m 20m 30m 40m 500k 600k 700k 800k 900k "")' \ 26 | '(--threshold --no-squash --nosquash --squash -t -s -n '{'--force-squash)--squash-force','--squash-force)--force-squash'}'[force resquash\: -t -2]' \ 27 | '(--threshold --force-squash --squash-force --no-squash --nosquash -t -n '{'--squash)-s','-s)--squash'}'[do resquash\: -t 0]' \ 28 | '(--threshold --force-squash --squash-force --squash -t -s '{'--no-squash --nosquash)-n','--nosquash -n)--no-squash','--no-squash -n)--nosquash'}'[no resquash\: -t -1]' \ 29 | {'(--separator)-S+','(-S)--separator='}'[use specified separator for print-...]:separator' \ 30 | '--squash-verbose=[use specified symbols for mksquash verbosity]:symbols [inpqrINPQR], flags (1-2+?!):(q nq ip pi r)' \ 31 | {'(--processors)-p+','(-p)--processors='}'[use specified mksquashfs -processors number]:processors:(\ 1 2 3 4 5 6 7 8 9)' \ 32 | {'(--mem)-m+','(-m)--mem='}'[use specified mksquashfs -mem size]:memory:(\ 210M 466M 1954M 3054M 7054M)' \ 33 | '--pass-dir[Args are paths]' \ 34 | {'(--interactive)-i','(-i)--interactive'}'[ask before cleaning directories]' \ 35 | '(--no-kill --nokill -K --kill-or-resquash -R '{'--kill)-k','-k)--kill'}'[clean without resquashing]' \ 36 | '(--no-kill --nokill -K --kill -k '{'--kill-or-resquash)-R','-R)--kill-or-resquash'}'[clean if not resquashing]' \ 37 | '(--kill -k --kill-or-resquash -R '{'--nokill --no-kill)-K','--nokill -K)--no-kill','--no-kill -K)--nokill'}'[Remove effect of --kill*]' \ 38 | {'(--force)-f','(-f)--force'}'[force action even if unreasonable]' \ 39 | {'(--ignore-state)-I','(-I)--ignore-state'}'[ignore state of mounts/umounts]' \ 40 | {'(--reset)-r','(-r)--reset'}'[reset after umounting]' \ 41 | '(--no-color --nocolor -C '{'-F)--color','(--color)-F'}'[force color on non-terminal]' \ 42 | '(--color -F '{'--no-color --nocolor)-C','--nocolor -C)--no-color','--no-color -E)--nocolor'}'[non-colored output]' \ 43 | '(--no-star --nostar)--star[print stars for info commands]' \ 44 | '(--star '{'--nostar)--no-star','--no-star)--nostar'}'[do not print stars]' \ 45 | '(--no-tar2sqfs --notar2sqfs --no-tar --notar '{'--tar)--tar2sqfs','--tar2sqfs)--tar'}'[use tar2sqfs]' \ 46 | '(--tar2sqfs --tar '{'--notar2sqfs --no-tar --notar)--no-tar2sqfs','--no-tar2sqfs --no-tar --notar)--notar2sqfs','--no-tar2sqfs --notar2sqfs --notar --notar)--no-tar','--no-tar2sqfs --notar2sqfs --no-tar)--notar'}'[do not use tar2sqfs]' \ 47 | '(--no-locking --nolocking)--locking[use file locking]' \ 48 | '(--locking '{'--nolocking)--no-locking','--no-locking)--nolocking'}'[do not use file locking]' \ 49 | '(--no-fatal --nofatal)--fatal[return nonzero on every failure]' \ 50 | '(--fatal '{'--nofatal)--no-fatal','--no-fatal)--nofatal'}'[return nonzero only on fatal failure]' \ 51 | '(--no-error -noerror -E '{'-e)--error','(--error)-e'}'[break on error]' \ 52 | '(--error -e '{'--no-error --noerror)-E','--noerror -E)--no-error','--no-error -E)--noerror'}'[no break on error]' \ 53 | '(--allow --noallow-other --no allow)--allow[allow_other default]' \ 54 | '(--allow '{'--noallow)--no-allow','--no-allow)--noallow'}'[no allow_other default]' \ 55 | '--user[user mode mounting]' \ 56 | {'(--lazy)-L+','(-L)--lazy='}'[0: not lazy, 1: lazy retry, -1: only lazy]:lazy mode:(0 1 -1)' \ 57 | {'(--lsof)-L+','(-l)--lsof='}'["": no lsof, 0: retry lazy, 1: error, -1: only lazy]:lsof mode:("" 0 1 -1)' \ 58 | '--lsof-ro=["": no lsof, 0: retry lazy, 1: error, -1: only lazy]:lsof mode:("" 0 1 -1)' \ 59 | '(--no-ll --noll)--ll[prefer squashfuse_ll over squashfuse]' \ 60 | '(--ll '{'--noll)--no-ll','--no-ll)--noll'}'[do not use squasfuse_ll]' \ 61 | {'(--order)-o+','(-o)--order='}'[set \@order to specified value]:tool order:("overlay!?,overlayfs!?,aufs!,unionfs-fuse!,unionfs!,funionfs!" "unionfs-fuse!!,funionfs!!" "overlay,overlayfs,aufs!,unionfs-fuse!" bind aufs overlay overlayfs unionfs unionfs-fuse funionfs)' \ 62 | {'(--squashorder)-O+','(-O)--squashorder='}'[set \@squashorder to specified value]:tool order:("squashfs!?,squashfuse!" "squasfuse!!" squashfs squashfuse)' \ 63 | {'*--title=','*-T+'}'[use specified title option]:title option:_title_opt' \ 64 | '1:command:->cmds' \ 65 | '*:mask:->mask' 66 | local ret=$? 67 | case $state in 68 | (cmds) 69 | local cmds 70 | cmds=( 71 | 'help:print a brief help' 72 | 'man:show extended help as a manpage' 73 | 'mount:mount' 74 | 'start:mount, creating squashfile first if necessary' 75 | 'umount:umount, squashing/cleaning if necessary' 76 | 'stop:umount and forget' 77 | 'check:check whether DIR is empty' 78 | 'forget:forget all information in /run/squashdir' 79 | 'remount:remount, squashing/cleaning if necessary' 80 | 'restart:stop and start' 81 | 'set:modify state in /run/squashdir' 82 | 'reset:restore state in /run/squashdir' 83 | {'status','list'}':output infos; depending on -v -vv' 84 | 'print-tag:print tag' 85 | 'print-dir:print DIR directory' 86 | 'print-readonly:print READONLY directory or 1' 87 | 'print-changes:print CHANGES directory' 88 | 'print-file:print squash-file path' 89 | 'print-mtime:print squash-file mtime' 90 | 'print-type:print mount type' 91 | 'print-squashtype:print squash mount type' 92 | 'print-new:print 1 if there is new data' 93 | 'print-will-squash:print 1 if data is resquashed' 94 | 'print-threshold:print active threshold value' 95 | 'print-kill:print 1 is --kill is active' 96 | ) 97 | _describe -t commands 'command' cmds && ret=0;; 98 | (mask) 99 | local expl 100 | if [[ -z ${opt_args[--pass-dir]++} ]] 101 | then _tags masks 102 | _tags && { 103 | local masks 104 | masks=(${(f)"$(_call_program print-masks 'squashmount --no-locking -q print-tag 2>/dev/null')"}) 105 | _description masks expl 'mask' 106 | compadd "$expl[@]" - $masks 107 | } && ret=0 108 | else local paths 109 | paths=(${(f)"$(_call_program print-dirs 'squashmount --no-locking -q print-dir 2>/dev/null')"}) 110 | _canonical_paths -A paths directories 'mount point' && ret=0 111 | fi;; 112 | esac 113 | return ret 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # squashmount 2 | 3 | (C) Martin Väth (martin at mvath.de) 4 | 5 | This project is under the BSD license 2.0 (“3-clause BSD license”). 6 | SPDX-License-Identifier: BSD-3-Clause 7 | 8 | Init and management script for mounting rewritable squashfs-compressed data 9 | 10 | This is the successor of the __squash_dir__ project 11 | - https://github.com/vaeth/squash_dir/ 12 | 13 | It is actually a ground-up rewrite of that project in perl with a 14 | highly improved control interface. 15 | 16 | One of its aims is to be init system independent. 17 | For openrc and systemd ready-to-use init/service-files are provided; 18 | I gladly add init-files for other init systems if I receive (tested) patches. 19 | 20 | __squashmount__ works with systemd in “standard” setups, but due to 21 | conceptional bugs of systemd in some setups (see section “Installation”), 22 | systemd is no longer officially supported. 23 | 24 | ## What is this project? 25 | 26 | This is __squashmount__, a generic initscript, user interface and management 27 | tool for keeping directories compressed by squashfs but simultaneously keep 28 | them writable using some of (depending on the configuration and what is 29 | available): 30 | 31 | - overlay (AKA overlayfs for linux kernels 3.18 and newer) 32 | - overlayfs, a variant for older linux kernels, see 33 | http://git.kernel.org/?p=linux/kernel/git/mszeredi/vfs.git 34 | - aufs, see http://aufs.sourceforge.net 35 | - fuse-overlayfs, see https://github.com/containers/fuse-overlayfs 36 | - unionfs-fuse, see http://podgorny.cz/moin/UnionFsFuse 37 | (unionfs-fuse-0.25 or newer is required) 38 | - unionfs, see http://www.fsl.cs.sunysb.edu/project-unionfs.html 39 | - funionfs, see http://bugs.gentoo.org/show_bug.cgi?id=151673 40 | 41 | Since __squashmount v15.0.0__ there is also a choice between 42 | 43 | - squashfs (the linux kernel module) 44 | - squashfuse, the fuse module, see https://github.com/vasi/squashfuse 45 | 46 | The idea is that, as a rule, on shutdown the data is recompressed 47 | (and the temporary modified data removed). 48 | This approach is originally due to synss' script from 49 | http://forums.gentoo.org/viewtopic-t-465367-highlight-.html 50 | In that forum thread you can also ask for help about this project. 51 | 52 | For some mount points different rules than “resquash and delete on umount” 53 | might be desired (see the examples section below), and moreover, 54 | it might be necessary to override these rules temporarily. 55 | For such things a powerful user interface is provided. 56 | 57 | This project can be useful for any linux distribution. 58 | Historically, the main motivations was to keep the Gentoo main repository 59 | compressed. This is still one of the most striking examples: 60 | 61 | If the Gentoo main repository (`/usr/portage` or `/var/db/repos/gentoo`) 62 | is compressed with __squashmount__ (without `DISTDIR` which you should store 63 | somewhere else when using this script), the required disk space is only 64 | about 50-100 MB (depending on your compression method), instead of 65 | 200-400 MB (or much higher, the actual space requirement 66 | depending essentially on the filesystem, e.g. how inodes are used). 67 | Usually, also the access is much faster. 68 | 69 | It is possible to combine __squashmount__ with portage's 70 | `sync-type = squashdelta` to mount the Gentoo repository writable. 71 | 72 | ## Screenshot with a typical usage 73 | 74 | ![Demo screenshot](demo.svg?sanitize=true) 75 | 76 | ## Requirements 77 | 78 | The script requires of course that squashfs support is activated in the 79 | kernel (and supports the COMPRESSION method), that the mksquashfs tool 80 | is available, and also that some of the above mentioned unionfs-type tools 81 | is available and supported by the kernel. 82 | 83 | ## Warning 84 | 85 | Since v17.0.0/v10.0.0 , __squashmount__ defaults to the COMPRESSION method 86 | `zstd`/`lz4`. This method is available only in linux-4.14/3.19 or higher 87 | or in squashfuse-0.1.101_alpha20170917/0.1.100_alpha20140523 or higher. 88 | So take care to either use a sufficiently new kernel/squashfuse version 89 | or to change the default! 90 | 91 | Moreover, you need a decently new version of _perl5_ together with some of 92 | its standard modules (which might need to be installed separately if your 93 | _perl5_ version should be too old). Decently new perl versions should have the 94 | `TERM::ANSIColor` module; you need this if you want to see nicely 95 | colored output. 96 | 97 | It is also strongly recommended to install the `File::Which` module 98 | (although there are some fallbacks if it is not available). 99 | 100 | If you want that the hard status line is set, also the title script from 101 | https://github.com/vaeth/runtitle (version >=2.3) is required in your path. 102 | 103 | 104 | ## Installation 105 | 106 | If you are a Gentoo user, you can just emerge __squashmount__ from the 107 | __mv overlay__. 108 | 109 | Otherwise you just have to copy `bin/squashmount` into `/usr/bin/squashmount` 110 | or any other directory of your `$PATH`. 111 | For zsh completion support also copy `zsh/_squashmount` into a directory of 112 | your zsh's `$fpath`. 113 | 114 | It is strongly recommended to put 115 | - `alias squashmount='noglob squashmount'` 116 | 117 | into your `~/.zshrc` or `/etc/zsh/zshrc` or `/etc/zshrc`, 118 | so that things like 119 | - `squashmount start *` 120 | 121 | will work in your zsh as intended without the need to quote *. 122 | (I assume that you do not use any poor shell instead of zsh.) ;) 123 | 124 | If you use __revdep-rebuild__ from Gentoo or similar distributions, and 125 | if you use the default naming scheme, it is recommended to copy the content of 126 | `etc/revdep-rebuild` into `/etc/revdep-rebuild` to cancel duplicate or obsolete 127 | paths search of revdep-rebuild. 128 | 129 | For __openrc__ support copy `openrc/init.d/squashmount` to 130 | `/etc/init.d/squashmount` and activate it in the usual way. 131 | For systemd-support copy `systemd/system/squashmount.service` to your 132 | systemd unit folder (`pkg-config --variable=systemdsystemunitdir systemd`, 133 | usually `/lib/systemd/system` or `/usr/lib/systemd/system`) 134 | and activate it in the usual way (or e.g. copy into `/etc/systemd/system`) 135 | 136 | If you use __systemd__ _be sure to compile the __mount__ binary 137 | with __systemd__ support_ 138 | (this should be the case in most distributions providing systemd; in Gentoo 139 | this means to enable `USE=systemd` for the util-linux package. If you compile 140 | util-linux manually, make sure to pass `--with-systemd` to `./configure`). 141 | In this case, __systemd__ will probably work for you in “standard” setups. 142 | With __systemd-219__ (or newer?) and some unusual setups like `--make-shared` 143 | on some partitions, it can happen nevertheless that __mount__ appears to work, 144 | but actually nothing is mounted if __systemd__ is in use. This is related with 145 | the fact that __systemd__ tries to control all mounts instead of letting the 146 | kernel do it alone. Of course, this breaks tools like __squashmount__ 147 | completely. 148 | Bug __systemd__ upstream about such problems, but not me: I am not planning 149 | to add hacks to fix the breakage introduced by some ill-conceived __systemd__ 150 | concepts. 151 | 152 | For __systemd__, you should set an appropriate timeout: There is no general 153 | rule how long compression can take “maximally”, so the timeout is set to 154 | infinity, by default. It is strongly recommended to set this to a realistic 155 | value for you system and setting by giving a (generous) upper estimate for 156 | your needs by copying the file `etc/system/squashmount.service.d/timeout.conf` 157 | to `/etc/systemd/squashmount/service.d/timeout.conf` and editing appropriately. 158 | If you copied the main script not to `/usr/bin/squashmount`, you should 159 | put into the same directory a file with appropriate modified paths. 160 | For instance, if you copied the main script to `/sbin/squashmount` then 161 | create `/etc/systemd/system/squashmount.service.d/exec.conf` with the content 162 | ``` 163 | [Service] 164 | ExecStart= 165 | ExecStart=/sbin/squashmount start 166 | ExecStop= 167 | ExecStop=/sbin/squashmount -f --lsof=0 stop 168 | ``` 169 | Also copy `tmpfiles.d/squashmount.conf` to `/usr/lib/tmpfiles.d`, although this 170 | is not absolutely necessary (squashmount will create the corresponding 171 | directories anyway). 172 | If you use an init-system which does not mount /run as a ramdisk, 173 | you should cleanup /run/squashmount on every fresh start before 174 | calling `squashmount start`. 175 | Depending on your init-system, a way to achieve this might be to change the 176 | first letter in the crucial line in `/usr/lib/tmpfiles.d/squashmount.conf` 177 | from `d` to `D!` and to make sure that the processing of `/usr/lib/tmpfiles.d` 178 | takes place before calling `squashmount start`. 179 | (Since accidental cleaning can have very inconvenient consequences, and 180 | currently only systemd supports the `D!` syntax, `d` is the default.) 181 | See section __Emergency Case__ what to do if `/run/squashmount` 182 | is removed accidentally anyway. 183 | If you use `find_cruft`, you might want to copy the content of 184 | `lib/find_cruft` to `/usr/lib/find_cruft` or `/etc` and adapt it to your needs. 185 | 186 | If you plan to use portage's `sync-type = squashdelta`, you might want to copy 187 | the content of `etc/portage/repo.postsync.d` to `/etc/portage/repo.postsync.d` 188 | Note that the hook-file in this directory treats the mount point “gentoo” 189 | specially! See the example configuration in `etc/squashmount.pl` how to 190 | setup an appropriate mount point “gentoo” for this setting. 191 | 192 | In all cases you have to copy `lib/squashmount.pl` to `/etc/squashmount.pl` 193 | and adapt it to your need! This is an essential point of squashmount, 194 | and it is impossible to use squashmount without setting up the configuration. 195 | You can optionally also copy `lib/squashmount.pl` to `/lib/squashmount.pl` or 196 | `/usr/lib/squashmount.pl` to provide a system-wide example config. 197 | Alternatively, you can also modify that file to use it as a fallback if 198 | `/etc/squashmount.pl` is not readable. 199 | 200 | 201 | ## Some Examples 202 | 203 | Essentially, the init-system (or you) has to call 204 | - `squashmount start` 205 | 206 | on start and 207 | - `squashmount -f --lsof=0 stop` 208 | 209 | on shutdown (at a time when the local filesystems are already/still mounted). 210 | The provided installation files for systemd and openrc do just this. 211 | 212 | This will cause all configured mount points to be mounted/umounted 213 | correspondingly. When umounting, by default the modified data is 214 | recompressed into the squash-files (but this can be customized). 215 | 216 | The configuration of the mount points happens in the file /etc/squashmount.pl 217 | This is a perl file, so you can use perl code in this file to source other 218 | files at your discretion. 219 | 220 | The provided example configuration file etc/squashmount.pl is rather 221 | realistic if you are a Gentoo user: It provides the following mount points 222 | 223 | - (a) guest: A guest user's home directory /home/guest 224 | - (b) tex: The installed files from texlive /usr/share/texmf-dist 225 | - (c1) portage: The Gentoo repository /usr/portage 226 | - (c2) gentoo: The Gentoo repository when using sync-type = squashdelta 227 | - (d) db: The Gentoo database of installed packages /var/db 228 | 229 | Further mount points are in the example config-file but not listed here. 230 | 231 | For all the mount points it is reasonable to use squashmount with them for 232 | different reasons: 233 | 234 | - (a) The guest-user should be able to modify data in /home/guest, but its 235 | changes should usually be forgotten. (Sometimes you will not want to 236 | forget these changes, e.g. when you want to update the “default” 237 | home directory which the user sees; see below how to do this). 238 | 239 | - (b) The tex directory is huge, and it saves considerable space to keep it 240 | compressed on disk. 241 | 242 | - (c1) Keeping the Gentoo repository compressed does not only save an enormous 243 | amount of disk space but actually also speeds up portage considerable, 244 | because the disk access is faster on a single (squashed) file. 245 | Moreover, after changes with eix --sync you might want to compare the 246 | new files with previous versions in the squashed file which you can still 247 | access when you use squashmount. 248 | 249 | - (c2) When you prefer to use portage's `sync-type = squashdelta`, you already 250 | have the advantage of a compressed portage tree. However, you might want to 251 | use squashmount to make this portage tree writable (e.g. in order to 252 | temporarily fix a broken Manifest file locally). 253 | 254 | - (d) The db directory is short but its data is very sensible and the 255 | number files is huge: Keeping it in a compressed file gives a lot 256 | of disk space and speedup, and it makes sense to keep a compressed backup 257 | of the last mounted version. 258 | 259 | In these examples, additional features of squashmount are used in 260 | the example configuration: 261 | 262 | 1. For (a), it is obviously necessary to use a different treatment: 263 | Normally, the squash-file should not be generated, and the temporary data 264 | should be removed. 265 | A similar remark holds for (c2). 266 | 267 | 2. For (d), squashmount will keep a backup even of the squash-file for 268 | the db directory. 269 | 270 | 3. squashing of (c1) and (d) should happen only when a certain 271 | threshold of changes to the data is reached. 272 | The modified data will survive the reboot even if it is not resquashed, 273 | but it takes more diskspace of course, and there is no readonly version of 274 | the corresponding files. 275 | 276 | 4. No resquash of the tex directory when only certain files (like the 277 | automatically generated `ls-R` file) were updated: 278 | In fact, if the only changes made to the directoy are in these files 279 | (it is optionally also checked that their content is not changed), 280 | the directory will be cleared when umounting/remounting/rebooting. 281 | 282 | You can also call squashmount at runtime to resquash or clean certain 283 | directories manually or to change states for the above “default” actions 284 | on future umounts. For instance, if you changed the skeleton of the 285 | guest user in (a) you can call 286 | - `squashmount --no-kill remount guest` 287 | 288 | to force immediate regeneration of the squashed file from the directory. 289 | Moreover, you can call squashmount to temporarily change the state of mounted 290 | directories. For example, if you want to change temporarily that the guest 291 | user's data is saved on remount, use 292 | - `squashmount --no-kill set guest` 293 | 294 | A changed state will remain active until reset, restart, or stop is executed. 295 | Another example: If a lot of data would be resquashed at the next umount, 296 | but you want to reboot urgently, just call 297 | - `squashmount --no-squash set` 298 | 299 | before rebooting. 300 | Conversely, if you want to squash the portage mount point despite its 301 | threshold is not reached (e.g. because you plan to make an experimental 302 | change which you plan to undo later), you can call 303 | - `squashmount --squash restart portage` 304 | 305 | If afterwards you made your experimental change and want to undo it, call 306 | - `squashmount --kill restart portage` 307 | 308 | If your changes take a longer time and you want to make sure that you do not 309 | forget to call the above command, you can temporarily change the state: 310 | - `squashmount --kill set portage` 311 | 312 | Normally, this setting will survive a remount. In order to reset to the 313 | original setting after remounting, use option `-r` with `remount`: 314 | - `squashmount -r remount portage` 315 | 316 | This is the same as calling 317 | - ``` 318 | squashmount remount portage 319 | squashmount reset portage 320 | ``` 321 | 322 | The above examples should perhaps be enough to give you an impression how 323 | to use __squashmount__. To get an exact description of the user interface and 324 | of the config file format just execute: 325 | - `squashmount man` 326 | 327 | 328 | ## Emergency Case 329 | 330 | If you accidentally removed or corrupted `/run/squashmount`, e.g. due to a bug 331 | in squashmount itself or in its configuration or if the init-system was 332 | misconfigured and removed /run/squashmount after calling `squashmount start`, 333 | you should try to umount unconditionally. 334 | You can instruct squashmount to do this with 335 | - `squashmount -fI umount` 336 | 337 | or (if you do not want resquashing in such a situation): 338 | - `squashmount -nfI umount` 339 | 340 | This will work reliably unless you used temporary directories in your setup. 341 | It will even work with temporary directories if their name is still stored 342 | in /run/squashmount, i.e. if the information there was not lost completely. 343 | 344 | 345 | ## A Word of None-Warning 346 | 347 | It is in general rather safe to squash a directory, even a rather vital one: 348 | Even if e.g. you boot from a kernel which has no support for some of 349 | __overlay__|__overlayfs__|__aufs__|__unionfs-fuse__|__unionfs__ |__funionfs__ 350 | to make the directory writable, __squashmount__ will mount it at least as 351 | read-only (using `mount --bind` if necessary). 352 | Moreover, if everything goes wrong you can still use the __unsquashfs__ tool 353 | to unpack the directory manually. 354 | Probably the only danger in packing “strange” directories are special files, 355 | hard links (this information will usually get lost), or special devices 356 | which are perhaps not supported by the used tools. 357 | 358 | 359 | ## Modules and Mounting 360 | 361 | Since version 3.0, unless configured otherwise, __squashmount__ will attempt 362 | to modprobe the modules 363 | - squashfs 364 | - aufs 365 | - fuse 366 | - overlay 367 | - overlayfs 368 | - unionfs 369 | 370 | when they are required; optionally/alternatively, also the corresponding 371 | kernel option can be checked in `/sys/module` or `/proc/config.gz`; 372 | also the existence of required binaries can be checked before actually 373 | the mounting is attempted. 374 | It depends on your setting whether this is done and/or whether in case 375 | of failure the corresponding tool is skipped tacitly without attempting 376 | to mount. 377 | 378 | If no tool mounts successfully, it is attempted to use `mount --bind` to get 379 | the directory at least readonly on the expected place, so even in 380 | this bad situation (which probably only happens if you boot from an 381 | experimental kernel or a brand new kernel without corresponding support) 382 | you can still access the directory read-only. Hence, also rather vital 383 | directories can be compressed as long as it is not vital to write to them 384 | (and as long as the relevant programs for mounting etc. are not contained 385 | within these directories, of course). 386 | 387 | 388 | ## User Permissions 389 | 390 | If you rely only on the tool squashfuse and either unionfs-fuse or funionfs 391 | (which are all based on the fuse userspace file system), then 392 | squashmount can also be used with user permissions. 393 | To support selecting only these tools and appropriate files and dirs from 394 | the calling user, the option `--user` is supported since squashmount v15.0.0. 395 | For details, call `squashmount man` and look for the option --user. 396 | 397 | 398 | ## Recent squashfs-tools 399 | 400 | It is recommended to use a new version than 4.3 of squashfs-tools which 401 | has the `-quiet` option. Cf. the description of `--mksquash-verbose` 402 | and the `$mksquash_verbose` variable in `./squashmount man` for details. 403 | As a Gentoo user you can install such a recent version from the mv overlay. 404 | 405 | However, this recommendation is only an eye-candy: `squashmount` will work 406 | without any problems also with an unpatched version of `squashfs-tools`; 407 | just the display when squashing will not be so nice. 408 | -------------------------------------------------------------------------------- /lib/squashmount.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl (this is only for editors) 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # To use this file as e.g. /etc/squashmount.pl, copy it to that path and 5 | # remove this comment and the following "fatal()" command from the file 6 | # and write into the subsequent configuration of the variables 7 | # (in particular of @mounts) what is appropriate for your system! 8 | # 9 | # It is impossible to guess which mount-points you want and for which purpose; 10 | # this default file contains just some examples showing what *might* be useful 11 | # for you (and sometimes even only to demonstrate the syntax and some 12 | # possibilities). 13 | # Do not use it unchanged! 14 | # 15 | # Use "squashmount man" for further details and a full list of options 16 | # (only a few are used in this file). 17 | fatal('The file /etc/squashmount.pl is not yet set up!', 18 | 'It must be configured first for the mount-points you want.', 19 | 'See "squashmount man". Examples for the file /etc/squashmount.pl', 20 | 'can be found in /usr/lib/squashmount.pl or /lib/squashmount.pl'); 21 | 22 | # The configuration might depend on the hostname: Test the variable $hostname 23 | # to use the same file for different configs on different machines. 24 | # (We do not employ this possibility in this example file). 25 | # The following line initializes $hostname appropriately: 26 | # use Sys::Hostname; 27 | # my $hostname = ($ENV{'HOSTNAME'} // hostname()); 28 | 29 | # First we specify the tools which we have (possibly) installed; 30 | # if possible, only the first in this list is used, but the others are 31 | # successively a fallback if that fails. 32 | # The last fallback is automatically bind --mount 33 | # 34 | # In this example, we deviate from the defaults by changing some of the flags: 35 | # We skip unionfs and funionfs tacitly unless *surely* available. 36 | # (Note that if you compiled e.g. unionfs as a module but /sys/module and 37 | # /proc/config.gz are not available this means that unionfs is not used 38 | # even if it could be). 39 | # 40 | # We also skip overlay and overlayfs if the module cannot be loaded 41 | # successfully. Note again that this means that overlayfs is skipped 42 | # if compiled into the kernel. Use "overlay? overlayfs?" instead 43 | # if you want a more reliable check for that case. 44 | 45 | @order = qw(overlay overlayfs aufs! fuse-overlayfs! unionfs-fuse! unionfs??# funionfs??#); 46 | 47 | # The tool to mount squash files (currently: kernel or user-space squashfuse) 48 | # is determined according to squashorder. The following is the default 49 | # if not changed by any options: 50 | # @squashorder = qw(squashfs!? squashfuse!); 51 | # Use this if you always want to use squashfuse (slower but can be done 52 | # fully with user permissions, only): 53 | # @squashorder = qw(squashfuse!); 54 | # If in doubt, do not set it explicitly. 55 | 56 | # Set $obsolete_overlayfs = 1 if you normally use a kernel older than 3.15. 57 | # Set $obsolete_overlayfs = undef if you only use >=kernel-3.15 58 | # Set $obsolete_overlayfs = 'force' if you never use overlayfs or 59 | # never use >=kernel-3.15 (and 'lz4', # We could omit this line as lz4 is default. 140 | COMPOPT_LZ4 => '-Xhc', # We could omit this line as -Xhc is default. 141 | COMPEXTRA_LZ4 = > 'hc', # We could omit this line as hc is default. 142 | # In case of COMPRESSION => 'xz', we use the following option. 143 | # Note that this option roughly doubles the squashing time for only 144 | # slightly better compression of binaries. 145 | COMPOPT_XZ => ['-Xbcj', 'x86'], 146 | COMPEXTRA_XZ => ['x86', 'powerpc', 'ia64', 'arm', 'armthumb', 'sparc'] 147 | }; 148 | # Add $pure_text, if the archive is essentially pure text: 149 | my $pure_text = { 150 | COMPOPT_XZ => undef, # "-Xbcj x86" is slower for pure text archives 151 | COMPEXTRA_XZ => undef, 152 | }; 153 | # Add $git to avoid recompression of git-compressed data. 154 | # The archive will usually be slightly larger, but speed gain can be huge. 155 | # See https://github.com/plougher/squashfs-tools/issues/24 156 | my $git = { MKSQUASHFS => [ 157 | '-action', 'uncompressed@subpathname(*/.git/objects/pack)' ], 158 | }; 159 | 160 | # We use here the @mounts = ( ... ); syntax (do not forget the semicolon!) 161 | # but we could use as well: push(@mounts, .... ); 162 | # The latter has the advantage that it can be used repeatedly to 163 | # successively add mount-points. 164 | 165 | @mounts = ( 166 | # This first example does not honor anything set in $defaults: 167 | { 168 | TAG => 'fixed', 169 | DIR => '/fixed/dir', 170 | FILE => '/fixed/content.sfs', 171 | READONLY => 1, # Do not use overlayfs/aufs/... 172 | }, 173 | # To make $defaults effective, we use the added_hash() function: 174 | added_hash($defaults, { 175 | TAG => 'guest', 176 | DIR => '/home/guest', 177 | FILE => '/home/guest-skeleton.sfs', 178 | CHMOD => 0400, # squash-file readonly by user 179 | CHOWN => [ (getpwnam('guest'))[2], # user and group of new ... 180 | (getgrnam('guest'))[2] ], # ... squash-file's owner 181 | KILL => 1, # normally remove data on every umount/remount 182 | # Clean temporary directories, independent of defaults: 183 | RM_CHANGES => 1, RM_WORKDIR => 1, RM_READONLY => 1, 184 | # If you want to cancel this KILL temporarily 185 | # (e.g. to make modifications on guest-skeleton.sqsf) 186 | # use something like "squashmount --nokill set" 187 | # In such a case, we must no postpone resquashing 188 | # even if $resquash_on_start should be true, because 189 | # CHANGES is a temporary directory: 190 | RESQUASH_ON_START => '', 191 | }), 192 | # The above block "added_hash(...)," is actually equivalent to 193 | # { 194 | # COMPRESSION => 'xz', 195 | # TAG => 'guest', 196 | # DIR => '/home/guest', 197 | # FILE => '/home/guest-skeleton.sfs', 198 | # KILL => 1, 199 | # RESQUASH_ON_START => '', 200 | # }, 201 | # because added_hash() "adds" our values to that from $defaults. 202 | 203 | # If you want to use portage's sync-type = squashdelta 204 | # a similar setup is useful. Start by putting the following into your 205 | # /etc/portage/repos.conf: 206 | 207 | # [gentoo] 208 | # location = /srv/repo-gentoo # Do *not* use /var/db/... (see below) 209 | # sync-type = squashdelta 210 | # sync-uri = mirror://gentoo/../snapshots/squashfs 211 | # auto-sync = yes 212 | 213 | # (Do *not* use the default location /var/db/repos/gentoo, if you 214 | # mount also /var/db with the recommended mount-point below, 215 | # since "stacking" mount-points is not a good idea: You would have to 216 | # take care about the order whenever you mount/umount.) 217 | 218 | # With squashmount, we can now mount the downloaded squash-file 219 | # read-writable. In this case, we keep all changes only temporary. 220 | # We will also have to hook into portage's sync mechanism to remount 221 | # after syncing: 222 | # The file etc/portage/repo.postsync.d/50-squashmount-gentoo is such a 223 | # hook (which requires that this mount-point as well as the repository 224 | # be called "gentoo", and that the sync-uri contains the string 225 | # "/squash"). 226 | added_hash($defaults, $pure_text, $git, { 227 | TAG => 'gentoo', 228 | DIR => '/srv/repo-gentoo', 229 | FILE => '/var/cache/portage/squashfs/gentoo-current.sfs', 230 | KILL => 1, 231 | RM_CHANGES => 1, RM_WORKDIR => 1, RM_READONLY => 1, 232 | RESQUASH_ON_START => '', 233 | }), 234 | # Here is yet another useful example: 235 | added_hash($defaults, $pure_text, { 236 | TAG => 'db', 237 | DIR => '/var/db', 238 | FILE => '/var/db.mount/db.sfs', 239 | BACKUP => '.bak', # keep a backup in /var/db.mount/db.sfs.bak 240 | # For an absolute path, we could have written: 241 | # BACKUP => '/backup-disk/db.sfs' 242 | CHANGES => '/var/db.mount/changes', 243 | WORKDIR => '/var/db.mount/workdir', 244 | READONLY => '/var/db.mount/readonly', 245 | 246 | # If /var is on a separate partition, you want probably that 247 | # the squash-file is first generated in /var/tmp so that it 248 | # can be moved without actually copying the data. 249 | # In this case, uncomment the following line: 250 | #TEMPDIR => '/var/tmp', 251 | 252 | # Do not resquash on every umount/remount but only when 253 | # 30 megabytes of fresh data are reached: 254 | THRESHOLD => '30m', 255 | # Since this directory contains only very small files, 256 | # we cheat with this size by using that each file takes 257 | # at least a full block: 258 | # Hence, the number of files is more important for THRESHOLD 259 | # than their size. In Gentoo, one installed package thus 260 | # "counts" about 2m in size 261 | # (although it produces actually only 20 very short files): 262 | BLOCKSIZE => 65536, 263 | }), 264 | # Instead of specifying TAG, DIR, FILE, CHANGES explicitly, 265 | # we use now that they are specified analogously to the above example 266 | # with the standard_mount function. 267 | standard_mount('kernel', '/usr/src', $defaults), 268 | # If you fetch kernel sources with git, you should use instead: 269 | # standard_mount('kernel', '/usr/src', $defaults, $git), 270 | # The above single line produces the equivalent of 271 | # added_hash({ 272 | # TAG => 'kernel', 273 | # DIR => '/usr/src', 274 | # FILE => '/usr/src.mount/src.sfs', 275 | # CHANGES => '/usr/src.mount/changes', 276 | # WORKDIR => '/usr/src.mount/workdir', 277 | # READONLY => '/usr/src.mount/readonly', 278 | # }, $defaults), 279 | # which in turn is effectively equivalent to 280 | # { 281 | # TAG => 'kernel', 282 | # DIR => '/usr/src', 283 | # FILE => '/usr/src.mount/src.sfs', 284 | # CHANGES => '/usr/src.mount/changes', 285 | # WORKDIR => '/usr/src.mount/workdir', 286 | # READONLY => '/usr/src.mount/readonly', 287 | # COMPRESSION => 'xz', 288 | # }, 289 | # (the WORKDIR is omitted if $no_workdir = 1 is set) 290 | # 291 | # You might want to add (before the end of the above brace: 292 | # { 293 | # BACKUP => '.bak', # Always keep a backup. 294 | # THRESHOLD => 1m, # Do not recompress for less than 1 MB changes 295 | # KILL => -1, # If there are less than 1 MB, kill them at "umount" 296 | # } 297 | # Note that the KILL => -1 means for kernel directory that e.g. a temporary 298 | # kernel reconfiguration is "forgotten" unless it is used to recompile most 299 | # of the kernel data: Thus, "tiny experiments" are cleaned up automatically. 300 | # (Be aware that this feature can be very irritating if you forget about it...) 301 | 302 | # We configure tex as in the "squashmount man" example: 303 | standard_mount('tex', '/usr/share/texmf-dist', $defaults, $pure_text, { 304 | DIFF => [ 305 | qr{^ls-R$}, 306 | qr{^tex(/generic(/config(/language(\.(dat(\.lua)?|def)))?)?)?$}n 307 | ], 308 | }), 309 | # The following example is useful if you use portage with a "traditional" 310 | # sync-type (like rsync, webrsync or also git). An example for 311 | # sync-type = squashdelta is given later. 312 | standard_mount('portage', '/usr/portage', $defaults, $pure_text, { 313 | # We know that no hardlinks or similar "tricky" things are used 314 | # in the portage tree, hence we "can" omit the umount helpers 315 | # of e.g. aufs. (This is only an example! Use this only if you 316 | # have problems and understand what you are doing; usually, 317 | # there is no reason to omit the umount helpers!) 318 | # In the following example, we use -i if nothing is passed 319 | # through --umount (or through the setting of @umount above). 320 | # *If* --umount is specified, we do not define UMOUNT, i.e. 321 | # the default value (the passed options) is chosen. 322 | UMOUNT => ((@umount) ? undef : '-i'), 323 | # It is reasonable to not recompress the directory always: 324 | THRESHOLD => '40m', 325 | # Any change in the local/ subdirectory (except in the .git 326 | # subdirectory) should lead to a resquash, even if the 327 | # threshold is not reached. 328 | FILL => qr{^local/(?!\.git(/|$))}n, 329 | # However, ignore identical rewrites of profiles/use.local.desc 330 | # in the local/ or layman/*/ subdirectories (which happens e.g. 331 | # if you use egencache --update-use-local-desc for repositories 332 | # in these subdirectories. Similarly for the files/dirs 333 | # .git/FETCH_HEAD, .git/index, and metadata/md5-cache 334 | DIFF => qr{^(local|(layman(/[^/]*)?))((/profiles(/use\.local\.desc)?)|(/\.git(/FETCH_HEAD|/index)?)|(/metadata(/md5\-cache)?))?$}n, 335 | }), 336 | standard_mount('games', '/usr/share/games', $defaults, { 337 | # games is huge: use the fastest compression algorithm for it. 338 | # (Note that this possibly overrides $defaults): 339 | COMPRESSION => 'lz4', 340 | COMPOPT_LZ4 => '', 341 | }), 342 | standard_mount('office', '/usr/lib/libreoffice', $defaults, { 343 | # Make sure to use the algorithm with best compression ratio, 344 | # possibly overriding $defaults: 345 | COMPRESSION => 'xz', 346 | }), 347 | # Generate a mount-point for every installed (according to the Gentoo 348 | # configuration) rust library: 349 | standard_mount('rust', [envlibs([glob('/etc/env.d/*rust-*')])], 350 | $defaults, { 351 | COMPRESSION => 'xz' 352 | }), 353 | ); 354 | 355 | 356 | # In the following example, we use mount --bind to provide a copy of 357 | # /usr/portage (from the mount-point portage) to /srv/copy 358 | # (This is an extension of the example from "squashmount man"): 359 | 360 | $after_mount = sub { 361 | my ($mountpoint, $store, $config) = @_; 362 | return 1 unless ($mountpoint eq 'portage'); 363 | system('mount', '--bind', $config->{DIR} // $store->{DIR}, '/srv/copy'); 364 | 1 # return a true value! 365 | }; 366 | 367 | $before_umount = sub { 368 | my ($mountpoint, $store, $config) = @_; 369 | return 1 unless ($mountpoint eq 'portage'); 370 | system('umount /srv/copy'); 371 | 1 # return a true value! 372 | }; 373 | 374 | # In case the user mounted /srv/copy without using squashmount, 375 | # we undo this, before mounting the portage directory with squashmount: 376 | 377 | $before_mount = sub { 378 | my ($mountpoint, $store, $config) = @_; 379 | return 1 unless ($mountpoint eq 'portage'); 380 | system('umount /srv/copy >/dev/null 2>&1'); 381 | 1 # return a true value! 382 | }; 383 | 384 | 385 | 386 | # Now we give an example of a mount-point "custom" which is only available 387 | # if a corresponding path to a squash file was passed with the option 388 | # --arg=file (or -a file). 389 | 390 | # This is the "luxury" variant of the code described with "squashmount man". 391 | 392 | # We use the variable "$custom" to indicate whether the mount-point is visible. 393 | # By default, it is only visible if an option was passed with --arg: 394 | 395 | my $custom = @ARGV; 396 | my $file = undef; 397 | if ($custom) { 398 | $file = pop(@ARGV); 399 | fatal("argument '$file' of --arg is not a file") unless (-f $file); 400 | 401 | # If B<--arg> was provided once, store it for later usage 402 | $locking = $storing = 1 # don't set $storing without $locking! 403 | } 404 | 405 | # The following is important: 406 | # The mount-point should always be visible if there is data stored for it 407 | # in $rundir. This is important so that when the init-system calls 408 | # "squashmount stop", this will properly shut down the mount-point 409 | # (even if the special option --arg=something does not occur in this command.) 410 | # This also has the nice side effect that the mount-point will appear 411 | # with "squashmount list", once it is mounted. 412 | 413 | $custom ||= have_stored_data('custom'); 414 | 415 | # Uncomment, if you want to hide "custom" only for "squashmount start": 416 | # $custom ||= ($command ne 'start'); 417 | 418 | # Uncomment, if you want to make "custom" visible to all query commands like 419 | # "squashmount list" or "squashmount print-...": 420 | # $custom ||= $storing; 421 | 422 | # We use a callback function to store/restore $file: 423 | 424 | $before = sub { 425 | # These are the 3 parameters provided to callback functions: 426 | my ($mountpoint, $store, $config) = @_; 427 | 428 | # Handle only that mount-point which is of interest for us: 429 | return 1 unless ($mountpoint eq 'custom'); 430 | 431 | my $stored = $store->{FILE}; 432 | 433 | if (defined($stored)) { 434 | if (defined($file) && ($stored ne $file)) { 435 | error("stored path $stored", 436 | "differs from --arg $file", 437 | 'Use "squashmount stop|forget custom"'); 438 | # We return a false value to skip the action: 439 | return '' 440 | } 441 | } else { 442 | # Store $file for future usage: 443 | $store->{FILE} = $stored = $file 444 | } 445 | # Note that $stored is undefined here if no data was stored and 446 | # if no --arg argument was provided 447 | 448 | # Use the stored value as the configuration value for FILE 449 | # (provided $stored is defined; if it undefined do not touch anything) 450 | $config->{FILE} = $stored if (defined($stored)); 451 | 452 | 1 # return a true value! 453 | }; 454 | 455 | # Finally, we make the mount-point available if $custom is true 456 | 457 | push(@mounts, # append the following to @mounts: 458 | 459 | # In this example, we use /var/custom as DIR, and 460 | # /var/custom.mount/{readonly,changes,workdir} as READONLY,CHANGES,WORKDIR. 461 | # Since almost everything is the setting of "standard_mount", we only 462 | # need to override FILE: 463 | standard_mount('custom', '/var/custom', { 464 | # if $file is undefined, we use some "dummy" path instead 465 | # (it should be an absolute path to avoid error messages) 466 | FILE => ($file // '/default.sfs'), 467 | }) 468 | # now we finish the above push command, indicating that this push command 469 | # should be executed only if $custom is true: 470 | ) if ($custom); 471 | 472 | 1; # The last executed command in this file should be a true expression 473 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | # ChangeLog for squashmount 2 | 3 | *squashmount-22.3: 4 | Martin Väth : 5 | - Adapt -quiet option parsing to squashfs-tools-4.7 6 | 7 | *squashmount-22.2: 8 | Martin Väth : 9 | - Add PrivateMounts=false to systemd unit; thanks to 10 | Jānis Šmēdiņš (https://github.com/Astro-Johnny) for investigating: 11 | https://github.com/vaeth/squashmount/issues/14 12 | 13 | *squashmount-22.1: 14 | Martin Väth : 15 | - Remove -o nonempty from MOUNT_FUSE_OVERLAYFS and MOUNT_SQUASHFUSE 16 | unless the new variable $mount_fuse_overlayfs_v3 or 17 | $mount_squashfuse_v3 is true, respectively, see 18 | https://github.com/vaeth/squashmount/issues/13 19 | 20 | *squashmount-22.0.1: 21 | Martin Väth : 22 | - Add SPDX-License-Identifier 23 | 24 | *squashmount-22.0: 25 | Martin Väth : 26 | - Introduce functions to handle rust libraries conveniently: 27 | - Let standard_mount accept a reference to a dir array 28 | - Introduce envlibs to return installed libraries as a dir array 29 | 30 | *squashmount-21.0.1: 31 | Martin Väth : 32 | - Clarify license 33 | 34 | *squashmount-21.0: 35 | Martin Väth : 36 | - Support https://github.com/containers/fuse-overlayfs 37 | 38 | *squashmount-20.0: 39 | Martin Väth : 40 | - Support https://github.com/AgentD/squashfs-tools-ng (--tar2sqfs) 41 | BEWARE: For me, this new tool does not work for unknown reasons: 42 | tar2sqfs produces files unreadable by the kernel or by unsquashfs 43 | (no matter whether squashfs-root is a parent directory), and 44 | sqfs2tar segfaults on files generated by mksquashfs. 45 | However, I added (untested) support for users without such problems. 46 | 47 | *squashmount-19.1: 48 | Martin Väth : 49 | - Introduce print-mtime 50 | - Output mtime of squashed file with squashmount -vv status 51 | 52 | *squashmount-19.0.2: 53 | Martin Väth : 54 | - Avoid wrong linebreak in manpage 55 | 56 | *squashmount-19.0.1: 57 | Martin Väth : 58 | - Fix quoting in manpage 59 | 60 | *squashmount-19: 61 | Martin Väth : 62 | - Add -o index=off to MOUNT_OVERLAY default 63 | 64 | *squashmount-18.2.1: 65 | Martin Väth : 66 | - Fix variable name which contains LAZY, LSOF, LSOF_RO 67 | (in 18.2 they were simply ignored due to this bug). 68 | 69 | *squashmount-18.2 70 | Martin Väth : 71 | - Change $lsof_ro default to 1 since sometimes (e.g. for 72 | /usr/lib*/firefox) umounting can fail even if lsof shows that only 73 | readonly directory is accessed. On the other hand, for 74 | /usr/share/texmf-dist the opposite is the case. Therefore: 75 | - Provide LAZY, LSOF, LSOF_RO to override $lazy, $lsof, $lsof_ro 76 | for individual mount points. The command line options --lazy, --lsof, 77 | and --lsof-ro override all these configurations. 78 | 79 | *squashmount-18.1 80 | Martin Väth : 81 | - Provide --root to deal with root directory information 82 | - Provide --bind which can manage bind-bounds flexible 83 | - The misguided --chroot from squashmount-18 has been removed. 84 | Use instead --root, supplemented with appropriate --bind options. 85 | - Write data in /run/squashmount sorted for easier comparison 86 | - Allow non-absolute paths in options 87 | - Fix/improve zsh completion for --color and --rundir 88 | 89 | *squashmount-18 90 | Martin Väth : 91 | - Detect root directory change and support override by --chroot 92 | 93 | *squashmount-17.1_p2 94 | Martin Väth : 95 | - Improve demo.svg: add example for modified but not resquashing 96 | 97 | *squashmount-17.1_p1 98 | Martin Väth : 99 | - Improve README.md5, add demo.svg 100 | 101 | *squashmount-17.1 102 | Martin Väth : 103 | - Do not print confusing warnings in File::Find 104 | - Cosmetical code reformatting 105 | 106 | *squashmount-17.0.0 107 | Martin Väth : 108 | - IMPORTANT: New default for COMPRESSION is zstd. 109 | This requires squashfs-tools-4.3.1_alpha20171114 or newer. Moreover: 110 | zstd must be enabled for squashfs when you use the new default! 111 | This is possible only with linux-4.14 or newer or with 112 | squashfuse-0.1.101_alpha20170917 or newer. 113 | 114 | *squashmount-16.1.0 115 | Martin Väth : 116 | - Document zstd on squashmount --man 117 | - Use default COMPOPT_ZSTD => ['-Xcompression-level', '22'] 118 | - Update zsh completion to support zstd and lz4 119 | 120 | *squashmount-16.0.0_p2 121 | Martin Väth : 122 | - Fix zsh-completion regression introduced in squashmount-16.0.0 123 | 124 | *squashmount-16.0.0_p1 125 | Martin Väth : 126 | - New find_cruft path; suggest to copy to system default directory 127 | 128 | *squashmount-16.0.0 129 | Martin Väth : 130 | - docs/examples: Exclude git compressed files for recompression 131 | - New option --system-config and default to {/usr,}/lib/squashmount.pl 132 | - Let standard_mount() and added_hash() add array-references to 133 | array-references or strings, and hash-references to hash-references 134 | (recursively). 135 | - Formulate zsh-completion help in a more standard manner 136 | 137 | *squashmount-15.4.3_p2 138 | Martin Väth : 139 | - Remove CapabilityBoundingSet: It breaks overlay and possibly others 140 | 141 | *squashmount-15.4.3_p1 142 | Martin Väth : 143 | - Fix systemd unit paths in README 144 | 145 | *squashmount-15.4.3 146 | Martin Väth : 147 | - Use state instead of closures 148 | 149 | *squashmount-15.4.2 150 | Martin Väth : 151 | - Treat 0 and - as false only if no symbol follows 152 | 153 | *squashmount-15.4.1 154 | Martin Väth : 155 | - Fix zsh completion return value 156 | 157 | *squashmount-15.4.0_p2 158 | Martin Väth : 159 | - Provide etc/revdep-rebuild/66-squashmount for python implementation 160 | 161 | *squashmount-15.4.0_p1 162 | Martin Väth : 163 | - Work around systemd cap https://github.com/vaeth/squashmount/issues/7 164 | 165 | *squashmount-15.4.0 166 | Martin Väth : 167 | - Honour BLOCKSIZE for files in DIFF 168 | - Omit comparison also once a negative prediction can be made, that is, 169 | if it is clear that $threshold can no longer be reached with DIFF 170 | 171 | *squashmount-15.3.3 172 | Martin Väth : 173 | - Force utf8 encoding in manpage 174 | - Check require at compile time 175 | 176 | *squashmount-15.3.2 177 | Martin Väth : 178 | - Document /etc/portage/repo.postsync.d/10-squashmount-gentoo better 179 | 180 | *squashmount-15.3.1 181 | Martin Väth : 182 | - Improve squashdelta postsyncd hook 183 | - Use the earlier name 10-squashmount-gentoo instead of 50-... 184 | - More verbose example for mounting of the gentoo repository 185 | - Fix typos in manpage 186 | 187 | *squashmount-15.3.0 188 | Martin Väth : 189 | - Prefer /sys/module over /proc/config.gz 190 | 191 | *squashmount-15.2.1 192 | Martin Väth : 193 | - Fix typo in -o allow_other default (o -> -o) 194 | - Fix typo in lazy fusermount -u (-l -> -z) 195 | - Add comments about @squashorder in example config 196 | 197 | *squashmount-15.2.0 198 | Martin Väth : 199 | - Improve security in provided systemd unit 200 | - Default timeout in systemd unit is now "only" 30 minutes 201 | 202 | *squashmount-15.1.2 203 | Martin Väth : 204 | - Fix lsof check (regression from v15.1.1) 205 | 206 | *squashmount-15.1.1 207 | Martin Väth : 208 | - Fix error handling with alternative binaries without File::Which 209 | 210 | *squashmount-15.1.0 211 | Martin Väth : 212 | - Optionally use squashfuse_ll: -ll --no-ll; default: $squashfuse_ll 213 | 214 | *squashmount-15.0.0 215 | Martin Väth : 216 | - Support mounting as a user with squashfuse. 217 | See the --user option in squashmount --man 218 | - Introduce $lsof_ro and --lsof-ro 219 | - Introduce @squash_order and remove obsolete $modprobe_squash 220 | - Be aware the $modprobe_loop slightly changed its meaning 221 | - Introduce --allow and --no-allow for fine-tuning options 222 | - Introduce FUMOUNT, FUMOUNT_RO, @fumount, @fumount_ro, 223 | and the options --fumount, --fumount-ro for fusermount -u. 224 | 225 | *squashmount-14.1.2 226 | Martin Väth : 227 | - Fix perl syntax errors in example config 228 | 229 | *squashmount-14.1.1 230 | Martin Väth : 231 | - Inform about found $killpower file (without -q) 232 | - Fix $nosquash -> $killpower in documentation 233 | 234 | *squashmount-14.1.0 235 | Martin Väth : 236 | - Deal better with vanished directories 237 | 238 | *squashmount-14.0.0 239 | Martin Väth : 240 | - Support KILL => -1 (and --kill-or-resquash) 241 | - New short options -R -l -L 242 | - Fix many typos in documentation 243 | 244 | *squashmount-13.0.0 245 | Martin Väth : 246 | - Require perl-5.22 to use the convenient qr{...}n feature; otherwise, 247 | perl-5.12 would be sufficient (// was the newest feature used) 248 | - Rewrite documentation for the qr{...}n feature 249 | - Serious bugfix: with current versions of File::Find, symlinks 250 | had mistakenly been followed for the size calculation 251 | - Support String::ShellQuote for improved output 252 | - Internal: new comment style 253 | 254 | *squashmount-12.2.1 255 | Martin Väth : 256 | - Bump to play a round of the systemd insanity game "all users: 257 | change your configs since our previous ideas were stupid again" 258 | 259 | *squashmount-12.2.0 260 | Martin Väth : 261 | - Support CHMOD_DIR and CHOWN_DIR 262 | 263 | *squashmount-12.1.1 264 | Martin Väth : 265 | - Add /etc/nut/killpower to $killpower by default 266 | 267 | *squashmount-12.1.0 268 | Martin Väth : 269 | - Support option --order (-o) to override @order 270 | - Support the value "bind" in @order to skip error message 271 | 272 | *squashmount-12.0.1 273 | Martin Väth : 274 | - Remove redundant quoting in shell scripts 275 | 276 | *squashmount-12.0.0 277 | Martin Väth : 278 | - Introduce --lsof and $lsof. 279 | - Note that --lsof=0 should be passed in init-scripts with stop 280 | - Now --lazy and $lazy are non-binary, but can be 0, 1, or -1. 281 | However, -1 (*only* lazy) is not recommended 282 | - On frequent request introduce magic meaning of THRESHOLD -2 283 | (shortcut: --force-squash) 284 | - Reformulate some passages of documentation (e.g. "gentoo repository" 285 | instead of "portage tree") 286 | 287 | *squashmount-11.0.1 288 | Martin Väth : 289 | - Fix error output in config file parsing 290 | 291 | *squashmount-11.0.0 292 | Martin Väth : 293 | - Provide etc/portage/repo.postsync.d/50-squashmount-gentoo 294 | and instructions for a special treatment of the mount point 295 | "gentoo" in connection with portage's sync-type = squashdelta 296 | - WARNING: The above file treats the mount-point "gentoo" specially! 297 | Do not use that name as a mount-point if you install this file but 298 | do not inted to use portage's sync-type = squashdelta! 299 | - Fix some typos in help/example texts 300 | 301 | *squashmount-10.1.0 302 | Martin Väth : 303 | - Support $before_{u,mount} $after_{u,mount} 304 | 305 | *squashmount-10.0.2 306 | Martin Väth : 307 | - Fix etc/revdep-rebuild 308 | 309 | *squashmount-10.0.1 310 | Martin Väth : 311 | - internal: prefer each() over index bookkeeping 312 | 313 | *squashmount-10.0.0 314 | Martin Väth : 315 | - IMPORTANT: New default for COMPRESSION is lz4. 316 | lz4 must be enabled for squashfs when you use the new default! 317 | This is possible only with linux-3.19 or newer! 318 | - systemd is no longer officially supported, although it might work 319 | for you. Reasons are explained in the README 320 | - Support $resquash_on_start and per mount-point RESQUASH_ON_START 321 | - Support $rm_rundir 322 | - Support $rm_dir, $rm_changes, $rm_workdir, $rm_readonly 323 | and per mount-point RM_DIR, RM_CHANGES, RM_WORKDIR, RM_READONLY 324 | - Provide etc/revdep-rebuild 325 | 326 | *squashmount-9.0.1 327 | Martin Väth : 328 | - Use openrc-run instead of deprecated runscript 329 | 330 | *squashmount-9.0.0 331 | Martin Väth : 332 | - Support overlay of linux kernel 3.18. 333 | Note the new name "overlay" in contrast to "overlayfs" which 334 | is available only for older linux kernels. 335 | squashmount uses "overlay" and "overlayfs" throughout to distinguish. 336 | - Fix logic for @order to work as documented 337 | - Fix $obsolete_overlay handling in config 338 | - Fix error in case of illegal cmd 339 | 340 | *squashmount-8.7.9 341 | Martin Väth : 342 | - Fix comments in example configuration, see 343 | https://github.com/vaeth/squashmount/issues/4 344 | Thanks to Arnaudv6 for reporting 345 | 346 | *squashmount-8.7.8 347 | Martin Väth : 348 | - Update description of recommended squashfs-tools patch 349 | 350 | *squashmount-8.7.7 351 | Martin Väth : 352 | - Use gnu_getopt 353 | 354 | *squashmount-8.7.6 355 | Martin Väth : 356 | - Support modprobe loop to work around a new udev bug 357 | 358 | *squashmount-8.7.5 359 | Martin Väth : 360 | - systemd: set timout to infinity and document how to change it 361 | - zsh completion: Fix _tags mask test 362 | 363 | *squashmount-8.7.4 364 | *squashmount-8.7.3 365 | Martin Väth : 366 | - require Pod::Usage only if necessary; don't use version 367 | - Replace 'EOF' by 1 to avoid stupid new perl warning 368 | 369 | *squashmount-8.7.1 370 | Martin Väth : 371 | - Use perl-5.12 versioning, dotted-decimal version format 372 | - Require correct minimal versions of perl and its modules 373 | 374 | *squashmount-8.7 375 | Martin Väth : 376 | - Provide sample find_cruft.d 377 | - Cosmetical code cleanup 378 | 379 | *squashmount-8.6 380 | Martin Väth : 381 | - Fix IO::Uncompress::Gunzip handling (regression from squashmount-7.6) 382 | - Treat nonexistent IO::Uncompress::Gunzip like unreadable config 383 | 384 | *squashmount-8.5 385 | Martin Väth : 386 | - Be graceful if stored directories are removed: Recreate from scratch 387 | - take care if -X returns undef 388 | 389 | *squashmount-8.4 390 | Martin Väth : 391 | - Create parent directories before calling mksquashfs. This fixes 392 | "squashmount create" with standard_mount and nonexistent DIR.mount 393 | - internal: omit & for function export 394 | 395 | *squashmount-8.3 396 | Martin Väth : 397 | - Fix some typos in manpage/examples introduced in 8.2 398 | - Cosmetical code rearrangements 399 | 400 | *squashmount-8.2 401 | Martin Väth : 402 | - use Exporter instead of manual manipulation of symbol glob table 403 | - more compatible indirect call syntax 404 | 405 | *squashmount-8.1 406 | Martin Väth : 407 | - Remove $rundir and $query from advanced configuration, and expose 408 | less details than in 8.0 to ensure stability with future versions. 409 | Instead: 410 | - Provide have_stored_data(mountpoint) 411 | - Introduce callback functionality to store user-defined data 412 | - Introduce $storing (with side effects! Change also $locking!) 413 | - export output functions info, warning, error, errorinfo, fatal 414 | to configuration file (and use them for errors in that file) 415 | - Full custom example with a "variable" custom FILE 416 | - code cleanup: always use explicit package names, no imports 417 | 418 | *squashmount-8.0 419 | Martin Väth : 420 | - Add possibilities for advanced configuration like conditional 421 | mount-points (e.g. for cds), 422 | - Add options -a --arg 423 | - Provide @ARGV, $command, $query, $rundir for configuration file 424 | - manpage: Add section "ADVANCED CONFIGURATION" 425 | - Add example to etc/squashmount.pl about CD mount-points 426 | - Add example about conditionals based on host-name 427 | - Improve parsing of configuration file 428 | - Document that configuration files must finish with a true expression 429 | 430 | *squashmount-7.12 431 | Martin Väth : 432 | - Introduce a 4th verbose level to make external tools more verbose 433 | - Do not suppress output in 3rd verbose level 434 | - Further minor code cleanup 435 | 436 | *squashmount-7.11 437 | Martin Väth : 438 | - code cleanup (prefer // over defined()) 439 | 440 | *squashmount-7.10 441 | Martin Väth : 442 | - Fix @umount{,_ro} and UMOUNT{,_RO} (they had swapped their meaning) 443 | 444 | *squashmount-7.9 445 | Martin Väth : 446 | - Include @umount{,_ro} in examples 447 | 448 | *squashmount-7.8 449 | Martin Väth : 450 | - Introduce UMOUNT{,_RO}, @umount{,_ro}, --umount{,-ro} 451 | 452 | *squashmount-7.7 453 | Martin Väth : 454 | - Fix wrong cutting of directories (regression of squashmount-7.6) 455 | - Use File::Spec->splitpath (should improve dir handling compatibility) 456 | 457 | *squashmount-7.6 458 | Martin Väth : 459 | - Interpret strings as multiline regexp 460 | - More compatible directory handling in threshold_dir 461 | - Consistent regexp syntax: m{}, qr{}, or s{}{} 462 | - Slight speedup by avoiding redundant return statements 463 | 464 | *squashmount-7.5 465 | Martin Väth : 466 | - Improve/fix some regexes; quote newlines correctly 467 | 468 | *squashmount-7.4 469 | Martin Väth : 470 | - Fix behaviour if directories with nonexisting parents are specified 471 | 472 | *squashmount-7.3 473 | *squashmount-7.2 474 | Martin Väth : 475 | - Check args in &added_hash() and &standard_mount() (>=perl-5.20) 476 | 477 | *squashmount-7.1 478 | Martin Väth : 479 | - Use type 'overlayfs-obsolete' for old overlayfs (without workdir) 480 | - Clean WORKDIR on every umount of an overlayfs (and only then) 481 | - Create WORKDIR only if really required 482 | - Introduce $obsolete_overlayfs = 'force' to skip creation of WORKDIR 483 | - Remove $no_workdir (unwisely introduced in squashmount-7.0) 484 | 485 | *squashmount-7.0 486 | Martin Väth : 487 | - WARNING: The meaning of &standard_mount() has changed! 488 | Paths are now dir/changes dir/workdir dir/readonly dir/dir.sfs 489 | You should reorganize your directory structure to reflect that! 490 | The reason is that WORKDIR is mandatory with new overlayfs. 491 | - Support current overlayfs (WORKDIR) 492 | 493 | *squashmount-6.3 494 | Martin Väth : 495 | - Introduce -p/--processors, -m/--mem and $processors, $mem defaults 496 | 497 | *squashmount-6.2 498 | Martin Väth : 499 | - Use the flexible $mksquash_verbose, --mksquash-verbose strings 500 | instead of the previous $squash_verbose, --squash-verbose numbers. 501 | To ease transition for users, currently an error is reported if 502 | the now unsupported $squash_verbose is still set. 503 | 504 | *squashmount-6.1 505 | Martin Väth : 506 | - Change meaning of squash_verbose 507 | Default prefers mksquashfs -quiet if available 508 | 509 | *squashmount-6.0a 510 | Martin Väth : 511 | - Revert to COMPRESSION=xz default until lz4 is supported by 512 | mainstream kernel 513 | 514 | *squashmount-6.0 515 | Martin Väth : 516 | - Support COMPOPT_* to allow setting algorithm-specific option. 517 | - Default to COMPRESSION=lz4 (this is the reason for new major version) 518 | - Default to COMPOPT_LZ4=-Xhc 519 | - squashmount -vv list now outputs effective mksquashfs options 520 | - Fix handling of mksquash compression option. 521 | 522 | *squashmount-5.0 523 | Martin Väth : 524 | - Use -always-use-fragments by default 525 | - Introduce DEFAULT_FRAGMENTS to avoid -always-use-fragments 526 | - Improve printed output of shell commands 527 | - Fix treatment of redirects 528 | - Provide example of special mksquash compression option 529 | 530 | *squashmount-4.5 531 | *squashmount-4.4 532 | Martin Väth : 533 | - Add sanity check before deleting DIR after first creation of 534 | squashfile, see https://github.com/vaeth/squashmount/issues/1 535 | 536 | *squashmount-4.3 537 | Martin Väth : 538 | - Add /etc/nosquash to $killpower default. Fix reference to --keep 539 | 540 | *squashmount-4.2 541 | Martin Väth : 542 | - Fix severely misleading typo on manpage for File::Temp::newdir 543 | 544 | *squashmount-4.1 545 | Martin Väth : 546 | - Support $killpower (/etc/killpower) for fast emergency shutdown 547 | 548 | *squashmount-4.0 549 | Martin Väth : 550 | - Introduce --backup, --no-backup, --tempdir, --compresssion 551 | for temporarily overriding configuration, e.g. with set/restore 552 | - Treat BACKUP as appendix if not an absolute path 553 | 554 | *squashmount-3.7 555 | Martin Väth : 556 | - Make clearer that etc/squashmount.pl is only an example 557 | - Fix typo in getpwnam() getgrnam() calls in example configuration 558 | 559 | *squashmount-3.6 560 | Martin Väth : 561 | - Introduce CHMOD, CHOWN; default to CHMOD = 0644 562 | 563 | *squashmount-3.5 564 | *squashmount-3.4 565 | Martin Väth : 566 | - No locking default for status and print-* 567 | - zsh completion: Use --no-locking when calling squashmount 568 | 569 | *squashmount-3.3 570 | *squashmount-3.2 571 | Martin Väth : 572 | - Improve documentation 573 | 574 | *squashmount-3.1 575 | *squashmount-3.0 576 | Martin Väth : 577 | - modprobe modules by default 578 | - Support flags !, !!, ?, ??, # in @order 579 | - Support $modprobe_squashfs 580 | - Set @order to empty string if not needed 581 | - Use qw(...) in examples where it makes sense 582 | - standard_mount() and added_hash() can now be called without & 583 | 584 | *squashmount-2.10 585 | Martin Väth : 586 | - Support FILL and FILLFUNC 587 | 588 | *squashmount-2.9 589 | Martin Väth : 590 | - fix tmpfiles.d content which caused sometimes breakage with systemd 591 | - fix systemd/openrc deps to avoid most problems even with "D" setting 592 | - document emergency case explicitly 593 | - improve behaviour in emergency case (getting DIR) 594 | - cosmetical code cleanup 595 | 596 | *squashmount-2.8 597 | Martin Väth : 598 | - fix: --error and --fatal can work together 599 | - fix restart: postpone forget, not releasing lock too early 600 | - Improve error handling for writing to /run/squashmount 601 | 602 | *squashmount-2.7 603 | Martin Väth : 604 | - Introduce --locking and $locking and make it default 605 | - New check command 606 | - Add tmpfiles.d 607 | - squashmount -fI {u,}mount now even continues after error 608 | - Allow -f for status and print-... and improve results without -f 609 | 610 | *squashmount-2.6 611 | Martin Väth : 612 | - Require -f for restart to forget+start an umounted mount-point 613 | - Introduce --ignore-state to deal better with exceptional 614 | situations caused by bugs (in squashmount or its config) or 615 | by manual interfering 616 | 617 | *squashmount-2.5 618 | Martin Väth : 619 | - Fix severe typo which caused umount to not save its state: 620 | Regression introduced in squashmount-2.3 (=squashmount-2.4) 621 | 622 | *squashmount-2.4 623 | *squashmount-2.3 624 | Martin Väth : 625 | - Fix serious bug with restart command (forgetting despite mounting) 626 | - Change of the /run/squashmount format (MOUNT_RW is now part of TYPE). 627 | Be aware that this can lead to problems for mount-points mounted 628 | with an older version of squashmount! 629 | - Never touch /run/squashmount for info (status, print-...) commands 630 | - Deal better with half-mounted/half-umounted directories (i.e. after 631 | fatal mount/umount failures) 632 | - More beautiful colored output if TERM::ANSIColor is available 633 | - New options -c -C (--color --no-color), --star, --no-star 634 | - Make most print-* commands return reasonable results also for 635 | mount-points never mounted 636 | - Rename option --pass-directory into --pass-dir 637 | - Let print-... produce now more verbose output by default; 638 | honour --separator only with -q 639 | - Let print-threshold without -v or -q print the human-readable form 640 | - Introduce --{no,}fatal and make --fatal default for {re,}start, stop 641 | - internal: use File::Spec for more compatibility 642 | - internal: make wanted function local to threshold_dir, using closures 643 | 644 | *squashmount-2.2 645 | Martin Väth : 646 | - Remember paths; check for existence with File::Which 647 | - Fix usage of unionfs-fuse and of unionfs. Thanks to yoshi314 for 648 | reporting: http://forums.gentoo.org/viewtopic-t-465367-start-248.html 649 | - Require -f on stop for umounted points to avoid accidental forget 650 | of a semi-mounted state (could happen in case of certain bugs in 651 | /etc/squashmount.pl or squashmount) 652 | - Use bigint for sizes/thresholds to make it reliable on 32 bit systems 653 | - Add more sanity checks 654 | 655 | *squashmount-2.1 656 | Martin Väth : 657 | - Fix division by 0 on 32 bit systems 658 | 659 | *squashmount-2.0 660 | Martin Väth : 661 | - Introduce &standard_mount, &added_hash config helpers, 662 | remove misguided &standard_hash 663 | - Let start, stop, restart differ from mount, umount, remount 664 | - Introduce a separate create command 665 | - Introduce reset, forget, --reset 666 | - internal: make $current, $user_config global 667 | - internal: reorder to allow prototyping if desired, 668 | but avoid it as it makes no sense in perl5 669 | 670 | *squashmount-1.1 671 | Martin Väth : 672 | - Fix handling of BACKUP 673 | - various cosmetical fixes 674 | 675 | *squashmount-1.0 676 | Martin Väth : 677 | - Improve documentation 678 | - Fix rounding 679 | - Fix sanity checks 680 | - Try to skip remount 681 | 682 | *squashmount-0.01 683 | Martin Väth : 684 | - Initial implementation, using some ideas of the squash_dir project 685 | --------------------------------------------------------------------------------