## 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"
_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() {
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