Bug 8375 - rsync with bandwidth limit sometimes expend extra time
Summary: rsync with bandwidth limit sometimes expend extra time
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.0.8
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
Depends on:
Reported: 2011-08-13 08:58 UTC by Francisco Moser
Modified: 2011-09-03 19:04 UTC (History)
0 users

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Francisco Moser 2011-08-13 08:58:38 UTC
If you transfer the arq1 file with 2,100 Kbytes using the option --bwlimit=16 the rsync expends about 131 seconds. This time is correct because the calculated time is 131.25 seconds.

But when you transfer the arq2 file with 2,200 Kbytes, using the same option --bwlimit=16 the rsync expends about 268 seconds that is about 130 seconds more that the calculated time of 137.5 seconds.

The test can be made transfering the files to the same machine and using the time command to measure the runtime.

The next lines demonstrates the problem: 

$ time rsync --bwlimit=16 /tmp/arq1 localhost::test

real    2m11.431s
user    0m0.001s
sys     0m0.014s

$ time rsync --bwlimit=16 /tmp/arq2 localhost::test

real    4m28.598s
user    0m0.000s
sys     0m0.020s

Using the source code from http://pkgs.repoforge.org/rsync/rsync-3.0.8-1.rfx.src.rpm was possible to discover the solution of the problem.

The next lines show the modifications needed in io.c file to resolve the problem. 

$ diff -u io.c io.c-MOSER
--- io.c        2010-06-30 13:17:26.000000000 -0300
+++ io.c-MOSER  2011-08-12 22:29:41.000000000 -0300
@@ -1402,7 +1402,7 @@
        if (prior_tv.tv_sec) {
                elapsed_usec = (start_tv.tv_sec - prior_tv.tv_sec) * ONE_SEC
                             + (start_tv.tv_usec - prior_tv.tv_usec);
-               total_written -= elapsed_usec * bwlimit / (ONE_SEC/1024);
+               total_written -= ((long long)((long long)elapsed_usec * bwlimit) / (ONE_SEC/1024));
                if (total_written < 0)
                        total_written = 0;

Thank you.

Francisco Moser
Comment 1 Wayne Davison 2011-09-03 19:04:16 UTC
I checked in a fix for this a few days ago.  Thanks!