diff --git a/zfs_send.zsh b/zfs_send.zsh index b4df0c9..05db978 100755 --- a/zfs_send.zsh +++ b/zfs_send.zsh @@ -210,6 +210,19 @@ local_datasets=(${=local_datasets}) # Конвертирование в масс backup_datasets=$(ssh $backup_user@$backup_server zfs list -o name | grep -v -e ix-app -e boot-pool -e system-data -e jails -e NAME) backup_datasets=(${=backup_datasets}) # Конвертирование в массив +# Свободное место на бэкап-сервере +declare -A backup_pool_free # ассоциативный массив: ключ = пул, значение = свободное место +backup_pool_free=() +ignored_pools=(boot-pool) +# Запрашиваем данные и парсим +while read -r pool free; do + if (( ${ignored_pools[(Ie)$pool]} )); then + continue + fi + backup_pool_free[$pool]="$free" +done < <(ssh "$backup_user@$backup_server" "zpool list -H -o name,free" 2>/dev/null) + + declare -A work_datasets # Словарь ключ = резервируемый локальный датасет, значение = имя датасета на удалённом сервере # Если заданы local_dataset & remote_dataset @@ -327,23 +340,60 @@ done # --------- Запрашиваем подтверждение пользователя ---------- -echo "" -echo "Список резервируемых датасетов:" -column_widths="%-4s %-35s %-20s -> %-35s\n" +estimate_changes_bytes() { + local loc_ds="$1" + local base_snap="$2" + local value + if [[ -z "$base_snap" ]]; then + # Полный бэкап → used в байтах + value=$(zfs get -H -p -o value used "$loc_ds" 2>/dev/null) + else + # Инкремент → written@ в байтах + value=$(zfs get -H -p -o value "written@$base_snap" "$loc_ds" 2>/dev/null) + fi + # Если ошибка — вернуть 0 + echo ${value:-0} +} + +echo +echo "Список резервируемых датасетов:" +column_widths="%-4s %-35s %-20s -> %-35s %10s\n" +printf "$column_widths" "#" "Локальный датасет" "Базовый снапшот" "Бэкап-датасет" "Изменения" +total_bytes=0 if [[ $incremental = true ]]; then i=0; for loc_ds bak_ds in ${(kv)work_datasets}; do (( i++ )) - printf $column_widths $i $loc_ds "${last_loc_snaps[$loc_ds]}" $bak_ds + bytes=$(estimate_changes_bytes "$loc_ds" "${last_loc_snaps[$loc_ds]}") + (( total_bytes += bytes )) + human_size=$(numfmt --to=iec --format="%.1f" "$bytes" 2>/dev/null || echo "${bytes}B") + printf $column_widths $i $loc_ds "${last_loc_snaps[$loc_ds]}" $bak_ds $human_size done printf "%-4s %-35s %-20s\n" "" "Инкрементный снимок:" "$inc_snapshot (*)" else i=0; for loc_ds bak_ds in ${(kv)work_datasets}; do (( i++ )) - printf $column_widths $i $loc_ds "$inc_snapshot (*)" "$bak_ds (*)" + bytes=$(estimate_changes_bytes "$loc_ds" "") + (( total_bytes += bytes )) + human_size=$(numfmt --to=iec --format="%.1f" "$bytes" 2>/dev/null || echo "${bytes}B") + printf $column_widths $i $loc_ds "$inc_snapshot (*)" "$bak_ds (*)" "$human_size" done fi +# Итоговая сумма +total_human=$(numfmt --to=iec --format="%.2f" "$total_bytes" 2>/dev/null || echo "${total_bytes}B") +echo +echo "Общий объём изменений: $total_human" +echo + +echo "Свободное место на пулах бэкап-сервера:" +# Сортируем по имени пула (опционально) +for pool in ${(ko)backup_pool_free}; do + printf " %-20s : %s\n" "$pool" "${backup_pool_free[$pool]}" +done +echo + + # --------- Выбор датасетов ---------- if [[ $check = true ]]; then