]> git.hungrycats.org Git - bees/commitdiff
scripts: make OpenRC init delegate the mount to beesd
authorZygo Blaxell <bees@furryterror.org>
Wed, 24 Jun 2026 20:53:16 +0000 (16:53 -0400)
committerZygo Blaxell <bees@furryterror.org>
Sat, 5 Sep 2026 04:03:57 +0000 (00:03 -0400)
The OpenRC init script mounted the btrfs filesystem itself in start_pre,
in the host mount namespace, and ran the bees binary directly.  That mount
was visible system-wide and leaked if stop_post did not run.  beesd (and
the systemd unit via PrivateMounts=yes) instead mount inside a private
slave-propagation namespace that is invisible to the rest of the system
and torn down automatically when bees exits.

Invoke `beesd --env-config ${fsuuid}` instead of bees directly, so the
mount, mount namespace, and BEESHOME/hash-table setup are all delegated to
beesd.  The script exports the configuration beesd reads in --env-config
mode (DB_SIZE, BEESHOME, BEESSTATUS, OPTIONS); start_pre is reduced to the
fsuuid/DB_SIZE checks and log-directory creation, and stop_post is dropped
because there is no host-namespace mount to clean up.  This removes the
duplicate mount/BEESHOME setup and gives OpenRC the same isolation and
cleanup semantics as the other two front ends.

bees options are passed through beesd's OPTIONS environment variable
rather than its command line: beesd's argument splitter would drop the
value of a space-separated option such as `--scan-mode 4`.

Assisted-by: Claude-Code:claude-opus-4-8
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
scripts/bees.initd.in

index f8089875aa5de999e48c580a8b1856f43f3e47a2..625471e49315bf0196c9d29605fee001d0787437 100644 (file)
 ## Internal variables derived from configuration
 rundir="/run/bees"
 logdir="/var/log/bees"
-mnt="${rundir}/mnt/${fsuuid}"
 device="/dev/disk/by-uuid/${fsuuid}"
-: "${beeshome:=".beeshome"}"
-export BEESHOME="${beeshome}"
-case "${beeshome}" in
-       /*) beeshome_path="${beeshome}" ;;           # absolute: use as-is
-       *)  beeshome_path="${mnt}/${beeshome}" ;;    # relative: resolve from filesystem root
-esac
-hashfile="${beeshome_path}/beeshash.dat"
 : "${logfile:="${logdir}/${RC_SVCNAME}.log"}"
 : "${loglevel:=5}"
 : "${bees_args:="--scan-mode 4"}"
 : "${scheduler:="batch"}"
+
+## The filesystem is mounted by beesd, not by this script.  beesd unshares a
+## private mount namespace (slave propagation) and mounts the btrfs root
+## subvolume inside it, exactly as it does when run standalone or under
+## systemd's PrivateMounts=yes.  The mount is therefore invisible to the rest
+## of the system and is torn down automatically when bees exits for any
+## reason, so this script never mounts or unmounts anything itself and needs
+## no stop_post cleanup.  beesd also creates BEESHOME and the hash table.
+##
+## beesd reads its configuration from the environment in --env-config mode.
+## It supplies "-o state.hash.size=$DB_SIZE -o state.hash.resize=yes" and the
+## mount path on its own; everything else for bees is passed through OPTIONS.
+## (bees options must go through OPTIONS, not beesd's command line: beesd's
+## argument splitter would drop the value of a space-separated option such as
+## "--scan-mode 4".)
+export DB_SIZE
+export BEESHOME="${beeshome:-.beeshome}"
 export BEESSTATUS="${statusfile:-${rundir}/${fsuuid}.status}"
+export OPTIONS="-v ${loglevel} ${bees_args}"
 
 ## OpenRC service definition
 name="${RC_SVCNAME}"
 description="Best-Effort Extent-Same, a btrfs dedupe agent"
-command="@LIBEXEC_PREFIX@/bees"
-command_args="-v ${loglevel} ${bees_args} -o state.hash.size=${DB_SIZE} -o state.hash.resize=yes ${mnt}"
+command="@PREFIX@/@BINDIR@/beesd"
+command_args="--env-config ${fsuuid}"
 command_background="true"
 command_progress="true"
 extra_started_commands="suspend resume"
@@ -78,33 +88,14 @@ start_pre() {
        _check_fsuuid || return 1
        _check_db_size || return 1
 
+       # beesd creates the run directory, mounts the filesystem, and sets up
+       # BEESHOME inside its own mount namespace.  Only the log directory and
+       # file are needed here, since start-stop-daemon opens the log in the
+       # host namespace before exec'ing beesd.
        checkpath -d -m 0700 -o root:root "${logdir}"
-       checkpath -d -m 0700 -o root:root "${rundir}"
-       checkpath -d -m 0700 -o root:root "${rundir}/mnt"
-       checkpath -d -m 0700 -o root:root "${mnt}"
-
        if [ -n "${logfile}" ]; then
                checkpath -f -m 0600 -o root:root "${logfile}"
        fi
-
-       ebegin "Mounting btrfs filesystem ${fsuuid}"
-       mount -o subvolid=5,noatime,nodev,noexec "${device}" "${mnt}"
-       eend $? || return 1
-
-       if [ ! -d "${beeshome_path}" ]; then
-               ebegin "Creating ${beeshome_path}"
-               if [ "$(stat -f -c %T "${mnt}")" = "btrfs" ]; then
-                       btrfs subvolume create "${beeshome_path}"
-               else
-                       mkdir "${beeshome_path}"
-               fi
-               eend $? || return 1
-               chmod 700 "${beeshome_path}"
-       fi
-
-       # Ensure hash table file exists with correct permissions.
-       # bees will handle creation and resizing natively.
-       checkpath -f -m 0600 -o root:root "${hashfile}"
 }
 
 stop_pre() {
@@ -112,12 +103,6 @@ stop_pre() {
        start-stop-daemon --signal SIGCONT --pidfile "${pidfile}" 2>/dev/null || true
 }
 
-stop_post() {
-       ebegin "Unmounting btrfs filesystem ${fsuuid}"
-       umount "${mnt}"
-       eend $?
-}
-
 suspend() {
        # Suspending bees avoids a btrfs send/receive kernel bug on some kernels.
        # See https://zygo.github.io/bees/btrfs-kernel.html