Merge branch 'master' into master

This commit is contained in:
shodanshok 2018-07-10 12:37:52 +02:00 committed by GitHub
commit 7171030bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 5 deletions

View File

@ -8,7 +8,7 @@ default for SSH transport since v1.4.6. Syncoid runs will fail if one of them
is not available on either end of the transport. is not available on either end of the transport.
On Ubuntu: apt install pv lzop mbuffer On Ubuntu: apt install pv lzop mbuffer
On CentOS: yum install lzo pv mbuffer lzop On CentOS: yum install lzo pv mbuffer lzop perl-Data-Dumper
On FreeBSD: pkg install pv mbuffer lzop On FreeBSD: pkg install pv mbuffer lzop
FreeBSD notes: FreeBSD may place pv and lzop in somewhere other than FreeBSD notes: FreeBSD may place pv and lzop in somewhere other than

View File

@ -132,10 +132,18 @@ As of 1.4.18, syncoid also automatically supports and enables resume of interrup
This is the destination dataset. It can be either local or remote. This is the destination dataset. It can be either local or remote.
+ --identifier=
Adds the given identifier to the snapshot name after "syncoid_" prefix and before the hostname. This enables the use case of reliable replication to multiple targets from the same host. The following chars are allowed: a-z, A-Z, 0-9, _, -, : and . .
+ -r --recursive + -r --recursive
This will also transfer child datasets. This will also transfer child datasets.
+ --skip-parent
This will skip the syncing of the parent dataset. Does nothing without '--recursive' option.
+ --compress <compression type> + --compress <compression type>
Currently accepted options: gzip, pigz-fast, pigz-slow, lzo (default) & none. If the selected compression method is unavailable on the source and destination, no compression will be used. Currently accepted options: gzip, pigz-fast, pigz-slow, lzo (default) & none. If the selected compression method is unavailable on the source and destination, no compression will be used.

7
sanoid
View File

