#!/bin/bash ############################################################################### # apply-bond-hash.sh # # Adds bond-xmit-hash-policy layer3+4 to bond0 in /etc/network/interfaces, # then reloads networking with ifreload -a. # # SSH survivability: this is safe IF your SSH session is on vmbr0/nic0 # (management network), NOT on bond0/datanet (storage network). # tsys7's topology confirms this: SSH comes in on vmbr0 (nic0). # # Safety: # - Dry-run by default (--apply to commit) # - Full backup of /etc/network/interfaces # - Generates rollback script # - Does NOT reboot — uses ifreload -a which is hot-reload ############################################################################### set -euo pipefail HOST="$(hostname -s)" TS_SHORT="$(date +%Y%m%d-%H%M%S)" BACKUP_DIR="/root/perfopt-backup-${TS_SHORT}" ROLLBACK="/root/perfopt-bond-rollback-${TS_SHORT}.sh" ACTION="${1:-dryrun}" [ "$ACTION" = "--apply" ] && ACTION="apply" || ACTION="dryrun" mkdir -p "$BACKUP_DIR" echo "===================================================================" echo " apply-bond-hash — $HOST" echo " mode: $ACTION" echo "===================================================================" if [ ! -r /etc/network/interfaces ]; then echo "FATAL: /etc/network/interfaces not readable" exit 1 fi # Check if bond0 exists in the config if ! grep -q 'bond0' /etc/network/interfaces; then echo "No bond0 found in /etc/network/interfaces — nothing to do." exit 0 fi # Check if the hash policy is already set if grep -q 'bond-xmit-hash-policy\|xmit_hash_policy' /etc/network/interfaces; then echo "bond-xmit-hash-policy already present:" grep 'bond-xmit-hash-policy\|xmit_hash_policy' /etc/network/interfaces echo "Checking value..." if grep -q 'layer3+4' /etc/network/interfaces; then echo "Already set to layer3+4 — nothing to do." exit 0 fi fi # Show current bond state echo "" echo "--- Current bond0 state ---" cat /proc/net/bonding/bond0 2>/dev/null | head -15 || echo "(bond0 not up or not present)" # Back up cp -a /etc/network/interfaces "$BACKUP_DIR/interfaces" # Generate rollback script cat > "$ROLLBACK" <&1 || systemctl restart networking 2>&1 || true echo "Done. bond0 hash policy reverted to original." EOF chmod +x "$ROLLBACK" echo "" echo "--- Proposed change ---" echo "Add line ' bond-xmit-hash-policy layer3+4' to the bond0 stanza." echo "" if [ "$ACTION" != "apply" ]; then echo "DRY RUN — no changes made." echo "To commit: bash $0 --apply" echo "Rollback script (pre-generated): $ROLLBACK" exit 0 fi # Apply: use sed to insert bond-xmit-hash-policy after bond-mode line # The bond0 stanza looks like: # auto bond0 # iface bond0 inet manual # bond-slaves nic1 nic2 # bond-miimon 100 # bond-mode 802.3ad # # We insert after the bond-mode line. echo "Applying..." # Check if bond-mode line exists (various formats) if grep -qE '^\s*bond-mode\s+802.3ad' /etc/network/interfaces; then # Insert after bond-mode 802.3ad line sed -i '/^\s*bond-mode\s+802\.3ad/a\\tbond-xmit-hash-policy layer3+4' /etc/network/interfaces echo "Inserted bond-xmit-hash-policy layer3+4 after bond-mode line." elif grep -qE '^\s*bond-mode\s+4' /etc/network/interfaces; then sed -i '/^\s*bond-mode\s+4/a\\tbond-xmit-hash-policy layer3+4' /etc/network/interfaces echo "Inserted bond-xmit-hash-policy layer3+4 after bond-mode 4 line." else echo "Could not find bond-mode line — inserting after bond-slaves line instead." sed -i '/^\s*bond-slaves/a\\tbond-xmit-hash-policy layer3+4' /etc/network/interfaces fi # Show the result echo "" echo "--- Updated bond0 stanza ---" awk '/^auto bond0/,/^$/' /etc/network/interfaces echo "" echo "--- Reloading networking (ifreload -a) ---" echo "SSH should survive (it's on vmbr0/nic0, not bond0)..." ifreload -a 2>&1 || { echo "ifreload failed, trying systemctl restart networking..." systemctl restart networking 2>&1 } # Wait a moment for bond to renegotiate echo "Waiting 5s for LACP to renegotiate..." sleep 5 echo "" echo "--- Post-change bond0 state ---" cat /proc/net/bonding/bond0 2>/dev/null | head -20 echo "" echo "===================================================================" echo " DONE." echo " Backup: $BACKUP_DIR/interfaces" echo " Rollback: bash $ROLLBACK" echo "==================================================================="