X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=scrub%2Fe2scrub_all.in;h=4288b969849066f51136b9839cfdb4470b7a95ac;hb=cb588deaaeefb63b7046f52e7563a007e7a054a6;hp=24b2c68106c8ab557239942a6aba6277402b353f;hpb=73c74fe26eed7ddd6341c71c47b068cd480684a4;p=tools%2Fe2fsprogs.git diff --git a/scrub/e2scrub_all.in b/scrub/e2scrub_all.in index 24b2c68..4288b96 100644 --- a/scrub/e2scrub_all.in +++ b/scrub/e2scrub_all.in @@ -25,6 +25,7 @@ if (( $EUID != 0 )); then exit 1 fi +periodic_e2scrub=0 scrub_all=0 snap_size_mb=256 reap=0 @@ -55,14 +56,8 @@ exitcode() { # section 22.2) and hope the admin will scan the log for what # actually happened. - # We have to sleep 2 seconds here because journald uses the pid to - # connect our log messages to the systemd service. This is critical - # for capturing all the log messages if the scrub fails, because the - # fail service uses the service name to gather log messages for the - # error report. - if [ -n "${SERVICE_MODE}" ]; then + if [ -n "${SERVICE_MODE}" -a "${ret}" -ne 0 ]; then test "${ret}" -ne 0 && ret=1 - sleep 2 fi exit "${ret}" @@ -79,10 +74,33 @@ while getopts "nrAV" opt; do done shift "$((OPTIND - 1))" +# If we're in service mode and the service is not enabled via config file... +if [ -n "${SERVICE_MODE}" -a "${periodic_e2scrub}" -ne 1 ]; then + # ...don't start e2scrub processes. + if [ "${reap}" -eq 0 ]; then + exitcode 0 + fi + + # ...and if we don't see any leftover e2scrub snapshots, don't + # run the reaping process either, because lvs can be slow. + if ! readlink -q -s -e /dev/mapper/*.e2scrub* > /dev/null; then + exitcode 0 + fi +fi + +# close file descriptor 3 (from cron) since it causes lvm to kvetch +exec 3<&- + # If some prerequisite packages are not installed, exit with a code # indicating success to avoid spamming the sysadmin with fail messages # when e2scrub_all is run out of cron or a systemd timer. +if ! type mapfile >& /dev/null ; then + test -n "${SERVICE_MODE}" && exitcode 0 + echo "e2scrub_all: can't find mapfile --- is bash 4.xx installed?" + exitcode 1 +fi + if ! type lsblk >& /dev/null ; then test -n "${SERVICE_MODE}" && exitcode 0 echo "e2scrub_all: can't find lsblk --- is util-linux installed?" @@ -97,7 +115,7 @@ fi # Find scrub targets, make sure we only do this once. ls_scan_targets() { - local devices=$(lvs -o lv_path --noheadings -S "lv_active=active,lv_role=public,lv_role!=snapshot,vg_free>${snap_size_mb}") + local devices=$(lvs -o lv_path --noheadings -S "lv_active=active,lv_role=public,lv_role!=snapshot,vg_free>=${snap_size_mb}") if [ -z "$devices" ]; then return 0; @@ -115,7 +133,8 @@ ls_scan_targets() { # Find leftover scrub snapshots ls_reap_targets() { - lvs -o lv_path -S lv_role=snapshot -S lv_name=~\(e2scrub$\) --noheadings + lvs -o lv_path -S lv_role=snapshot -S lv_name=~\(e2scrub$\) \ + --noheadings | sed -e 's/.e2scrub$//' } # Figure out what we're targeting @@ -146,13 +165,13 @@ escape_path_for_systemd() { } # Scrub any mounted fs on lvm by creating a snapshot and fscking that. -stdin="$(realpath /dev/stdin)" -ls_targets | while read tgt; do +mapfile -t targets < <(ls_targets) +for tgt in "${targets[@]}"; do # If we're not reaping and systemd is present, try invoking the # systemd service. if [ "${reap}" -ne 1 ] && type systemctl > /dev/null 2>&1; then tgt_esc="$(escape_path_for_systemd "${tgt}")" - ${DBG} systemctl start "e2scrub@${tgt_esc}" 2> /dev/null < "${stdin}" + ${DBG} systemctl start "e2scrub@${tgt_esc}" 2> /dev/null res=$? if [ "${res}" -eq 0 ] || [ "${res}" -eq 1 ]; then continue; @@ -160,7 +179,7 @@ ls_targets | while read tgt; do fi # Otherwise use direct invocation - ${DBG} "@root_sbindir@/e2scrub" ${scrub_args} "${tgt}" < "${stdin}" + ${DBG} "@root_sbindir@/e2scrub" ${scrub_args} "${tgt}" done exitcode 0