Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37910138
en ru br
ALT Linux repos
S:0.4.2-alt5

Group :: System/Base
RPM: btrfsmaintenance

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: btrfsmaintenance-0.4.2-alt.patch
Download


 .gear/btrfsmaintenance.spec                        | 126 +++++++++++++++++
 .gear/rules                                        |   3 +
 .../tags/cbe4c25b3339aeff07046040f360fb63931ecc90  |  22 +++
 .gear/tags/list                                    |   1 +
 80-btrfsmaintenance.preset                         |  12 ++
 README.md                                          |  17 ++-
 btrfs-balance.sh                                   |  18 +--
 btrfs-defrag-plugin.py                             |   2 +-
 btrfs-defrag-plugin.sh                             | 151 +++++++++++++++++++++
 btrfs-defrag.sh                                    |   6 +-
 btrfs-scrub.sh                                     |   8 +-
 btrfs-trim.sh                                      |   8 +-
 btrfsmaintenance-functions                         |  24 ++++
 btrfsmaintenance-refresh-cron.sh                   |  18 ++-
 dist-install.sh                                    |   3 +-
 prepare-release.sh                                 |   2 +-
 sysconfig.btrfsmaintenance                         |  31 ++++-
 17 files changed, 410 insertions(+), 42 deletions(-)
