From d2bdcba5556f0295c208b2793908d92721065ca2 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 21 Dec 2021 20:08:16 +0800 Subject: [PATCH 1/3] btrfsmaintenance: add tests framework and functional test cases Create a framework to test btrfsmaintenance. This test environment needs the following variables configured in the file './check'. TESTPATH Specify the path to the btrfsmaintenance code under test. For example: TESTPATH=/usr/share/btrfsmaintenance # Tests the rpm installed code. TESTPATH=../ # Tests script from the btrfsmaintenance workspace. SCRATCH_MNT Provide a scratch btrfs filesystem for which the scripts run. For example: SCRATCH_MNT=/mnt/scratch Run tests as: ./check <-- runs all the available test cases. ./check 1-timer-systemd.sh <-- runs only the specified test case. As of now, there are a set of 6 test cases to test the anacron, systemd timers setups and the task scripts using a configuration file 'sysconfig.btrfsmaintenance.testall'. Please note, this adds the basic functionality test cases more elaborate test cases to be added based on the feedback. Signed-off-by: Anand Jain --- test/1-timer-systemd.expected | 24 ++++++++ test/1-timer-systemd.sh | 17 ++++++ test/2-timer-cron.expected | 27 +++++++++ test/2-timer-cron.sh | 24 ++++++++ test/3-task-balance.sh | 18 ++++++ test/4-task-defrag.sh | 13 +++++ test/5-task-scrub.sh | 13 +++++ test/6-task-trim.sh | 13 +++++ test/check | 54 ++++++++++++++++++ test/results/.full | 4 ++ test/sysconfig.btrfsmaintenance.testall | 21 +++++++ test/utils | 74 +++++++++++++++++++++++++ 12 files changed, 302 insertions(+) create mode 100644 test/1-timer-systemd.expected create mode 100755 test/1-timer-systemd.sh create mode 100644 test/2-timer-cron.expected create mode 100755 test/2-timer-cron.sh create mode 100755 test/3-task-balance.sh create mode 100755 test/4-task-defrag.sh create mode 100755 test/5-task-scrub.sh create mode 100755 test/6-task-trim.sh create mode 100755 test/check create mode 100644 test/results/.full create mode 100755 test/sysconfig.btrfsmaintenance.testall create mode 100755 test/utils diff --git a/test/1-timer-systemd.expected b/test/1-timer-systemd.expected new file mode 100644 index 0000000..2348458 --- /dev/null +++ b/test/1-timer-systemd.expected @@ -0,0 +1,24 @@ +btrfsmaintenance-refresh.path disabled +btrfs-balance.service static +btrfs-defrag.service static +btrfs-scrub.service static +btrfs-trim.service static +btrfsmaintenance-refresh.service static +btrfs-balance.timer enabled +btrfs-defrag.timer enabled +btrfs-scrub.timer enabled +btrfs-trim.timer enabled +btrfs-balance.timer btrfs-balance.service +btrfs-defrag.timer btrfs-defrag.service +btrfs-scrub.timer btrfs-scrub.service +btrfs-trim.timer btrfs-trim.service +btrfsmaintenance-refresh.path disabled +btrfs-balance.service static +btrfs-defrag.service static +btrfs-scrub.service static +btrfs-trim.service static +btrfsmaintenance-refresh.service static +btrfs-balance.timer disabled +btrfs-defrag.timer disabled +btrfs-scrub.timer disabled +btrfs-trim.timer disabled diff --git a/test/1-timer-systemd.sh b/test/1-timer-systemd.sh new file mode 100755 index 0000000..44af555 --- /dev/null +++ b/test/1-timer-systemd.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Test if the systemd timers are enabled as per the config file + +. $(dirname $(realpath "$0"))/utils + +load_config "sysconfig.btrfsmaintenance.testall" +timer_setup "systemd-timer" + +systemctl list-unit-files | grep btrfs +systemctl --all list-timers | grep btrfs | rev | awk '{print $1" "$2}' | rev + +timer_reset "systemd-timer" +systemctl list-unit-files | grep btrfs +systemctl --all list-timers | grep btrfs | rev | awk '{print $1" "$2}' | rev + +unload_config diff --git a/test/2-timer-cron.expected b/test/2-timer-cron.expected new file mode 100644 index 0000000..6015672 --- /dev/null +++ b/test/2-timer-cron.expected @@ -0,0 +1,27 @@ +btrfsmaintenance-refresh.path disabled +btrfs-balance.service static +btrfs-defrag.service static +btrfs-scrub.service static +btrfs-trim.service static +btrfsmaintenance-refresh.service static +btrfs-balance.timer disabled +btrfs-defrag.timer disabled +btrfs-scrub.timer disabled +btrfs-trim.timer disabled +daily: +weekly: +btrfs-balance +btrfs-scrub +monthly: +btrfs-defrag +btrfs-trim +btrfsmaintenance-refresh.path disabled +btrfs-balance.service static +btrfs-defrag.service static +btrfs-scrub.service static +btrfs-trim.service static +btrfsmaintenance-refresh.service static +btrfs-balance.timer disabled +btrfs-defrag.timer disabled +btrfs-scrub.timer disabled +btrfs-trim.timer disabled diff --git a/test/2-timer-cron.sh b/test/2-timer-cron.sh new file mode 100755 index 0000000..fceafc3 --- /dev/null +++ b/test/2-timer-cron.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Test if the cron timers are enabled as per the config file + +. $(dirname $(realpath "$0"))/utils + +load_config "sysconfig.btrfsmaintenance.testall" + +timer_setup "cron" +systemctl list-unit-files | grep btrfs +echo daily: +ls /etc/cron.daily | grep btrfs +echo weekly: +ls /etc/cron.weekly| grep btrfs +echo monthly: +ls /etc/cron.monthly | grep btrfs + +timer_reset "cron" +systemctl list-unit-files | grep btrfs +ls /etc/cron.daily | grep btrfs +ls /etc/cron.weekly| grep btrfs +ls /etc/cron.monthly | grep btrfs + +unload_config diff --git a/test/3-task-balance.sh b/test/3-task-balance.sh new file mode 100755 index 0000000..1f8e503 --- /dev/null +++ b/test/3-task-balance.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Test is the task: Balance + +. $(dirname $(realpath "$0"))/utils + +timer_reset "cron" +timer_reset "systemd-timer" +load_config "sysconfig.btrfsmaintenance.testall" + +$TESTPATH/btrfs-balance.sh > ./results/$TESTNAME.full + +cat ./results/$TESTNAME.full | grep -q "Before balance of" +[ $? != 0 ] && echo "Balance did not run" +cat ./results/$TESTNAME.full | grep -q "Done," +[ $? != 0 ] && echo "Balance did not complete?" + +unload_config diff --git a/test/4-task-defrag.sh b/test/4-task-defrag.sh new file mode 100755 index 0000000..7b41f66 --- /dev/null +++ b/test/4-task-defrag.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Test is the task: defrag + +. $(dirname $(realpath "$0"))/utils + +timer_reset "cron" +timer_reset "systemd-timer" +load_config "sysconfig.btrfsmaintenance.testall" + +$TESTPATH/btrfs-defrag.sh > ./results/$TESTNAME.full + +unload_config diff --git a/test/5-task-scrub.sh b/test/5-task-scrub.sh new file mode 100755 index 0000000..bcb095d --- /dev/null +++ b/test/5-task-scrub.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Test is the task: scrub + +. $(dirname $(realpath "$0"))/utils + +timer_reset "cron" +timer_reset "systemd-timer" +load_config "sysconfig.btrfsmaintenance.testall" + +$TESTPATH/btrfs-scrub.sh > ./results/$TESTNAME.full + +unload_config diff --git a/test/6-task-trim.sh b/test/6-task-trim.sh new file mode 100755 index 0000000..905730e --- /dev/null +++ b/test/6-task-trim.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Test is the task: trim + +. $(dirname $(realpath "$0"))/utils + +timer_reset "cron" +timer_reset "systemd-timer" +load_config "sysconfig.btrfsmaintenance.testall" + +$TESTPATH/btrfs-trim.sh > ./results/$TESTNAME.full + +unload_config diff --git a/test/check b/test/check new file mode 100755 index 0000000..19fc110 --- /dev/null +++ b/test/check @@ -0,0 +1,54 @@ +#!/bin/bash + +#### Modify as needed ##### + +# Where is the code under test +TESTPATH="/usr/share/btrfsmaintenance" +#TESTPATH="../" + +# A btrfs filesystem on which the btrfsmaintenance script shall run. +SCRATCH_MNT="/mnt/scratch" + +verbose=false + +########################### + +. $(dirname $(realpath "$0"))/utils + +do_test() +{ + local testcase=$1 + local testname + local should_match_expected=false + + testname=$(echo $testcase | cut -d"." -f1) + rm ./results/$testname.out > /dev/null 2>&1 + rm ./results/$testname.full > /dev/null 2>&1 + + . ./$testcase > ./results/$testname.out + + # No expected output file means testcase breaks the silence upon error + if [ -f $testname.expected ]; then + diff -Z ./results/${testname}.out ./${testname}.expected + [ $? != 0 ] && \ + echo "$testname ..... [Failed]" || \ + echo "$testname ..... [Passed]" + elif [ $(cat ./results/$testname.out | wc -l) != 0 ]; then + echo "$testname ..... [Failed: check ./results/$testname.out|full]" + else + echo "$testname ..... [Passed]" + fi +} + +update_btrfs_mnt sysconfig.btrfsmaintenance.testall + +if [ ! -z $1 ]; then + tests=$* +else + tests=$(ls *.sh | grep -E '^[0-9]') +fi + +for testcase in $tests +do + do_test $testcase +done diff --git a/test/results/.full b/test/results/.full new file mode 100644 index 0000000..f4dc018 --- /dev/null +++ b/test/results/.full @@ -0,0 +1,4 @@ +Running fstrim on /mnt/scratch +fstrim: /mnt/scratch: the discard operation is not supported +flock: getting lock took 0.000005 seconds +flock: executing fstrim diff --git a/test/sysconfig.btrfsmaintenance.testall b/test/sysconfig.btrfsmaintenance.testall new file mode 100755 index 0000000..c3e5608 --- /dev/null +++ b/test/sysconfig.btrfsmaintenance.testall @@ -0,0 +1,21 @@ +BTRFS_SCRUB_MOUNTPOINTS=/mnt/scratch +BTRFS_DEFRAG_PATHS=/mnt/scratch +BTRFS_BALANCE_MOUNTPOINTS=/mnt/scratch +BTRFS_TRIM_MOUNTPOINTS=/mnt/scratch + +BTRFS_SCRUB_PERIOD="weekly" +BTRFS_DEFRAG_PERIOD="monthly" +BTRFS_BALANCE_PERIOD="weekly" +BTRFS_TRIM_PERIOD="monthly" + +BTRFS_DEFRAG_MIN_SIZE="+1M" + +BTRFS_BALANCE_DUSAGE="5 10" +BTRFS_BALANCE_MUSAGE="5" + +BTRFS_SCRUB_PRIORITY="idle" +BTRFS_SCRUB_READ_ONLY="false" + +BTRFS_LOG_OUTPUT="stdout" + +BTRFS_ALLOW_CONCURRENCY="false" diff --git a/test/utils b/test/utils new file mode 100755 index 0000000..85e6234 --- /dev/null +++ b/test/utils @@ -0,0 +1,74 @@ +#!/bin/bash + +tell() +{ + [ $verbose = true ] && echo $* + : +} + +timer_setup() +{ + local timertype=$1 + + $verbose == true && \ + $TESTPATH/btrfsmaintenance-refresh-cron.sh $timertype || \ + $TESTPATH/btrfsmaintenance-refresh-cron.sh $timertype > /dev/null +} + +timer_reset() +{ + local timertype=$1 + + $verbose = true && \ + $TESTPATH/btrfsmaintenance-refresh-cron.sh $timertype uninstall || \ + $TESTPATH/btrfsmaintenance-refresh-cron.sh $timertype uninstall > /dev/null +} + +sysconf_file() +{ + if [ -f /etc/sysconfig/btrfsmaintenance ]; then + echo "/etc/sysconfig/btrfsmaintenance" + return + elif [ -f /etc/default/btrfsmaintenance ]; then + echo "/etc/default/btrfsmaintenance" + return + fi + + echo "ERROR: btrfsmaintenance config file is not found" + exit 1 +} + +load_config() +{ + local sys_config=$(sysconf_file) + local test_configfile=$1 + + if ! [ -f "$test_configfile" ]; then + echo "ERROR: config file '$test_configfile' is not found." + exit 1 + fi + + # btrfsmaintenance-refresh-cron.sh and the tasks scripts have configfile + # path hard coded. So move our test config file there. + + mv $sys_config ${sys_config}.org + cp $test_configfile $sys_config +} + +unload_config() +{ + local sys_config=$(sysconf_file) + + mv ${sys_config}.org $sys_config +} + +update_btrfs_mnt() +{ + local configfile=$1 + + for script in BTRFS_SCRUB_MOUNTPOINTS BTRFS_DEFRAG_PATHS \ + BTRFS_BALANCE_MOUNTPOINTS BTRFS_TRIM_MOUNTPOINTS + do + sed -i -E "s,($script=).*,\1$SCRATCH_MNT," $configfile + done +} From d6e964ab9c1daed57f9f970587e48f04b7f3bd77 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 14 Dec 2021 23:58:57 +0800 Subject: [PATCH 2/3] btrfs-defrag: add -r option We specify the top-level directory in the btrfsmaintenance config file. Why not add -r recursive option. Signed-off-by: Anand Jain --- btrfs-defrag.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/btrfs-defrag.sh b/btrfs-defrag.sh index 5511833..6725d5e 100755 --- a/btrfs-defrag.sh +++ b/btrfs-defrag.sh @@ -28,7 +28,7 @@ for P in $BTRFS_DEFRAG_PATHS; do continue fi find "$P" -xdev -size "$BTRFS_DEFRAG_MIN_SIZE" -type f \ - -exec btrfs filesystem defrag -t 32m -f $BTRFS_VERBOSITY '{}' \; + -exec btrfs filesystem defrag -r -t 32m -f $BTRFS_VERBOSITY '{}' \; done } | \ From 6f4d450a968294a92457e1c81e62d07f19aabae3 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Wed, 29 Dec 2021 07:20:55 +0800 Subject: [PATCH 3/3] btrfsmaintenance: modify default timer for balance and scrub to none The default values of these tasks are entirely system dependent. Larger servers are fine; however, balance or scrub on small RPi stalls the system. And the users without being aware of such an impact will have bad experiences. Defaults to none help use cases to review. Signed-off-by: Anand Jain --- sysconfig.btrfsmaintenance | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sysconfig.btrfsmaintenance b/sysconfig.btrfsmaintenance index cfaa81e..60c54f3 100644 --- a/sysconfig.btrfsmaintenance +++ b/sysconfig.btrfsmaintenance @@ -44,7 +44,7 @@ BTRFS_BALANCE_MOUNTPOINTS="/" ## Path: System/File systems/btrfs ## Type: string(none,daily,weekly,monthly) -## Default: "weekly" +## Default: * ## ServiceRestart: btrfsmaintenance-refresh # # Frequency of periodic balance. @@ -52,7 +52,7 @@ BTRFS_BALANCE_MOUNTPOINTS="/" # 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" +BTRFS_BALANCE_PERIOD="none" ## Path: System/File systems/btrfs ## Type: string @@ -89,7 +89,7 @@ BTRFS_SCRUB_MOUNTPOINTS="/" ## Path: System/File systems/btrfs ## Type: string(none,weekly,monthly) -## Default: "monthly" +## Default: * ## ServiceRestart: btrfsmaintenance-refresh # # Frequency of periodic scrub. @@ -97,7 +97,7 @@ BTRFS_SCRUB_MOUNTPOINTS="/" # 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" +BTRFS_SCRUB_PERIOD="none" ## Path: System/File systems/btrfs ## Type: string(idle,normal)