Compare commits

...

10 Commits

Author SHA1 Message Date
Пётр e51fce25d3
Merge f70a961d79 into dbcaeef1ac 2025-09-01 19:45:42 +02:00
Jim Salter dbcaeef1ac
Remove Alpine Linux ps installation instructions
Removed instructions for installing ps on Alpine Linux.
2025-08-24 17:30:21 -04:00
Jim Salter 2c98f0501c
Merge pull request #634 from asche77/patch-1
Update INSTALL.md to include OmniOS installation instructions
2025-08-24 11:29:35 -04:00
Jim Salter 0f3a9c94d9
Merge branch 'master' into patch-1 2025-08-24 11:28:40 -04:00
Peter f70a961d79 Implement --restore-properties and --target-properties 2025-04-10 15:05:01 +02:00
asche d493ef7592
Merge branch 'jimsalterjrs:master' into patch-1 2021-10-24 18:16:46 +02:00
asche 876685a636
Update INSTALL.md 2021-04-08 21:41:45 +02:00
asche b1c2bcf859
Update INSTALL.md 2021-04-08 21:40:51 +02:00
asche 41ee154d2c
Update INSTALL.md
Add installation instructions for OmniOS; cleaned up description somewhat.
2021-04-08 21:38:46 +02:00
asche a61808d3bf
Update INSTALL.md 2021-04-04 12:28:21 +02:00
2 changed files with 177 additions and 13 deletions

View File

