Skip to content

Instantly share code, notes, and snippets.

@ryochin
Last active January 30, 2017 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryochin/556ca9f916afcc13ee6a4996d2d6a3b0 to your computer and use it in GitHub Desktop.
Save ryochin/556ca9f916afcc13ee6a4996d2d6a3b0 to your computer and use it in GitHub Desktop.
rsync on first sync patch for rsnapshot 1.4.2.
--- a/rsnapshot
+++ b/rsnapshot
@@ -3470,14 +3470,14 @@ sub rotate_lowest_snapshots {
if (-d "$config_vars{'snapshot_root'}/.sync") {
print_cmd(
- "mv",
+ "rsync -a --link-dest=../.sync/",
"$config_vars{'snapshot_root'}/.sync/",
"$config_vars{'snapshot_root'}/$interval.0/"
);
if (0 == $test) {
my $result =
- safe_rename("$config_vars{'snapshot_root'}/.sync", "$config_vars{'snapshot_root'}/$interval.0");
+ safe_rename("$config_vars{'snapshot_root'}/.sync", "$config_vars{'snapshot_root'}/$interval.0", 1);
if (0 == $result) {
my $errstr = '';
$errstr .= "Error! safe_rename(\"$config_vars{'snapshot_root'}/.sync/\", \"";
@@ -6183,6 +6183,7 @@ sub file_diff {
sub safe_rename {
my $src = shift(@_);
my $dest = shift(@_);
+ my $is_initial_rotate = shift(@_) // 0;
my $st;
my $retval;
@@ -6198,6 +6199,17 @@ sub safe_rename {
return (0);
}
+ # touch .sync before stat
+ if ($is_initial_rotate) {
+ print_cmd("touch", "$src");
+
+ my $result = utime(time(), time(), "$src");
+ if (!$result) {
+ print_err("Warning! Could not set utime(time(), time(), \"$src\") : $!", 2);
+ return (0);
+ }
+ }
+
# stat file before rename
$st = stat($src);
if (!defined($st)) {
@@ -6206,7 +6218,12 @@ sub safe_rename {
}
# rename the file
- $retval = rename("$src", "$dest");
+ if ($is_initial_rotate) {
+ $retval = rename_using_rsync("$src", "$dest");
+ }
+ else{
+ $retval = rename("$src", "$dest");
+ }
if (1 != $retval) {
print_err("Could not rename(\"$src\", \"$dest\")", 2);
return (0);
@@ -6223,6 +6240,42 @@ sub safe_rename {
return (1);
}
+# accepts src, dest (file paths)
+# sync files using rsync instead of simple rename()
+# returns 1 on success, 0 on failure
+sub rename_using_rsync {
+ my $src = shift(@_);
+ my $dest = shift(@_);
+
+ my @cmd_stack;
+ push(@cmd_stack, $config_vars{'cmd_rsync'});
+ push(@cmd_stack, "-a"); # TODO: merge rsync_short_args or something?
+ push(@cmd_stack, "--link-dest=../.sync/");
+ push(@cmd_stack, "$src/");
+ push(@cmd_stack, "$dest/");
+
+ print_cmd(@cmd_stack);
+
+ # prepare dest for rsync
+ if (not -e $dest) {
+ mkpath("$dest", 0, 0755);
+ }
+
+ my ($rsync_in, $rsync_out);
+ my $pid = open3($rsync_in, $rsync_out, undef, @cmd_stack)
+ or die "Couldn't fork rsync: $!\n";
+
+ # add autoflush to get output by time and not at the end when rsync is finished
+ $rsync_out->autoflush();
+
+ while (<$rsync_out>) {
+ print_msg($_, 4);
+ }
+
+ waitpid($pid, 0);
+ return (get_retval($?) == 0);
+}
+
# accepts no args
# checks the config file for version number
# prints the config version to stdout
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment