[PATCH] --timelimit and --stopat

John Taylor john at fcs.uga.edu
Thu Apr 22 20:20:07 GMT 2004


Greetings,

Upon a suggestion to improve the --timelimit patch, I have also added a --stopat option.
You can get the patch from this URL and/or cut/paste it from below.
http://www.terry.uga.edu/~jft/rsync-timelimit-stopat.patch.gz


Here are the details...


 --timelimit=T
        This option allows you to specify the maximum number of  minutes
        rsync  will run for. This time starts when rsync starts to "con-
        sider" which files need transferring.


 --stopat=YYMMDDHHMMSS
        This option allows you to specify at what time to stop rsync, in
        yr-mon-day-hr-min-sec numeric format.


-John




diff -urN rsync-2.6.1pre-2/NEWS rsync-2.6.1pre-2_modified/NEWS
--- rsync-2.6.1pre-2/NEWS	2004-04-15 14:23:52.000000000 -0400
+++ rsync-2.6.1pre-2_modified/NEWS	2004-04-22 15:30:17.000000000 -0400
@@ -23,6 +23,13 @@
     * Added a couple extra diffs in the "patches" dir, removed the
       ones that got applied, and rebuilt the rest.
 
+    * Added --time-limit=T which will stop rsync after T number
+      of minutes
+
+    * Added --stopat=YYMMDDHHMMSS which will stio rsync at time
+      yr-mon-day-hr-min-sec
+
+
   BUG FIXES:
 
     * When -x (--one-file-system) is combined with -L (--copy-links)
diff -urN rsync-2.6.1pre-2/io.c rsync-2.6.1pre-2_modified/io.c
--- rsync-2.6.1pre-2/io.c	2004-01-16 11:31:47.000000000 -0500
+++ rsync-2.6.1pre-2_modified/io.c	2004-04-22 15:52:21.000000000 -0400
@@ -47,13 +47,14 @@
 static int no_flush;
 
 extern int bwlimit;
+extern int timelimit;
 extern int verbose;
 extern int io_timeout;
 extern int am_server;
 extern int am_daemon;
 extern int am_sender;
 extern struct stats stats;
-
+extern char *stopat;
 
 const char phase_unknown[] = "unknown";
 
@@ -759,6 +760,58 @@
 	select(0, NULL, NULL, NULL, &tv);
 }
 
+/**
+  When --timelimit is used, compare rsync_start_time and the current time and
+  return 1 when the timelimit has been reached.
+  **/
+static int has_timelimit_expired()
+{
+	struct timeval tv;
+	time_t start_time = 0;
+	time_t expiration_time = 0;
+
+	assert(timelimit > 0);
+
+	start_time = get_rsync_start_time();
+	assert( start_time > 0);
+
+	gettimeofday(&tv, NULL);
+	expiration_time = start_time + (timelimit * 60);
+
+	return ( tv.tv_sec > expiration_time ) ? 1 : 0;
+}
+
+/**
+  When --stopat is used, compare current stopat time and the current calendar time,
+  and return 1 when the stopat time has been reached.
+  **/
+static int has_stopat_expired()
+{
+	static time_t stop_time_secs = 0;
+	time_t now = 0;
+	struct tm stopat_time;
+	char *valid_time = NULL;
+
+	assert(stopat != NULL);
+
+	if( 0 == stop_time_secs ) {
+		valid_time = strptime(stopat, "%y%m%d%H%M%S", &stopat_time);
+		if( NULL == valid_time ) {
+			rprintf(FERROR, "ERROR: invalid --stopat format: %s\n", stopat );
+			exit_cleanup(RERR_SYNTAX);
+		}
+		stop_time_secs = mktime( &stopat_time );
+	}
+
+	if( -1 == stop_time_secs ) {
+		rprintf(FERROR, "ERROR: mktime() returned -1\n" );
+		exit_cleanup(RERR_SYNTAX);
+	}
+
+	now = time(NULL);
+
+	return ( now > stop_time_secs ) ? 1 : 0;
+}
 
 /**
  * Write len bytes to the file descriptor @p fd.
@@ -772,6 +825,7 @@
 	fd_set w_fds, r_fds;
 	int fd_count, count;
 	struct timeval tv;
+	int time_expired = 0;
 
 	msg_list_push(NORMAL_FLUSH);
 
@@ -837,6 +891,19 @@
 			}
 
 			sleep_for_bwlimit(ret);
+
+			if( timelimit ) {
+				time_expired = has_timelimit_expired();
+				if( 1 == time_expired ) {
+					rprintf(FERROR, RSYNC_NAME ": \n%d minute time limit exceeded.\n", timelimit);
+					exit_cleanup(RERR_PARTIAL);
+				}
+			}
+
+			if( stopat && has_stopat_expired() ) {
+				rprintf(FERROR, RSYNC_NAME ": \n%s stopat time exceeded.\n", stopat);
+				exit_cleanup(RERR_PARTIAL);
+			}
  
 			total += ret;
 
diff -urN rsync-2.6.1pre-2/options.c rsync-2.6.1pre-2_modified/options.c
--- rsync-2.6.1pre-2/options.c	2004-04-17 13:07:23.000000000 -0400
+++ rsync-2.6.1pre-2_modified/options.c	2004-04-22 15:46:03.000000000 -0400
@@ -83,6 +83,7 @@
 int copy_unsafe_links = 0;
 int size_only = 0;
 int bwlimit = 0;
+int timelimit = 0;
 int delete_after = 0;
 int only_existing = 0;
 int opt_ignore_existing = 0;
@@ -142,6 +143,9 @@
  * address, or a hostname. **/
 char *bind_address;
 
