diff --git a/zsc-sync.sh b/zsc-sync.sh index 0c4d5b9..517dd64 100755 --- a/zsc-sync.sh +++ b/zsc-sync.sh @@ -26,12 +26,22 @@ if ! lockfile-create -p -r 2 "$0"; then fi +echo "Fetching remote snapshots..." +remote_snapshots=$(ssh $REMOTE zfs list -H -t snapshot -o name -s creation) + +echo "Fetching subdatasets..." +remote_subdatasets=$(ssh $REMOTE zfs list -H -o name -s creation -r "$REMOTE_ROOT_DATASET") + +echo "Fetching resume tokens..." +resume_tokens=$(ssh $REMOTE zfs get -H -p receive_resume_token -o name,value -t filesystem) + + ### Resume existing transfer ### # Returns 0 if no action was performed, 1 if a transfer was resumed and finished successfully, -1 if there was an error during resumed transfer resume_transfer() { remote_dataset=$1 - RESUME_TOKEN=$(ssh $REMOTE zfs get -H -p receive_resume_token -o value "$remote_dataset") + RESUME_TOKEN=$(echo -e "$resume_tokens" | grep -P "^$remote_dataset\t.*\$" | cut -d$'\t' -f2) if [ "$RESUME_TOKEN" != "" ] && [ "$RESUME_TOKEN" != "-" ]; then echo "Resuming interrupted transfer..." zfs send -v -t "$RESUME_TOKEN" | ssh $REMOTE zfs receive -F -s "$remote_dataset" || return -1 @@ -60,7 +70,7 @@ handle_dataset() { PREFIX="" fi - TARGET_REMOTE_DATASET="$REMOTE_ROOT_DATASET/"$(echo -e $DATASET | sed -r "s/\//_/g") + TARGET_REMOTE_DATASET="$REMOTE_ROOT_DATASET/"$(echo -e "$DATASET" | sed -r "s/\//_/g") echo "[$DATASET -> $TARGET_REMOTE_DATASET]" echo -e @@ -70,15 +80,14 @@ handle_dataset() { ### Sync existing snapshots ### - REMOTE_SNAPSHOTS=($(ssh $REMOTE zfs list -H -t snapshot -o name -s creation $TARGET_REMOTE_DATASET | cut -d"@" -f 2)) - LOCAL_SNAPSHOTS=($(zfs list -H -t snapshot -o name -s creation $DATASET | cut -d"@" -f 2)) + REMOTE_SNAPSHOTS=($(echo -e "$remote_snapshots" | grep "$TARGET_REMOTE_DATASET@" | cut -d"@" -f 2)) + LOCAL_SNAPSHOTS=($(zfs list -H -t snapshot -o name -s creation "$DATASET" | cut -d"@" -f 2)) echo "Remote snapshots: ${#REMOTE_SNAPSHOTS[@]}" echo "Local snapshots: ${#LOCAL_SNAPSHOTS[@]}" echo -e for local_snapshot in "${LOCAL_SNAPSHOTS[@]}"; do - echo "Syncing local snapshot $local_snapshot ..." found=false for remote_snapshot in "${REMOTE_SNAPSHOTS[@]}"; do if [ "$remote_snapshot" = "$local_snapshot" ] ; then @@ -88,18 +97,16 @@ handle_dataset() { done if [ $found = true ] ; then - echo "> Found remotely, setting as last snapshot" + echo "> $local_snapshot found remotely" FROM_SNAPSHOT=$local_snapshot TO_SNAPSHOT="" else - echo "> Needs sync" + echo "> $local_snapshot needs sync" TO_SNAPSHOT=$local_snapshot fi - - echo -e done - echo "Snapshot are synchronized up to $FROM_SNAPSHOT" + echo "Snapshots are synchronized up to $FROM_SNAPSHOT" echo -e if test ! -z "$TO_SNAPSHOT"; then @@ -122,21 +129,11 @@ init_subdataset() { PARENT_DATASET=$2 TARGET_REMOTE_DATASET="$REMOTE_ROOT_DATASET/"$(echo -e $PARENT_DATASET | sed -r "s/\//_/g")"/"${DATASET:$(echo -e "$PARENT_DATASET" | wc -c)} - REMOTE_DATASETS=($(ssh $REMOTE zfs list -H -o name -s creation -r $REMOTE_ROOT_DATASET)) resume_transfer "$TARGET_REMOTE_DATASET" || return 0 - - found=false - for d in "${REMOTE_DATASETS[@]}"; do - if [ "$TARGET_REMOTE_DATASET" == "$d" ]; then - found=true - break - fi - done - - if [ $found = false ]; then + if [ $(echo -e "$remote_subdatasets" | grep -e "^$TARGET_REMOTE_DATASET\$" | wc -l) -eq 0 ]; then echo "Subdataset not found on $TARGET_REMOTE_DATASET, initializing..." LOCAL_SNAPSHOT=($(zfs list -H -t snapshot -o name -s creation "$DATASET" | cut -d"@" -f 2 | tail -n 1))