with this parameter set 1) any file newer then TIME (>=) will not be deleted at dest 2) any file older then TIME (<) will not be added to dest some workaround for directories add (file in dir newer or older) added. -------------------------------------------------------------------- *** work/rsync-3.0.7/options.c.orig 2009-12-22 00:40:41.000000000 +0200 --- work/rsync-3.0.7/options.c 2010-07-09 15:16:22.000000000 +0300 *************** *** 165,170 **** --- 165,171 ---- char *rsync_path = RSYNC_PATH; char *backup_dir = NULL; char backup_dir_buf[MAXPATHLEN]; + long check_point = -1; char *sockopts = NULL; int rsync_port = 0; int compare_dest = 0; *************** *** 325,330 **** --- 326,332 ---- rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n"); rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n"); rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); + rprintf(F," --check-point=FILE don't delete files newer than FILE\n"); rprintf(F," -u, --update skip files that are newer on the receiver\n"); rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); rprintf(F," --append append data onto shorter files\n"); *************** *** 609,614 **** --- 611,617 ---- {"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 }, {"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 }, {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 }, + {"check-point", 0, POPT_ARG_INT, &check_point, 0, 0, 0 }, {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 }, {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 }, {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 }, *************** *** 1924,1929 **** --- 1927,1938 ---- args[ac++] = backup_dir; } + if (check_point >= 0) { + if (asprintf(&arg, "--check-point=%d", check_point) < 0) + goto oom; + args[ac++] = arg; + } + /* Only send --suffix if it specifies a non-default value. */ if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) { /* We use the following syntax to avoid weirdness with '~'. */ -------------------------------------------------------------------- *** work/rsync-3.0.7/generator.c.orig 2009-12-23 21:36:27.000000000 +0200 --- work/rsync-3.0.7/generator.c 2010-07-09 15:36:01.000000000 +0300 *************** *** 96,101 **** --- 96,102 ---- extern char *backup_dir; extern char *backup_suffix; extern int backup_suffix_len; + extern long check_point; extern struct file_list *cur_flist, *first_flist, *dir_flist; extern struct filter_list_struct daemon_filter_list; *************** *** 132,138 **** }; enum delret { ! DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY }; /* Forward declarations. */ --- 133,139 ---- }; enum delret { ! DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY, DR_NEWER }; /* Forward declarations. */ *************** *** 160,165 **** --- 161,192 ---- char *what; int ok; + struct stat attrib; + stat(fbuf, &attrib); + if ( (check_point>=0)&&(check_point <= attrib.st_mtime) ) { + //if (!S_ISDIR(mode)) { + if (verbose > 0) { + rprintf(FINFO, "checkpoint: new item (%s), deletion skiped", fbuf); + rprintf(FINFO, verbose > 1 ? " (%d <= %d)\n" : "\n", check_point, attrib.st_mtime ); + } + return DR_NEWER; + //} + /* + DIR *d = opendir(fbuf); + struct dirent *p; + int is_empty = 1; + while ((is_empty>0)&&(p=readdir(d))) { + if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue; + is_empty = 0; + } + closedir(d); + if ((is_empty>0)&&(verbose > 0)) { + rprintf(FINFO, "empty dir (%s) is newer", fbuf); + rprintf(FINFO, verbose > 1 ? " (%d <= %d)\n" : "\n", check_point, attrib.st_mtime ); + } + */ + } + if (verbose > 2) { rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n", fbuf, (int)mode, (int)flags); *************** *** 1369,1374 **** --- 1396,1409 ---- stat_errno = errno; } + if ( (check_point>=0)&&(statret != 0)&&(check_point > file->modtime) ) { + if (verbose > 0) { + rprintf(FINFO, is_dir ? "checkpoint: old directory (%s)" : "checkpoint: old item (%s), creation skipped", fname); + rprintf(FINFO, verbose > 1 ? " (%d > %d)\n" : "\n", check_point, file->modtime); + } + if ( !is_dir ) return; + } + if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) { if (is_dir) { if (is_dir < 0) -------------------------------------------------------------------- USAGE example DEBUG=0 src=asfasfasfasfa dest=sfasfasf if [ ! -d $src ]; then req=1 fi if [ ! -d $dest ]; then req=1 fi if [ $req ]; then echo "SRC and DST required" exit 1 fi exit if [ "$1" != "" ]; then echo RECREATE ITEMS IN HOME..... date rm -rf /$dest/OLD* touch /$dest/NEW rm -rf /$dest/NEWDIR mkdir /$dest/NEWDIR touch -t 200808080808 /$dest/NEWDIR/OLD-IN-NEW touch /$dest/NEWDIR sleep 1 rm -rf /$src/NEW* touch -t 200808080808 /$src/OLD rm -rf /$src/OLDDIR mkdir /$src/OLDDIR touch /$src/OLDDIR/NEWINOLD touch -A 010101 /$src/OLDDIR/NEW-IN-OLD touch -t 200808080808 /$src/OLDDIR echo " SRC LIST --------------------------------------" ls -laTG /$src/ ls -laTG /$src/OLDDIR/NEW-IN-OLD echo " DEST LIST --------------------------------------" ls -laTG /$dest/ ls -laTG /$dest/NEWDIR/OLD-IN-NEW echo " --------------------------------------" fi synchronize() { logfile=/home/.rsync.$1.log lastrun=/home/.rsync.$1.lastrun started=/home/.rsync.$1.started if [ -f $lastrun ]; then checkpoint=$(stat -f %m $lastrun) mv $lastrun $lastrun~ fi rm -f $logfile if [ -f $started ]; then rm -f $started fi touch $started rsync $verbose --delete --recursive \ -v --log-file=$logfile \ --check-point=$checkpoint \ --backup-dir=$4 --backup \ --prune-empty-dirs --links --perms --owner --group --times \ --exclude=.rsync** \ $2 $3 rsyncExitCode=$? if [ $rsyncExitCode -gt 0 ]; then cat $logfile echo "rsync exit code is $rsyncExitCode" exit $rsyncExitCode fi mv $started $lastrun } synchronize home.to.root /home/ 172.16.4.32::rhome /.rsync.backup synchronize root.to.home 172.16.4.32::rhome /home/ /home/.rsync.backup if [ "$1" != "" ]; then echo " SRC LIST --------------------------------------" ls -laTG /$src/ ls -laTG /$src/OLDDIR/NEW-IN-OLD echo " DEST LIST --------------------------------------" ls -laTG /$dest/ ls -laTG /$dest/NEWDIR/OLD-IN-NEW echo " --------------------------------------" fi
Created attachment 5840 [details] check_point var declaration
Created attachment 5841 [details] check-point checking during deleting/adding
Created attachment 5842 [details] testcase
What use do you have in mind for this option?
(In reply to comment #4) > What use do you have in mind for this option? > this is a first step to a full bidirectional synchronization. So far as I know, a good feature for the bidirectional synchronization is rsync wrapper drsync, but it has several problems (backup, memory, etc). This option enables to run rsync twice instead of using drsync for a full master-master replication.
(In reply to comment #5) > this is a first step to a full bidirectional synchronization. And that is not a goal of rsync. See bug 2094. *** This bug has been marked as a duplicate of bug 2094 ***
Created attachment 5843 [details] bash wrapper see inside