Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Krayer ccd4d37027 number of streams is specified as optional argument now 2024-04-02 17:32:47 +02:00
Michael Krayer 975280a456 Added verbose output 2024-04-02 17:25:42 +02:00
1 changed files with 36 additions and 14 deletions

50
prsync
View File

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