new option --inodes=N for the percent of used inodes max.
authorColas Nahaboo <colas@nahaboo.net>
Tue, 13 Jun 2017 07:46:17 +0200
changeset 21988e6cac2745
parent 20 31f4cf98b45a
child 22 566bb1d3ec3c
new option --inodes=N for the percent of used inodes max.
E.g. --inodes=95 ensures we have at least 5% inodes free.
N must be an integer between 50 and 99. Defaults to 95.
rsync-incr
     1.1 --- a/rsync-incr	Tue Jun 06 08:21:42 2017 +0200
     1.2 +++ b/rsync-incr	Tue Jun 13 07:46:17 2017 +0200
     1.3 @@ -26,12 +26,14 @@
     1.4  only_clean=false
     1.5  declare -a options
     1.6  no_cross_devs=true
     1.7 +inodespcmaxpc=95
     1.8  while test -z "${1##-*}" -a -n "$1";do case "$1" in
     1.9    --snap) snapshot=true;; --nohl) hardlinks=;; --cbf)do_gzip=true;;
    1.10    --grem) global_remove=true;;
    1.11    --pbsm=*) pbsm="${1##*=}";;
    1.12    --cross-devs) no_cross_devs=false;;
    1.13    --clean) only_clean=true;;
    1.14 +  --inodes=*) inodespcmaxpc="${1##*=}";;
    1.15    *) options[options_n]="$1"; let options_n++;;
    1.16  esac;shift;done
    1.17  
    1.18 @@ -41,6 +43,7 @@
    1.19     echo "$USAGE";exit 1;fi
    1.20  if let 'n<=1'; then echo "$USAGE
    1.21  N must be > 1";exit 1;fi
    1.22 +let '( inodespcmaxpc > 50 ) && ( inodespcmaxpc < 100 )' || { echo "Option --inodes=N must have N between 50 and 99, not $inodespcmaxpc"; exit 1; }
    1.23  if $no_cross_devs; then options[options_n]="-x"; let options_n++; fi
    1.24  
    1.25  #------------------------------------------------------------------ utils
    1.26 @@ -48,6 +51,16 @@
    1.27  rootof () { df -P "$1" |tail -1 |sed -e 's/^[^%]*% *//'; }
    1.28  find_ld () { find `rootof "$1"` -xdev -name LAST_DATE -type f; }
    1.29  dfof () { df -mP "$1" |tail -1|awk '{print $4}'; }
    1.30 +inodesok () { 
    1.31 +  local ipc=$(df -imP "$1" |tail -1|grep -oP ' \K[0-9]+(?=%)')
    1.32 +  if let 'ipc > inodespcmaxpc'; then 
    1.33 +    echo "Not enough free inodes (used: $ipc%), cleaning..."
    1.34 +    return 1
    1.35 +  else
    1.36 +    return 0
    1.37 +  fi
    1.38 +}
    1.39 +
    1.40  remdir () { 
    1.41    local empty=/tmp/empty-dir-for-rsync.$LOGNAME
    1.42    local path=$(realpath "$1")
    1.43 @@ -95,16 +108,20 @@
    1.44  	RSYNCINCR_LASTDATES=`find_ld "$destold"`
    1.45        fi
    1.46        freespace=`dfof "$destold"`
    1.47 -      if let 'freespace<n'; then
    1.48 +      if let 'freespace<n' || ! inodesok "$destold"; then
    1.49  	backup_siblings "$destold" | while read f; do
    1.50  	  freespace=`dfof "$destold"`
    1.51 -	  if let 'freespace>=n'; then break; else remdir "$freespace" "$f"; fi
    1.52 +	  if let 'freespace>=n' && inodesok "$destold"; then break
    1.53 +	  else remdir "$freespace" "$f"
    1.54 +	  fi
    1.55          done
    1.56        fi
    1.57      else # just remove in dest dir
    1.58        for f in "$destold/"[0-9]*; do
    1.59  	freespace=`dfof "$destold"`
    1.60 -	if let 'freespace>=n'; then break; else remdir "$freespace" "$f"; fi
    1.61 +	if let 'freespace>=n' && inodesok "$destold"; then break
    1.62 +	else remdir "$freespace" "$f"
    1.63 +	fi
    1.64        done
    1.65      fi
    1.66      echo "Free space is $freespace M, ok"