99 lines
3.9 KiB
Markdown
99 lines
3.9 KiB
Markdown
# scoutfs-notify
|
|
|
|
Observer-only file access notifications for [ScoutFS](https://github.com/versity/scoutfs),
|
|
distributed as a rebasable `git format-patch` series plus a small Go
|
|
userspace relay daemon. Maintained as one long-lived branch per
|
|
currently-supported upstream scoutfs version.
|
|
|
|
## What the series adds
|
|
|
|
Three patches against each supported scoutfs release:
|
|
|
|
1. **Kmod core** — a per-mount 64 KiB ring of 64-byte notification records and
|
|
a single-reader drain ioctl (`SCOUTFS_IOC_READ_NOTIFY`, nr 26). Emit is
|
|
non-blocking, drop-on-full; the monotonic `seq` field exposes drops to
|
|
consumers. Three percpu counters (`notify_emitted`,
|
|
`notify_dropped_ring_full`, `notify_reader_attached`). No mount option,
|
|
no sysfs toggle.
|
|
2. **Kmod hooks** — `->open` wrapper and READ emit in
|
|
`scoutfs_file_read_iter`. Every hook is a single predicted-false
|
|
branch when no reader is attached. Nothing in the data-waiter state
|
|
machine is touched. (Branches up to `v1.32` also hooked
|
|
`scoutfs_file_aio_read`; scoutfs v1.33 removed the
|
|
`KC_LINUX_HAVE_FOP_AIO_READ` compat paths, so `read_iter` is now the
|
|
only read path.)
|
|
3. **scoutfs-notifyd (Go)** — userspace daemon that binds
|
|
`/run/scoutfs/<fsid>/notify.sock` (AF_UNIX SOCK_SEQPACKET, mode 0600,
|
|
root-only), drains the ring, and broadcasts each record to connected
|
|
clients. Pure-stdlib Go; no external module dependencies. Shipped
|
|
with a systemd template unit `scoutfs-notifyd@<mountpoint>.service`.
|
|
|
|
The 64-byte event record layout is identical on every branch, so
|
|
consumers and the daemon do not need per-version branching in their own
|
|
code. The ioctl number is not: it is nr 25 on `v1.28`-`v1.30` and nr 26
|
|
from `v1.32` on, because upstream v1.32 took nr 25 for
|
|
`SCOUTFS_IOC_INJECT_TOTL_DELTA`. scoutfs v1.33 did not renumber again.
|
|
|
|
## Repository layout
|
|
|
|
Each supported scoutfs version lives on its own long-lived branch. The
|
|
patches in each branch are tuned for that specific scoutfs tree; they do
|
|
NOT apply cross-version without rebasing.
|
|
|
|
| Branch | Targets scoutfs | Tag |
|
|
|----------------|-----------------|------------------|
|
|
| `v1.28` | `v1.28` | `v1.28-notify-1` |
|
|
| `v1.29` | `v1.29` | `v1.29-notify-1` |
|
|
| `v1.30` | `v1.30` | `v1.30-notify-1` |
|
|
| `v1.32` | `v1.32` | `v1.32-notify-1` |
|
|
| `v1.33` | `v1.33` | `v1.33-notify-1` |
|
|
|
|
`main` tracks the newest supported scoutfs version. When a new scoutfs
|
|
release ships, a new branch is created and the patches are rebased onto
|
|
it; when a scoutfs version ages out of support, its branch stays in the
|
|
repo for historical builds but is no longer maintained.
|
|
|
|
## Applying
|
|
|
|
Against a scoutfs git working tree at the matching upstream tag:
|
|
|
|
```sh
|
|
git clone -b v1.29 https://git.anomalous.dev/alphacentri/scoutfs-notify.git /tmp/notify
|
|
/tmp/notify/apply.sh /path/to/scoutfs-v1.29-checkout
|
|
```
|
|
|
|
The script runs `git am --3way` on each patch in order.
|
|
|
|
## Rebasing onto a new upstream release
|
|
|
|
```sh
|
|
# In a fresh scoutfs checkout:
|
|
git checkout v1.31
|
|
git checkout -b notify-v1.31
|
|
|
|
# Apply the previous branch's patches (usually clean; resolve any
|
|
# conflicts, git am --continue).
|
|
git am --3way /path/to/scoutfs-notify-v1.30/patches/*.patch
|
|
git format-patch v1.31..notify-v1.31 -o /tmp/new-patches/
|
|
|
|
# Push a new branch + tag in this repo:
|
|
cd /path/to/scoutfs-notify
|
|
git checkout -b v1.31 main
|
|
rm patches/*.patch
|
|
cp /tmp/new-patches/*.patch patches/
|
|
echo v1.31 > base.txt
|
|
git commit -am 'v1.31-notify-1: rebase onto scoutfs v1.31'
|
|
git push -u origin v1.31
|
|
git tag v1.31-notify-1 && git push origin v1.31-notify-1
|
|
# Fast-forward main to the new tip once you're ready to promote it.
|
|
```
|
|
|
|
## Quick smoke test after installation
|
|
|
|
```sh
|
|
systemctl enable --now scoutfs-notifyd@mnt-scoutfs.service
|
|
FSID=$(scoutfs stat /mnt/scoutfs | awk '/fsid/ { print $2 }')
|
|
socat - UNIX-CONNECT:/run/scoutfs/${FSID}/notify.sock | xxd | head
|
|
# touch some files in /mnt/scoutfs in another terminal
|
|
```
|