From a61808d3bf3f24dcf99424c5640fdce8ff54f507 Mon Sep 17 00:00:00 2001 From: asche <47307281+asche77@users.noreply.github.com> Date: Sun, 4 Apr 2021 12:28:21 +0200 Subject: [PATCH 01/13] Update INSTALL.md --- INSTALL.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index c8411d3..dd65501 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -171,6 +171,97 @@ For Alpine Linux this can be done with: `apk --no-cache add procps` + +## OmniOS / Illumos based distributions + +Used with OmniOS r34, r36 and r37 with napp-it installed. Hence, we presume you have a standard perl installation etc. + +1. Install prerequisites: Perl module Config::IniFiles, ssh, pv, gzip, lzop, and mbuffer + +```# 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 +# do this as root +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 +``` +Optionally, to update your perl installation (use with care!): + +```# OPTIONALLY install cpanm (CPAN Minus) and cpan-outdated +# do this as root +curl -L http://cpanmin.us | perl - --sudo App::cpanminus +/usr/perl5/5.32/bin/cpanm App::cpanoutdated +# update using cpanm / cpan-outdated +# do this as root +/usr/perl5/5.32/bin/cpan-outdated -p | /usr/perl5/5.32/bin/cpanm +``` + +2. Download the Sanoid repo: + +``` +# do this as root +# install git +pfexec pkg install git +# 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 re: regexp check for zfs resume (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"); +# Install the executables +pfexec mkdir /opt/sanoid +pfexec cp sanoid syncoid findoid sleepymutex /opt/sanoid +# link executables to 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 and put sanoid.defaults.conf in there, and create sanoid.conf in it too: +```# Create the config directory +pfexec mkdir /etc/sanoid +# Install default config +pfexec cp sanoid.defaults.conf /etc/sanoid +# Create a blank config file +pfexec touch /etc/sanoid/sanoid.conf +# Place the sample config in the conf directory for reference +pfexec cp sanoid.conf /etc/sanoid/sanoid.example.conf +## ... and do not forget to edit the empty(!) sanoid.conf file! (we are using nano as editor): +pfexec nano /etc/sanoid/sanoid.conf +``` + +4. Set up SSH connections between two remote hosts + + # missing !!!!!!!!!!!!!!!! + +5. Create a cron job or a systemd timer that runs sanoid --cron once per [every 30 min] + + # missing !!!!!!!!!!!!!!!! + + napp-it --> Jobs --> Other --> Create Other Job "/usr/bin/sanoid --cron --quiet" + ## Other OSes **Sanoid** depends on the Perl module Config::IniFiles and will not operate without it. Config::IniFiles may be installed from CPAN, though the project strongly recommends using your distribution's repositories instead. From 41ee154d2ce7fcd1170cc2a343b12875fa802df2 Mon Sep 17 00:00:00 2001 From: asche <47307281+asche77@users.noreply.github.com> Date: Thu, 8 Apr 2021 21:38:46 +0200 Subject: [PATCH 02/13] Update INSTALL.md Add installation instructions for OmniOS; cleaned up description somewhat. --- INSTALL.md | 88 +++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index dd65501..72fed7b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -171,10 +171,9 @@ For Alpine Linux this can be done with: `apk --no-cache add procps` - ## OmniOS / Illumos based distributions -Used with OmniOS r34, r36 and r37 with napp-it installed. Hence, we presume you have a standard perl installation etc. +Used with OmniOS r34, r36 and r37 (with napp-it installed). Hence, we presume you have a standard perl installation etc. 1. Install prerequisites: Perl module Config::IniFiles, ssh, pv, gzip, lzop, and mbuffer @@ -184,83 +183,72 @@ 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 +# install LZOP (from OpenCSW) pfexec pkg install lzop # install Perl modules -# do this as root -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 -``` -Optionally, to update your perl installation (use with care!): +pfexec perl -MCPAN -e shell + install CPAN ## update CPAN + reload cpan ## reload -```# OPTIONALLY install cpanm (CPAN Minus) and cpan-outdated -# do this as root -curl -L http://cpanmin.us | perl - --sudo App::cpanminus -/usr/perl5/5.32/bin/cpanm App::cpanoutdated -# update using cpanm / cpan-outdated -# do this as root -/usr/perl5/5.32/bin/cpan-outdated -p | /usr/perl5/5.32/bin/cpanm + 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 the Sanoid repo: +2. Download and clone the Sanoid repo: ``` -# do this as root # install git pfexec pkg install git -# Download the repo as root to avoid changing permissions later + +# 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 re: regexp check for zfs resume (https://github.com/jimsalterjrs/sanoid/issues/554) + +# 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"); -# Install the executables + +# 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 -# link executables to 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 + +# 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 and put sanoid.defaults.conf in there, and create sanoid.conf in it too: +3. Create the config directory /etc/sanoid, put default sanoid files there, and create and edit sanoid.conf: ```# Create the config directory pfexec mkdir /etc/sanoid -# Install default config -pfexec cp sanoid.defaults.conf /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 -# Place the sample config in the conf directory for reference -pfexec cp sanoid.conf /etc/sanoid/sanoid.example.conf -## ... and do not forget to edit the empty(!) sanoid.conf file! (we are using nano as editor): +## and edit it (using e.g. nano as editor): pfexec nano /etc/sanoid/sanoid.conf ``` -4. Set up SSH connections between two remote hosts - - # missing !!!!!!!!!!!!!!!! - -5. Create a cron job or a systemd timer that runs sanoid --cron once per [every 30 min] - - # missing !!!!!!!!!!!!!!!! - - napp-it --> Jobs --> Other --> Create Other Job "/usr/bin/sanoid --cron --quiet" +Further steps (not OmniOS specific): +- set up SSH connections between two remote hosts +- create a cron job that runs sanoid --cron --quiet periodically ## Other OSes From b1c2bcf8596f051b06c0aee8eadffebbf750f292 Mon Sep 17 00:00:00 2001 From: asche <47307281+asche77@users.noreply.github.com> Date: Thu, 8 Apr 2021 21:40:51 +0200 Subject: [PATCH 03/13] Update INSTALL.md --- INSTALL.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 72fed7b..cd3c768 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -9,6 +9,7 @@ - [CentOS](#centos) - [FreeBSD](#freebsd) - [Alpine Linux / busybox](#alpine-Linux-busybox-based-distributions) + - [OmniOS](#OmniOS-Illumos-based-distributions) - [Other OSes](#other-oses) - [Configuration](#configuration) - [Sanoid](#sanoid) @@ -177,7 +178,8 @@ Used with OmniOS r34, r36 and r37 (with napp-it installed). Hence, we presume y 1. Install prerequisites: Perl module Config::IniFiles, ssh, pv, gzip, lzop, and mbuffer -```# install/update standard programs +```bash +# install/update standard programs pfexec pkg install openssh gzip mbuffer pipe-viewer # include OpenCSW repository @@ -205,7 +207,7 @@ pfexec perl -MCPAN -e shell 2. Download and clone the Sanoid repo: -``` +```bash # install git pfexec pkg install git @@ -234,7 +236,8 @@ pfexec ln -s /opt/sanoid/sanoid /usr/bin/sanoid & pfexec ln -s /opt/sanoid/synco ``` 3. Create the config directory /etc/sanoid, put default sanoid files there, and create and edit sanoid.conf: -```# Create the config directory +```bash +# Create the config directory pfexec mkdir /etc/sanoid # Copy default config and sample config From 876685a636492d58c237ddd1b7b9cab2d256ec24 Mon Sep 17 00:00:00 2001 From: asche <47307281+asche77@users.noreply.github.com> Date: Thu, 8 Apr 2021 21:41:45 +0200 Subject: [PATCH 04/13] Update INSTALL.md --- INSTALL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index cd3c768..d401179 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -8,8 +8,8 @@ - [Debian/Ubuntu](#debianubuntu) - [CentOS](#centos) - [FreeBSD](#freebsd) - - [Alpine Linux / busybox](#alpine-Linux-busybox-based-distributions) - - [OmniOS](#OmniOS-Illumos-based-distributions) + - [Alpine Linux / busybox](#alpine-Linux-or-busybox-based-distributions) + - [OmniOS](#OmniOS) - [Other OSes](#other-oses) - [Configuration](#configuration) - [Sanoid](#sanoid) @@ -165,14 +165,14 @@ pkg install p5-Config-Inifiles p5-Capture-Tiny pv mbuffer lzop * See note about mbuffer and other things in FREEBSD.readme -## Alpine Linux / busybox based distributions +## Alpine Linux or busybox based distributions 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: `apk --no-cache add procps` -## OmniOS / Illumos based distributions +## OmniOS Used with OmniOS r34, r36 and r37 (with napp-it installed). Hence, we presume you have a standard perl installation etc. From 749490830f74def5dddd32244fa19b39b4e61de1 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Mon, 31 Mar 2025 14:54:46 +0200 Subject: [PATCH 05/13] syncoid: fix directtimeout in directmbuffer mode If --insecure-direct-connection contained 4 parts (including the ',mbuffer' at the end), the 3rd part (timeout) was silently ignored and left at the default 60s. Do not ignore the timeout part even in directmbuffer mode. --- syncoid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syncoid b/syncoid index 79ad45f..91bc277 100755 --- a/syncoid +++ b/syncoid @@ -178,7 +178,7 @@ if (length $args{'insecure-direct-connection'}) { $directlisten = $args{'insecure-direct-connection'}; } - if (scalar @parts == 3) { + if (scalar @parts >= 3) { $directtimeout = $parts[2]; } From efd52f416d1ecf95c9e7db225476c6a5fd1d1808 Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Tue, 12 Aug 2025 14:19:47 +0200 Subject: [PATCH 06/13] fixed file handle conflict --- sanoid | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sanoid b/sanoid index 4a71319..8e0d186 100755 --- a/sanoid +++ b/sanoid @@ -1084,11 +1084,9 @@ sub init { @datasets = getchilddatasets($config{$section}{'path'}); DATASETS: foreach my $dataset(@datasets) { if (! @cachedatasets) { - push (@updatedatasets, $dataset); + push (@updatedatasets, "$dataset\n"); } - chomp $dataset; - if ($zfsRecursive) { # don't try to take the snapshot ourself, recursive zfs snapshot will take care of that $config{$dataset}{'autosnap'} = 0; @@ -1691,7 +1689,7 @@ sub getchilddatasets { my $getchildrencmd = "$mysudocmd $zfs list -o name -t filesystem,volume -Hr $fs |"; if ($args{'debug'}) { print "DEBUG: getting list of child datasets on $fs using $getchildrencmd...\n"; } open FH, $getchildrencmd; - my @children = ; + chomp( my @children = ); close FH; # parent dataset is the first element @@ -1781,25 +1779,26 @@ sub addcachedsnapshots { copy($cache, "$cache.tmp") or die "Could not copy to $cache.tmp!\n"; - open FH, ">> $cache.tmp" or die "Could not write to $cache.tmp!\n"; + open my $fh, ">> $cache.tmp" or die "Could not write to $cache.tmp!\n"; while((my $snap, my $details) = each(%taken)) { my @parts = split("@", $snap, 2); my $suffix = $parts[1] . "\tcreation\t" . $details->{time} . "\t-"; my $dataset = $parts[0]; - print FH "${dataset}\@${suffix}\n"; + print $fh "${dataset}\@${suffix}\n"; if ($details->{recursive}) { my @datasets = getchilddatasets($dataset); foreach my $dataset(@datasets) { - print FH "${dataset}\@${suffix}\n"; + print "${dataset}\@${suffix}\n"; + print $fh "${dataset}\@${suffix}\n"; } } } - close FH; + close $fh; # preserve mtime of cache for expire check my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($cache); From dbcaeef1ac55bd3dd929b86a8f6082fef16f02b1 Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Sun, 24 Aug 2025 17:30:21 -0400 Subject: [PATCH 07/13] Remove Alpine Linux ps installation instructions Removed instructions for installing ps on Alpine Linux. --- INSTALL.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 879d257..e32de4e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -176,13 +176,6 @@ 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 or busybox based distributions - -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: - -`apk --no-cache add procps` - ## OmniOS Used with OmniOS r34, r36 and r37 (with napp-it installed). Hence, we presume you have a standard perl installation etc. From 361e6839d170cbc1d5286ba85977859853f09a24 Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Mon, 19 Jan 2026 23:23:34 -0500 Subject: [PATCH 08/13] Add disk space check script for ZFS filesystems This script checks the available disk space on all mounted filesystems, producing Nagios-ready exit codes and brief, human-readable text. --- check_all_disk_space | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 check_all_disk_space diff --git a/check_all_disk_space b/check_all_disk_space new file mode 100644 index 0000000..bf08cdd --- /dev/null +++ b/check_all_disk_space @@ -0,0 +1,67 @@ +#!/usr/bin/perl + +# nagios plugin format: exit 0,1,2,3 for OK, WARN, CRITICAL, or ERROR. + +# check_all_space_avail - test space available on all ZFS filesystems on host +# different values for pools named "backup" and other pools: +# +# default: warn 93%, crit 98% + +my $warnlevel = .93; +my $critlevel = .98; + +# accept warnlevel and critlevel as arguments if passed +if (defined $ARGV[0] && defined $ARGV[1] && $ARGV[0] >=0 && $ARGV[0] <=1 && $ARGV[1] >=0 && $ARGV[1] <=1) { + $warnlevel = $ARGV[0]; + $critlevel = $ARGV[1]; +} + +my $msg,$warnfound,$critfound,$errfound; + +# get standard df output, but skip the tmpfs and devtmpfs crap - this should leave us with +# nothing but disks. we WILL also get nfs or other network filesystems here, since we +# didn't use the -l flag. Feature, not bug. also skip UDF so we don't check free space on CDs! +my @filesystems = `/bin/df -x tmpfs -x devtmpfs -x udf`; + +# get rid of header line +shift @filesystems; + +foreach my $fs (@filesystems) { + chomp $fs; + # compress space to make sure split works right + $fs =~ s/ +/ /g; + my ($dev,$space,$used,$available,$percent,$mounted) = split(' ',$fs); + my $calcpercent = $used/$space; + my $prettypercent = sprintf('%.1F%',($calcpercent * 100)); + if ($calcpercent > $critlevel) { + $critfound = 1; + $msg .= "$mounted: $prettypercent, "; + } elsif ($calcpercent > $warnlevel) { + $warnfound = 1; + $msg .= "$mounted: $prettypercent, "; + } elsif ($calcpercent < 0 || $calcpercent > 1) { + $errfound = 1; + $msg .= "$mounted: $prettypercent (WTF?), "; + } +} + +$msg =~ s/, $//; +$msg .= "\n"; + +if ($critfound) { + print "CRITICAL: $msg"; + exit 2; +} elsif ($warnfound) { + print "WARNING: $msg"; + exit 1; +} elsif ($errfound) { + print "ERROR: $msg"; + exit 3; +} else { + print "OK\n"; + exit 0; +} + + +print "ERROR: $msg ?"; +exit 3; From 536cceea954f9dd3f0c094c03a890b062231f88e Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Mon, 19 Jan 2026 23:30:35 -0500 Subject: [PATCH 09/13] Enhance comments for check_all_disk_space script Updated comments to clarify script functionality and usage. --- check_all_disk_space | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/check_all_disk_space b/check_all_disk_space index bf08cdd..33b3f33 100644 --- a/check_all_disk_space +++ b/check_all_disk_space @@ -1,12 +1,17 @@ #!/usr/bin/perl -# nagios plugin format: exit 0,1,2,3 for OK, WARN, CRITICAL, or ERROR. - -# check_all_space_avail - test space available on all ZFS filesystems on host -# different values for pools named "backup" and other pools: +# This is a Nagios-compatible script which checks all mounted filesystems--not just ZFS filesystems--to see +# if any are running dangerously low on space. It's generally bright enough to avoid weird mounts where +# free space checks don't apply, eg dev, tmpfs, CD or DVDs, and so forth. # -# default: warn 93%, crit 98% +# usage: +# check_all_disk_space [warnlevel] [critlevel] +# +# example: +# root@banshee:~/check_all_disk_space 80 90 +# OK +# default levels: warn if a filesystem is 93% full, crit if it's 98% full my $warnlevel = .93; my $critlevel = .98; @@ -48,6 +53,8 @@ foreach my $fs (@filesystems) { $msg =~ s/, $//; $msg .= "\n"; +# nagios plugin format: exit 0,1,2,3 for OK, WARN, CRITICAL, or ERROR. + if ($critfound) { print "CRITICAL: $msg"; exit 2; @@ -62,6 +69,5 @@ if ($critfound) { exit 0; } - print "ERROR: $msg ?"; exit 3; From 74b61d149f9e6aaec48fb7d2ba84594f1df59880 Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Mon, 19 Jan 2026 23:51:15 -0500 Subject: [PATCH 10/13] Enhance disk space check script functionality Updated the script to accept warning and critical levels as decimal arguments. Added support for excluding 'squashfs' filesystems from the df command output. --- check_all_disk_space | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/check_all_disk_space b/check_all_disk_space index 33b3f33..ca25790 100644 --- a/check_all_disk_space +++ b/check_all_disk_space @@ -12,10 +12,12 @@ # OK # default levels: warn if a filesystem is 93% full, crit if it's 98% full +# default: warn 93%, crit 98% + my $warnlevel = .93; my $critlevel = .98; -# accept warnlevel and critlevel as arguments if passed +# accept warnlevel and critlevel as arguments if passed. Must be passed as decimals, eg 0.4 for 40% if (defined $ARGV[0] && defined $ARGV[1] && $ARGV[0] >=0 && $ARGV[0] <=1 && $ARGV[1] >=0 && $ARGV[1] <=1) { $warnlevel = $ARGV[0]; $critlevel = $ARGV[1]; @@ -26,7 +28,7 @@ my $msg,$warnfound,$critfound,$errfound; # get standard df output, but skip the tmpfs and devtmpfs crap - this should leave us with # nothing but disks. we WILL also get nfs or other network filesystems here, since we # didn't use the -l flag. Feature, not bug. also skip UDF so we don't check free space on CDs! -my @filesystems = `/bin/df -x tmpfs -x devtmpfs -x udf`; +my @filesystems = `/bin/df -x tmpfs -x devtmpfs -x udf -x squashfs`; # get rid of header line shift @filesystems; @@ -47,14 +49,12 @@ foreach my $fs (@filesystems) { } elsif ($calcpercent < 0 || $calcpercent > 1) { $errfound = 1; $msg .= "$mounted: $prettypercent (WTF?), "; - } + } } $msg =~ s/, $//; $msg .= "\n"; -# nagios plugin format: exit 0,1,2,3 for OK, WARN, CRITICAL, or ERROR. - if ($critfound) { print "CRITICAL: $msg"; exit 2; @@ -69,5 +69,6 @@ if ($critfound) { exit 0; } + print "ERROR: $msg ?"; exit 3; From 89d3cbcda381f3ddbceea66913b7d7a62af42841 Mon Sep 17 00:00:00 2001 From: Ifaz Kabir Date: Tue, 17 Feb 2026 10:37:04 -0500 Subject: [PATCH 11/13] Fix bookmark last snapshot sync early exit --- syncoid | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/syncoid b/syncoid index 680afbe..fb8aa26 100755 --- a/syncoid +++ b/syncoid @@ -726,11 +726,8 @@ sub syncdataset { # do a normal replication if bookmarks aren't used or if previous # bookmark replication was only done to the next oldest snapshot - if (!$bookmark || $nextsnapshot) { - if ($matchingsnap eq $newsyncsnap) { - # edge case: bookmark replication used the latest snapshot - return 0; - } + # edge case: skip repilcation if bookmark replication used the latest snapshot + if ((!$bookmark || $nextsnapshot) && !($matchingsnap eq $newsyncsnap)) { ($exit, $stdout) = syncincremental($sourcehost, $sourcefs, $targethost, $targetfs, $matchingsnap, $newsyncsnap, defined($args{'no-stream'})); From d8ff385691143ed3e4bfe8baba5119b14b48e9d4 Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Tue, 17 Feb 2026 11:53:42 -0500 Subject: [PATCH 12/13] Change comparison from '==' to 'ne' for error checks Zpool status reports error counts with unit suffixes after the first 999 errors in any given column; as originally written, the monitor-health plugin used strictly numeric comparison checks which would error out when encountering a value like "1.09K" for checksum errors. --- sanoid | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sanoid b/sanoid index 8e0d186..a5591b9 100755 --- a/sanoid +++ b/sanoid @@ -1375,9 +1375,9 @@ sub check_zpool() { # check for io/checksum errors my @vdeverr = (); - if ($read != 0) { push @vdeverr, "read" }; - if ($write != 0) { push @vdeverr, "write" }; - if ($cksum != 0) { push @vdeverr, "cksum" }; + if ($read ne 0) { push @vdeverr, "read" }; + if ($write ne 0) { push @vdeverr, "write" }; + if ($cksum ne 0) { push @vdeverr, "cksum" }; if (scalar @vdeverr) { $dmge=$dmge . "(" . $dev . ":" . join(", ", @vdeverr) . " errors) "; From 1ae8f26e825c5c222fabf54131c158411885e1c1 Mon Sep 17 00:00:00 2001 From: Jim Salter Date: Wed, 18 Feb 2026 00:19:37 -0500 Subject: [PATCH 13/13] avoid bug with snapshots named 0 Updated error handling to check for empty string instead of false for snapshot retrieval. --- syncoid | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/syncoid b/syncoid index fb8aa26..8c9c2f2 100755 --- a/syncoid +++ b/syncoid @@ -431,7 +431,7 @@ sub syncdataset { if (!defined $args{'no-sync-snap'} && !defined $skipsnapshot) { # create a new syncoid snapshot on the source filesystem. $newsyncsnap = newsyncsnap($sourcehost,$sourcefs,$sourceisroot); - if (!$newsyncsnap) { + if ($newsyncsnap eq '') { # we already whined about the error return 0; } @@ -439,7 +439,7 @@ sub syncdataset { # --include-snaps if (!snapisincluded($newsyncsnap)) { $newsyncsnap = getnewestsnapshot($sourcehost,$sourcefs,$sourceisroot); - if ($newsyncsnap eq 0) { + if ($newsyncsnap eq '') { writelog('WARN', "CRITICAL: no snapshots exist on source $sourcefs, and you asked for --no-sync-snap."); if ($exitcode < 1) { $exitcode = 1; } return 0; @@ -448,7 +448,7 @@ sub syncdataset { } else { # we don't want sync snapshots created, so use the newest snapshot we can find. $newsyncsnap = getnewestsnapshot($sourcehost,$sourcefs,$sourceisroot); - if ($newsyncsnap eq 0) { + if ($newsyncsnap eq '') { writelog('WARN', "CRITICAL: no snapshots exist on source $sourcefs, and you asked for --no-sync-snap."); if ($exitcode < 1) { $exitcode = 1; } return 0; @@ -476,13 +476,13 @@ sub syncdataset { writelog('DEBUG', "target $targetfs does not exist, and --no-stream selected. Finding newest available snapshot on source $sourcefs ..."); } my $oldestsnap = getoldestsnapshot(\%snaps); - if (! $oldestsnap) { + if ($oldestsnap eq '') { if (defined ($args{'no-sync-snap'}) ) { # we already whined about the missing snapshots return 0; } - # getoldestsnapshot() returned false, so use new sync snapshot + # getoldestsnapshot() returned null, so use new sync snapshot writelog('DEBUG', "getoldestsnapshot() returned false, so using $newsyncsnap."); $oldestsnap = $newsyncsnap; } @@ -1538,7 +1538,7 @@ sub getoldestsnapshot { # well, actually we set --no-sync-snap, so no we *didn't* already make one. Whoops. writelog('CRITICAL', "--no-sync-snap is set, and getoldestsnapshot() could not find any snapshots on source!"); } - return 0; + return ''; } sub getnewestsnapshot { @@ -1560,7 +1560,7 @@ sub getnewestsnapshot { writelog('WARN', "--no-sync-snap is set, and getnewestsnapshot() could not find any snapshots on source for current dataset. Continuing."); if ($exitcode < 2) { $exitcode = 2; } } - return 0; + return ''; } sub buildsynccmd {