#!/bin/bash # reboot-verify.sh - reboots a host, waits for it to come back, verifies state. # Usage: bash reboot-verify.sh set -uo pipefail HOST="$1" SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=5 -o ServerAliveInterval=5 -o StrictHostKeyChecking=accept-new) echo "================================================================" echo "[$HOST] PRE-REBOOT STATE" echo "================================================================" echo "--- Running VMs ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'qm list 2>/dev/null | awk "NR==1 || \$3==\"running\"{print}"' 2>&1 echo "--- NFS mount count ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'nfsstat -m 2>/dev/null | grep -c "^/mnt"' 2>&1 echo "--- NFS TCP connections to :2049 ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'ss -tn state established "( dport = :2049 )" 2>/dev/null | tail -n +2 | wc -l' 2>&1 echo "--- Uptime ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'uptime' 2>&1 echo "" echo "================================================================" echo "[$HOST] ISSUING REBOOT" echo "================================================================" # Issue reboot; ssh will disconnect with non-zero — that's expected. ssh "${SSH_OPTS[@]}" "root@$HOST" 'nohup sh -c "(sleep 2; systemctl reboot)" >/dev/null 2>&1 &' 2>&1 echo "Reboot command sent at $(date +%H:%M:%S). Host will drop now." echo "" echo "================================================================" echo "[$HOST] WAITING FOR SSH TO RETURN (max 10 minutes)" echo "================================================================" DEADLINE=$(( $(date +%s) + 600 )) LAST_PRINT=0 while [ "$(date +%s)" -lt "$DEADLINE" ]; do now=$(date +%s) # Print a heartbeat every 15s if [ $((now - LAST_PRINT)) -ge 15 ]; then elapsed=$((DEADLINE - now - 600)); elapsed=${elapsed#-} echo " [$(date +%H:%M:%S)] still waiting... (${elapsed}s elapsed)" LAST_PRINT=$now fi # Try SSH if ssh "${SSH_OPTS[@]}" "root@$HOST" 'echo ok' >/dev/null 2>&1; then echo " [$(date +%H:%M:%S)] SSH is back!" break fi sleep 5 done # Final check if ! ssh "${SSH_OPTS[@]}" "root@$HOST" 'echo ok' >/dev/null 2>&1; then echo " [$(date +%H:%M:%S)] FAILED: host not reachable after 10 minutes" exit 1 fi # Give services a moment to settle after SSH returns echo " Waiting 20s for services to settle..." sleep 20 echo "" echo "================================================================" echo "[$HOST] POST-REBOOT VERIFICATION" echo "================================================================" echo "--- Uptime ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'uptime' 2>&1 echo "" echo "--- TCP congestion control ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc' 2>&1 echo "" echo "--- vm.swappiness ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'sysctl vm.swappiness' 2>&1 echo "" echo "--- scaling_governor ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo "(no cpufreq driver)"' 2>&1 echo "" echo "--- NFS mount options (looking for nconnect + noatime) ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'nfsstat -m 2>/dev/null | head -20' 2>&1 echo "" echo "--- NFS TCP connection count (expect ~8 = 4 per server with nconnect=4) ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'ss -tn state established "( dport = :2049 )" 2>/dev/null | tail -n +2 | wc -l' 2>&1 echo "" echo "--- Running VMs ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'qm list 2>/dev/null' 2>&1 echo "" echo "--- Failed services? ---" ssh "${SSH_OPTS[@]}" "root@$HOST" 'systemctl --failed --no-legend 2>/dev/null | head -10' 2>&1 echo "" echo "================================================================" echo "[$HOST] DONE" echo "================================================================"