diff --git a/README.org b/README.org index 5587aae..099a8ca 100644 --- a/README.org +++ b/README.org @@ -1,5 +1,5 @@ ** Overview - zap automates the management of zfs snapshots. With a few crontab entries, it can be used to create a comprehensive zfs backup system. There are no configuration files. All parameters are supplied on the command line or in zfs properties and all snapshot information is stored in snapshot names. + zap automates the management of zfs snapshots. With a few crontab entries, it can be used to create a comprehensive zfs backup system. There are no configuration files. Parameters are supplied on the command line or in zfs properties and all snapshot information is stored in snapshot names. zap will not interfere with manually created snapshots or snapshots from other tools. It will only operate on snapshots it creates. @@ -37,10 +37,10 @@ #+BEGIN_SRC sh # zap rep zap@bravo:rback/phe -r zroot/ROOT zroot/usr/home/jrm #+END_SRC - Replicate datasets that originated from the host awarnach to the remote host bravo, under the zback/phe dataset. If you use a non-default ssh port, specify it in =~/.ssh/config=. + Replicate datasets that originated from the host awarnach to the remote host bravo, under the zback/phe dataset. If you use a non-default ssh port, specify it in =~/.ssh/config=. Filter the transfer through =~mbuffer~= by setting the =~ZAP_FILTER~= environment variable. Note that =~mbuffer~= must be installed on both the sending and receiving hosts. #+BEGIN_SRC sh # zfs set zap:rep='zap@bravo:zback/phe' zroot/ROOT zroot/usr/home/jrm - # zap rep -v -h awarnach + # ZAP_FILTER="mbuffer -s 128k -m 10M" zap rep -v -h awarnach #+END_SRC Destroy expired snapshots. Be verbose. #+BEGIN_SRC sh @@ -83,7 +83,7 @@ =rep= | =replicate= - Use the =rep= subcommand to replicate datasets. If a destination and datasets are not supplied on the command line, datasets with a destination set in the =zap:rep= user property are replicated. If the destination does not contain a =host=, or if the supplied host is one of =localhost=, =127.x.x.x=, or =::1=, then any =user@= is ignored and =ssh= is not be used. If the =canmount= property of the local dataset is set to =on=, after replication an attempt is made to set =canmount= to =noauto= on the remote side. This is done to prevent mountpoint collisions. + Use the =rep= subcommand to replicate datasets. If a destination and datasets are not supplied on the command line, datasets with a destination set in the =zap:rep= user property are replicated. If the destination does not contain a =host=, or if the supplied host is one of =localhost=, =127.x.x.x=, or =::1=, then any =user@= is ignored and =ssh= is not be used. If the =canmount= property of the local dataset is set to =on=, after replication an attempt is made to set =canmount= to =noauto= on the remote side. This is done to prevent mountpoint collisions. Set the =~ZAP_FILTER~= environment variable to a command to filter the transfer. For example, =~ZAP_FILTER="mbuffer -s 128k -m 10M"~= will filter the transfer through =~mbuffer~=. Note that the filter command must be installed on both the sending and receiving hosts. =destroy= diff --git a/zap b/zap index 898f6bb..e898901 100755 --- a/zap +++ b/zap @@ -352,11 +352,12 @@ rep_full() { else warn "Failed to replicate $lsnap to $sshto:$rloc" fi else # replicating remotely - [ -n "$v_opt" ] && \ - echo "zfs send -Lep $C_opt $lsnap | ssh $sshto \"sh -c 'zfs recv -Fu \ -$v_opt -d $rloc'\"" - if zfs send -Lep $C_opt "$lsnap" | \ - ssh "$sshto" "sh -c 'zfs recv -Fu $v_opt -d $rloc'"; then + if [ -n "$v_opt" ]; then + echo -n "zfs send -Lep $C_opt $lsnap " + if [ -n "$ZAP_FILTER" ]; then echo "| $ZAP_FILTER "; fi + echo "| ssh $sshto \"sh -c 'zfs recv -Fu $v_opt -d $rloc'\"" + fi + if rsend "-Lep $C_opt $lsnap" "zfs recv -Fu $v_opt -d $rloc'"; then [ -n "$v_opt" ] && \ echo "zfs bookmark $lsnap $(echo "$lsnap" | sed 's/@/#/')" zfs bookmark "$lsnap" "$(echo "$lsnap" | sed 's/@/#/')" @@ -419,11 +420,12 @@ $rloc" else warn "Failed to replicate $lsnap to $sshto:$rloc." fi else # replicate remotely - [ -n "$v_opt" ] && \ - echo "zfs send -Le $C_opt $i $sp $lsnap | ssh $sshto \"sh -c \ -'zfs recv -du $F_opt $v_opt $rloc'\"" - if zfs send -Le $C_opt $i "$sp" "$lsnap" | \ - ssh "$sshto" "sh -c 'zfs recv -du $F_opt $v_opt $rloc'"; then + if [ -n "$v_opt" ]; then + echo -n "zfs send -Le $C_opt $i $sp $lsnap " + if [ -n "$ZAP_FILTER" ]; then echo -n "| $ZAP_FILTER "; fi + echo "| ssh $sshto \"sh -c 'zfs recv -du $F_opt $v_opt $rloc'\"" + fi + if rsend "-Le $C_opt $i $sp $lsnap" "zfs recv -du $F_opt $v_opt $rloc"; then [ -n "$v_opt" ] && \ echo "zfs bookmark $lsnap $(echo "$lsnap" | sed 's/@/#/')" if zfs bookmark "$lsnap" "$(echo "$lsnap" | sed 's/@/#/')"; then @@ -484,6 +486,14 @@ $sshto:$rloc/$fs was not created by zap." fi } +rsend() { + if [ -n "$ZAP_FILTER" ]; then + zfs send $1 | $ZAP_FILTER | ssh "$sshto" "sh -c '$ZAP_FILTER | $2'" + else + zfs send $1 | ssh "$sshto" "sh -c '$2'" + fi +} + # snap_parse [-DLSv] TTL [[-r] dataset [[-r] dataset]...] snap_parse () { while getopts ":DLSv" opt; do diff --git a/zap.1 b/zap.1 index cacec9f..9e94e35 100644 --- a/zap.1 +++ b/zap.1 @@ -1,4 +1,4 @@ -.Dd May 9, 2021 +.Dd June 14, 2021 .Dt ZAP 1 .Os .Sh NAME @@ -101,6 +101,11 @@ snapshots originating from the local host (as returned by .Ic -h host can be used to replicate snapshots originating from .Ic host Ns . +Set the ZAP_FILTER environment variable to a command to filter the transfer. +For example, ZAP_FILTER="mbuffer -s 128k -m 10M" will filter the transfer +through mbuffer. +Note that the filter command must be available on both the sending and receiving +hosts. .Pp .Ss Ar destroy Use the @@ -161,6 +166,17 @@ Recursively create or replicate snapshots of all descendants. .It Fl v Be verbose. .El +.Sh ENVIRONMENT +The following environment variable affects the execution of +.Nm : +.Bl -tag -width ".Ev CLICOLOR_FORCE" +.It Ev ZAP_FILTER +Filter +.Ar rep +through the command contained in the variable. For example, a value of "mbuffer +-s 128k -m 10M" will filter the transfer through mbuffer. Note that the filter +command must be available on both the sending and receiving hosts. +.El .Sh EXAMPLES Create snapshots that will expire after three weeks. .Bd -literal -offset indent @@ -196,7 +212,9 @@ zap rep zap@bravo:rback/phe -r zroot/ROOT zroot/usr/home/jrm .Pp Replicate datasets originating from awarnach to the remote host bravo, under the zback/phe dataset. If you use a non-default ssh port, specify it in -~/.ssh/config. +~/.ssh/config. Filter the transfer through mbuffer by setting the ZAP_FILTER +environment variable. Note that mbuffer must be available on both the sending +and receiving hosts. .Bd -literal -offset indent zfs set zap:rep='zap@bravo:zback/phe' zroot/ROOT zroot/usr/home/jrm zap rep -v -h awarnach @@ -245,6 +263,8 @@ disks, so only do it every 24 hours. .It An David Samms Mt dsamms@nw-ds.com .It An Victor Naumov Mt vicnaumov@gmail.com .It An Dries Michiels Mt driesm.michiels@gmail.com +.It An Louis Kowolowski Mt louisk@cryptomonkeys.org +.It An Maxime Soul\('e .El .Sh BUGS .Lk http://github.com/jehops/zap/issues Issue tracker