X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=cprogs%2Frcopy-repeatedly.c;h=fc2741d31b038bbcd2e7626bd20fa1e648a3256c;hp=68aedcfe85fc33dcd45fc491d4c450a9bbf65c25;hb=1e17ba9014e80fc58acfa88b20e8fd2744d994d5;hpb=76d935083795438ff360cb1d13543b215da94d2a diff --git a/cprogs/rcopy-repeatedly.c b/cprogs/rcopy-repeatedly.c index 68aedcf..fc2741d 100644 --- a/cprogs/rcopy-repeatedly.c +++ b/cprogs/rcopy-repeatedly.c @@ -1,7 +1,52 @@ /* * rcopy-repeatedly + * + * You say rcopy-repeatedly local-file user@host:remote-file + * and it polls for changes to local-file and copies them to + * remote-file. rcopy-repeatedly must be installed at the far end. + * You can copy in either direction but not between two remote + * locations. + * + * Limitations: + * * Cannot cope with files which are modified between us opening + * and statting them for the first time; if the file shrinks + * we may bomb out. Workaround: use rename-in-place. + * * When transferring large files, bandwidth limiter will + * be `lumpy' as the whole file is transferred and then we + * sleep. + * * Cannot copy between two local files. Workaround: a symlink + * (but presumably there was some reason you weren't doing that) + * * No ability to synchronise more than just exactly one file + * * Polls. It would be nice to use inotify or something. + * + * Inherent limitations: + * * Can only copy plain files. + * + * See the --help for options. */ - + +/* + * rcopy-repeatedly is + * Copyright (C) 2008 Ian Jackson + * and the option parser we use is + * Copyright (C) 1994,1995 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, consult the Free Software + * Foundation's website at www.fsf.org, or the GNU Project website at + * www.gnu.org. + */ + /* * protocol is: * server sends banner @@ -58,8 +103,7 @@ static const char banner[]= "#rcopy-repeatedly#\n"; static FILE *commsi, *commso; -static double max_bw_prop_mean= 0.2; -static double max_bw_prop_burst= 0.8; +static double max_bw_prop= 0.2; static int txblocksz= INT_MAX, verbose=1; static int min_interval_usec= 100000; /* 100ms */ @@ -73,7 +117,6 @@ static int server_upcopy=-1; /* -1 means not yet known; 0 means download */ * since we regard the subprocess as `down' */ static int udchar; -static double stream_allow_secsperbyte= 1/1e6; /* for initial transfer */ static char mainbuf[65536]; /* must be at least 2^16 */ @@ -206,19 +249,16 @@ static void bandlimit_sendend(uint64_t bytes, int *interval_usec_update) { double elapsed= mgettime_elapsed(ts_sendstart, &ts_buf); double secsperbyte_observed= elapsed / bytes; - stream_allow_secsperbyte= - secsperbyte_observed * max_bw_prop_mean / max_bw_prop_burst; - - double min_update= elapsed / max_bw_prop_mean; + double min_update= elapsed / max_bw_prop; if (min_update > 1e3) min_update= 1e3; int min_update_usec= min_update * 1e6; - if (*interval_usec_update > min_update_usec) + if (*interval_usec_update < min_update_usec) *interval_usec_update= min_update_usec; - verbosespinprintf("%12lluby %10.3fs %13.2fkby/s", + verbosespinprintf("%12lluby %10.3fs %13.2fkby/s %8dms", (unsigned long long)bytes, elapsed, - 1e-3/secsperbyte_observed); + 1e-3/secsperbyte_observed, *interval_usec_update/1000); } static void copyfile(FILE *sf, copyfile_die_fn *sdie, const char *sxi, @@ -234,24 +274,16 @@ static void copyfile(FILE *sf, copyfile_die_fn *sdie, const char *sxi, now= l < sizeof(mainbuf) ? l : sizeof(mainbuf); if (now > txblocksz) now= txblocksz; + r= fread(mainbuf,1,now,sf); if (r!=now) sdie(sf,sxi); + r= fwrite(mainbuf,1,now,df); if (r!=now) ddie(df,dxi); + l -= now; + done += now; + if (verbose) { fprintf(stderr," %3d%% \r", (int)(done*100.0/lstart)); flushstderr(); } - - if (amsender) { - double elapsed_want= now * stream_allow_secsperbyte; - double elapsed= mgettime_elapsed(ts_last, &ts_last); - double needwait= elapsed_want - elapsed; - if (needwait > 1) needwait= 1; - if (needwait > 0) usleep(ceil(needwait * 1e6)); - } - - r= fread(mainbuf,1,now,sf); if (r!=now) sdie(sf,sxi); - r= fwrite(mainbuf,1,now,df); if (r!=now) ddie(df,dxi); - l -= now; - done += now; } } @@ -392,7 +424,8 @@ static void sender(const char *filename) { if (!f) { if (errno!=ENOENT) diee("could not access source file `%s'",filename); if (told != told_remove) { - verbosespinprintf(" ENOENT "); + verbosespinprintf + (" ENOENT "); sendbyte(REPLMSG_RM); told= told_remove; } @@ -491,8 +524,7 @@ void usagemessage(void) { " --help\n" " --quiet | -q\n" "options for bandwidth (and cpu time) control:\n" - " --max-bandwidth-percent-mean (default %d)\n" - " --max-bandwidth-percent-burst (default %d)\n" + " --max-bandwidth-percent (default %d)\n" " --tx-block-size (default/max %d)\n" " --min-interval-usec (default %d)\n" "options for finding programs:\n" @@ -500,14 +532,12 @@ void usagemessage(void) { " --rsh-program (default: $RCOPY_REPEATEDLY_RSH or $RSYNC_RSH or ssh)\n" "options passed to server side via ssh:\n" " --receiver --sender, bandwidth control options\n", - (int)(max_bw_prop_mean*100), (int)(max_bw_prop_burst*100), - (int)sizeof(mainbuf), min_interval_usec); + (int)(max_bw_prop*100), (int)sizeof(mainbuf), min_interval_usec); } static const struct cmdinfo cmdinfos[]= { { "help", .call= of_help }, - { "max-bandwidth-percent-mean", 0,1,.call=of_bw,.parg=&max_bw_prop_mean }, - { "max-bandwidth-percent-burst",0,1,.call=of_bw,.parg=&max_bw_prop_burst }, + { "max-bandwidth-percent", 0,1,.call=of_bw,.parg=&max_bw_prop }, { "tx-block-size",0, 1,.call=of_server_int, .parg=&txblocksz }, { "min-interval-usec",0, 1,.call=of_server_int, .parg=&min_interval_usec }, { "rcopy-repeatedly",0, 1, .sassignto=&rcopy_repeatedly_program }, @@ -673,10 +703,6 @@ int main(int argc, const char *const *argv) { if (!rsh_program) rsh_program= getenv("RSYNC_RSH"); if (!rsh_program) rsh_program= "ssh"; - if (max_bw_prop_burst / max_bw_prop_mean < 1.1) - badusage("max bandwidth prop burst must be at least 1.1x" - " max bandwidth prop mean"); - if (txblocksz<1) badusage("transmit block size must be at least 1"); if (min_interval_usec<0) badusage("minimum update interval may not be -ve");