Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion contrib/manual-zfssync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
# - MANUAL_ZFSSYNC_OVERWRITE_NEWER_SNAPSHOTS=1

ssh_target="$1"; shift # remotebackup@DEST
REMOTE_CMD="/usr/bin/ssh -oLogLevel=error $ssh_target" # options?
REMOTE_CMD_OPTIONS=
if test -n "${SSH_CONTROL_PATH:-}"; then
REMOTE_CMD_OPTIONS="-oControlMaster=no -oControlPath=$SSH_CONTROL_PATH "
fi
REMOTE_CMD="/usr/bin/ssh -oLogLevel=error ${REMOTE_CMD_OPTIONS}${ssh_target}"

LOCAL_PREFIX="$1"; shift # "tank" both local and remote
REMOTE_PREFIX="$LOCAL_PREFIX"
Expand Down
29 changes: 29 additions & 0 deletions contrib/planb-double-backup
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,35 @@ RESTART_EVERY=${3:-0}
test -z "$USERATHOST" -o -z "$DESTPOOL" &&
echo "usage: $0 user@host destpool [restartsec]" >&2 && exit 1

# Multiplexing ssh connections: one master TCP/login for the whole run, so the
# many zfs-list/snapshot/send calls in manual-zfssync.sh don't require
# separate logins (slow and log-spammy).
# WARNING: Cannot contain spaces or awkward shell characters.
SSH_MUX_DIR=$(mktemp -d "${TMPDIR:-/tmp}/planb-ssh.XXXXXX")
SSH_CONTROL_PATH="$SSH_MUX_DIR/ctl"
export SSH_CONTROL_PATH

start_master() {
ssh -oLogLevel=error -oControlMaster=yes \
-oControlPath="$SSH_CONTROL_PATH" \
-oControlPersist=60 -oServerAliveInterval=60 -oServerAliveCountMax=3 \
-oBatchMode=yes -N -f "$USERATHOST"
}
stop_master() {
ssh -oControlPath="$SSH_CONTROL_PATH" -O exit "$USERATHOST" 2>/dev/null ||
true
}
cleanup() {
stop_master
rm -rf "$SSH_MUX_DIR"
}
trap 'cleanup' EXIT
trap 'cleanup; trap - INT; kill -INT $$' INT
trap 'cleanup; trap - TERM; kill -TERM $$' TERM


while true; do
start_master
ret=0
DATASETS=$("$here/planb-double-backup-sources.py" "$USERATHOST") || ret=$?

Expand All @@ -35,6 +63,7 @@ while true; do
echo

"$here/manual-zfssync.sh" "$USERATHOST" "$DESTPOOL" $DATASETS
stop_master

# The zfssync wipes this trigger. Re-set it.
if test $ret -eq 2 -a -f /etc/zabbix/zabbix_agentd.conf; then
Expand Down
9 changes: 8 additions & 1 deletion contrib/planb-double-backup-sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Right now:
# - assuming you're running this as root
# - remote has planb access
import os
import sys

from argparse import ArgumentParser
Expand Down Expand Up @@ -62,8 +63,14 @@ def __iter__(self):


def get_server_datasets(server):
ssh_opts = ['-oLogLevel=error']
if os.environ.get('SSH_CONTROL_PATH'):
ssh_opts.extend([
'-oControlMaster=no',
'-oControlPath={}'.format(os.environ['SSH_CONTROL_PATH']),
])
return check_output(
['ssh', server, '-oLogLevel=error', 'planb', 'blist', '--double'],
['ssh'] + ssh_opts + [server, 'planb', 'blist', '--double'],
text=True).splitlines()


Expand Down
32 changes: 27 additions & 5 deletions contrib/planb-zfssync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ if test "$contains" != "filesystems"; then
sudo zfs set planb:contains=filesystems "$planb_storage_name"
fi

target_snapshot=$planb_snapshot_target
target_snapshot_prefix=${planb_snapshot_target%-*}
# XXX: do we?
test "$target_snapshot_prefix" = "planb" # (not needed, we use planb:owner)


ssh_target="$1"; shift # remotebackup@DEST (options like -luser disallowed)
# XXX: todo: sanitize $1? (no spaces, no funny chars)
Expand All @@ -114,16 +119,19 @@ else
ssh_options="$ssh_options -o StrictHostKeyChecking=no"
fi

target_snapshot=$planb_snapshot_target
target_snapshot_prefix=${planb_snapshot_target%-*}
# XXX: do we?
test "$target_snapshot_prefix" = "planb" # (not needed, we use planb:owner)
# Multiplexing ssh connections: one master TCP/login for the whole run, so the
# many zfs-list/snapshot/send calls below don't require separate logins (slow
# and log-spammy).
# WARNING: Cannot contain spaces or awkward shell characters. It's our
# job to clean up ssh_mux_dir now.
ssh_mux_dir=$(mktemp -d "${TMPDIR:-/tmp}/planb-ssh.XXXXXX")
ssh_control_path="$ssh_mux_dir/ctl"

# Prepare globals, so we know what to refactor
ZFS_SEND_OPTION=$zfs_send_option
ZFS_RECV_OPTION=$zfs_recv_option
ZFS_RECURSIVE=$zfs_recursive
SSH_OPTIONS=$ssh_options
SSH_OPTIONS="$ssh_options -o ControlMaster=no -o ControlPath=$ssh_control_path"
SSH_TARGET=$ssh_target
TARGET_SNAPSHOT=$target_snapshot
TARGET_SNAPSHOT_PREFIX=$target_snapshot_prefix
Expand Down Expand Up @@ -281,6 +289,20 @@ prune_remote_snapshots() {
}


# Setup cleanup handler and start master ssh connection.
stop_ssh() {
ssh -o ControlPath="$ssh_control_path" -O exit "$ssh_target" 2>/dev/null \
|| true
rm -rf "$ssh_mux_dir"
}
trap 'stop_ssh' EXIT
trap 'stop_ssh; trap - INT; kill -INT $$' INT
trap 'stop_ssh; trap - TERM; kill -TERM $$' TERM
ssh -o LogLevel=error $ssh_options \
-o ControlMaster=yes -o ControlPath=$ssh_control_path \
-o ControlPersist=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 \
-o BatchMode=yes -N -f "$ssh_target"

# Download snapshots (make them on remote if necessary).
for arg in "$@"; do
process_zfssync_arg download_snapshot "$arg"
Expand Down
Loading