@ -8,7 +8,8 @@
- [Debian/Ubuntu](#debianubuntu)
- [RHEL/CentOS/AlmaLinux](#RHEL/CentOS/AlmaLinux)
- [FreeBSD](#freebsd)
- [Alpine Linux / busybox](#alpine-Linux-busybox-based-distributions)
- [Alpine Linux / busybox](#alpine-Linux-or-busybox-based-distributions)
- [OmniOS](#OmniOS)
- [Other OSes](#other-oses)
- [Configuration](#configuration)
- [Sanoid](#sanoid)
@ -175,13 +176,88 @@ pkg install p5-Config-Inifiles p5-Capture-Tiny pv mbuffer lzop sanoid
* See note about tcsh unpleasantness and other things in FREEBSD.readme
## Alpine Linux / busybox based distributions
## OmniOS
The busybox implementation of ps is lacking needed arguments so a proper ps program needs to be installed.
For Alpine Linux this can be done with:
Used with OmniOS r34, r36 and r37 (with napp-it installed). Hence, we presume you have a standard perl installation etc.
`apk --no-cache add procps`
1. Install prerequisites: Perl module Config::IniFiles, ssh, pv, gzip, lzop, and mbuffer
```bash
# install/update standard programs
pfexec pkg install openssh gzip mbuffer pipe-viewer
# include OpenCSW repository
pfexec pkg set-publisher -G '*' -g https://sfe.opencsw.org/localhostomnios localhostomnios
# install LZOP (from OpenCSW)
pfexec pkg install lzop
# install Perl modules
pfexec perl -MCPAN -e shell
install CPAN ## update CPAN
reload cpan ## reload
install inc::latest ## not sure if required
install IO::Scalar ## not sure if required
install Config::IniFiles
install Capture::Tiny
install Data::Dumper ## not sure if required, may be installed already
install File::Path ## not sure if required, may be installed already
install Getopt::Long ## not sure if required
install Pod::Usage ## not sure if required
install Time::Local ## not sure if required
exit
```
2. Download and clone the Sanoid repo:
```bash
# install git
pfexec pkg install git
# Tip: download the repo as root to avoid changing permissions later
pfexec git clone https://github.com/jimsalterjrs/sanoid.git
cd sanoid
# checkout latest stable release or stay on master for bleeding edge stuff (but expect bugs!)
pfexec git checkout $(git tag | grep "^v" | tail -n 1)
# patch syncoid, so that it correctly recognises the "zfs resume" capability under OmniOS (see https://github.com/jimsalterjrs/sanoid/issues/554)
<< $avail{'sourceresume'} = system("$sourcessh $resumechkcmd $srcpool 2>/dev/null | grep '\\(active\\|enabled\\)' >/dev/null 2>&1");
>> $avail{'sourceresume'} = system("$sourcessh $resumechkcmd $srcpool 2>/dev/null | grep -E '^(active|enabled)' >/dev/null 2>&1");
<< $avail{'targetresume'} = system("$targetssh $resumechkcmd $dstpool 2>/dev/null | grep '\\(active\\|enabled\\)' >/dev/null 2>&1");
>> $avail{'targetresume'} = system("$targetssh $resumechkcmd $dstpool 2>/dev/null | grep -E '^(active|enabled)' >/dev/null 2>&1");
# most likely not required, but make the executables eXecutable
pfexec chmod +x sanoid syncoid findoid sleepymutex
# Install the executables into /opt/sanoid
pfexec mkdir /opt/sanoid
pfexec cp sanoid syncoid findoid sleepymutex /opt/sanoid
# add symbolic links to executables to a directory in $path
pfexec ln -s /opt/sanoid/sanoid /usr/bin/sanoid & pfexec ln -s /opt/sanoid/syncoid /usr/bin/syncoid & pfexec ln -s /opt/sanoid/findoid /usr/bin/findoid & pfexec ln -s /opt/sanoid/sleepymutex /usr/bin/sleepymutex
```
3. Create the config directory /etc/sanoid, put default sanoid files there, and create and edit sanoid.conf:
```bash
# Create the config directory
pfexec mkdir /etc/sanoid
# Copy default config and sample config
pfexec cp sanoid.defaults.conf sanoid.conf /etc/sanoid/sanoid.example.conf
# Create a blank config file
pfexec touch /etc/sanoid/sanoid.conf
## and edit it (using e.g. nano as editor):
pfexec nano /etc/sanoid/sanoid.conf
```
Further steps (not OmniOS specific):
- set up SSH connections between two remote hosts
- create a cron job that runs sanoid --cron --quiet periodically
=======
## MacOS
Install prerequisite software:

94
syncoid
View File

@ -27,7 +27,7 @@ GetOptions(\%args, "no-command-checks", "monitor-version", "compress=s", "dumpsn
"no-clone-handling", "no-privilege-elevation", "force-delete", "no-rollback", "create-bookmark", "use-hold",
"pv-options=s" => \$pvoptions, "keep-sync-snap", "preserve-recordsize", "mbuffer-size=s" => \$mbuffer_size,
"delete-target-snapshots", "insecure-direct-connection=s", "preserve-properties",
"include-snaps=s@", "exclude-snaps=s@", "exclude-datasets=s@")
"include-snaps=s@", "exclude-snaps=s@", "exclude-datasets=s@", "target-properties=s@", "restore-properties")
or pod2usage(2);
my %compressargs = %{compressargset($args{'compress'} || 'default')}; # Can't be done with GetOptions arg, as default still needs to be set
@ -42,6 +42,12 @@ if (defined($args{'exclude'})) {
}
}
if (defined $args{'restore-properties'} && defined $args{'preserve-properties'}) {
writelog('WARN', "invalid argument combination, --restore-properties and --preserve-properties aren't compatible!");
pod2usage(2);
exit 127;
}
my @sendoptions = ();
if (length $args{'sendoptions'}) {
@sendoptions = parsespecialoptions($args{'sendoptions'});
@ -912,15 +918,58 @@ sub runsynccmd {
# if no rollbacks are allowed, disable forced receive
if (!defined $args{'no-rollback'}) { $recvoptions .= ' -F'; }
if (defined $args{'preserve-properties'}) {
my %properties = getlocalzfsvalues($sourcehost,$sourcefs,$sourceisroot);
if (defined $args{'restore-properties'}) {
foreach my $key (keys %properties) {
my $value = $properties{$key};
my ($skey, $ikey) = split(/:/, $key);
if (!length($ikey)) {
my $skeypresent = 0;
foreach my $key1 (keys %properties) {
my ($skey1, $ikey1) = split(/:/, $key1);
if (length($ikey1)) {
if($ikey1 eq $key) {
$skeypresent = 1;
}
}
}
if (!$skeypresent) {
if(!istargetpropertypresent($key)) {
writelog('DEBUG', "will set $key to $value ...");
my $pair = escapeshellparam("$key=$value");
$recvoptions .= " -o $pair";
}
}
} else {
if(!istargetpropertypresent($ikey)) {
if($value eq "*default*") {
writelog('DEBUG', "will unset $ikey ...");
$recvoptions .= " -x $ikey";
} else {
writelog('DEBUG', "will set $ikey to $value ...");
my $pair = escapeshellparam("$ikey=$value");
$recvoptions .= " -o $pair";
}
}
}
}
}
if (defined $args{'preserve-properties'}) {
foreach my $key (keys %properties) {
my $value = $properties{$key};
if(!istargetpropertypresent($key)) {
writelog('DEBUG', "will set $key to $value ...");
my $pair = escapeshellparam("$key=$value");
$recvoptions .= " -o $pair";
} else {
my $newkey .= "syncoid:$key";
writelog('DEBUG', "will set $newkey to $value ...");
my $pair = escapeshellparam("$newkey=$value");
$recvoptions .= " -o $pair";
}
}
} elsif (defined $args{'preserve-recordsize'}) {
my $type = getzfsvalue($sourcehost,$sourcefs,$sourceisroot,'type');
if ($type eq "filesystem") {
@ -929,6 +978,26 @@ sub runsynccmd {
}
}
if (defined $args{'target-properties'}) {
my $props = $args{'target-properties'};
foreach (@$props) {
my ($tkey, $tvalue) = split(/=/);
my $tpair = escapeshellparam("$tkey=$tvalue");
$recvoptions .= " -o $tpair";
my $localpresent = 0;
foreach my $key (keys %properties) {
my $value = $properties{$key};
if ($tkey eq $key) {
$localpresent = 1;
}
}
if(!$localpresent && defined $args{'preserve-properties'}) {
$tpair = escapeshellparam("syncoid:$tkey=*default*");
$recvoptions .= " -o $tpair";
}
}
}
my $sendcmd = "$sourcesudocmd $zfscmd send $sendoptions $sendsource";
my $recvcmd = "$targetsudocmd $zfscmd receive $recvoptions $targetfsescaped 2>&1";
@ -2331,6 +2400,23 @@ sub writelog {
}
}
sub istargetpropertypresent {
my ($propname) = @_;
if (defined $args{'target-properties'}) {
my $props = $args{'target-properties'};
foreach (@$props) {
my ($tkey, $tvalue) = split(/=/);
if ($propname =~ /$tkey/) {
writelog('DEBUG', "source property $propname will be overwritten by value set in target-properties /$_/");
return 1;
}
}
}
return 0;
}
sub snapisincluded {
my ($snapname) = @_;
@ -2414,7 +2500,9 @@ Options:
--create-bookmark Creates a zfs bookmark for the newest snapshot on the source after replication succeeds (only works with --no-sync-snap)
--use-hold Adds a hold to the newest snapshot on the source and target after replication succeeds and removes the hold after the next successful replication. The hold name includes the identifier if set. This allows for separate holds in case of multiple targets
--preserve-recordsize Preserves the recordsize on initial sends to the target
--preserve-properties Preserves locally set dataset properties similar to the zfs send -p flag but this one will also work for encrypted datasets in non raw sends
--preserve-properties Preserves locally set dataset properties similar to the zfs send -p flag but this one will also work for encrypted datasets in non raw sends. If --target-properties overrides locally set property, it will be saved with 'syncoid:' prefix on target dataset.
--restore-properties Works like --preserve-properties but also sets properties present locally with 'syncoid:' prefix on target dataset (without this prefix).
--target-properties Set properties on target dataset, for example --target-properties=canmount=noauto. Can be specified multiple times. The properties defined by this parameter override the properties set by --preserve-properties and --restore-properties.
--no-rollback Does not rollback snapshots on target (it probably requires a readonly target)
--delete-target-snapshots With this argument snapshots which are missing on the source will be destroyed on the target. Use this if you only want to handle snapshots on the source.
--exclude=REGEX DEPRECATED. Equivalent to --exclude-datasets, but will be removed in a future release. Ignored if --exclude-datasets is also provided.