diff --git a/.gear/btrfsmaintenance.spec b/.gear/btrfsmaintenance.spec
new file mode 100644
index 0000000..d57fa04
--- /dev/null
+++ b/.gear/btrfsmaintenance.spec
@@ -0,0 +1,126 @@
+Name: btrfsmaintenance
+Version: 0.4.2
+Release: alt5
+Summary: Scripts for btrfs periodic maintenance tasks
+License: GPLv2
+Group: System/Base
+Url: https://github.com/kdave/btrfsmaintenance
+Source0: %name-%version.tar
+Patch: %name-%version-alt.patch
+BuildArch: noarch
+
+BuildRequires: pkgconfig(systemd)
+# https://bugzilla.altlinux.org/35388
+BuildRequires: rpm-macros-fedora-compat
+Requires: btrfs-progs
+
+%description
+Scripts for btrfs maintenance tasks like periodic scrub, balance, trim or defrag
+on selected mountpoints or directories. Hints for periodic snapshot tuning (eg.
+for snapper).
+
+%prep
+%setup
+%patch -p1
+
+%build
+%install
+# scripts
+install -m 755 -d %buildroot%_datadir/%name/
+install -m 755 btrfs-defrag.sh %buildroot%_datadir/%name/
+install -m 755 btrfs-balance.sh %buildroot%_datadir/%name/
+install -m 755 btrfs-scrub.sh %buildroot%_datadir/%name/
+install -m 755 btrfs-trim.sh %buildroot%_datadir/%name/
+install -m 755 btrfsmaintenance-refresh-cron.sh %buildroot%_datadir/%name/
+install -m 644 btrfsmaintenance-functions %buildroot%_datadir/%name/
+
+# systemd services and timers
+install -m 755 -d %buildroot%_unitdir/
+install -m 755 -d %buildroot%_presetdir/
+install -m 644 -D btrfsmaintenance-refresh.service %buildroot%_unitdir/
+install -m 644 -D btrfsmaintenance-refresh.path %buildroot%_unitdir/
+install -m 644 -D btrfs-balance.service %buildroot%_unitdir/
+install -m 644 -D btrfs-defrag.service %buildroot%_unitdir/
+install -m 644 -D btrfs-scrub.service %buildroot%_unitdir/
+install -m 644 -D btrfs-trim.service %buildroot%_unitdir/
+install -m 644 -D btrfs-balance.timer %buildroot%_unitdir/
+install -m 644 -D btrfs-defrag.timer %buildroot%_unitdir/
+install -m 644 -D btrfs-scrub.timer %buildroot%_unitdir/
+install -m 644 -D btrfs-trim.timer %buildroot%_unitdir/
+install -m 644 -D 80-btrfsmaintenance.preset %buildroot%_presetdir/
+
+# config
+install -m 644 -D sysconfig.btrfsmaintenance %buildroot%_sysconfdir/sysconfig/%name
+
+%post
+# According to 80-btrfmaintenance.preset,
+# needed systemd units will be enabled automatically on package installation
+%systemd_post btrfsmaintenance-refresh.service btrfsmaintenance-refresh.path btrfs-balance.service btrfs-balance.timer btrfs-defrag.service btrfs-defrag.timer btrfs-scrub.service btrfs-scrub.timer btrfs-trim.service btrfs-trim.timer
+
+%preun
+%systemd_preun btrfsmaintenance-refresh.service btrfsmaintenance-refresh.path btrfs-balance.service btrfs-balance.timer btrfs-defrag.service btrfs-defrag.timer btrfs-scrub.service btrfs-scrub.timer btrfs-trim.service btrfs-trim.timer
+
+%files
+%doc COPYING README.md
+%config(noreplace) %_sysconfdir/sysconfig/%name
+%dir %_datadir/%name
+%_datadir/%name/*
+%_unitdir/btrfsmaintenance-refresh.path
+%_unitdir/btrfsmaintenance-refresh.service
+%_unitdir/btrfs-balance.service
+%_unitdir/btrfs-defrag.service
+%_unitdir/btrfs-scrub.service
+%_unitdir/btrfs-trim.service
+%_unitdir/btrfs-balance.timer
+%_unitdir/btrfs-defrag.timer
+%_unitdir/btrfs-scrub.timer
+%_unitdir/btrfs-trim.timer
+%_presetdir/80-btrfsmaintenance.preset
+
+%check
+# Check correctness of the config
+set -efu
+. %buildroot%_sysconfdir/sysconfig/%name
+echo "$BTRFS_LOG_OUTPUT"
+echo "$BTRFS_DEFRAG_PATHS"
+echo "$BTRFS_DEFRAG_PERIOD"
+echo "$BTRFS_DEFRAG_MIN_SIZE"
+echo "$BTRFS_BALANCE_MOUNTPOINTS"
+echo "$BTRFS_BALANCE_PERIOD"
+echo "$BTRFS_BALANCE_DUSAGE"
+echo "$BTRFS_BALANCE_MUSAGE"
+echo "$BTRFS_SCRUB_MOUNTPOINTS"
+echo "$BTRFS_SCRUB_PERIOD"
+echo "$BTRFS_SCRUB_PRIORITY"
+echo "$BTRFS_SCRUB_READ_ONLY"
+echo "$BTRFS_TRIM_PERIOD"
+echo "$BTRFS_TRIM_MOUNTPOINTS"
+echo "$BTRFS_ALLOW_CONCURRENCY"
+
+%changelog
+
+* Mon Dec 23 2019 Mikhail Novosyolov <mikhailnov@altlinux.org> 0.4.2-alt5
+- Fix git merge mistake
+- Add simple test to prevent such mistakes in /etc/sysconfig/btrfsmaintenance
+  in the future
+
+* Sun Dec 22 2019 Mikhail Novosyolov <mikhailnov@altlinux.org> 0.4.2-alt4
+- Update to git master df43313e (21.12.2019)
+- Prevent running balance, trim, scrub at the same time by flocking
+  (main change from upstream)
+
+* Fri May 31 2019 Mikhail Novosyolov <mikhailnov@altlinux.org> 0.4.2-alt3
+- Fix %%post and %%preun scripts:
+  - not only systemd *.service units, but also *.timer and *.path should be
+    processed by systemctl set-default
+- Add systemd preset to autoenable needed systemd units (humans will not
+  understand which ones must be enabled manually as there are too many of them)
+- Adjusted default config /etc/sysconfig/btrfsmaintenance:
+  - Process all btrfs mount points by default, not only /
+  - Disable scrub by default;
+    it is not really needed on desktops and causes very high Load Average
+- These changes are in sync with
+  https://gitlab.com/nixtux-packaging/btrfsmaintenance
+
+* Sat Jan 12 2019 Vera Blagoveschenskaya <vercha@altlinux.org> 0.4.2-alt1
+- Initial build for ALT
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 0000000..e445bd8
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,3 @@
+spec: .gear/btrfsmaintenance.spec
+tar: v@version@:.
+diff: v@version@:. . name=@name@-@version@-alt.patch
diff --git a/.gear/tags/cbe4c25b3339aeff07046040f360fb63931ecc90 b/.gear/tags/cbe4c25b3339aeff07046040f360fb63931ecc90
new file mode 100644
index 0000000..aa6fd00
--- /dev/null
+++ b/.gear/tags/cbe4c25b3339aeff07046040f360fb63931ecc90
@@ -0,0 +1,22 @@
+object cf421fcadbbad9665ce3d14cba7d673d9386346d
+type commit
+tag v0.4.2
+tagger David Sterba <dsterba@suse.com> 1537884069 +0200
+
+v0.4.2
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAluqP6oACgkQxWXV+ddt
+WDsPbg//eUgoCiQME7FItjYhApXEKFDTaXYLBEw2lGnc5dMTXjtgMFSn1GJDw6oQ
+puxwnAB1/sMeJZ8LPUqlWTIs9Y5aXtndf7mHHyFTk4pFnE35ZG/Y5UnPMqSOcSlN
+5mBcr8Iwo0G/zzgYQbaeaSx3NKIqNKO4qoIpcyZx+Tpr2Oik4xb7sRxzoVKf3e4A
+KaCQJx6jXwbCSLcTwT9ECqbZFS6FLdhQ1/C6+GNd2z5IuANg7KfNd+flFE755Lgj
+0zInnM0dIVc5b7G9hslOLxMZy7b67KK1Xta8UXvcDk35Jb6iYdsD2ScM/h8Gw5l2
+lLkm1ftSK3SHelXF2xvXVrAXQjJrZlcLVYmN3O9kzol8hTohg+CE5rnOsZW7WXlQ
+eGZLq0ek10wKad2A3Udl7EVR8ii8UAX+oho45KcSNjBfIKmCTGr449TjS9qgVyaE
+gMy7CQN5+/Q4oMGPadFQLm+/ZSuk8ofEtB0S5tOZvnk2f4COBzJmg4IJHjiL10Rz
+uDC7kQk39ZpGRymrrRjmhDPu5EUno+SVXXbQ2UcdpyWsAGwgiF6NRZWpzjoDM/fm
+GFHvZfAGYb1gIq5aRGWbGFion7y/lVYn86Y9M4IcgVQB+TXcCU69on9JJO9WD/00
+MKAiAVwe8HaSOpIUcwAse5QVWOwviua0kJDOfI9dCFcokliwEug=
+=03ay
+-----END PGP SIGNATURE-----
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 0000000..491105b
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+cbe4c25b3339aeff07046040f360fb63931ecc90 v0.4.2
diff --git a/80-btrfsmaintenance.preset b/80-btrfsmaintenance.preset
new file mode 100644
index 0000000..4326be2
--- /dev/null
+++ b/80-btrfsmaintenance.preset
@@ -0,0 +1,12 @@
+enable btrfsmaintenance-refresh.service
+#enable btrfsmaintenance-refresh.path
+enable btrfs-balance.timer
+enable btrfs-defrag.timer
+enable btrfs-scrub.timer
+enable btrfs-trim.timer
+
+# Services, which are activated by timers, cannot be enabled or disabled
+#enable btrfs-balance.service
+#enable btrfs-defrag.service
+#enable btrfs-scrub.service
+#enable btrfs-trim.service
diff --git a/README.md b/README.md
index be29736..8129015 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,11 @@ the same set of blocks is affected.
 
 The balance command uses filters to do the work in smaller batches.
 
+Before kernel version 5.2, the impact with quota groups enabled can be extreme.
+The balance operation performs quota group accounting for every extent being
+relocated, which can have the impact of stalling the file system for an
+extended period of time.
+
 __Expected result:__ If possible all the underused chunks are removed, the
 value of `total` in output of `btrfs fi df /path` should be lower than before.
 Check the logs.
@@ -156,7 +161,9 @@ If the period is changed, the cron symlinks have to be refreshed:
 
 There's a set of timer units that run the respective task script. The periods
 are configured in the `/etc/sysconfig/btrfsmaintenance` file as well. The
-timers have to be installed using a similar way as cron.
+timers have to be installed using a similar way as cron.  Please note that the
+'*.timer' and respective '*.service' files have to be installed so the timers
+work properly.
 
 
 ## Quick start ##
@@ -182,10 +189,14 @@ do manual installation of files as described below.
 * `sysconfig.btrfsmaintenance` configuration template is put to:
  * `/etc/sysconfig/btrfsmaintenance` on SUSE and RedHat based systems or derivatives
  * `/etc/default/btrfsmaintenance` on Debian and derivatives
-* `/usr/lib/zypp/plugins/commit/btrfs-defrag-plugin.py` post-update script for
+* `/usr/lib/zypp/plugins/commit/btrfs-defrag-plugin.sh` or
+  `/usr/lib/zypp/plugins/commit/btrfs-defrag-plugin.py` post-update script for
   zypper (the package manager), applies to SUSE-based distros for now
 * cron refresh scripts are installed (see bellow)
 
+The defrag plugin has a shell and python implementation, choose what suits the
+installation better.
+
 ### cron jobs ###
 
 The periodic execution of the tasks is done by the 'cron' service.  Symlinks to
@@ -206,7 +217,7 @@ configuration file in `/etc/sysconfig/btrfsmaintenance` by installing the
 The package database files tend to be updated in a random way and get
 fragmented, which particularly hurts on btrfs. For rpm-based distros this means files
 in `/var/lib/rpm`. The script or plugin simpy runs a defragmentation on the affected files.
-See `btrfs-defrag-plugin.py` for more details.
+See `btrfs-defrag-plugin.sh` or `btrfs-defrag-plugin.py` for more details.
 
 At the moment the 'zypper' package manager plugin exists. As the package
 managers differ significantly, there's no single plugin/script to do that.
diff --git a/btrfs-balance.sh b/btrfs-balance.sh
old mode 100755
new mode 100644
index 978c1fa..8c3e1b3
--- a/btrfs-balance.sh
+++ b/btrfs-balance.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 
@@ -10,10 +10,6 @@ if [ -f /etc/sysconfig/btrfsmaintenance ] ; then
     . /etc/sysconfig/btrfsmaintenance
 fi
 
-if [ -f /etc/default/btrfsmaintenance ] ; then
-    . /etc/default/btrfsmaintenance
-fi
-
 LOGIDENTIFIER='btrfs-balance'
 . $(dirname $(realpath "$0"))/btrfsmaintenance-functions
 
@@ -33,7 +29,7 @@ for MM in $BTRFS_BALANCE_MOUNTPOINTS; do
 	df -H "$MM"
 
 	if detect_mixed_bg "$MM"; then
-		btrfs balance start -musage=0 -dusage=0 "$MM"
+		run_task btrfs balance start -musage=0 -dusage=0 "$MM"
 		# we use the MUSAGE values for both, supposedly less aggressive
 		# values, but as the data and metadata space is shared on
 		# mixed-bg this does not lead to the situations we want to
@@ -41,18 +37,18 @@ for MM in $BTRFS_BALANCE_MOUNTPOINTS; do
 		# blockgroups)
 		for BB in $BTRFS_BALANCE_MUSAGE; do
 			# quick round to clean up the unused block groups
-			btrfs balance start -v -musage=$BB -dusage=$BB "$MM"
+			run_task btrfs balance start -v -musage=$BB -dusage=$BB "$MM"
 		done
 	else
-		btrfs balance start -dusage=0 "$MM"
+		run_task btrfs balance start -dusage=0 "$MM"
 		for BB in $BTRFS_BALANCE_DUSAGE; do
 			# quick round to clean up the unused block groups
-			btrfs balance start -v -dusage=$BB "$MM"
+			run_task btrfs balance start -v -dusage=$BB "$MM"
 		done
-		btrfs balance start -musage=0 "$MM"
+		run_task btrfs balance start -musage=0 "$MM"
 		for BB in $BTRFS_BALANCE_MUSAGE; do
 			# quick round to clean up the unused block groups
-			btrfs balance start -v -musage="$BB" "$MM"
+			run_task btrfs balance start -v -musage="$BB" "$MM"
 		done
 	fi
 
diff --git a/btrfs-defrag-plugin.py b/btrfs-defrag-plugin.py
index 36b7285..dab9556 100644
--- a/btrfs-defrag-plugin.py
+++ b/btrfs-defrag-plugin.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 # This plugin defragments rpm files after update.
 #
diff --git a/btrfs-defrag-plugin.sh b/btrfs-defrag-plugin.sh
new file mode 100755
index 0000000..5a2c06d
--- /dev/null
+++ b/btrfs-defrag-plugin.sh
@@ -0,0 +1,151 @@
+#!/bin/bash
+#
+# This plugin defragments rpm files after update.
+#
+# If the filesystem is btrfs, run defrag command in /var/lib/rpm, set the
+# desired extent size to 32MiB, but this may change in the result depending
+# on the fragmentation of the free space
+#
+## Why 32MiB:
+# - the worst fragmentation has been observed on /var/lib/rpm/Packages
+# - this can grow up to several hundred of megabytes
+# - the file gets updated at random places
+# - although the file will be composed of many extents, it's faster to
+#   merge only the extents that affect some portions of the file, instead
+#   of the whole file; the difference is negligible
+# - due to the free space fragmentation over time, it's hard to find
+#   contiguous space, the bigger the extent is, the worse and the extent
+#   size hint is not reached anyway
+
+DEBUG="false"
+EXTENT_SIZE="32M"
+
+RPMDIR=$(rpm --eval "%_dbpath")
+SCRIPTNAME="$(basename "$0")"
+
+cleanup() {
+    test -n "$tmpdir" -a -d "$tmpdir" && execute rm -rf "$tmpdir"
+}
+
+trap cleanup EXIT
+
+tmpdir=$(mktemp -d /tmp/btrfs-defrag-plugin.XXXXXX)
+
+log() {
+    logger -p info -t $SCRIPTNAME --id=$$ "$@"
+}
+
+debug() {
+    $DEBUG && log "$@"
+}
+
+respond() {
+    debug "<< [$1]"
+    echo -ne "$1\n\n\x00"
+}
+
+execute() {
+    debug -- "Executing: $@"
+
+    $@ 2> $tmpdir/cmd-output
+    ret=$?
+
+    if $DEBUG; then
+        if test $ret -ne 0; then
+            log -- "Command failed, output follows:"
+            log -f $tmpdir/cmd-output
+            log -- "End output"
+        else
+            log -- "Command succeeded"
+        fi
+    fi
+    return $ret
+}
+
+btrfs_defrag() {
+    # defrag options:
+    # - verbose
+    # - recursive
+    # - flush each file before going to the next one
+    # - set the extent target hint
+    execute btrfs filesystem defragment -v -f -r -t "$EXTENT_SIZE" "$RPMDIR"
+}
+
+debug_fragmentation() {
+    if $DEBUG; then
+        log -- "Fragmentation $1"
+        execute filefrag $RPMDIR/* > $tmpdir/filefrag-output
+        if test $? -eq 0; then
+            log -f $tmpdir/filefrag-output
+	    log -- "End output"
+        else
+            log "Non-fatal error ignored."
+        fi
+    fi
+}
+
+ret=0
+
+# The frames are terminated with NUL.  Use that as the delimeter and get
+# the whole frame in one go.
+while IFS= read -r -d $'\0' FRAME; do
+    echo ">>" $FRAME | debug
+
+    # We only want the command, which is the first word
+    read COMMAND <<<$FRAME
+
+    # libzypp will only close the plugin on errors, which may also be logged.
+    # It will also log if the plugin exits unexpectedly.  We don't want
+    # to create a noisy log when using another file system, so we just
+    # wait until COMMITEND to do anything.  We also need to ACK _DISCONNECT
+    # or libzypp will kill the script, which means we can't clean up.
+    debug "COMMAND=[$COMMAND]"
+    case "$COMMAND" in
+    COMMITEND) ;;
+    _DISCONNECT)
+        respond "ACK"
+        break
+        ;;
+    *)
+        respond "_ENOMETHOD"
+        continue
+        ;;
+    esac
+
+    # We don't have anything to do if it's not btrfs.
+    FSTYPE=$(execute stat -f --format=%T $RPMDIR)
+    if test $? -ne 0; then
+        respond "ERROR"
+        ret=1
+        break
+    fi
+    debug "Output follows:"
+    debug "$FSTYPE"
+    debug -- "End output"
+
+    if test "$FSTYPE" != "btrfs"; then
+	debug "Nothing to do: RPM Database is on $FSTYPE file system."
+        respond "_ENOMETHOD"
+	continue
+    fi
+
+    debug_fragmentation "before defrag run"
+
+    btrfs_defrag > $tmpdir/defrag-output
+    if test $? -ne 0; then
+        respond "ERROR"
+        ret=1
+        break
+    fi
+
+    # Log the output if we're in debug mode
+    debug "Output follows:"
+    debug -f $tmpdir/defrag-output
+    debug -- "End output"
+
+    debug_fragmentation "after defrag run"
+
+    respond "ACK"
+done
+debug "Terminating with exit code $ret"
+exit $ret
diff --git a/btrfs-defrag.sh b/btrfs-defrag.sh
index 5ced921..bb5584c 100755
--- a/btrfs-defrag.sh
+++ b/btrfs-defrag.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 
@@ -10,10 +10,6 @@ if [ -f /etc/sysconfig/btrfsmaintenance ] ; then
     . /etc/sysconfig/btrfsmaintenance
 fi
 
-if [ -f /etc/default/btrfsmaintenance ] ; then
-    . /etc/default/btrfsmaintenance
-fi
-
 LOGIDENTIFIER='btrfs-defrag'
 . $(dirname $(realpath "$0"))/btrfsmaintenance-functions
 
diff --git a/btrfs-scrub.sh b/btrfs-scrub.sh
old mode 100755
new mode 100644
index 5680b56..72c3baf
--- a/btrfs-scrub.sh
+++ b/btrfs-scrub.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 
@@ -10,10 +10,6 @@ if [ -f /etc/sysconfig/btrfsmaintenance ] ; then
     . /etc/sysconfig/btrfsmaintenance
 fi
 
-if [ -f /etc/default/btrfsmaintenance ] ; then
-    . /etc/default/btrfsmaintenance
-fi
-
 LOGIDENTIFIER='btrfs-scrub'
 . $(dirname $(realpath "$0"))/btrfsmaintenance-functions
 
@@ -40,7 +36,7 @@ for MNT in $BTRFS_SCRUB_MOUNTPOINTS; do
 		echo "Path $MNT is not btrfs, skipping"
 		continue
 	fi
-	btrfs scrub start -Bd $ioprio $readonly "$MNT"
+	run_task btrfs scrub start -Bd $ioprio $readonly "$MNT"
 	if [ "$?" != "0" ]; then
 		echo "Scrub cancelled at $MNT"
 		exit 1
diff --git a/btrfs-trim.sh b/btrfs-trim.sh
old mode 100755
new mode 100644
index 9e01d19..8b5f409
--- a/btrfs-trim.sh
+++ b/btrfs-trim.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 
@@ -10,10 +10,6 @@ if [ -f /etc/sysconfig/btrfsmaintenance ] ; then
     . /etc/sysconfig/btrfsmaintenance
 fi
 
-if [ -f /etc/default/btrfsmaintenance ] ; then
-    . /etc/default/btrfsmaintenance
-fi
-
 LOGIDENTIFIER='btrfs-trim'
 . $(dirname $(realpath "$0"))/btrfsmaintenance-functions
 
@@ -29,7 +25,7 @@ for MNT in $BTRFS_TRIM_MOUNTPOINTS; do
 		continue
 	fi
 	echo "Running fstrim on $MNT"
-	fstrim --verbose "$MNT"
+	run_task fstrim --verbose "$MNT"
 done
 
 } | \
diff --git a/btrfsmaintenance-functions b/btrfsmaintenance-functions
index 10f90d1..852728a 100644
--- a/btrfsmaintenance-functions
+++ b/btrfsmaintenance-functions
@@ -76,3 +76,27 @@ is_btrfs() {
 	[ "$FS" = "btrfs" ] && return 0
 	return 1
 }
+
+# function: btrfs_fsid
+# parameter: path to a mounted filesystem
+#
+# return filesystem UUID on a given path
+btrfs_fsid() {
+	btrfs filesystem show "$1" | sed -n -e '/uuid:/ {s/^.*uuid: //;p }'
+}
+
+# function: run_task
+# parameter: command to run, expecting the mountpoint to be the last argument
+#
+# run the given command with concurrency protection unless allowed by the
+# config, use for tasks that should not run at the same time due to heavy IO
+run_task() {
+	MNT="${@:$#}"
+	UUID=$(btrfs_fsid "$MNT")
+
+	if test "$BTRFS_ALLOW_CONCURRENCY" = "true"; then
+		"$@"
+	else
+		/usr/bin/flock --verbose /run/btrfs-maintenance-running."$UUID" "$@"
+	fi
+}
diff --git a/btrfsmaintenance-refresh-cron.sh b/btrfsmaintenance-refresh-cron.sh
index 2bf5f8e..7519df6 100755
--- a/btrfsmaintenance-refresh-cron.sh
+++ b/btrfsmaintenance-refresh-cron.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 
@@ -15,10 +15,6 @@ if [ -f /etc/sysconfig/btrfsmaintenance ]; then
     . /etc/sysconfig/btrfsmaintenance
 fi
 
-if [ -f /etc/default/btrfsmaintenance ]; then
-    . /etc/default/btrfsmaintenance
-fi
-
 case "$1" in
 	cron)
 		BTRFS_TIMER_IMPLEMENTATION="cron"
@@ -35,6 +31,18 @@ refresh_cron() {
 	SCRIPT="$2"
 	echo "Refresh script $SCRIPT for $EXPECTED"
 
+	valid=false
+	for PERIOD in daily weekly monthly none uninstall; do
+		if [ "$PERIOD" = "$EXPECTED" ]; then
+			valid=true
+		fi
+	done
+
+	if ! $valid; then
+		echo "$EXPECTED is not a valid period for cron.  Not changing."
+		return
+	fi
+
 	for PERIOD in daily weekly monthly; do
 	        # NOTE: debian does not allow filenames with dots in /etc/cron.*
 	        LINK="${SCRIPT%.*}"
diff --git a/dist-install.sh b/dist-install.sh
index 18be352..543635c 100755
--- a/dist-install.sh
+++ b/dist-install.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # usage: $0 [sysconfdir]
 #
 # Install configuration template, documentation and scripts. Target path is
@@ -35,4 +35,5 @@ echo "- run ./btrfsmaintenance-refresh-cron.sh to update cron symlinks"
 echo ""
 echo "For systemd.timer-based setups:"
 echo "- copy *.timer files to the systemd.unit path (eg. /usr/lib/systemd/system/ or /etc/systemd/system)"
+echo "- copy *.service files to the systemd.unit path (eg. /usr/lib/systemd/system/ or /etc/systemd/system)"
 echo "- run './btrfsmaintenance-refresh-cron.sh timer' to enable and schedule the timers"
diff --git a/prepare-release.sh b/prepare-release.sh
index 4f5240a..12a2c81 100755
--- a/prepare-release.sh
+++ b/prepare-release.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 base=btrfsmaintenance
 version=$(grep -i ^version: ${base}.spec | awk '{print $2}')
diff --git a/sysconfig.btrfsmaintenance b/sysconfig.btrfsmaintenance
index 4088254..819bc53 100644
--- a/sysconfig.btrfsmaintenance
+++ b/sysconfig.btrfsmaintenance
@@ -40,7 +40,7 @@ BTRFS_DEFRAG_MIN_SIZE="+1M"
 # (Colon separated paths)
 # The special word/mountpoint "auto" will evaluate all mounted btrfs
 # filesystems
-BTRFS_BALANCE_MOUNTPOINTS="/"
+BTRFS_BALANCE_MOUNTPOINTS="auto"
 
 ## Path:           System/File systems/btrfs
 ## Type:           string(none,daily,weekly,monthly)
@@ -48,6 +48,10 @@ BTRFS_BALANCE_MOUNTPOINTS="/"
 ## ServiceRestart: btrfsmaintenance-refresh
 #
 # Frequency of periodic balance.
+#
+# The frequency may be specified using one of the listed values or
+# in the format documented in the "Calendar Events" section of systemd.time(7),
+# if available.
 BTRFS_BALANCE_PERIOD="weekly"
 
 ## Path:        System/File systems/btrfs
@@ -81,7 +85,7 @@ BTRFS_BALANCE_MUSAGE="1 5 10 20 30"
 # (Colon separated paths)
 # The special word/mountpoint "auto" will evaluate all mounted btrfs
 # filesystems
-BTRFS_SCRUB_MOUNTPOINTS="/"
+BTRFS_SCRUB_MOUNTPOINTS="auto"
 
 ## Path:        System/File systems/btrfs
 ## Type:        string(none,weekly,monthly)
@@ -89,6 +93,10 @@ BTRFS_SCRUB_MOUNTPOINTS="/"
 ## ServiceRestart: btrfsmaintenance-refresh
 #
 # Frequency of periodic scrub.
+#
+# The frequency may be specified using one of the listed values or
+# in the format documented in the "Calendar Events" section of systemd.time(7),
+# if available.
 BTRFS_SCRUB_PERIOD="monthly"
 
 ## Path:        System/File systems/btrfs
@@ -115,6 +123,10 @@ BTRFS_SCRUB_READ_ONLY="false"
 # Frequency of periodic trim. Off by default so it does not collide with
 # fstrim.timer . If you do not use the timer, turn it on here. The recommended
 # period is 'weekly'.
+#
+# The frequency may be specified using one of the listed values or
+# in the format documented in the "Calendar Events" section of systemd.time(7),
+# if available.
 BTRFS_TRIM_PERIOD="none"
 
 ## Path:        System/File systems/btrfs
@@ -126,4 +138,17 @@ BTRFS_TRIM_PERIOD="none"
 # (Colon separated paths)
 # The special word/mountpoint "auto" will evaluate all mounted btrfs
 # filesystems
-BTRFS_TRIM_MOUNTPOINTS="/"
+BTRFS_TRIM_MOUNTPOINTS="auto"
+
+## Path:	System/File systems/btrfs
+## Description:	Configuration to allow concurrent jobs
+## Type: 	boolean
+## Default:	"false"
+#
+# These maintenance tasks may compete for resources with each other, blocking
+# out other tasks from using the file systems.  This option will force
+# these jobs to run in FIFO order when scheduled at overlapping times.  This
+# may include tasks scheduled to run when a system resumes or boots when
+# the timer for these tasks(s) elapsed while the system was suspended
+# or powered off.
+BTRFS_ALLOW_CONCURRENCY="false"
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin