#!/bin/bash # Brett Kelly CONF_DIR="/root/.cephfs/cephfssyncd.conf" mkdir -p /var/lib/ceph/cephfssync/ source $CONF_DIR ## CHECKS # check cluster membership & permission # check cephfs is mounted. # check recv'r connection # check recv FS exists and is writable # turn on snapshots ## FUNCTIONS getrctime(){ # getrctime <1||2> # Returns recursive ctime of local ctime=$(getfattr --absolute-names -n ceph.dir.rctime $1 --only-values | cut -d. -f$2) echo "$ctime" } getsubdirs(){ # getsubdir # Returns number of subdirs in local subdir=$(getfattr --absolute-names -n ceph.dir.subdir $1 --only-values) echo "$subdir" } getfiles(){ # getfiles # Return number of files in local files=$(getfattr --absolute-names -n ceph.dir.files $1 --only-values) echo "$files" } takesnap(){ # takesnap # Creates snapshot and appends timestamp to name, updates last_rctime to the moment after the snapshot # Returns snapshot directory to sync from local RCTIME_1=$1 local SNAP_DIR="$SND_SYNC_DIR/.snap/$RCTIME_1" mkdir $SNAP_DIR echo "$SNAP_DIR" } formattime(){ # converts epoch time to human readable # for logging purposes only local EPOCH=$1 local TIME=$(date -d @$EPOCH '+%Y-%m-%d %H:%M:%S') echo $TIME } log(){ # log if [ "$2" -lt $(( LOG_LEVEL + 1 )) ];then echo $1 fi } main(){ local RCTIME_0=$1 local DIR=$2 for dir in $DIR/*;do if [ -d $dir ];then local RCTIME_1=$(getrctime $dir 1) log "parent:$(formattime $RCTIME_0) dir:$(formattime $RCTIME_1):$dir" 2 if [ "$RCTIME_1" -eq "$RCTIME_0" ];then log "CHANGE DETECTED IN $dir" 0 if [ $(getfiles $dir) -gt 0 ];then cephfssync $dir $RECV_SYNC_HOST $RECV_SYNC_DIR sync $RCTIME_1 & fi main $RCTIME_0 $dir elif [ "$RCTIME_1" -lt "$RCTIME_0" ];then log "NO CHANGE DETECTED IN $dir OR BELOW" 1 elif [ "$RCTIME_1" -gt "$RCTIME_0" ];then log "$dir WAS MODIFIED AFTER STARTING CHECK. WAIT FOR NEXT CYCLE" 0 log "This really should not happen if syncing from a snapshot" 0 fi fi done } # START HERE log "started" 0 SYNC_FREQ=5 while sleep $SYNC_FREQ ; do SYNC_FREQ=$(cat $CONF_DIR | grep "SYNC_FREQ" | cut -d= -f2) log "watching : $SND_SYNC_DIR" 1 if [ -e /var/lib/ceph/cephfssync/last_rctime ];then log "last_rctime exists, init RCTIME=last_rctime" 2 RCTIME_0=$(cat /var/lib/ceph/cephfssync/last_rctime) else log "last_rctime does not exist, init RCTIME=0" 2 RCTIME_0=0 fi RCTIME_1=$(getrctime $SND_SYNC_DIR 1) log "rctime_0 : $RCTIME_0 " 2 log "rctime_1 : $RCTIME_1 " 2 if [ "$RCTIME_1" -gt "$RCTIME_0" ];then log "CHANGE DETECTED IN $SND_SYNC_DIR" 0 SNAP_DIR=$(takesnap $RCTIME_1) RCTIME_SNAP=$(getrctime $SND_SYNC_DIR 1) echo "$RCTIME_SNAP" > /var/lib/ceph/cephfssync/last_rctime /usr/bin/cephfssync $SNAP_DIR $RECV_SYNC_HOST $RECV_SYNC_DIR init $RCTIME_1 if [ $(getfiles $SND_SYNC_DIR) -gt 0 ];then /usr/bin/cephfssync $SNAP_DIR $RECV_SYNC_HOST $RECV_SYNC_DIR sync $RCTIME_1 & fi main $RCTIME_1 $SNAP_DIR fi syncwatcher $RCTIME_1 $SNAP_DIR & ## If changes were detected kick off (parallel)? rsync of that dir to the recv. # -- Complete. Single threaded rsync per subdir, but running multiple subdir sync at once. # If directory is already currently syncing dont start again # Dont start too many rsync tasks at once. Limit based on # CPU thread # cpu_count=$(cat /proc/cpuinfo|grep processor | wc -l) # let max_threads=cpu_count*30 done