From b98d7877fc225e8719f860ea16fca9627bd0b8d2 Mon Sep 17 00:00:00 2001 From: Tero Date: Tue, 1 Sep 2026 23:59:40 +0300 Subject: [PATCH] Ass ability to move all datasets --- README.md | 19 ++++++++++--------- zfs-move-over-ssh.sh | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 2cc893a..3d123a8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # ZFS Move Over SSH -`zfs-move-over-ssh.sh` snapshots every ZFS filesystem at and beneath a source -dataset, then sends each snapshot to a remote ZFS server over SSH. +`zfs-move-over-ssh.sh` snapshots every ZFS filesystem in a source pool, then +sends each snapshot to a remote ZFS server over SSH. A vdev is the underlying +storage device; ZFS filesystems belong to a pool, so pass the pool name. For a source tree such as: @@ -36,13 +37,13 @@ incremental sends or resume tokens. ## Usage ```bash -bash zfs-move-over-ssh.sh [options] SOURCE_ROOT REMOTE_HOST DESTINATION_ROOT +bash zfs-move-over-ssh.sh [options] SOURCE_POOL REMOTE_HOST DESTINATION_ROOT ``` Example: ```bash -bash zfs-move-over-ssh.sh tank/data root@new-server backup/data +bash zfs-move-over-ssh.sh tank root@new-server backup/tank ``` Use a non-standard SSH key or port when needed: @@ -51,7 +52,7 @@ Use a non-standard SSH key or port when needed: bash zfs-move-over-ssh.sh \ --identity-file ~/.ssh/zfs-migration \ --ssh-port 2222 \ - tank/data admin@new-server backup/data + tank admin@new-server backup/tank ``` Options: @@ -69,7 +70,7 @@ Options: 1. Confirm the source datasets: ```bash - zfs list -r tank/data + zfs list -r tank ``` 2. Confirm remote privileged ZFS access: @@ -81,19 +82,19 @@ Options: 3. Preview the operation. Review every destination name in the output: ```bash - bash zfs-move-over-ssh.sh --dry-run tank/data admin@new-server backup/data + bash zfs-move-over-ssh.sh --dry-run tank admin@new-server backup/tank ``` 4. Run the migration: ```bash - bash zfs-move-over-ssh.sh tank/data admin@new-server backup/data + bash zfs-move-over-ssh.sh tank admin@new-server backup/tank ``` 5. Verify the received datasets and data before retiring the source: ```bash - ssh admin@new-server 'sudo zfs list -r backup/data' + ssh admin@new-server 'sudo zfs list -r backup/tank' ``` ## Safety and Recovery diff --git a/zfs-move-over-ssh.sh b/zfs-move-over-ssh.sh index 5c15436..e31bdc2 100644 --- a/zfs-move-over-ssh.sh +++ b/zfs-move-over-ssh.sh @@ -5,13 +5,13 @@ set -Eeuo pipefail usage() { cat <<'EOF' -Usage: zfs-move-over-ssh.sh [options] SOURCE_ROOT REMOTE_HOST DESTINATION_ROOT +Usage: zfs-move-over-ssh.sh [options] SOURCE_POOL REMOTE_HOST DESTINATION_ROOT -Create one snapshot for every filesystem under SOURCE_ROOT and send each one -over SSH. Filesystems retain their relative paths below DESTINATION_ROOT. +Create one snapshot for every filesystem in SOURCE_POOL and send each one over +SSH. Filesystems retain their relative paths below DESTINATION_ROOT. Arguments: - SOURCE_ROOT Source ZFS filesystem, for example: tank/data + SOURCE_POOL Source ZFS pool, for example: tank REMOTE_HOST SSH host, optionally user@host DESTINATION_ROOT Existing or new destination ZFS filesystem, for example: backup/data @@ -77,14 +77,15 @@ done exit 2 } -SOURCE_ROOT="$1" +SOURCE_POOL="$1" REMOTE_HOST="$2" DESTINATION_ROOT="${3%/}" SNAPSHOT_NAME="move-$(date +%Y%m%d-%H%M%S)" command -v zfs >/dev/null || die "zfs command was not found" +command -v zpool >/dev/null || die "zpool command was not found" command -v ssh >/dev/null || die "ssh command was not found" -zfs list -H -o name -t filesystem "$SOURCE_ROOT" >/dev/null || die "source filesystem does not exist: $SOURCE_ROOT" +zpool list -H -o name "$SOURCE_POOL" >/dev/null || die "source pool does not exist: $SOURCE_POOL" if ! $DRY_RUN; then ssh "${SSH_OPTIONS[@]}" "$REMOTE_HOST" 'sudo -n zfs list -H -o name -t filesystem >/dev/null' \ @@ -93,7 +94,7 @@ fi map_destination() { local filesystem="$1" - local relative_path="${filesystem#"$SOURCE_ROOT"}" + local relative_path="${filesystem#"$SOURCE_POOL"}" printf '%s%s\n' "$DESTINATION_ROOT" "$relative_path" } @@ -107,8 +108,8 @@ run() { fi } -mapfile -t FILESYSTEMS < <(zfs list -H -o name -t filesystem -r "$SOURCE_ROOT") -((${#FILESYSTEMS[@]} > 0)) || die "no filesystems found below $SOURCE_ROOT" +mapfile -t FILESYSTEMS < <(zfs list -H -o name -t filesystem -r "$SOURCE_POOL") +((${#FILESYSTEMS[@]} > 0)) || die "no filesystems found in $SOURCE_POOL" printf 'Migration snapshot: %s\n' "$SNAPSHOT_NAME" for filesystem in "${FILESYSTEMS[@]}"; do