+/** YYMMDDHHMMSS format for the --stopat */
+char *stopat;
+
 
 static void print_rsync_version(enum logcode f)
 {
@@ -288,6 +292,8 @@
   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");
   rprintf(F,"     --password-file=FILE    get password from FILE\n");
   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
+  rprintf(F,"     --timelimit=T           Stop rsync after T minutes\n");
+  rprintf(F,"     --stopat=YYMMDDHHMMSS   Stop rsync at time yr-mon-day-hr-min-sec\n");
   rprintf(F,"     --write-batch=PREFIX    write batch fileset starting with PREFIX\n");
   rprintf(F,"     --read-batch=PREFIX     read batch fileset starting with PREFIX\n");
   rprintf(F," -h, --help                  show this help screen\n");
@@ -377,6 +383,8 @@
   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
+  {"timelimit",        0,  POPT_ARG_INT,    &timelimit, 0, 0, 0 },
+  {"stopat",           0,  POPT_ARG_STRING, &stopat, 0, 0, 0 },
   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
@@ -885,6 +893,18 @@
 		args[ac++] = arg;
 	}
 
+	if (timelimit) {
+		if (asprintf(&arg, "--timelimit=%d", timelimit) < 0)
+			goto oom;
+		args[ac++] = arg;
+	}
+
+	if (stopat) {
+		if (asprintf(&arg, "--stopat=%s", stopat) < 0)
+			goto oom;
+		args[ac++] = arg;
+	}
+
 	if (backup_dir) {
 		args[ac++] = "--backup-dir";
 		args[ac++] = backup_dir;
diff -urN rsync-2.6.1pre-2/proto.h rsync-2.6.1pre-2_modified/proto.h
--- rsync-2.6.1pre-2/proto.h	2004-04-14 19:33:30.000000000 -0400
+++ rsync-2.6.1pre-2_modified/proto.h	2004-04-22 15:36:33.000000000 -0400
@@ -267,6 +267,7 @@
 int unsafe_symlink(const char *dest, const char *src);
 char *timestring(time_t t);
 int msleep(int t);
+time_t get_rsync_start_time(void);
 int cmp_modtime(time_t file1, time_t file2);
 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6);
 void *_new_array(unsigned int size, unsigned long num);
diff -urN rsync-2.6.1pre-2/rsync.1 rsync-2.6.1pre-2_modified/rsync.1
--- rsync-2.6.1pre-2/rsync.1	2004-04-17 14:38:47.000000000 -0400
+++ rsync-2.6.1pre-2_modified/rsync.1	2004-04-22 15:36:04.000000000 -0400
@@ -383,6 +383,8 @@
      --log-format=FORMAT     log file transfers using specified format
      --password-file=FILE    get password from FILE
      --bwlimit=KBPS          limit I/O bandwidth, KBytes per second
+     --timelimit=T           Stop rsync after T minutes
+     --stopat=YYMMDDHHMMSS   Stop rsync at this given time
      --write-batch=PREFIX    write batch fileset starting with PREFIX
      --read-batch=PREFIX     read batch fileset starting with PREFIX
  -h, --help                  show this help screen
@@ -1026,6 +1028,15 @@
 transfer was too fast, it will wait before sending the next data block\&. The
 result is an average transfer rate equaling the specified limit\&. A value
 of zero specifies no limit\&.
+.IP
+.IP "\fB--timelimit=T\fP" 
+This option allows you to specify the maximum
+number of minutes rsync will run for\&. This time starts when rsync starts
+to "consider" which files need transferring\&.
+.IP
+.IP "\fB--stopat=YYMMDDHHMMSS\fP"
+This option allows you to specify at what time to stop rsync,
+in yr-mon-day-hr-min-sec numeric format\&.
 .IP 
 .IP "\fB--write-batch=PREFIX\fP" 
 Generate a set of files that can be
diff -urN rsync-2.6.1pre-2/util.c rsync-2.6.1pre-2_modified/util.c
--- rsync-2.6.1pre-2/util.c	2004-04-17 13:06:03.000000000 -0400
+++ rsync-2.6.1pre-2_modified/util.c	2004-04-22 15:29:57.000000000 -0400
@@ -1050,6 +1050,22 @@
 	return True;
 }
 
+/**
+  * Return the time that rsync is started, used by --time-limit
+  **/
+time_t get_rsync_start_time(void)
+{
+	static struct timeval tval;
+	static int has_set_rsync_start_time = 0;
+
+	if( ! has_set_rsync_start_time ) {
+		gettimeofday(&tval, NULL);
+		has_set_rsync_start_time = 1;
+	}
+
+	return tval.tv_sec;
+}
+
 
 /**
  * Determine if two file modification times are equivalent (either


More information about the rsync mailing list