PNG  IHDR* pHYs+ IDATx]n#; cdLb Ǚ[at¤_:uP}>!Usă cag޿ ֵNu`ݼTâabO7uL&y^wFٝA"l[|ŲHLN밪4*sG3|Dv}?+y߉{OuOAt4Jj.u]Gz*҉sP'VQKbA1u\`& Af;HWj hsO;ogTu uj7S3/QzUr&wS`M$X_L7r2;aE+ώ%vikDA:dR+%KzƉo>eOth$z%: :{WwaQ:wz%4foɹE[9<]#ERINƻv溂E%P1i01 |Jvҗ&{b?9g=^wζXn/lK::90KwrюO\!ջ3uzuGv^;騢wq<Iatv09:tt~hEG`v;3@MNZD.1]L:{ծI3`L(÷ba")Y.iljCɄae#I"1 `3*Bdz>j<fU40⨬%O$3cGt]j%Fߠ_twJ;ABU8vP3uEԑwQ V:h%))LfraqX-ۿX]v-\9I gl8tzX ]ecm)-cgʒ#Uw=Wlێn(0hPP/ӨtQ“&J35 $=]r1{tLuǮ*i0_;NƝ8;-vݏr8+U-kruȕYr0RnC]*ެ(M:]gE;{]tg(#ZJ9y>utRDRMdr9㪩̞zֹb<ģ&wzJM"iI( .ꮅX)Qw:9,i좜\Ԛi7&N0:asϓc];=ΗOӣ APqz93 y $)A*kVHZwBƺnWNaby>XMN*45~ղM6Nvm;A=jֲ.~1}(9`KJ/V F9[=`~[;sRuk]rєT!)iQO)Y$V ی ۤmzWz5IM Zb )ˆC`6 rRa}qNmUfDsWuˤV{ Pݝ'=Kֳbg,UҘVz2ﴻnjNgBb{? ߮tcsͻQuxVCIY۠:(V뺕 ٥2;t`@Fo{Z9`;]wMzU~%UA蛚dI vGq\r82iu +St`cR.6U/M9IENDB`#!/bin/bash # Copyright (C) 2014-2017 Neil Brown # # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Author: Neil Brown # Email: # This script should be run periodically to automatically # perform a 'check' on any md arrays. # # It supports a 'time budget' such that any incomplete 'check' # will be checkpointed when that time has expired. # A subsequent invocation can allow the 'check' to continue. # # Options are: # --continue Don't start new checks, only continue old ones. # --duration This is passed to "date --date=$duration" to find out # when to finish # # To support '--continue', arrays are identified by UUID and the 'sync_completed' # value is stored in /var/lib/mdcheck/$UUID # convert a /dev/md name into /sys/.../md equivalent sysname() { set `ls -lLd $1` maj=${5%,} min=$6 readlink -f /sys/dev/block/$maj:$min } args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@") rv=$? if [ $rv -ne 0 ]; then exit $rv; fi eval set -- $args cont= endtime= while [ " $1" != " --" ] do case $1 in --help ) echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]' echo >&2 ' time-offset must be understood by "date --date"' exit 0 ;; --continue ) cont=yes ;; --duration ) shift; dur=$1 endtime=$(date --date "$dur" "+%s") ;; esac shift done shift # We need a temp file occasionally... tmp=/var/lib/mdcheck/.md-check-$$ trap 'rm -f "$tmp"' 0 2 3 15 # firstly, clean out really old state files mkdir -p /var/lib/mdcheck find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \; # Now look at each md device. cnt=0 for dev in /dev/md?* do [ -e "$dev" ] || continue sys=`sysname $dev` if [ ! -f "$sys/md/sync_action" ] then # cannot check this array continue fi if [ "`cat $sys/md/sync_action`" != 'idle' ] then # This array is busy continue fi mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue source $tmp fl="/var/lib/mdcheck/MD_UUID_$MD_UUID" if [ -z "$cont" ] then start=0 logger -p daemon.info mdcheck start checking $dev elif [ -z "$MD_UUID" -o ! -f "$fl" ] then # Nothing to continue here continue else start=`cat "$fl"` logger -p daemon.info mdcheck continue checking $dev from $start fi cnt=$[cnt+1] eval MD_${cnt}_fl=\$fl eval MD_${cnt}_sys=\$sys eval MD_${cnt}_dev=\$dev echo $start > $fl echo $start > $sys/md/sync_min echo check > $sys/md/sync_action done if [ -z "$endtime" ] then exit 0 fi while [ `date +%s` -lt $endtime ] do any= for i in `eval echo {1..$cnt}` do eval fl=\$MD_${i}_fl eval sys=\$MD_${i}_sys eval dev=\$MD_${i}_dev if [ -z "$fl" ]; then continue; fi if [ "`cat $sys/md/sync_action`" != 'check' ] then logger -p daemon.info mdcheck finished checking $dev eval MD_${i}_fl= rm -f $fl continue; fi read a rest < $sys/md/sync_completed echo $a > $fl any=yes done # mdcheck_continue.timer is started by mdcheck_start.timer. # When the check action can be finished in mdcheck_start.service, # it doesn't need mdcheck_continue anymore. if [ -z "$any" ]; then systemctl stop mdcheck_continue.timer exit 0; fi sleep 120 done # We've waited, and there are still checks running. # Time to stop them. for i in `eval echo {1..$cnt}` do eval fl=\$MD_${i}_fl eval sys=\$MD_${i}_sys eval dev=\$MD_${i}_dev if [ -z "$fl" ]; then continue; fi if [ "`cat $sys/md/sync_action`" != 'check' ] then eval MD_${i}_fl= rm -f $fl continue; fi echo idle > $sys/md/sync_action cat $sys/md/sync_min > $fl logger -p daemon.info pause checking $dev at `cat $fl` done