Hi, How about adding now option '--backup-only' that means making backups only and don't change any destination files?
(I posted similar patch a month ago, but the patch was made for nightly snapshot of 20020808, which was tooo old! Laugh at me...) I want to use rsync with LVM snapshot to make incremental backups like below: 1) Make LVM snapshot of file system and mount it. 2) Compare it to yesterday's snapshot, and backup files which are updated or deleted. ex) rsync -a --delete --backup --backup-dir=/backup/backup_on_$DATE 3) Delete yesterday's snapshot. The problem is that LVM snapshots are read-only, so I need rsync not to modefy any destination files. I made trial patch against latest CVS, and this works fine for me. With this patch, new options '--backup-only' is added, and the '--backup-dir' option implies '--backup' for convinience. How about merging it? Regards, ----------------------- Takeru Komoriya [EMAIL PROTECTED] http://www.paken.org/ =================================================================== diff -ur rsync/backup.c rsync-backuponly/backup.c --- rsync/backup.c 2003-08-22 09:30:46.000000000 +0900 +++ rsync-backuponly/backup.c 2003-09-02 15:29:03.000000000 +0900 @@ -25,6 +25,7 @@ extern int backup_dir_len; extern char *backup_suffix; extern char *backup_dir; +extern int backup_only; extern int am_root; extern int preserve_devices; @@ -133,21 +134,26 @@ int keep_trying = 4; int keep_path_extfs = 0; int failed; + int saveerrno; while (keep_trying) { - if (keep_path_extfs) { + if (keep_path_extfs || backup_only) { failed = copy_file(src, dst, 0755); + saveerrno = errno; if (!failed) { do_unlink(src); + saveerrno = errno; } } else { failed = robust_rename (src, dst); + saveerrno = errno; } if (failed) { if (verbose > 2) rprintf (FERROR, "robust_move failed: %s(%d)\n", strerror (errno), errno); + errno = saveerrno; switch (errno) { /* external filesystem */ case EXDEV: @@ -225,7 +231,8 @@ } } kept = 1; - do_unlink(fname); + if (!backup_only) + do_unlink(fname); } #endif @@ -233,11 +240,11 @@ /* make an empty directory */ make_bak_dir(fname, backup_dir); do_mkdir(keep_name, file->mode); - ret_code = do_rmdir(fname); - if(verbose>2) { - rprintf(FINFO, "make_backup : RMDIR %s returns %i\n", - fname, ret_code); + if (!backup_only) { + ret_code=do_rmdir(fname); + if(verbose>2) + rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code); } kept = 1; } @@ -257,7 +264,8 @@ rprintf(FERROR, "link %s -> %s : %s\n", keep_name, file->link, strerror(errno)); } - do_unlink(fname); + if (!backup_only) + do_unlink(fname); kept = 1; } #endif diff -ur rsync/generator.c rsync-backuponly/generator.c --- rsync/generator.c 2003-08-22 14:42:13.000000000 +0900 +++ rsync-backuponly/generator.c 2003-09-02 15:44:26.000000000 +0900 @@ -41,6 +41,7 @@ extern int modify_window; extern char *compare_dest; extern int link_dest; +extern int backup_only; /* choose whether to skip a particular file */ @@ -295,6 +296,9 @@ return; } + if (backup_only && statret == -1 && errno == ENOENT) + return; + if (statret == 0 && !preserve_perms && (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) { @@ -313,6 +317,8 @@ if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */ if (statret == 0 && !S_ISDIR(st.st_mode)) { + if (backup_only) + return; if (robust_unlink(fname) != 0) { rprintf(FERROR, RSYNC_NAME ": recv_generator: unlink \"%s\" to make room for directory: %s\n", @@ -321,6 +327,8 @@ } statret = -1; } + if (backup_only) + return; if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) { if (!(relative_paths && errno==ENOENT && create_directory_path(fname, orig_umask)==0 && @@ -357,6 +365,8 @@ * right place -- no further action * required. */ if (strcmp(lnk,file->link) == 0) { + if (backup_only) + return; set_perms(fname,file,&st,1); return; } @@ -364,8 +374,12 @@ /* Not a symlink, so delete whatever's * already there and put a new symlink * in place. */ + if (backup_only) + return; delete_file(fname); } + if (backup_only) + return; if (do_symlink(file->link,fname) != 0) { rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n", fname,file->link,strerror(errno)); @@ -384,6 +398,8 @@ if (statret != 0 || st.st_mode != file->mode || (DEV64_T)st.st_rdev != file->rdev) { + if (backup_only) + return; delete_file(fname); if (verbose > 2) rprintf(FINFO,"mknod(%s,0%o,0x%x)\n", @@ -396,6 +412,8 @@ rprintf(FINFO,"%s\n",fname); } } else { + if (backup_only) + return; set_perms(fname,file,&st,1); } return; @@ -454,6 +472,8 @@ } if (!S_ISREG(st.st_mode)) { + if (backup_only) + return; if (delete_file(fname) != 0) { return; } @@ -477,7 +497,7 @@ } if (skip_file(fname, file, &st)) { - if (fnamecmp == fname) + if ((fnamecmp == fname) && !backup_only) set_perms(fname,file,&st,1); return; } @@ -487,6 +507,11 @@ return; } + if (backup_only) { + make_backup(fname); + return; + } + if (disable_deltas_p()) { write_int(f_out,i); write_sum_head(f_out, NULL); diff -ur rsync/options.c rsync-backuponly/options.c --- rsync/options.c 2003-08-06 15:45:14.000000000 +0900 +++ rsync-backuponly/options.c 2003-09-02 15:53:10.000000000 +0900 @@ -119,6 +119,7 @@ char *backup_dir = NULL; int rsync_port = RSYNC_PORT; int link_dest = 0; +int backup_only = 0; int verbose = 0; int quiet = 0; @@ -222,6 +223,7 @@ rprintf(F," -b, --backup make backups (default %s suffix)\n",BACKUP_SUFFIX); rprintf(F," --backup-dir make backups into this directory\n"); rprintf(F," --suffix=SUFFIX override backup suffix\n"); + rprintf(F," --backup-only make backups only, keeping destination files unchanged\n"); rprintf(F," -u, --update update only (don't overwrite newer files)\n"); rprintf(F," -l, --links copy symlinks as symlinks\n"); rprintf(F," -L, --copy-links copy the referent of symlinks\n"); @@ -297,7 +299,7 @@ enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST, OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, - OPT_READ_BATCH, OPT_WRITE_BATCH}; + OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_BACKUP_DIR}; static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ @@ -369,13 +371,14 @@ {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 }, {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 }, {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 }, - {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 }, + {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, OPT_BACKUP_DIR, 0, 0 }, {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 }, {"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 }, {"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 }, {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 }, {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0}, {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 }, + {"backup-only", 0, POPT_ARG_NONE, &backup_only , 0, 0, 0 }, #ifdef INET6 {0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 }, {0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 }, @@ -584,6 +587,11 @@ return 0; #endif + case OPT_BACKUP_DIR: + /* --backup-dir implies --backup */ + make_backups = 1; + break; + default: /* FIXME: If --daemon is specified, then errors for later @@ -644,6 +652,12 @@ if (do_progress && !verbose) verbose = 1; + if (backup_only && !backup_dir) { + rprintf(FERROR, + "--backup-dir must be specified with --backup-only\n"); + exit_cleanup(RERR_SYNTAX); + } + *argv = poptGetArgs(pc); if (*argv) *argc = count_args(*argv); @@ -879,6 +893,9 @@ args[ac++] = tmpdir; } + if (backup_only && am_sender) + args[ac++] = "--backup-only"; + if (compare_dest && 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 diff -ur rsync/receiver.c rsync-backuponly/receiver.c --- rsync/receiver.c 2003-09-05 14:53:55.000000000 +0900 +++ rsync-backuponly/receiver.c 2003-09-05 15:06:37.000000000 +0900 @@ -39,6 +39,7 @@ extern char *backup_dir; extern char *backup_suffix; extern int backup_suffix_len; +extern int backup_only; static struct delete_list { DEV64_T dev; @@ -159,13 +160,14 @@ char *f = f_name(local_file_list->files[i]); if (make_backups && (backup_dir || !is_backup_file(f))) { (void) make_backup(f); - if (verbose) + if (verbose && !backup_only) rprintf(FINFO, "deleting %s\n", f); } else { int mode = local_file_list->files[i]->mode; delete_one(f, S_ISDIR(mode) != 0); } - deletion_count++; + if (!backup_only) + deletion_count++; } } flist_free(local_file_list); @@ -535,15 +537,17 @@ } } - if (preserve_hard_links) - do_hard_links(); - - /* now we need to fix any directory permissions that were - modified during the transfer */ - for (i = 0; i < flist->count; i++) { - file = flist->files[i]; - if (!file->basename || !S_ISDIR(file->mode)) continue; - recv_generator(local_name?local_name:f_name(file),flist,i,-1); + if (!backup_only) { + if (preserve_hard_links) + do_hard_links(); + + /* now we need to fix any directory permissions that were + modified during the transfer */ + for (i = 0; i < flist->count; i++) { + file = flist->files[i]; + if (!file->basename || !S_ISDIR(file->mode)) continue; + recv_generator(local_name?local_name:f_name(file),flist,i,-1); + } } if (verbose > 2) diff -ur rsync/rsync.c rsync-backuponly/rsync.c --- rsync/rsync.c 2003-02-19 03:07:36.000000000 +0900 +++ rsync-backuponly/rsync.c 2003-09-02 16:12:51.000000000 +0900 @@ -30,6 +30,7 @@ extern int preserve_gid; extern int preserve_perms; extern int make_backups; +extern int backup_only; /* @@ -237,6 +238,9 @@ if (make_backups && !make_backup(fname)) return; + if (backup_only) + return; + /* move tmp file over real file */ if (robust_rename(fnametmp,fname) != 0) { if (errno == EXDEV) { diff -ur rsync/util.c rsync-backuponly/util.c --- rsync/util.c 2003-07-02 06:45:31.000000000 +0900 +++ rsync-backuponly/util.c 2003-09-02 16:06:44.000000000 +0900 @@ -268,18 +268,23 @@ ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode); if (ofd == -1) { - rprintf(FERROR,"open %s: %s\n", - dest,strerror(errno)); - close(ifd); + int saveerrno = errno; + if (verbose > 2) + rprintf(FERROR,"open %s: %s\n", + dest,strerror(errno)); + close(ifd); + errno = saveerrno; return -1; } while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) { if (full_write(ofd, buf, len) < 0) { + int saveerrno = errno; rprintf(FERROR,"write %s: %s\n", dest,strerror(errno)); close(ifd); close(ofd); + errno = saveerrno; return -1; } } ===================== end of the patch ============================= -- To unsubscribe or change options: http://lists.samba.org/mailman/listinfo/rsync Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html