From 8877f9871fc113b05783f3f4bdf5ee8c691b86b3 Mon Sep 17 00:00:00 2001 From: jcastro <190036+jcastro@users.noreply.github.com> Date: Thu, 14 May 2026 06:45:59 +0200 Subject: [PATCH] Enable ZFS autotrim in auto post-install --- scripts/menus/menu_post_install.sh | 1 + scripts/post_install/auto_post_install.sh | 110 +++++++++++++++++++++- scripts/post_install/uninstall-tools.sh | 40 +++++++- 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/scripts/menus/menu_post_install.sh b/scripts/menus/menu_post_install.sh index a0e6165b..62b30b15 100644 --- a/scripts/menus/menu_post_install.sh +++ b/scripts/menus/menu_post_install.sh @@ -60,6 +60,7 @@ confirm_automated_script() { script_info+="• $(translate "Optionally remove") \Z4subscription banner\Z0 $(translate "from Proxmox web interface (you will be asked)")\n" script_info+="• $(translate "Optimize") \Z4memory\Z0, \Z4kernel\Z0, $(translate "and") \Z4network\Z0 $(translate "for better performance and stability")\n" script_info+="• $(translate "Install and configure") \Z4Log2RAM\Z0 $(translate "(only on SSD/NVMe) to protect your disk")\n" + script_info+="• $(translate "Enable") \Z4ZFS autotrim\Z0 $(translate "on SSD/NVMe pools that support discard")\n" script_info+="• $(translate "Improve log rotation and limit log size to save space and extend disk life")\n" script_info+="• $(translate "Increase file and process limits for advanced workloads")\n" script_info+="• $(translate "Set up time synchronization and entropy generation")\n" diff --git a/scripts/post_install/auto_post_install.sh b/scripts/post_install/auto_post_install.sh index 4efae937..57762a4a 100644 --- a/scripts/post_install/auto_post_install.sh +++ b/scripts/post_install/auto_post_install.sh @@ -9,7 +9,7 @@ # Version : 1.0 # ========================================================== # Description: -# Applies a curated set of 13 safe optimizations to a fresh +# Applies a curated set of 14 safe optimizations to a fresh # Proxmox VE host without prompts. Every change is registered # in installed_tools.json so it can be reversed later from the # Uninstall Optimizations menu. @@ -18,7 +18,8 @@ # - Zero-interaction baseline: repos, upgrade, banner, APT # IPv4, skip translations, kernel limits, memory tuning, # kernel-panic behaviour, network stack tuning, bashrc, -# Log2RAM (SSD-aware), journald, logrotate, persistent NIC names. +# Log2RAM (SSD-aware), ZFS autotrim, journald, logrotate, +# persistent NIC names. # - Hardware-aware: auto-detects SSD/NVMe for Log2RAM and sizes # its ramdisk according to host RAM (128M/256M/512M). # - Registration: tracks each tool in installed_tools.json. @@ -829,6 +830,108 @@ EOF } +# ========================================================== +enable_zfs_autotrim() { + local FUNC_VERSION="1.0" + # description: Enable ZFS autotrim on detected pools and record only pools changed by ProxMenux. + local state_file="$BASE_DIR/zfs_autotrim_pools" + local tmp_file="${state_file}.tmp" + local pools=() + local pool current + local changed=false + + pool_supports_autotrim() { + local pool_name="$1" + local vdev dev_path block_device rotational discard_granularity + local found_device=false + + while read -r vdev; do + [[ -z "$vdev" ]] && continue + found_device=true + + dev_path=$(readlink -f "$vdev" 2>/dev/null || true) + if [[ -z "$dev_path" || ! -b "$dev_path" ]]; then + return 1 + fi + + block_device=$(lsblk -no PKNAME "$dev_path" 2>/dev/null | head -n1) + [[ -z "$block_device" ]] && block_device=$(basename "$dev_path") + + rotational=$(cat "/sys/block/$block_device/queue/rotational" 2>/dev/null || true) + discard_granularity=$(cat "/sys/block/$block_device/queue/discard_granularity" 2>/dev/null || true) + + if [[ "$rotational" != "0" || -z "$discard_granularity" || "$discard_granularity" == "0" ]]; then + return 1 + fi + done < <( + zpool status -P "$pool_name" 2>/dev/null | + awk ' + $1 == "NAME" { in_config=1; next } + in_config && $1 == "errors:" { exit } + in_config && $1 ~ /^\// && $2 ~ /^(ONLINE|DEGRADED|FAULTED|OFFLINE|UNAVAIL|REMOVED)$/ { print $1 } + ' + ) + + [[ "$found_device" == true ]] + } + + if ! command -v zpool >/dev/null 2>&1; then + msg_info2 "$(translate "ZFS not detected. Skipping ZFS autotrim.")" + return 0 + fi + + mapfile -t pools < <(zpool list -H -o name 2>/dev/null) + if [[ ${#pools[@]} -eq 0 ]]; then + msg_info2 "$(translate "No ZFS pools detected. Skipping ZFS autotrim.")" + return 0 + fi + + msg_info "$(translate "Checking ZFS autotrim configuration...")" + mkdir -p "$BASE_DIR" + : > "$tmp_file" + + for pool in "${pools[@]}"; do + current=$(zpool get -H -o value autotrim "$pool" 2>/dev/null || true) + + if [[ "$current" == "on" ]]; then + msg_ok "$(translate "ZFS autotrim already enabled for pool:") $pool" + continue + fi + + if [[ "$current" != "off" ]]; then + msg_warn "$(translate "ZFS autotrim is not supported for pool:") $pool" + continue + fi + + if ! pool_supports_autotrim "$pool"; then + msg_info2 "$(translate "Pool does not appear to use SSD/NVMe devices with discard support. Skipping ZFS autotrim for pool:") $pool" + continue + fi + + if zpool set autotrim=on "$pool" >/dev/null 2>&1; then + printf '%s\n' "$pool" >> "$tmp_file" + changed=true + msg_ok "$(translate "ZFS autotrim enabled for pool:") $pool" + else + msg_warn "$(translate "Failed to enable ZFS autotrim for pool:") $pool" + fi + done + + if [[ "$changed" == true ]]; then + if [[ -s "$state_file" ]]; then + sort -u "$state_file" "$tmp_file" > "${tmp_file}.merged" + mv "${tmp_file}.merged" "$state_file" + rm -f "$tmp_file" + else + mv "$tmp_file" "$state_file" + fi + register_tool "zfs_autotrim" true "$FUNC_VERSION" + else + rm -f "$tmp_file" + fi +} + + @@ -923,6 +1026,7 @@ run_complete_optimization() { #disable_rpc customize_bashrc install_log2ram_auto + enable_zfs_autotrim optimize_journald optimize_logrotate setup_persistent_network @@ -960,4 +1064,4 @@ run_complete_optimization() { check_extremeshok_warning if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then run_complete_optimization -fi \ No newline at end of file +fi diff --git a/scripts/post_install/uninstall-tools.sh b/scripts/post_install/uninstall-tools.sh index 7d879042..840f5f4a 100644 --- a/scripts/post_install/uninstall-tools.sh +++ b/scripts/post_install/uninstall-tools.sh @@ -915,6 +915,43 @@ uninstall_zfs_auto_snapshot() { register_tool "zfs_auto_snapshot" false } +uninstall_zfs_autotrim() { + local state_file="$BASE_DIR/zfs_autotrim_pools" + local pools=() + local pool + + msg_info2 "$(translate 'Disabling ZFS autotrim applied by ProxMenux...')" + + if ! command -v zpool >/dev/null 2>&1; then + msg_warn "$(translate 'ZFS not detected. Nothing to disable.')" + rm -f "$state_file" + register_tool "zfs_autotrim" false + return 0 + fi + + if [[ ! -s "$state_file" ]]; then + msg_warn "$(translate 'No ProxMenux ZFS autotrim state file found.')" + register_tool "zfs_autotrim" false + return 0 + fi + + mapfile -t pools < <(sort -u "$state_file") + for pool in "${pools[@]}"; do + if zpool list -H "$pool" >/dev/null 2>&1; then + if zpool set autotrim=off "$pool" >/dev/null 2>&1; then + msg_ok "$(translate 'ZFS autotrim disabled for pool:') $pool" + else + msg_warn "$(translate 'Failed to disable ZFS autotrim for pool:') $pool" + fi + else + msg_warn "$(translate 'ZFS pool not found:') $pool" + fi + done + + rm -f "$state_file" + register_tool "zfs_autotrim" false +} + uninstall_vzdump_speed() { msg_info2 "$(translate 'Reverting vzdump speed tuning...')" if [[ -f /etc/vzdump.conf.bak ]]; then @@ -933,7 +970,7 @@ show_uninstall_menu() { ensure_tools_json migrate_installed_tools - mapfile -t tools_installed < <(jq -r 'to_entries | map(select(.value==true)) | .[].key' "$TOOLS_JSON") + mapfile -t tools_installed < <(jq -r 'to_entries | map(select(.value==true or .value.installed==true)) | .[].key' "$TOOLS_JSON") if [[ ${#tools_installed[@]} -eq 0 ]]; then dialog --backtitle "ProxMenux" --title "ProxMenux" \ @@ -975,6 +1012,7 @@ show_uninstall_menu() { pigz) desc="pigz (parallel gzip wrapper)";; zfs_arc) desc="ZFS ARC size tuning";; zfs_auto_snapshot) desc="zfs-auto-snapshot package";; + zfs_autotrim) desc="ZFS autotrim";; vzdump_speed) desc="vzdump bwlimit/ionice tuning";; *) desc="$tool";; esac