aboutsummaryrefslogtreecommitdiffstats
path: root/send-backup.pl
diff options
context:
space:
mode:
Diffstat (limited to 'send-backup.pl')
-rwxr-xr-xsend-backup.pl54
1 files changed, 54 insertions, 0 deletions
diff --git a/send-backup.pl b/send-backup.pl
new file mode 100755
index 0000000..ac12f32
--- /dev/null
+++ b/send-backup.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use YAML::Tiny;
+use Data::Dumper;
+
+my $conffile = 'backup.conf';
+
+my $conf = YAML::Tiny->read($conffile);
+my $srcs = $conf->[0]->{sources};
+my $dest = $conf->[0]->{dest};
+
+system("zfs list $dest > /dev/null 2>&1") == 0 or
+ die "Error: pool '$dest' not found. Is it imported?\n";
+
+foreach my $src (@$srcs) {
+ my ($pool, $fs) = split(/\//, $src, 2);
+ my ($from, $to) = limits($pool, $dest, $fs);
+
+ unless (defined $from) {
+ print "Warning: $dest does not contain $fs. Initialize with:\n" .
+ "\tzfs send -R $pool/$to | zfs recv $dest/$fs\n";
+ next;
+ }
+
+ if ($from eq $to) {
+ print "No new snapshots for $pool/$fs.\n";
+ next;
+ }
+
+ print "Sending to $dest: $pool/$from -> $to\n";
+ my $cmd = "zfs send -RI $pool/$from $pool/$to | zfs recv $dest/$fs";
+ system($cmd) == 0 or die "Error: couldn't send snapshots with:\n\t$cmd\n."
+}
+
+sub limits {
+ my ($src, $dst, $fs) = @_;
+
+ my @dstsnaps = snaps("$dst/$fs");
+ my @srcsnaps = snaps("$src/$fs");
+
+ ($dstsnaps[$#dstsnaps], $srcsnaps[$#srcsnaps]);
+}
+
+sub snaps {
+ my $fs = shift;
+
+ map {
+ chomp;
+ (split /\//, $_, 2)[1];
+ } `zfs list -Ht snap -d 1 -o name -s creation $fs`;
+}