|
#!/bin/bash |
|
|
|
# Enhanced Debian 13 FUSE Deadlock Fix Script |
|
# Fixes kernel 6.12 FUSE regression causing complete network failures and unkillable processes |
|
# Version 2.0 - Enhanced for critical D-state deadlocks |
|
|
|
set -e |
|
|
|
RED='\033[0;31m' |
|
GREEN='\033[0;32m' |
|
YELLOW='\033[1;33m' |
|
BLUE='\033[0;34m' |
|
NC='\033[0m' # No Color |
|
|
|
print_header() { |
|
echo -e "${BLUE}" |
|
echo "╔════════════════════════════════════════════════════════════════════════════════╗" |
|
echo "║ ENHANCED DEBIAN 13 FUSE DEADLOCK FIX ║" |
|
echo "║ Kernel 6.12 Critical Regression Fix ║" |
|
echo "║ FOR UNKILLABLE D-STATE PROCESSES ║" |
|
echo "╚════════════════════════════════════════════════════════════════════════════════╝" |
|
echo -e "${NC}" |
|
} |
|
|
|
error_exit() { |
|
echo -e "${RED}❌ ERROR: $1${NC}" >&2 |
|
exit 1 |
|
} |
|
|
|
warning() { |
|
echo -e "${YELLOW}⚠️ WARNING: $1${NC}" |
|
} |
|
|
|
success() { |
|
echo -e "${GREEN}✅ $1${NC}" |
|
} |
|
|
|
info() { |
|
echo -e "${BLUE}ℹ️ $1${NC}" |
|
} |
|
|
|
check_environment() { |
|
info "Checking system environment..." |
|
|
|
# Check if we're on Linux |
|
if [[ "$(uname -s)" != "Linux" ]]; then |
|
error_exit "This script is only for Linux systems" |
|
fi |
|
|
|
# Check kernel version (should be 6.12.x) |
|
KERNEL_VERSION=$(uname -r) |
|
if [[ ! "$KERNEL_VERSION" =~ ^6\.12\. ]]; then |
|
warning "Kernel version $KERNEL_VERSION is not 6.12.x" |
|
warning "This fix is specifically for kernel 6.12 FUSE regressions" |
|
echo "Continue anyway? (y/N)" |
|
read -r response |
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then |
|
exit 0 |
|
fi |
|
fi |
|
|
|
# Check if running Debian (preferred, but not required) |
|
if [[ -f /etc/debian_version ]]; then |
|
DEBIAN_VERSION=$(cat /etc/debian_version) |
|
info "Detected Debian version: $DEBIAN_VERSION" |
|
if [[ ! "$DEBIAN_VERSION" =~ ^13 ]] && [[ ! "$DEBIAN_VERSION" =~ ^trixie ]]; then |
|
warning "This fix was developed for Debian 13/trixie" |
|
warning "You're running Debian $DEBIAN_VERSION" |
|
fi |
|
else |
|
warning "Not running Debian - this fix was developed for Debian 13" |
|
warning "Proceed with caution on other distributions" |
|
fi |
|
|
|
# Check for sudo access |
|
if ! sudo -n true 2>/dev/null; then |
|
error_exit "This script requires sudo access. Run 'sudo echo test' first." |
|
fi |
|
|
|
# Check for FUSE usage |
|
FUSE_PROCESSES=$(ps aux | grep -c "[r]clone\|[s]shfs\|fuse\|[t]darr" || echo 0) |
|
if [[ $FUSE_PROCESSES -eq 0 ]]; then |
|
warning "No FUSE processes detected. This fix may not be necessary." |
|
echo "Continue anyway? (y/N)" |
|
read -r response |
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then |
|
exit 0 |
|
fi |
|
fi |
|
|
|
success "Environment checks passed" |
|
} |
|
|
|
check_existing_deadlocks() { |
|
info "Checking for active deadlocks..." |
|
|
|
D_STATE_PROCS=($(ps aux | awk '$8 ~ /D/ {print $2}' 2>/dev/null)) |
|
if [[ ${#D_STATE_PROCS[@]} -gt 0 ]]; then |
|
echo -e "${RED}" |
|
echo "╔════════════════════════════════════════════════════════════════════════════════╗" |
|
echo "║ ACTIVE DEADLOCK DETECTED! ║" |
|
echo "╠════════════════════════════════════════════════════════════════════════════════╣" |
|
echo "║ Found ${#D_STATE_PROCS[@]} processes stuck in unkillable D-state: ║" |
|
for pid in "${D_STATE_PROCS[@]:0:5}"; do |
|
PNAME=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown") |
|
printf "║ PID %-8s: %-50s ║\n" "$pid" "$PNAME" |
|
done |
|
echo "║ ║" |
|
echo "║ EMERGENCY ACTIONS (try these first): ║" |
|
echo "║ 1. sudo bash -c 'echo 1 | tee /sys/fs/fuse/connections/*/abort 2>/dev/null' ║" |
|
echo "║ 2. docker stop \$(docker ps -q) --time=1 ║" |
|
echo "║ 3. sudo reboot -f ║" |
|
echo "║ ║" |
|
echo "║ Then run this script AFTER rebooting! ║" |
|
echo "╚════════════════════════════════════════════════════════════════════════════════╝" |
|
echo -e "${NC}" |
|
|
|
echo "Try emergency abort first? (y/N)" |
|
read -r response |
|
if [[ "$response" =~ ^[Yy]$ ]]; then |
|
info "Attempting emergency FUSE abort..." |
|
sudo bash -c 'echo 1 | tee /sys/fs/fuse/connections/*/abort 2>/dev/null' && success "FUSE connections aborted" || warning "FUSE abort failed" |
|
sleep 3 |
|
|
|
NEW_D_STATE=$(ps aux | awk '$8 ~ /D/ {count++} END {print count+0}') |
|
if [[ $NEW_D_STATE -gt 0 ]]; then |
|
error_exit "Still $NEW_D_STATE stuck processes. REBOOT REQUIRED: sudo reboot -f" |
|
else |
|
success "Deadlock appears to be broken! Continuing with fix..." |
|
fi |
|
else |
|
error_exit "Cannot apply fix with active deadlock. Address deadlock first." |
|
fi |
|
fi |
|
|
|
success "No active deadlocks detected" |
|
} |
|
|
|
show_warnings() { |
|
echo -e "${RED}" |
|
echo "╔════════════════════════════════════════════════════════════════════════════════╗" |
|
echo "║ CRITICAL WARNING ║" |
|
echo "╠════════════════════════════════════════════════════════════════════════════════╣" |
|
echo "║ This ENHANCED script will modify critical system files: ║" |
|
echo "║ ║" |
|
echo "║ • /etc/default/grub (kernel boot parameters) ║" |
|
echo "║ • /etc/sysctl.d/98-fuse-aggressive-fix.conf (aggressive kernel tuning) ║" |
|
echo "║ • /etc/systemd/system/docker.service.d/ (Docker restrictions) ║" |
|
echo "║ • /etc/systemd/system/fuse-deadlock-prevention.service (prevention service) ║" |
|
echo "║ ║" |
|
echo "║ AGGRESSIVE changes affect: ║" |
|
echo "║ • FUSE filesystem behavior (passthrough DISABLED) ║" |
|
echo "║ • Memory management (aggressive dirty page limits) ║" |
|
echo "║ • Network processing (restricted for stability) ║" |
|
echo "║ • Docker service (strict concurrency limits) ║" |
|
echo "║ • Hung task detection (30 second timeout) ║" |
|
echo "║ ║" |
|
echo "║ ⚠️ MANDATORY REBOOT REQUIRED after applying these changes. ║" |
|
echo "║ ║" |
|
echo "║ This is a TEMPORARY WORKAROUND for kernel 6.12 FUSE regressions. ║" |
|
echo "║ Consider downgrading to kernel 6.11 for permanent solution. ║" |
|
echo "╚════════════════════════════════════════════════════════════════════════════════╝" |
|
echo -e "${NC}" |
|
|
|
echo "" |
|
echo -e "${YELLOW}Type 'yes' to proceed with the enhanced fix, or 'no' to abort:${NC}" |
|
read -r response |
|
echo "You entered: '$response'" |
|
|
|
case "$response" in |
|
[Yy]|[Yy][Ee][Ss]|yes|YES) |
|
success "Proceeding with enhanced FUSE deadlock fix..." |
|
;; |
|
*) |
|
warning "Fix aborted by user. To run without prompts, use: sudo bash $0 --force" |
|
exit 0 |
|
;; |
|
esac |
|
|
|
echo "" |
|
echo -e "${YELLOW}This will make AGGRESSIVE changes to prevent deadlocks. Continue? (yes/no):${NC}" |
|
read -r response2 |
|
echo "You entered: '$response2'" |
|
|
|
case "$response2" in |
|
[Yy]|[Yy][Ee][Ss]|yes|YES) |
|
success "Confirmed. Applying aggressive FUSE deadlock fixes..." |
|
;; |
|
*) |
|
warning "Fix aborted by user. Changes cancelled." |
|
exit 0 |
|
;; |
|
esac |
|
} |
|
|
|
backup_configs() { |
|
info "Creating configuration backups..." |
|
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S) |
|
|
|
if [[ -f /etc/default/grub ]]; then |
|
sudo cp /etc/default/grub "/etc/default/grub.backup.$TIMESTAMP" |
|
success "GRUB config backed up" |
|
fi |
|
|
|
if [[ -f /etc/sysctl.conf ]]; then |
|
sudo cp /etc/sysctl.conf "/etc/sysctl.conf.backup.$TIMESTAMP" |
|
success "sysctl.conf backed up" |
|
fi |
|
|
|
# Backup any existing Docker overrides |
|
if [[ -d /etc/systemd/system/docker.service.d ]]; then |
|
sudo cp -r /etc/systemd/system/docker.service.d "/etc/systemd/system/docker.service.d.backup.$TIMESTAMP" |
|
success "Docker service overrides backed up" |
|
fi |
|
} |
|
|
|
apply_enhanced_kernel_parameters() { |
|
info "Applying ENHANCED kernel boot parameters..." |
|
|
|
# More aggressive FUSE parameters for kernel 6.12 regression |
|
ENHANCED_PARAMS="fuse.passthrough=0 fuse.max_user_mounts=50 fuse.congestion_threshold=1 fuse.max_user_conns=100" |
|
|
|
# Check if already applied and remove old versions |
|
if grep -q "fuse.passthrough=0" /etc/default/grub 2>/dev/null; then |
|
warning "Removing existing FUSE parameters to apply enhanced version" |
|
sudo sed -i '/GRUB_CMDLINE_LINUX.*fuse\./d' /etc/default/grub |
|
fi |
|
|
|
# Add enhanced FUSE parameters to GRUB |
|
echo "GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX $ENHANCED_PARAMS\"" | sudo tee -a /etc/default/grub |
|
|
|
info "Updating GRUB configuration..." |
|
sudo update-grub |
|
success "Enhanced kernel parameters added to GRUB" |
|
} |
|
|
|
apply_aggressive_sysctl_tuning() { |
|
info "Applying AGGRESSIVE sysctl tuning..." |
|
|
|
sudo tee /etc/sysctl.d/98-fuse-aggressive-fix.conf > /dev/null << 'EOF' |
|
# AGGRESSIVE Debian 13 / Kernel 6.12 FUSE deadlock prevention |
|
# Enhanced fixes for critical D-state process deadlocks |
|
# This configuration is more aggressive than the basic fix |
|
|
|
# FUSE safety settings (critical for deadlock prevention) |
|
fs.pipe-max-size=1000 |
|
fs.pipe-user-pages-hard=8192 |
|
|
|
# Hung task detection (aggressive - detect deadlocks faster) |
|
kernel.hung_task_timeout_secs=30 |
|
kernel.hung_task_check_count=4 |
|
kernel.hung_task_warnings=5 |
|
kernel.hung_task_panic=0 |
|
|
|
# Memory management (prevent memory pressure deadlocks) |
|
vm.max_map_count=524288 |
|
vm.dirty_background_ratio=3 |
|
vm.dirty_ratio=5 |
|
vm.dirty_expire_centisecs=500 |
|
vm.dirty_writeback_centisecs=250 |
|
vm.overcommit_memory=0 |
|
vm.oom_kill_allocating_task=1 |
|
|
|
# Network processing improvements (keep network responsive) |
|
net.core.netdev_budget=8192 |
|
net.core.netdev_budget_usecs=8000 |
|
net.core.netdev_max_backlog=2000 |
|
|
|
# Process and thread limits (prevent resource exhaustion) |
|
kernel.pid_max=131072 |
|
kernel.threads-max=65536 |
|
|
|
# I/O and filesystem tuning |
|
kernel.io_delay_type=1 |
|
fs.file-max=2097152 |
|
|
|
# Additional safety measures |
|
kernel.panic=10 |
|
kernel.panic_on_oops=0 |
|
EOF |
|
|
|
# Apply immediately |
|
sudo /usr/sbin/sysctl -p /etc/sysctl.d/98-fuse-aggressive-fix.conf |
|
success "Aggressive sysctl tuning applied and made persistent" |
|
} |
|
|
|
apply_docker_limits() { |
|
info "Applying STRICT Docker service limits..." |
|
|
|
if systemctl is-active docker >/dev/null 2>&1 || systemctl is-enabled docker >/dev/null 2>&1; then |
|
sudo mkdir -p /etc/systemd/system/docker.service.d |
|
|
|
# Strict Docker limits to prevent FUSE deadlocks |
|
sudo tee /etc/systemd/system/docker.service.d/fuse-strict-limits.conf > /dev/null << 'EOF' |
|
[Service] |
|
Environment="DOCKER_OPTS=--max-concurrent-downloads=1 --max-concurrent-uploads=1 --default-ulimit nofile=4096:8192" |
|
LimitNOFILE=8192 |
|
LimitNPROC=4096 |
|
MemoryLimit=8G |
|
TasksMax=4096 |
|
|
|
# Prevent containers from causing system deadlocks |
|
ExecStartPre=/bin/bash -c 'echo 30 > /proc/sys/kernel/hung_task_timeout_secs' |
|
ExecStartPre=/bin/bash -c 'echo 1 > /proc/sys/fs/fuse/congestion_threshold 2>/dev/null || true' |
|
ExecStartPre=/bin/bash -c 'echo 3 > /proc/sys/vm/dirty_background_ratio' |
|
EOF |
|
|
|
sudo systemctl daemon-reload |
|
success "Strict Docker concurrency limits applied" |
|
else |
|
info "Docker not installed or enabled - skipping Docker limits" |
|
fi |
|
} |
|
|
|
apply_systemd_deadlock_prevention() { |
|
info "Creating deadlock prevention systemd service..." |
|
|
|
sudo tee /etc/systemd/system/fuse-deadlock-prevention.service > /dev/null << 'EOF' |
|
[Unit] |
|
Description=FUSE Deadlock Prevention Service for Kernel 6.12 |
|
Documentation=https://github.com/your-repo/fuse-deadlock-fix |
|
After=multi-user.target |
|
Before=docker.service |
|
|
|
[Service] |
|
Type=oneshot |
|
RemainAfterExit=yes |
|
ExecStart=/bin/bash -c 'echo 30 > /proc/sys/kernel/hung_task_timeout_secs' |
|
ExecStart=/bin/bash -c 'echo 1 > /proc/sys/fs/fuse/congestion_threshold 2>/dev/null || true' |
|
ExecStart=/bin/bash -c 'echo 3 > /proc/sys/vm/dirty_background_ratio' |
|
ExecStart=/bin/bash -c 'echo 5 > /proc/sys/vm/dirty_ratio' |
|
ExecStart=/usr/bin/logger "FUSE deadlock prevention service started - kernel 6.12 workaround active" |
|
|
|
[Install] |
|
WantedBy=multi-user.target |
|
EOF |
|
|
|
sudo systemctl enable fuse-deadlock-prevention.service |
|
sudo systemctl start fuse-deadlock-prevention.service 2>/dev/null || warning "Service will start on next boot" |
|
success "Deadlock prevention service installed and enabled" |
|
} |
|
|
|
create_monitoring_script() { |
|
info "Creating enhanced deadlock monitoring script..." |
|
|
|
cat > monitor_deadlock.sh << 'EOF' |
|
#!/bin/bash |
|
echo "🔍 ENHANCED FUSE Deadlock Monitor Starting - $(date)" |
|
echo "Monitoring for kernel 6.12 FUSE deadlocks and D-state processes..." |
|
echo "Enhanced version - detects unkillable processes" |
|
echo "Press Ctrl+C to stop" |
|
|
|
while true; do |
|
D_PROCS=$(ps aux | awk '$8 ~ /D/ {count++} END {print count+0}') |
|
FUSE_CONNS=$(ls /sys/fs/fuse/connections/ 2>/dev/null | wc -l) |
|
LOAD=$(cut -d' ' -f1 /proc/loadavg) |
|
RCLONE_MOUNTS=$(mount | grep -c rclone 2>/dev/null || echo 0) |
|
DOCKER_CONTAINERS=$(docker ps -q 2>/dev/null | wc -l) |
|
|
|
TIMESTAMP=$(date '+%H:%M:%S') |
|
|
|
if [[ $D_PROCS -gt 0 ]]; then |
|
echo "🚨 [$TIMESTAMP] DEADLOCK DETECTED!" |
|
echo " D-state processes: $D_PROCS" |
|
echo " FUSE connections: $FUSE_CONNS" |
|
echo " Load: $LOAD" |
|
echo " Docker containers: $DOCKER_CONTAINERS" |
|
echo " Stuck processes:" |
|
ps aux | awk '$8 ~ /D/ {printf " PID %-8s: %s\n", $2, $11}' | head -8 |
|
echo "" |
|
echo " 🔧 EMERGENCY ACTIONS:" |
|
echo " 1. sudo bash -c 'echo 1 | tee /sys/fs/fuse/connections/*/abort 2>/dev/null'" |
|
echo " 2. docker stop \$(docker ps -q) --time=1" |
|
echo " 3. sudo ./break_deadlock.sh" |
|
echo " 4. sudo reboot -f (if nothing else works)" |
|
echo " Immediate action needed!" |
|
elif [[ $D_PROCS -eq 0 && $FUSE_CONNS -gt 0 ]]; then |
|
echo "✅ [$TIMESTAMP] System healthy - D:$D_PROCS FUSE:$FUSE_CONNS Load:$LOAD Mounts:$RCLONE_MOUNTS Docker:$DOCKER_CONTAINERS" |
|
else |
|
echo "ℹ️ [$TIMESTAMP] Monitoring - D:$D_PROCS FUSE:$FUSE_CONNS Load:$LOAD Mounts:$RCLONE_MOUNTS Docker:$DOCKER_CONTAINERS" |
|
fi |
|
|
|
sleep 15 |
|
done |
|
EOF |
|
|
|
chmod +x monitor_deadlock.sh |
|
success "Enhanced monitoring script created (./monitor_deadlock.sh)" |
|
} |
|
|
|
create_emergency_deadlock_breaker() { |
|
info "Creating emergency deadlock breaker script..." |
|
|
|
cat > break_deadlock.sh << 'EOF' |
|
#!/bin/bash |
|
echo "🔧 EMERGENCY DEADLOCK BREAKER - $(date)" |
|
echo "Breaking kernel 6.12 FUSE deadlocks aggressively..." |
|
echo "This script attempts to recover from unkillable D-state processes" |
|
|
|
# Function to check D-state processes |
|
check_d_state() { |
|
ps aux | awk '$8 ~ /D/ {count++} END {print count+0}' |
|
} |
|
|
|
echo "Initial D-state process count: $(check_d_state)" |
|
|
|
# Step 1: Abort all FUSE connections immediately |
|
echo "Step 1: Aborting all FUSE connections..." |
|
FUSE_ABORTED=0 |
|
for conn in /sys/fs/fuse/connections/*/abort; do |
|
if [[ -f "$conn" ]]; then |
|
sudo echo 1 > "$conn" 2>/dev/null && { |
|
echo " ✅ Aborted connection $(dirname "$conn")" |
|
((FUSE_ABORTED++)) |
|
} || echo " ❌ Failed to abort $(dirname "$conn")" |
|
fi |
|
done |
|
echo " Total FUSE connections aborted: $FUSE_ABORTED" |
|
|
|
# Step 2: Set aggressive congestion thresholds |
|
echo "Step 2: Setting aggressive FUSE congestion thresholds..." |
|
for conn in /sys/fs/fuse/connections/*/congestion_threshold; do |
|
if [[ -f "$conn" ]]; then |
|
sudo echo 1 > "$conn" 2>/dev/null && echo " ✅ Set congestion threshold for $(dirname "$conn")" |
|
fi |
|
done |
|
|
|
# Step 3: Attempt to kill stuck processes (may not work for D-state) |
|
echo "Step 3: Attempting to terminate stuck processes..." |
|
STUCK_PIDS=($(ps aux | awk '$8 ~ /D/ {print $2}')) |
|
if [[ ${#STUCK_PIDS[@]} -gt 0 ]]; then |
|
echo " Found ${#STUCK_PIDS[@]} stuck processes: ${STUCK_PIDS[*]}" |
|
for pid in "${STUCK_PIDS[@]}"; do |
|
PNAME=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown") |
|
sudo kill -KILL "$pid" 2>/dev/null && { |
|
echo " ✅ Killed $pid ($PNAME)" |
|
} || { |
|
echo " ❌ Could not kill $pid ($PNAME) - expected for D-state" |
|
} |
|
done |
|
else |
|
echo " No stuck processes found" |
|
fi |
|
|
|
# Step 4: Stop Docker containers that might be causing issues |
|
echo "Step 4: Managing Docker containers..." |
|
RUNNING_CONTAINERS=($(docker ps -q 2>/dev/null)) |
|
if [[ ${#RUNNING_CONTAINERS[@]} -gt 0 ]]; then |
|
echo " Found ${#RUNNING_CONTAINERS[@]} running containers" |
|
echo " Stopping containers gracefully (1 second timeout)..." |
|
docker stop "${RUNNING_CONTAINERS[@]}" --time=1 2>/dev/null && echo " ✅ Containers stopped" || echo " ⚠️ Some containers may not have stopped" |
|
|
|
# Force kill if still running |
|
STILL_RUNNING=($(docker ps -q 2>/dev/null)) |
|
if [[ ${#STILL_RUNNING[@]} -gt 0 ]]; then |
|
echo " Force killing remaining containers..." |
|
docker kill "${STILL_RUNNING[@]}" 2>/dev/null && echo " ✅ Containers force killed" || echo " ❌ Force kill failed" |
|
fi |
|
else |
|
echo " No running containers found" |
|
fi |
|
|
|
# Step 5: Force unmount FUSE filesystems |
|
echo "Step 5: Force unmounting FUSE filesystems..." |
|
FUSE_MOUNTS=($(mount | grep fuse | awk '{print $3}')) |
|
if [[ ${#FUSE_MOUNTS[@]} -gt 0 ]]; then |
|
echo " Found ${#FUSE_MOUNTS[@]} FUSE mounts: ${FUSE_MOUNTS[*]}" |
|
for mount_point in "${FUSE_MOUNTS[@]}"; do |
|
sudo umount -f -l "$mount_point" 2>/dev/null && { |
|
echo " ✅ Unmounted $mount_point" |
|
} || { |
|
echo " ❌ Failed to unmount $mount_point" |
|
} |
|
done |
|
else |
|
echo " No FUSE mounts found" |
|
fi |
|
|
|
# Step 6: Apply emergency sysctl tuning |
|
echo "Step 6: Applying emergency sysctl tuning..." |
|
sudo sysctl -w kernel.hung_task_timeout_secs=15 2>/dev/null && echo " ✅ Reduced hung task timeout" |
|
sudo sysctl -w vm.dirty_ratio=2 2>/dev/null && echo " ✅ Reduced dirty ratio" |
|
sudo sysctl -w vm.dirty_background_ratio=1 2>/dev/null && echo " ✅ Reduced dirty background ratio" |
|
|
|
# Step 7: Wait and recheck |
|
echo "Step 7: Waiting 10 seconds for system to stabilize..." |
|
sleep 10 |
|
|
|
# Final status check |
|
echo "Step 8: Final status check..." |
|
FINAL_D_STATE=$(check_d_state) |
|
FINAL_FUSE=$(ls /sys/fs/fuse/connections/ 2>/dev/null | wc -l) |
|
LOAD_AVG=$(cat /proc/loadavg) |
|
|
|
echo "" |
|
echo "═══ DEADLOCK BREAKER RESULTS ═══" |
|
echo "D-state processes: $FINAL_D_STATE" |
|
echo "FUSE connections: $FINAL_FUSE" |
|
echo "System load: $LOAD_AVG" |
|
|
|
if [[ $FINAL_D_STATE -eq 0 ]]; then |
|
echo "" |
|
echo "🎉 SUCCESS: Deadlock appears to be broken!" |
|
echo "✅ No D-state processes remaining" |
|
echo "🔧 System should be responsive again" |
|
echo "" |
|
echo "Recommended next steps:" |
|
echo "1. Monitor system with: ./monitor_deadlock.sh" |
|
echo "2. Consider kernel downgrade to 6.11 to prevent recurrence" |
|
echo "3. Restart necessary services carefully" |
|
else |
|
echo "" |
|
echo "❌ PARTIAL SUCCESS: $FINAL_D_STATE processes still stuck" |
|
echo "🚨 REBOOT IS REQUIRED" |
|
echo "" |
|
echo "Emergency reboot command:" |
|
echo "sudo reboot -f" |
|
echo "" |
|
echo "After reboot:" |
|
echo "1. Apply the full fix script" |
|
echo "2. Consider downgrading to kernel 6.11" |
|
fi |
|
EOF |
|
|
|
chmod +x break_deadlock.sh |
|
success "Emergency deadlock breaker created (./break_deadlock.sh)" |
|
} |
|
|
|
create_kernel_downgrade_guide() { |
|
info "Creating kernel downgrade guide..." |
|
|
|
cat > downgrade_to_kernel_6.11.sh << 'EOF' |
|
#!/bin/bash |
|
|
|
# Kernel 6.11 Downgrade Script for Debian 13 |
|
# Recommended solution for kernel 6.12 FUSE deadlocks |
|
|
|
echo "🔄 Debian 13 Kernel Downgrade to 6.11" |
|
echo "This is the RECOMMENDED solution for kernel 6.12 FUSE issues" |
|
echo "" |
|
|
|
# Add snapshot repository for kernel 6.11 |
|
echo "Adding Debian snapshot repository for kernel 6.11..." |
|
echo "deb [check-valid-until=no] https://snapshot.debian.org/archive/debian/20241101/ trixie main" | sudo tee /etc/apt/sources.list.d/kernel-6.11-snapshot.list |
|
|
|
# Update package lists |
|
echo "Updating package lists..." |
|
sudo apt update |
|
|
|
# Show available 6.11 kernels |
|
echo "Available kernel 6.11 versions:" |
|
apt list linux-image-6.11* 2>/dev/null | grep -v WARNING |
|
|
|
echo "" |
|
echo "Installing kernel 6.11 (this will take a few minutes)..." |
|
sudo apt install -y linux-image-6.11.10-amd64 linux-headers-6.11.10-amd64 |
|
|
|
# Hold kernel to prevent auto-upgrade back to 6.12 |
|
echo "Holding kernel 6.11 to prevent auto-upgrade..." |
|
sudo apt-mark hold linux-image-6.11.10-amd64 linux-headers-6.11.10-amd64 |
|
|
|
# Create apt preferences to block kernel 6.12 |
|
echo "Creating apt preferences to block kernel 6.12..." |
|
sudo tee /etc/apt/preferences.d/block-kernel-6.12 << 'APT_PREFS' |
|
# Block problematic kernel 6.12 due to FUSE deadlocks |
|
Package: linux-image-6.12* |
|
Pin: version 6.12* |
|
Pin-Priority: -1 |
|
|
|
Package: linux-headers-6.12* |
|
Pin: version 6.12* |
|
Pin-Priority: -1 |
|
|
|
# Prefer kernel 6.11 |
|
Package: linux-image-6.11* |
|
Pin: version 6.11* |
|
Pin-Priority: 900 |
|
|
|
Package: linux-headers-6.11* |
|
Pin: version 6.11* |
|
Pin-Priority: 900 |
|
APT_PREFS |
|
|
|
# Update GRUB |
|
echo "Updating GRUB configuration..." |
|
sudo update-grub |
|
|
|
echo "" |
|
echo "✅ Kernel 6.11 installation complete!" |
|
echo "" |
|
echo "🔄 REBOOT REQUIRED to use kernel 6.11" |
|
echo "After reboot:" |
|
echo "1. Verify kernel: uname -r (should show 6.11.x)" |
|
echo "2. Test FUSE applications (rclone, sshfs, Tdarr)" |
|
echo "3. Remove this fix if 6.11 resolves the deadlocks" |
|
echo "" |
|
echo "To reboot now: sudo reboot" |
|
EOF |
|
|
|
chmod +x downgrade_to_kernel_6.11.sh |
|
success "Kernel downgrade script created (./downgrade_to_kernel_6.11.sh)" |
|
} |
|
|
|
verify_configuration() { |
|
echo -e "\n${BLUE}═══ ENHANCED CONFIGURATION VERIFICATION ═══${NC}" |
|
|
|
echo "Enhanced kernel parameters in GRUB:" |
|
grep "fuse" /etc/default/grub | grep -o "fuse[^\"]*" || echo "Not found" |
|
|
|
echo -e "\nAggressive sysctl configuration:" |
|
if [[ -f /etc/sysctl.d/98-fuse-aggressive-fix.conf ]]; then |
|
head -10 /etc/sysctl.d/98-fuse-aggressive-fix.conf |
|
echo "... (full file created)" |
|
else |
|
echo "Not found" |
|
fi |
|
|
|
echo -e "\nDocker service overrides:" |
|
if [[ -f /etc/systemd/system/docker.service.d/fuse-strict-limits.conf ]]; then |
|
echo "✅ Docker strict limits configured" |
|
else |
|
echo "❌ Docker limits not found" |
|
fi |
|
|
|
echo -e "\nDeadlock prevention service:" |
|
systemctl is-enabled fuse-deadlock-prevention.service 2>/dev/null && echo "✅ Service enabled" || echo "❌ Service not enabled" |
|
|
|
echo -e "\nCurrent applied values:" |
|
/usr/sbin/sysctl vm.max_map_count net.core.netdev_budget net.core.netdev_budget_usecs fs.pipe-max-size kernel.hung_task_timeout_secs 2>/dev/null || echo "Values will apply after reboot" |
|
} |
|
|
|
final_status_check() { |
|
echo -e "\n${BLUE}═══ FINAL STATUS CHECK ═══${NC}" |
|
|
|
GRUB_OK=$(grep -c "fuse.passthrough=0" /etc/default/grub 2>/dev/null || echo 0) |
|
SYSCTL_OK=$(test -f /etc/sysctl.d/98-fuse-aggressive-fix.conf && echo 1 || echo 0) |
|
DOCKER_OK=$(test -f /etc/systemd/system/docker.service.d/fuse-strict-limits.conf && echo 1 || echo 0) |
|
SERVICE_OK=$(systemctl is-enabled fuse-deadlock-prevention.service >/dev/null 2>&1 && echo 1 || echo 0) |
|
SYSTEM_CLEAN=$(ps aux | awk '$8 ~ /D/ {count++} END {print count+0}') |
|
|
|
echo "Enhanced configuration status:" |
|
[[ $GRUB_OK -eq 1 ]] && success "Enhanced GRUB configuration applied" || error_exit "GRUB configuration failed" |
|
[[ $SYSCTL_OK -eq 1 ]] && success "Aggressive sysctl configuration applied" || error_exit "sysctl configuration failed" |
|
[[ $SERVICE_OK -eq 1 ]] && success "Deadlock prevention service enabled" || warning "Prevention service not enabled" |
|
[[ $DOCKER_OK -eq 1 ]] && success "Docker strict limits applied" || info "Docker configuration skipped (not installed)" |
|
[[ $SYSTEM_CLEAN -eq 0 ]] && success "System is clean (no stuck processes)" || warning "System has $SYSTEM_CLEAN stuck processes" |
|
|
|
# Check if core configurations succeeded |
|
if [[ $GRUB_OK -eq 1 && $SYSCTL_OK -eq 1 ]]; then |
|
echo -e "\n${GREEN}🎉 SUCCESS! Enhanced FUSE deadlock fixes applied successfully.${NC}" |
|
|
|
# Warn about stuck processes but don't fail |
|
if [[ $SYSTEM_CLEAN -gt 0 ]]; then |
|
echo -e "\n${YELLOW}⚠️ NOTE: $SYSTEM_CLEAN processes currently stuck in D-state.${NC}" |
|
echo -e "${YELLOW} This is likely the existing deadlock that prompted you to run this fix.${NC}" |
|
echo -e "${YELLOW} The fix will take effect after reboot.${NC}" |
|
fi |
|
|
|
echo -e "\n${YELLOW}📋 CRITICAL NEXT STEPS:${NC}" |
|
echo "1. 🔄 REBOOT YOUR SYSTEM: sudo reboot" |
|
echo "2. ✅ After reboot, verify the fix:" |
|
echo " cat /proc/cmdline | grep fuse" |
|
echo "3. 📊 Monitor for deadlocks: ./monitor_deadlock.sh" |
|
echo "4. 🛠️ Emergency breaker ready: ./break_deadlock.sh" |
|
echo "5. 🔽 Consider kernel downgrade: ./downgrade_to_kernel_6.11.sh" |
|
echo "" |
|
echo -e "${RED}⚠️ IMPORTANT: Kernel 6.12 has severe FUSE regressions.${NC}" |
|
echo -e "${RED} Downgrading to kernel 6.11 is the most reliable solution.${NC}" |
|
echo "" |
|
echo -e "${GREEN}🛡️ Your system will be protected against kernel 6.12 FUSE deadlocks after reboot.${NC}" |
|
echo -e "${BLUE}📞 Need help? Monitor output and report issues to the community.${NC}" |
|
else |
|
echo -e "\n${RED}❌ CONFIGURATION FAILURES DETECTED:${NC}" |
|
[[ $GRUB_OK -ne 1 ]] && echo " - GRUB configuration failed" |
|
[[ $SYSCTL_OK -ne 1 ]] && echo " - sysctl configuration failed" |
|
echo "" |
|
echo "Please check the output above for specific error messages." |
|
exit 1 |
|
fi |
|
} |
|
|
|
print_system_info() { |
|
echo -e "\n${BLUE}═══ SYSTEM INFORMATION ═══${NC}" |
|
echo "Kernel version: $(uname -r)" |
|
echo "Debian version: $(cat /etc/debian_version 2>/dev/null || echo 'Unknown')" |
|
echo "FUSE processes: $(ps aux | grep -c "[r]clone\|[s]shfs\|fuse\|[t]darr" || echo 0)" |
|
echo "Docker status: $(systemctl is-active docker 2>/dev/null || echo 'not running')" |
|
echo "System load: $(cat /proc/loadavg)" |
|
echo "Memory usage: $(free -h | grep ^Mem | awk '{print $3 "/" $2}')" |
|
} |
|
|
|
# Main execution |
|
main() { |
|
print_header |
|
print_system_info |
|
|
|
echo -e "This ENHANCED script fixes FUSE deadlocks in Debian 13 (kernel 6.12)" |
|
echo -e "that cause unkillable D-state processes, complete network failures," |
|
echo -e "and system hangs. This version includes aggressive workarounds.\n" |
|
|
|
check_environment |
|
check_existing_deadlocks |
|
|
|
# Skip warnings if --force flag is used |
|
if [[ "$1" != "--force" ]]; then |
|
show_warnings |
|
else |
|
warning "Running in FORCE mode - skipping user confirmations" |
|
fi |
|
|
|
echo -e "\n${BLUE}═══ APPLYING ENHANCED FIXES ═══${NC}" |
|
|
|
backup_configs |
|
apply_enhanced_kernel_parameters |
|
apply_aggressive_sysctl_tuning |
|
apply_docker_limits |
|
apply_systemd_deadlock_prevention |
|
create_monitoring_script |
|
create_emergency_deadlock_breaker |
|
create_kernel_downgrade_guide |
|
|
|
verify_configuration |
|
final_status_check |
|
} |
|
|
|
# Help text |
|
if [[ "$1" == "--help" || "$1" == "-h" ]]; then |
|
echo "Enhanced Debian 13 FUSE Deadlock Fix Script v2.0" |
|
echo "" |
|
echo "This script fixes critical FUSE regressions in Linux kernel 6.12" |
|
echo "that cause unkillable D-state processes and complete system hangs." |
|
echo "" |
|
echo "Usage: $0 [options]" |
|
echo "" |
|
echo "Options:" |
|
echo " --help, -h Show this help message" |
|
echo " --version, -v Show version information" |
|
echo " --force Skip user confirmation prompts" |
|
echo "" |
|
echo "What it does (ENHANCED VERSION):" |
|
echo "• Disables FUSE passthrough mode (source of deadlocks)" |
|
echo "• Applies aggressive FUSE mount limits (50 vs 100)" |
|
echo "• Sets strict congestion thresholds" |
|
echo "• Tunes memory management aggressively" |
|
echo "• Configures strict Docker limits" |
|
echo "• Creates deadlock prevention service" |
|
echo "• Creates emergency deadlock breaker" |
|
echo "• Creates kernel downgrade helper" |
|
echo "• Creates enhanced monitoring tools" |
|
echo "" |
|
echo "Requirements:" |
|
echo "• Linux kernel 6.12.x (typically Debian 13)" |
|
echo "• sudo access" |
|
echo "• System experiencing FUSE deadlocks" |
|
echo "" |
|
echo "Critical files created:" |
|
echo "• ./monitor_deadlock.sh - Enhanced deadlock monitoring" |
|
echo "• ./break_deadlock.sh - Emergency deadlock breaker" |
|
echo "• ./downgrade_to_kernel_6.11.sh - Kernel downgrade helper" |
|
echo "" |
|
echo "⚠️ A reboot is MANDATORY after running this script." |
|
echo "🔽 Kernel downgrade to 6.11 is RECOMMENDED for permanent fix." |
|
exit 0 |
|
fi |
|
|
|
# Version check |
|
if [[ "$1" == "--version" || "$1" == "-v" ]]; then |
|
echo "Enhanced Debian 13 FUSE Deadlock Fix Script v2.0" |
|
echo "Fixes critical kernel 6.12 FUSE regression causing unkillable processes" |
|
echo "Enhanced version with aggressive workarounds for D-state deadlocks" |
|
exit 0 |
|
fi |
|
|
|
# Run main function |
|
main "$@" |