Multiple compare-dest args
Vidar Madsen
vidar at prosalg.no
Thu Apr 15 10:04:09 GMT 2004
Hi all.
I have just finished a small patch that adds support for multiple
--compare-dest or --link-dest args. Its primary usage is to do incremental
backups on top of eachother. (My current backup system stores each
incremental as a single diff of the latest full.)
Example:
First full backup:
rsync -a somedir full-20040415/
First incremental:
rsync -a --compare-dest=../full-20040415 \
somedir incr-20040416/
Second incremental, on top of first:
rsync -a --compare-dest=../incr-20040416 --compare-dest=../full-20040415
somedir incr-20040417/
The args must be given in the correct order; Latest incremental first,
last resort last.
It scratches my itch, at least. Perhaps it can be of use to others as
well. :)
Vidar
-------------- next part --------------
diff -ru rsync-2.6.1pre-1/generator.c rsync-2.6.1pre-1-vidar/generator.c
--- rsync-2.6.1pre-1/generator.c 2004-03-07 21:29:59.000000000 +0100
+++ rsync-2.6.1pre-1-vidar/generator.c 2004-04-15 11:23:17.000000000 +0200
@@ -41,7 +41,7 @@
extern int io_timeout;
extern int protocol_version;
extern int always_checksum;
-extern char *compare_dest;
+extern char *compare_dest[];
extern int link_dest;
@@ -69,13 +69,13 @@
if (always_checksum && S_ISREG(st->st_mode)) {
char sum[MD4_SUM_LENGTH];
char fnamecmpdest[MAXPATHLEN];
+ int i = 0;
- if (compare_dest != NULL) {
- if (access(fname, 0) != 0) {
- pathjoin(fnamecmpdest, sizeof fnamecmpdest,
- compare_dest, fname);
- fname = fnamecmpdest;
- }
+ while ((access(fname, 0) != 0) && compare_dest[i] != NULL) {
+ pathjoin(fnamecmpdest, sizeof fnamecmpdest,
+ compare_dest[i], fname);
+ fname = fnamecmpdest;
+ i++;
}
file_checksum(fname,sum,st->st_size);
return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
@@ -270,7 +270,7 @@
int statret;
char *fnamecmp;
char fnamecmpbuf[MAXPATHLEN];
- extern char *compare_dest;
+ extern char *compare_dest[];
extern int list_only;
extern int only_existing;
extern int orig_umask;
@@ -408,11 +408,15 @@
fnamecmp = fname;
- if (statret == -1 && compare_dest != NULL) {
+ if (statret == -1 && compare_dest[0] != NULL) {
/* try the file at compare_dest instead */
int saveerrno = errno;
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
- statret = link_stat(fnamecmpbuf,&st);
+ int i = 0;
+ while (statret == -1 && compare_dest[i] != NULL) {
+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest[i], fname);
+ statret = link_stat(fnamecmpbuf,&st);
+ i++;
+ }
if (!S_ISREG(st.st_mode))
statret = -1;
if (statret == -1)
Only in rsync-2.6.1pre-1-vidar/lib: dummy
diff -ru rsync-2.6.1pre-1/options.c rsync-2.6.1pre-1-vidar/options.c
--- rsync-2.6.1pre-1/options.c 2004-02-22 09:56:43.000000000 +0100
+++ rsync-2.6.1pre-1-vidar/options.c 2004-04-15 11:29:35.000000000 +0200
@@ -112,7 +112,8 @@
char *backup_suffix = NULL;
char *tmpdir = NULL;
-char *compare_dest = NULL;
+char *compare_dest[MAX_COMP_DEST+1];
+int num_comp_dest = 0;
char *config_file = NULL;
char *shell_cmd = NULL;
char *log_format = NULL;
@@ -301,7 +302,7 @@
}
enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
- OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
+ OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_COMPARE_DEST, OPT_LINK_DEST,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
OPT_READ_BATCH, OPT_WRITE_BATCH,
OPT_REFUSED_BASE = 9000};
@@ -358,7 +359,7 @@
{"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
{"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
- {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
+ {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
/* TODO: Should this take an optional int giving the compression level? */
{"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
@@ -564,9 +565,31 @@
checksum_seed = FIXED_CHECKSUM_SEED;
break;
+ case OPT_COMPARE_DEST:
+#if HAVE_LINK
+ if (num_comp_dest >= MAX_COMP_DEST-1) {
+ rprintf(FERROR, "ERROR: %s\n", "too many --compare-dest args given");
+ return 0;
+ }
+ compare_dest[num_comp_dest] = (char *)poptGetOptArg(pc);
+ num_comp_dest++;
+ break;
+#else
+ snprintf(err_buf, sizeof err_buf,
+ "hard links are not supported on this %s\n",
+ am_server ? "server" : "client");
+ rprintf(FERROR, "ERROR: %s", err_buf);
+ return 0;
+#endif
+
case OPT_LINK_DEST:
#if HAVE_LINK
- compare_dest = (char *)poptGetOptArg(pc);
+ if (num_comp_dest >= MAX_COMP_DEST-1) {
+ rprintf(FERROR, "ERROR: %s\n", "too many --compare-dest args given");
+ return 0;
+ }
+ compare_dest[num_comp_dest] = (char *)poptGetOptArg(pc);
+ num_comp_dest++;
link_dest = 1;
break;
#else
@@ -925,13 +948,16 @@
args[ac++] = tmpdir;
}
- if (compare_dest && am_sender) {
+ if (compare_dest[0] && am_sender) {
/* the server only needs this option if it is not the sender,
* and it may be an older version that doesn't know this
* option, so don't send it if client is the sender.
*/
- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
- args[ac++] = compare_dest;
+ int i;
+ for (i = 0; i < num_comp_dest; i++) {
+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
+ args[ac++] = compare_dest[i];
+ }
}
if (files_from && (!am_sender || remote_filesfrom_file)) {
Only in rsync-2.6.1pre-1-vidar: options.c~
Only in rsync-2.6.1pre-1-vidar/popt: dummy
diff -ru rsync-2.6.1pre-1/receiver.c rsync-2.6.1pre-1-vidar/receiver.c
--- rsync-2.6.1pre-1/receiver.c 2004-03-23 17:50:40.000000000 +0100
+++ rsync-2.6.1pre-1-vidar/receiver.c 2004-04-15 11:07:43.000000000 +0200
@@ -35,7 +35,7 @@
extern int cvs_exclude;
extern int io_error;
extern char *tmpdir;
-extern char *compare_dest;
+extern char *compare_dest[];
extern int make_backups;
extern int do_progress;
extern char *backup_dir;
@@ -295,7 +295,7 @@
char *fnamecmp;
char fnamecmpbuf[MAXPATHLEN];
struct map_struct *mapbuf;
- int i;
+ int i, j;
struct file_struct *file;
int phase=0;
int recv_ok;
@@ -361,12 +361,14 @@
/* open the file */
fd1 = do_open(fnamecmp, O_RDONLY, 0);
- if (fd1 == -1 && compare_dest != NULL) {
+ j = 0;
+ while (fd1 == -1 && compare_dest[j] != NULL) {
/* try the file at compare_dest instead */
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
- compare_dest, fname);
+ compare_dest[j], fname);
fnamecmp = fnamecmpbuf;
fd1 = do_open(fnamecmp, O_RDONLY, 0);
+ j++;
}
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
diff -ru rsync-2.6.1pre-1/rsync.h rsync-2.6.1pre-1-vidar/rsync.h
--- rsync-2.6.1pre-1/rsync.h 2004-03-06 08:43:55.000000000 +0100
+++ rsync-2.6.1pre-1-vidar/rsync.h 2004-04-15 11:42:33.000000000 +0200
@@ -97,6 +97,8 @@
#define MAX_ARGS 1000
+#define MAX_COMP_DEST 20
+
#define MPLEX_BASE 7
#define NO_EXCLUDES 0
Only in rsync-2.6.1pre-1-vidar: rsync.h~
Only in rsync-2.6.1pre-1-vidar/zlib: dummy
More information about the rsync
mailing list