Squashmount
Init and management script for mounting rewritable squashfs-compressed data
Install / Use
/learn @vaeth/SquashmountREADME
squashmount
(C) Martin Väth (martin at mvath.de)
This project is under the BSD license 2.0 (“3-clause BSD license”). SPDX-License-Identifier: BSD-3-Clause
Init and management script for mounting rewritable squashfs-compressed data
This is the successor of the squash_dir project
- https://github.com/vaeth/squash_dir/
It is actually a ground-up rewrite of that project in perl with a highly improved control interface.
One of its aims is to be init system independent. For openrc and systemd ready-to-use init/service-files are provided; I gladly add init-files for other init systems if I receive (tested) patches.
squashmount works with systemd in “standard” setups, but due to conceptional bugs of systemd in some setups (see section “Installation”), systemd is no longer officially supported.
What is this project?
This is squashmount, a generic initscript, user interface and management tool for keeping directories compressed by squashfs but simultaneously keep them writable using some of (depending on the configuration and what is available):
- overlay (AKA overlayfs for linux kernels 3.18 and newer)
- overlayfs, a variant for older linux kernels, see http://git.kernel.org/?p=linux/kernel/git/mszeredi/vfs.git
- aufs, see http://aufs.sourceforge.net
- fuse-overlayfs, see https://github.com/containers/fuse-overlayfs
- unionfs-fuse, see http://podgorny.cz/moin/UnionFsFuse (unionfs-fuse-0.25 or newer is required)
- unionfs, see http://www.fsl.cs.sunysb.edu/project-unionfs.html
- funionfs, see http://bugs.gentoo.org/show_bug.cgi?id=151673
Since squashmount v15.0.0 there is also a choice between
- squashfs (the linux kernel module)
- squashfuse, the fuse module, see https://github.com/vasi/squashfuse
The idea is that, as a rule, on shutdown the data is recompressed (and the temporary modified data removed). This approach is originally due to synss' script from http://forums.gentoo.org/viewtopic-t-465367-highlight-.html In that forum thread you can also ask for help about this project.
For some mount points different rules than “resquash and delete on umount” might be desired (see the examples section below), and moreover, it might be necessary to override these rules temporarily. For such things a powerful user interface is provided.
This project can be useful for any linux distribution. Historically, the main motivations was to keep the Gentoo main repository compressed. This is still one of the most striking examples:
If the Gentoo main repository (/usr/portage or /var/db/repos/gentoo)
is compressed with squashmount (without DISTDIR which you should store
somewhere else when using this script), the required disk space is only
about 50-100 MB (depending on your compression method), instead of
200-400 MB (or much higher, the actual space requirement
depending essentially on the filesystem, e.g. how inodes are used).
Usually, also the access is much faster.
It is possible to combine squashmount with portage's
sync-type = squashdelta to mount the Gentoo repository writable.
Screenshot with a typical usage
Requirements
The script requires of course that squashfs support is activated in the kernel (and supports the COMPRESSION method), that the mksquashfs tool is available, and also that some of the above mentioned unionfs-type tools is available and supported by the kernel.
Warning
Since v17.0.0/v10.0.0 , squashmount defaults to the COMPRESSION method
zstd/lz4. This method is available only in linux-4.14/3.19 or higher
or in squashfuse-0.1.101_alpha20170917/0.1.100_alpha20140523 or higher.
So take care to either use a sufficiently new kernel/squashfuse version
or to change the default!
Moreover, you need a decently new version of perl5 together with some of
its standard modules (which might need to be installed separately if your
perl5 version should be too old). Decently new perl versions should have the
TERM::ANSIColor module; you need this if you want to see nicely
colored output.
It is also strongly recommended to install the File::Which module
(although there are some fallbacks if it is not available).
If you want that the hard status line is set, also the title script from https://github.com/vaeth/runtitle (version >=2.3) is required in your path.
Installation
If you are a Gentoo user, you can just emerge squashmount from the mv overlay.
Otherwise you just have to copy bin/squashmount into /usr/bin/squashmount
or any other directory of your $PATH.
For zsh completion support also copy zsh/_squashmount into a directory of
your zsh's $fpath.
It is strongly recommended to put
alias squashmount='noglob squashmount'
into your ~/.zshrc or /etc/zsh/zshrc or /etc/zshrc,
so that things like
squashmount start *
will work in your zsh as intended without the need to quote *. (I assume that you do not use any poor shell instead of zsh.) ;)
If you use revdep-rebuild from Gentoo or similar distributions, and
if you use the default naming scheme, it is recommended to copy the content of
etc/revdep-rebuild into /etc/revdep-rebuild to cancel duplicate or obsolete
paths search of revdep-rebuild.
For openrc support copy openrc/init.d/squashmount to
/etc/init.d/squashmount and activate it in the usual way.
For systemd-support copy systemd/system/squashmount.service to your
systemd unit folder (pkg-config --variable=systemdsystemunitdir systemd,
usually /lib/systemd/system or /usr/lib/systemd/system)
and activate it in the usual way (or e.g. copy into /etc/systemd/system)
If you use systemd be sure to compile the mount binary
with systemd support
(this should be the case in most distributions providing systemd; in Gentoo
this means to enable USE=systemd for the util-linux package. If you compile
util-linux manually, make sure to pass --with-systemd to ./configure).
In this case, systemd will probably work for you in “standard” setups.
With systemd-219 (or newer?) and some unusual setups like --make-shared
on some partitions, it can happen nevertheless that mount appears to work,
but actually nothing is mounted if systemd is in use. This is related with
the fact that systemd tries to control all mounts instead of letting the
kernel do it alone. Of course, this breaks tools like squashmount
completely.
Bug systemd upstream about such problems, but not me: I am not planning
to add hacks to fix the breakage introduced by some ill-conceived systemd
concepts.
For systemd, you should set an appropriate timeout: There is no general
rule how long compression can take “maximally”, so the timeout is set to
infinity, by default. It is strongly recommended to set this to a realistic
value for you system and setting by giving a (generous) upper estimate for
your needs by copying the file etc/system/squashmount.service.d/timeout.conf
to /etc/systemd/squashmount/service.d/timeout.conf and editing appropriately.
If you copied the main script not to /usr/bin/squashmount, you should
put into the same directory a file with appropriate modified paths.
For instance, if you copied the main script to /sbin/squashmount then
create /etc/systemd/system/squashmount.service.d/exec.conf with the content
[Service]
ExecStart=
ExecStart=/sbin/squashmount start
ExecStop=
ExecStop=/sbin/squashmount -f --lsof=0 stop
Also copy tmpfiles.d/squashmount.conf to /usr/lib/tmpfiles.d, although this
is not absolutely necessary (squashmount will create the corresponding
directories anyway).
If you use an init-system which does not mount /run as a ramdisk,
you should cleanup /run/squashmount on every fresh start before
calling squashmount start.
Depending on your init-system, a way to achieve this might be to change the
first letter in the crucial line in /usr/lib/tmpfiles.d/squashmount.conf
from d to D! and to make sure that the processing of /usr/lib/tmpfiles.d
takes place before calling squashmount start.
(Since accidental cleaning can have very inconvenient consequences, and
currently only systemd supports the D! syntax, d is the default.)
See section Emergency Case what to do if /run/squashmount
is removed accidentally anyway.
If you use find_cruft, you might want to copy the content of
lib/find_cruft to /usr/lib/find_cruft or /etc and adapt it to your needs.
If you plan to use portage's sync-type = squashdelta, you might want to copy
the content of etc/portage/repo.postsync.d to /etc/portage/repo.postsync.d
Note that the hook-file in this directory treats the mount point “gentoo”
specially! See the example configuration in etc/squashmount.pl how to
setup an appropriate mount point “gentoo” for this setting.
In all cases you have to copy lib/squashmount.pl to /etc/squashmount.pl
and adapt it to your need! This is an essential point of squashmount,
and it is impossible to use squashmount without setting up the configuration.
You can optionally also copy lib/squashmount.pl to /lib/squashmount.pl or
/usr/lib/squashmount.pl to provide a system-wide example config.
Alternatively, you can also modify that file to use it as a fallback if
/etc/squashmount.pl is not readable.
Some Examples
Essentially, the init-system (or you) has to call
squashmount start
on start and
squashmount -f --lsof=0 stop
on shutdown (at a time when the local filesystems are already/still mounted). The provided installation files for systemd and openrc do just this.
This will cause all configured mount points to be mounted/umounted correspondingly. When umounting, by default the modified data is recompressed into the squash-files (but this can be customized).
The configuration of the mount points happens in the file /etc/squashmount.pl This is a perl file, so you can use perl code in this file to source other files at your discretion.
The provided example configur
