Skip to content

systemd

PolicyFS is designed to be operated via systemd:

  • pfs@<mount>.service is the long-running daemon (FUSE mount).
  • pfs-index@<mount>.timer runs indexing periodically.
  • pfs-move@<mount>.timer runs mover periodically.
  • pfs-prune@<mount>.timer runs prune periodically.
  • pfs-maint@<mount>.timer runs a batched maintenance flow.

Timer schedules

The Debian package ships these default schedules:

Unit Schedule Notes
pfs-move@<mount>.timer OnCalendar=*-*-* 00:30:00 RandomizedDelaySec=5m, Persistent=true
pfs-maint@<mount>.timer OnCalendar=*-*-* 00:30:00 RandomizedDelaySec=10m, Persistent=true
pfs-prune@<mount>.timer OnCalendar=*-*-* 04:15:00 RandomizedDelaySec=10m, Persistent=true
pfs-index@<mount>.timer OnCalendar=*-*-* 05:30:00 RandomizedDelaySec=2m, Persistent=true

You typically enable either:

  • The maint timer (pfs-maint) if you want one schedule and a single maintenance window. It runs a batched flow.
  • Individual timers (pfs-index, pfs-move, pfs-prune) if you want to stagger work across the day or tune each phase separately.

I recommend starting with pfs-maint unless you have a reason to separate the phases.

Avoid enabling pfs-maint@<mount>.timer at the same time as the individual timers.

Inspect timer settings

Show the effective unit (including drop-ins):

sudo systemctl cat [email protected]

List next runs:

systemctl list-timers 'pfs-*@media.timer'

Directory layout

PolicyFS uses standard Linux locations:

  • Config: /etc/pfs/pfs.yaml
  • State: /var/lib/pfs/<mount>/
  • Runtime: /run/pfs/<mount>/
  • Logs: journald by default; optional file logging can be enabled via config.

Check job output

View the last run of a maintenance job:

journalctl -u [email protected] -n 50

Example output:

Mar 22 00:30:12 host pfs[1234]: move: moved 3 files (2.1 GB) from ssd1 → hdd1
Mar 22 00:30:15 host pfs[1234]: prune: applied 7 events (4 deletes, 3 renames)
Mar 22 00:30:18 host pfs[1234]: index: indexed 12483 files across hdd1, hdd2

Exit code 3 means the job ran but found nothing to do - this is normal when disks are not above the threshold or there are no deferred events.

Common operations

Start/restart a mount:

sudo systemctl restart [email protected]

Disable all scheduled jobs for a mount:

sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]

Package upgrades

Debian and Ubuntu package upgrades preserve existing pfs@<mount>.service and timer enablement.

During an upgrade, the package snapshots previously enabled mount services and timers before dpkg runs the old cleanup hooks, reloads systemd after unpack, and then restores those specific units. Aborted install or upgrade paths discard that transient snapshot instead of replaying it later.

That means a mount such as [email protected] and any enabled maintenance timers come back after the package upgrade without needing a manual systemctl enable pass.

Packaged unit files live in the distro-managed vendor unit directory; keep local changes in /etc/systemd/system/*.d/ drop-ins rather than editing vendor files in place.

Newer Debian and Ubuntu packages also migrate legacy packaged copies under /etc/systemd/system/pfs* back to the vendor unit directory and rewrite stale wants links, while leaving drop-ins under *.d/ alone.

Package removal and purge also clean up PolicyFS wants links so reinstall does not silently resurrect old enablement.

Overrides

Use drop-ins instead of editing vendor unit files:

sudo systemctl edit [email protected]

To change a timer schedule, edit the timer unit:

sudo systemctl edit [email protected]

Example override:

[Timer]
OnCalendar=
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=0

Then reload and restart the timer:

sudo systemctl daemon-reload
sudo systemctl restart [email protected]