@ -976,6 +976,11 @@ sub check_zpool() {
## other cases ## other cases
my ($dev, $sta) = /^\s+(\S+)\s+(\S+)/; my ($dev, $sta) = /^\s+(\S+)\s+(\S+)/;
if (!defined($sta)) {
# cache and logs are special and don't have a status
next;
}
## pool online, not degraded thanks to dead/corrupted disk ## pool online, not degraded thanks to dead/corrupted disk
if ($state eq "OK" && $sta eq "UNAVAIL") { if ($state eq "OK" && $sta eq "UNAVAIL") {
$state="WARNING"; $state="WARNING";
@ -1111,7 +1116,7 @@ sub checklock {
# make sure lockfile contains something # make sure lockfile contains something
if ( -z $lockfile) { if ( -z $lockfile) {
# zero size lockfile, something is wrong # zero size lockfile, something is wrong
die "ERROR: something is wrong! $lockfile is empty\n"; die "ERROR: something is wrong! $lockfile is empty\n";
} }
# lockfile exists. read pid and mutex from it. see if it's our pid. if not, see if # lockfile exists. read pid and mutex from it. see if it's our pid. if not, see if

24
syncoid
View File

@ -19,7 +19,7 @@ use Sys::Hostname;
my %args = ('sshkey' => '', 'sshport' => '', 'sshcipher' => '', 'sshoption' => [], 'target-bwlimit' => '', 'source-bwlimit' => ''); my %args = ('sshkey' => '', 'sshport' => '', 'sshcipher' => '', 'sshoption' => [], 'target-bwlimit' => '', 'source-bwlimit' => '');
GetOptions(\%args, "no-command-checks", "monitor-version", "compress=s", "dumpsnaps", "recursive|r", GetOptions(\%args, "no-command-checks", "monitor-version", "compress=s", "dumpsnaps", "recursive|r",
"source-bwlimit=s", "target-bwlimit=s", "sshkey=s", "sshport=i", "sshcipher|c=s", "sshoption|o=s@", "source-bwlimit=s", "target-bwlimit=s", "sshkey=s", "sshport=i", "sshcipher|c=s", "sshoption|o=s@",
"debug", "quiet", "no-stream", "no-sync-snap", "no-clone-rollback", "no-rollback", "no-resume", "exclude=s@") or pod2usage(2); "debug", "quiet", "no-stream", "no-sync-snap", "no-resume", "exclude=s@", "skip-parent", "identifier=s", "no-clone-rollback", "no-rollback") or pod2usage(2);
my %compressargs = %{compressargset($args{'compress'} || 'default')}; # Can't be done with GetOptions arg, as default still needs to be set my %compressargs = %{compressargset($args{'compress'} || 'default')}; # Can't be done with GetOptions arg, as default still needs to be set
@ -71,6 +71,17 @@ if (length $args{'sshkey'}) {
} }
my $sshoptions = join " ", map { "-o " . $_ } @{$args{'sshoption'}}; # deref required my $sshoptions = join " ", map { "-o " . $_ } @{$args{'sshoption'}}; # deref required
my $identifier = "";
if (length $args{'identifier'}) {
if ($args{'identifier'} !~ /^[a-zA-Z0-9-_:.]+$/) {
# invalid extra identifier
print("CRITICAL: extra identifier contains invalid chars!\n");
pod2usage(2);
exit 127;
}
$identifier = "$args{'identifier'}_";
}
# figure out if source and/or target are remote. # figure out if source and/or target are remote.
$sshcmd = "$sshcmd $args{'sshcipher'} $sshoptions $args{'sshport'} $args{'sshkey'}"; $sshcmd = "$sshcmd $args{'sshcipher'} $sshoptions $args{'sshport'} $args{'sshkey'}";
if ($debug) { print "DEBUG: SSHCMD: $sshcmd\n"; } if ($debug) { print "DEBUG: SSHCMD: $sshcmd\n"; }
@ -141,6 +152,11 @@ sub getchilddatasets {
my @children = <FH>; my @children = <FH>;
close FH; close FH;
if (defined $args{'skip-parent'}) {
# parent dataset is the first element
shift @children;
}
if (defined $args{'exclude'}) { if (defined $args{'exclude'}) {
my $excludes = $args{'exclude'}; my $excludes = $args{'exclude'};
foreach (@$excludes) { foreach (@$excludes) {
@ -849,7 +865,7 @@ sub pruneoldsyncsnaps {
# only prune snaps beginning with syncoid and our own hostname # only prune snaps beginning with syncoid and our own hostname
foreach my $snap(@snaps) { foreach my $snap(@snaps) {
if ($snap =~ /^syncoid_\Q$hostid\E/) { if ($snap =~ /^syncoid_\Q$identifier$hostid\E/) {
# no matter what, we categorically refuse to # no matter what, we categorically refuse to
# prune the new sync snap we created for this run # prune the new sync snap we created for this run
if ($snap ne $newsyncsnap) { if ($snap ne $newsyncsnap) {
@ -935,7 +951,7 @@ sub newsyncsnap {
if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; } if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; }
my $hostid = hostname(); my $hostid = hostname();
my %date = getdate(); my %date = getdate();
my $snapname = "syncoid\_$hostid\_$date{'stamp'}"; my $snapname = "syncoid\_$identifier$hostid\_$date{'stamp'}";
my $snapcmd = "$rhost $mysudocmd $zfscmd snapshot $fsescaped\@$snapname\n"; my $snapcmd = "$rhost $mysudocmd $zfscmd snapshot $fsescaped\@$snapname\n";
system($snapcmd) == 0 system($snapcmd) == 0
or die "CRITICAL ERROR: $snapcmd failed: $?"; or die "CRITICAL ERROR: $snapcmd failed: $?";
@ -1173,7 +1189,9 @@ syncoid - ZFS snapshot replication tool
Options: Options:
--compress=FORMAT Compresses data during transfer. Currently accepted options are gzip, pigz-fast, pigz-slow, lzo (default) & none --compress=FORMAT Compresses data during transfer. Currently accepted options are gzip, pigz-fast, pigz-slow, lzo (default) & none
--identifier=EXTRA Extra identifier which is included in the snapshot name. Can be used for replicating to multiple targets.
--recursive|r Also transfers child datasets --recursive|r Also transfers child datasets
--skip-parent Skips syncing of the parent dataset. Does nothing without '--recursive' option.
--source-bwlimit=<limit k|m|g|t> Bandwidth limit on the source transfer --source-bwlimit=<limit k|m|g|t> Bandwidth limit on the source transfer
--target-bwlimit=<limit k|m|g|t> Bandwidth limit on the target transfer --target-bwlimit=<limit k|m|g|t> Bandwidth limit on the target transfer
--no-stream Replicates using newest snapshot instead of intermediates --no-stream Replicates using newest snapshot instead of intermediates