From 2c33d40d0e410d0e56da479c702c597b7fe784e4 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 27 Aug 2026 08:42:54 -0500 Subject: [PATCH] skip lost+found during the ownership sweep --- docker/main/rootfs/usr/local/bin/fix-ownership | 6 ++++-- docs/docs/configuration/non_root.md | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docker/main/rootfs/usr/local/bin/fix-ownership b/docker/main/rootfs/usr/local/bin/fix-ownership index d899dae2cd..6c230606e9 100755 --- a/docker/main/rootfs/usr/local/bin/fix-ownership +++ b/docker/main/rootfs/usr/local/bin/fix-ownership @@ -10,6 +10,8 @@ # on every boot) # # Only files whose uid OR gid differs are touched, so re-runs are cheap. +# lost+found is skipped: it belongs to the filesystem, not to Frigate, and +# fsck puts recovered fragments of arbitrary files there under root-only 0700. # Top-level /config additionally grants group frigate-data TRAVERSE ONLY # (g+rx) so the separate go2rtc user can reach its pre-created HomeKit file # on hosts where /config is mounted 0700. Never g+w: directory write means @@ -82,7 +84,7 @@ for path in "$@"; do # stale mount. Tolerate it rather than aborting under errexit, but never # read a failed scan as "nothing to do": that would record the sweep as # complete without having looked. - if ! count=$(find "$path" \( -not -uid "$target_uid" -o -not -gid "$target_gid" \) -printf '.' 2>/dev/null | wc -c); then + if ! count=$(find "$path" -name lost+found -prune -o \( -not -uid "$target_uid" -o -not -gid "$target_gid" \) -printf '.' 2>/dev/null | wc -c); then swept_clean=0 echo "[WARN] fix-ownership: could not scan ${path}; will retry on next boot" continue @@ -109,7 +111,7 @@ for path in "$@"; do # -print feeds the progress counter while -exec {} + keeps the chown # batched; the scan above is what makes a real percentage possible started=$SECONDS - if find "$path" \( -not -uid "$target_uid" -o -not -gid "$target_gid" \) \ + if find "$path" -name lost+found -prune -o \( -not -uid "$target_uid" -o -not -gid "$target_gid" \) \ -print -exec chown -h "${target_uid}:${target_gid}" {} + \ | awk -v total="$count" -v path="$path" ' BEGIN { next_pct = 5 } diff --git a/docs/docs/configuration/non_root.md b/docs/docs/configuration/non_root.md index 28ab28bdc3..74e66dd49e 100644 --- a/docs/docs/configuration/non_root.md +++ b/docs/docs/configuration/non_root.md @@ -56,6 +56,10 @@ Pass `PUID` and `PGID` as the third and fourth arguments if you're not using the Once the volumes are aligned, start Frigate normally. A sentinel at `/config/.permissions_version` records what was done, so later boots skip the sweep entirely unless you change `PUID`/`PGID`. +`lost+found` is left alone. It belongs to the filesystem rather than to Frigate, and `fsck` recovers fragments of arbitrary files into it under root-only permissions, so handing it to the runtime user would expose whatever ends up there. Expect to see it still owned by root afterward, on any volume that's a dedicated mount. + +If something under your volumes genuinely can't be chowned, a read-only btrfs snapshot directory for example, the sweep warns and names the path, and it deliberately doesn't write the sentinel. That means it retries on the next boot rather than recording a migration that didn't finish. Either move those paths outside `/media/frigate` or expect the scan to repeat. + ### Network storage Storing recordings on a NAS is common, and ownership behaves differently there. Check what you have before migrating anything: