Compare commits

..

No commits in common. "ccd4d37027005e2efc3aae6f24849a0177e0e63a" and "94fa4f5e721a9f789d5f8983c9879a70d4a0b399" have entirely different histories.

1 changed files with 14 additions and 36 deletions

50
prsync
View File

@ -5,7 +5,7 @@ cat << EOF
A wrapper around rsync which partitions the input files to blocks of roughly A wrapper around rsync which partitions the input files to blocks of roughly
equal sizes and transfers them in multiple streams in parallel. equal sizes and transfers them in multiple streams in parallel.
Usage: $(basename $0) [opt] <src>... <dest> Usage: $(basename $0) [rsync flags] <num_streams> <src>... <dest>
Options: Options:
<num_streams> Number of blocks/transfer streams. <num_streams> Number of blocks/transfer streams.
<src> Source files (potentially multiple files). <src> Source files (potentially multiple files).
@ -14,20 +14,16 @@ Options:
-h, --help Print this message. -h, --help Print this message.
-n, --dry-run Do not transfer any data. -n, --dry-run Do not transfer any data.
-r, --recursive Copy directories recursively -r, --recursive Copy directories recursively
-s, --streams <num> Use <num> parallel streams.
-v, --verbose List files as they are transferred.
EOF EOF
} }
# Parse arguments # Parse arguments
declare -a positional flags_rsync flags_du declare -a positional flags_rsync flags_du
declare -i num_streams=1
positional=() positional=()
flags_rsync=('-R' '-v' '--info=stats0,misc0,flist0') flags_rsync=()
flags_du=('-b') flags_du=('-b')
flag_copy_links=0 flag_copy_links=0
flag_recursive=0 flag_recursive=0
flag_verbose=0
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
'-h'|'--help') '-h'|'--help')
@ -51,15 +47,6 @@ while [[ $# -gt 0 ]]; do
flag_recursive=1 flag_recursive=1
shift shift
;; ;;
'-s'|'--streams')
num_streams=$2
shift
shift
;;
'-v'|'--verbose')
flag_verbose=1
shift
;;
-*|--*) -*|--*)
echo "Invalid option: $1" >&2 echo "Invalid option: $1" >&2
exit 1 exit 1
@ -73,11 +60,13 @@ done
declare -i num_args declare -i num_args
num_args=${#positional[@]} num_args=${#positional[@]}
[[ $num_args -lt 2 ]] && usage && exit 1 [[ $num_args -lt 3 ]] && usage && exit 1
# Parse <num_streams> # Parse <num_streams>
if [[ $num_streams -lt 1 ]]; then declare -i num_streams
echo "Error: invalid number of streams" >&2 num_streams=${positional[0]}
if [[ $num_streams -eq 0 ]]; then
echo "Error: invalid value for <num_streams> (${positional[0]})" >&2
exit 1 exit 1
fi fi
@ -93,7 +82,7 @@ function walk_dir {
done done
} }
declare -a src declare -a src
for path in "${positional[@]:0:num_args-1}"; do for path in "${positional[@]:1:num_args-2}"; do
if [[ -L ${path} ]] && [[ $flag_copy_links -eq 0 ]]; then if [[ -L ${path} ]] && [[ $flag_copy_links -eq 0 ]]; then
continue continue
elif [[ -f ${path} ]]; then elif [[ -f ${path} ]]; then
@ -121,7 +110,7 @@ src=($(echo "$tmp" | awk '{print $2}'))
totalsize=$(IFS=+; echo "$((${filesize[*]}))") totalsize=$(IFS=+; echo "$((${filesize[*]}))")
# Create file lists # Create file lists
dir_temp=$(mktemp -dt prsync.XXXXX) dir_temp=$(mktemp -dt rsync.XXXXX)
for ((istream=0;istream<num_streams;istream++)); do for ((istream=0;istream<num_streams;istream++)); do
file_temp="${dir_temp}/rsync-stream-${istream}.files" file_temp="${dir_temp}/rsync-stream-${istream}.files"
echo -n > $file_temp echo -n > $file_temp
@ -131,16 +120,13 @@ for ((istream=0;istream<num_streams;istream++)); do
done done
# Transfer data # Transfer data
declare -a rsync_pids tail_pids declare -a rsync_pids
declare -i timer dt_transfer declare -i timer dt_transfer
function rsync_sigint { function rsync_sigint {
echo "Sending SIGINT to remaining streams..." echo "Sending SIGINT to remaining streams..."
for pid in ${rsync_pids[@]}; do for pid in ${rsync_pids[@]}; do
kill -s SIGINT ${pid} kill -s SIGINT ${pid}
done done
for pid in ${tail_pids[@]}; do
kill -s SIGINT ${pid}
done
} }
rsync_pids=() rsync_pids=()
timer=$(date +%s%N) timer=$(date +%s%N)
@ -149,23 +135,15 @@ trap rsync_sigint SIGINT
for ((istream=0;istream<num_streams;istream++)); do for ((istream=0;istream<num_streams;istream++)); do
file_temp="${dir_temp}/rsync-stream-${istream}.files" file_temp="${dir_temp}/rsync-stream-${istream}.files"
file_log="${dir_temp}/rsync-stream-${istream}.log" file_log="${dir_temp}/rsync-stream-${istream}.log"
rsync ${flags_rsync[@]} $(cat $file_temp) $dest > $file_log & rsync -v ${flags_rsync[@]} $(cat $file_temp) $dest > $file_log &
rsync_pids+=($!) rsync_pids+=($!)
if [ $flag_verbose -gt 0 ]; then
tail -F $file_log 2>/dev/null &
tail_pids+=($!)
fi
echo "Started stream #${istream}... pid=${rsync_pids[istream]}, log=${file_log}" echo "Started stream #${istream}... pid=${rsync_pids[istream]}, log=${file_log}"
done done
for ((istream=0;istream<num_streams;istream++)); do for pid in ${rsync_pids[@]}; do
wait ${rsync_pids[istream]} wait $pid
ec_=$? ec_=$?
echo "Process ${rsync_pids[istream]} finished with exit code $ec_" echo "Process ${pid} finished with exit code $ec_"
[[ $ec_ -ne 0 ]] && flag_fail=1 [[ $ec_ -ne 0 ]] && flag_fail=1
if [ $flag_verbose -gt 0 ]; then
kill ${tail_pids[istream]}
wait ${tail_pids[istream]} 2>/dev/null
fi
done done
if [ $flag_fail -ne 0 ]; then if [ $flag_fail -ne 0 ]; then
echo "Transfer failed." echo "Transfer failed."