Snapper 2.0 (or just Snapper) is a snapshot mechanism for the virtual memory space of the persistent operating system PhantomOS. It uses the a logging file system (e.g. ext4) to ensure that file operations (e.g. modification or deletion) are resistant to OS crashes mid-way through the operation.
A vital property of Snapper is that it needs to be disk space efficient in order not to bloat the file system. This is done by utilizing a mapping from the virtual pages (from now on referred only as pages) to a file containing their contents. Thus if a page remains unchanged its contents will still be mapped to a file from a previous snapshot, hence no new file needs to be created.
- Genode + Goa
- Lwext4 Plugin (optional)
Install the requirements. This pre-built container image comes with all the dependencies needed for Genode:
git clone --depth 1 https://github.com/genodelabs/genode.git
git clone --depth 1 https://github.com/genodelabs/goa.git genode/goa
git clone --depth 1 https://github.com/rumenmitov/snapper genode/repos/snapper
podman run -d --name genode --cap-add SYS_PTRACE -v $PWD/genode:/genode -w /genode docker.io/rmitov/genode:25.05 tail -f /dev/null
❗ Make sure to setup Genode’s build directory before continuing! ❗
Add the following to <genode>/build/x86_64/etc/build.conf:
REPOSITORIES += $(GENODE_DIR)/repos/wundertuete REPOSITORIES += $(GENODE_DIR)/repos/snapper
Optionally add the Lwext plugin:
git clone -b 25.05-2025-07-07 --depth 1 https://codeberg.org/jws/genode-wundertuete.git genode/repos/wundertuete
Run this inside the container:
/genode/tool/ports/prepare_port lwext4
DEPOT_DIR=/genode/repos/snapper/var/depot goa depot-dir
DEPOT_DIR=/genode/repos/snapper/var/depot FORCE_VERSION=2025-07-09 /genode/tool/depot/create rumen/bin/x86_64/vfs_lwext4
mkdir /genode/repos/snapper/raw
dd if=/dev/zero of=/genode/repos/snapper/raw/snapper_block.raw bs=1M seek=16 count=0
mkfs.ext4 -O^metadata_csum -F /genode/repos/snapper/raw/snapper_block.raw
If you are using the container, the following should be run inside the container.
cd /genode/repos/snapper
goa run --pkg snapper
This will run the main Snapper binary. If instead you want to run the tests:
goa run --pkg snappertests
To specify the number of snapshot objects that should be in the test simulation (TESTS
defaults to 1000):
TESTS=50 goa run --pkg snappertests
cd /genode
make -C build/x86_64 run/snapper KERNEL=linux BOARD=linux
Or, to run the tests:
make -C build/x86_64 run/snappertests KERNEL=linux BOARD=linux
To (optionally) specify how many test objects to create (see Running With Goa for more details):
TESTS=50 make -C build/x86_64 run/snappertests KERNEL=linux BOARD=linux
Snapper should be configurable through Genode’s XML. The configuration options are stored inNOTE: On subsequent runs, if you want to change
TESTS
, you have torm -rf /genode/build/x86_64/test/snapper/
before running.
Snapper::Config
:
<l10> | <c30> | <r50> |
OPTION | TYPE | DESCRIPTION |
---|---|---|
verbose | bool | Whether to print verbose output. |
threshold | unsigned int | The maximum number of files in a snapshot sub-directory. |
integrity | bool | If true, crash the system on failed integrity checks, |
otherwise log a warning. | ||
redundancy | unsigned int | After reaching this reference count, a redundant file |
copy will be created for subsequent snapshot. | ||
max_snapshots | unsigned int | The maximum number of complete snapshots inside |
<snapper-root>. | ||
min_snapshots | unsigned int | The minimum number of generations that need to be present |
for a purge to be possible. | ||
expiration | unsigned int | How many seconds a generation should be kept. |
(seconds) |