Merge branch 'master' into master
This commit is contained in:
commit
7171030bd0
2
INSTALL
2
INSTALL
|
@ -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
|
||||||
|
|
|
@ -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
7
sanoid
|
@ -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
24
syncoid
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue