Critical bug fix: - Script was exiting after 'Application Configuration Status:' - Issue: ((total_browsers++)) returns 1 when var is 0 - With 'set -e', non-zero return causes immediate exit - Solution: Use var=$((var + 1)) instead of ((var++)) Changed all increment operations: - ((total_browsers++)) → total_browsers=$((total_browsers + 1)) - ((configured_browsers++)) → configured_browsers=$((configured_browsers + 1)) This prevents script termination and allows proper browser detection to complete and display configuration status for all browsers.
1314 lines
50 KiB
Bash
Executable File
1314 lines
50 KiB
Bash
Executable File
#!/bin/bash
|
||
# Working Interactive System Optimizer
|
||
|
||
set -euo pipefail
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# Configuration
|
||
BACKUP_DIR="/var/lib/system-tuning/backups"
|
||
LOG_FILE="/var/log/system-optimization.log"
|
||
|
||
log() {
|
||
echo -e "${BLUE}[INFO]${NC} $1"
|
||
[[ -w "$(dirname "$LOG_FILE")" ]] && echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
success() {
|
||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
[[ -w "$(dirname "$LOG_FILE")" ]] && echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
warn() {
|
||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
[[ -w "$(dirname "$LOG_FILE")" ]] && echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
[[ -w "$(dirname "$LOG_FILE")" ]] && echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
check_root() {
|
||
if [[ $EUID -ne 0 ]]; then
|
||
error "This script must be run as root"
|
||
echo "Usage: sudo $0"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
analyze_and_prompt() {
|
||
log "Analyzing current system optimizations..."
|
||
|
||
# Get system info
|
||
local ram_gb=$(free -g | awk '/^Mem:|^Speicher:/{print $2}')
|
||
local cpu_cores=$(nproc)
|
||
|
||
echo ""
|
||
echo "📊 System Information:"
|
||
echo " 💾 RAM: ${ram_gb}GB"
|
||
echo " 🖥️ CPU: ${cpu_cores} cores"
|
||
echo ""
|
||
|
||
# Check and prompt for each optimization
|
||
local needs_changes=false
|
||
|
||
# === ZRAM CHECK ===
|
||
echo "🗜️ zram Compressed Swap Analysis:"
|
||
local optimal_size=$((ram_gb / 2))
|
||
[[ $optimal_size -lt 2 ]] && optimal_size=2
|
||
|
||
if [[ -e /dev/zram0 ]] && swapon --show | grep -q zram0; then
|
||
local zram_size=$(swapon --show | grep zram0 | awk '{print $3}')
|
||
local zram_gb=$(echo "$zram_size" | sed 's/[^0-9.]//g' | cut -d. -f1)
|
||
|
||
echo " 📈 Current: $zram_size"
|
||
echo " 📊 Optimal: ${optimal_size}GB"
|
||
|
||
if [[ $zram_gb -gt $((optimal_size + 2)) ]] || [[ $zram_gb -lt $((optimal_size - 1)) ]]; then
|
||
echo " ⚠️ Current size is suboptimal"
|
||
needs_changes=true
|
||
read -p " Would you like to reconfigure zram to ${optimal_size}GB? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_ZRAM=true
|
||
else
|
||
SETUP_ZRAM=false
|
||
fi
|
||
else
|
||
echo " ✅ Size is optimal"
|
||
SETUP_ZRAM=false
|
||
fi
|
||
else
|
||
echo " ❌ Not configured"
|
||
echo " 📊 Recommended: ${optimal_size}GB"
|
||
needs_changes=true
|
||
read -p " Would you like to configure zram? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_ZRAM=true
|
||
else
|
||
SETUP_ZRAM=false
|
||
fi
|
||
fi
|
||
echo ""
|
||
|
||
# === TMPFS CHECK ===
|
||
echo "💾 tmpfs Cache System Analysis:"
|
||
local tmpfs_count=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l)
|
||
if [[ $tmpfs_count -gt 0 ]]; then
|
||
echo " ✅ Well configured ($tmpfs_count active mounts)"
|
||
echo " 📁 Current mounted caches:"
|
||
mount | grep "tmpfs.*tmpfs-cache" | head -3 | awk '{print " " $3 " (" $6 ")"}' | tr -d '()'
|
||
[[ $tmpfs_count -gt 3 ]] && echo " ... and $((tmpfs_count - 3)) more"
|
||
echo ""
|
||
echo " 🔍 Scanning for additional optimization opportunities..."
|
||
else
|
||
echo " ❌ Not configured"
|
||
echo " 🔍 Scanning system for cache directories..."
|
||
fi
|
||
|
||
# === OVERLAY FILESYSTEM CHECK ===
|
||
echo "🗂️ Overlay Filesystem Analysis:"
|
||
local overlay_count=$(mount -t overlay | wc -l)
|
||
if [[ $overlay_count -gt 0 ]]; then
|
||
echo " ⚠️ Found $overlay_count overlay mounts (deprecated for desktop use)"
|
||
echo " 📁 Current overlay mounts:"
|
||
mount -t overlay | head -3 | awk '{print " " $3 " (overlay)"}'
|
||
[[ $overlay_count -gt 3 ]] && echo " ... and $((overlay_count - 3)) more"
|
||
echo ""
|
||
echo " 💡 Overlays are complex and rarely needed on desktop systems."
|
||
echo " 💡 Consider removing them unless specifically required."
|
||
needs_changes=true
|
||
read -p " Would you like to remove overlay mounts? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
REMOVE_OVERLAYS=true
|
||
else
|
||
REMOVE_OVERLAYS=false
|
||
fi
|
||
else
|
||
echo " ✅ No overlay mounts found (good - not needed for desktop)"
|
||
REMOVE_OVERLAYS=false
|
||
fi
|
||
echo ""
|
||
|
||
# Always analyze potential tmpfs candidates (even if already configured)
|
||
local cache_analysis=""
|
||
local total_cache_size=0
|
||
local additional_opportunities=""
|
||
|
||
# Check browser caches
|
||
for user_home in /home/*; do
|
||
if [[ -d "$user_home" ]]; then
|
||
local browser_cache_size=0
|
||
for cache_dir in "$user_home/.cache/google-chrome" "$user_home/.cache/firefox" "$user_home/.cache/chromium" "$user_home/.cache/microsoft-edge" "$user_home/.cache/brave" "$user_home/.cache/opera"; do
|
||
if [[ -d "$cache_dir" ]]; then
|
||
local size=$(du -sm "$cache_dir" 2>/dev/null | cut -f1 || echo 0)
|
||
browser_cache_size=$((browser_cache_size + size))
|
||
fi
|
||
done
|
||
if [[ $browser_cache_size -gt 0 ]]; then
|
||
cache_analysis="${cache_analysis} Browser caches: ${browser_cache_size}MB\n"
|
||
total_cache_size=$((total_cache_size + browser_cache_size))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Check development tool caches
|
||
for user_home in /home/*; do
|
||
if [[ -d "$user_home" ]]; then
|
||
local dev_cache_size=0
|
||
|
||
# Node.js/npm cache
|
||
if [[ -d "$user_home/.npm" ]]; then
|
||
local npm_size=$(du -sm "$user_home/.npm" 2>/dev/null | cut -f1 || echo 0)
|
||
dev_cache_size=$((dev_cache_size + npm_size))
|
||
fi
|
||
|
||
# Python pip cache
|
||
if [[ -d "$user_home/.cache/pip" ]]; then
|
||
local pip_size=$(du -sm "$user_home/.cache/pip" 2>/dev/null | cut -f1 || echo 0)
|
||
dev_cache_size=$((dev_cache_size + pip_size))
|
||
fi
|
||
|
||
# VS Code cache
|
||
if [[ -d "$user_home/.vscode" ]]; then
|
||
local vscode_size=$(du -sm "$user_home/.vscode" 2>/dev/null | cut -f1 || echo 0)
|
||
dev_cache_size=$((dev_cache_size + vscode_size))
|
||
fi
|
||
|
||
if [[ $dev_cache_size -gt 0 ]]; then
|
||
cache_analysis="${cache_analysis} Development caches: ${dev_cache_size}MB\n"
|
||
total_cache_size=$((total_cache_size + dev_cache_size))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Check KDE/Plasma caches if detected
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
for user_home in /home/*; do
|
||
if [[ -d "$user_home" ]]; then
|
||
local kde_cache_size=0
|
||
for kde_dir in ".cache/baloo" ".cache/plasma" ".cache/krunner" ".cache/thumbnails" ".cache/mesa_shader_cache"; do
|
||
if [[ -d "$user_home/$kde_dir" ]]; then
|
||
local size=$(du -sm "$user_home/$kde_dir" 2>/dev/null | cut -f1 || echo 0)
|
||
kde_cache_size=$((kde_cache_size + size))
|
||
fi
|
||
done
|
||
if [[ $kde_cache_size -gt 0 ]]; then
|
||
cache_analysis="${cache_analysis} KDE/Plasma caches: ${kde_cache_size}MB\n"
|
||
total_cache_size=$((total_cache_size + kde_cache_size))
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
|
||
# Look for additional optimization opportunities
|
||
for user_home in /home/*; do
|
||
if [[ -d "$user_home" ]]; then
|
||
# Check for gaming caches
|
||
if [[ -d "$user_home/.steam" ]]; then
|
||
local steam_cache_size=$(du -sm "$user_home/.steam/steam/appcache" 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $steam_cache_size -gt 50 ]]; then
|
||
additional_opportunities="${additional_opportunities} Steam cache: ${steam_cache_size}MB (gaming profile recommended)\n"
|
||
fi
|
||
fi
|
||
|
||
# Check for shader caches (important for gaming/graphics)
|
||
if [[ -d "$user_home/.local/share/Steam/steamapps/shadercache" ]]; then
|
||
local shader_cache_size=$(du -sm "$user_home/.local/share/Steam/steamapps/shadercache" 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $shader_cache_size -gt 100 ]]; then
|
||
additional_opportunities="${additional_opportunities} GPU shader cache: ${shader_cache_size}MB (CRITICAL for gaming performance)\n"
|
||
fi
|
||
fi
|
||
|
||
# Check for container development caches
|
||
if [[ -d "$user_home/.docker" ]]; then
|
||
local docker_cache_size=$(du -sm "$user_home/.docker" 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $docker_cache_size -gt 100 ]]; then
|
||
additional_opportunities="${additional_opportunities} Docker cache: ${docker_cache_size}MB (development profile)\n"
|
||
fi
|
||
fi
|
||
|
||
# Check for large build caches
|
||
if [[ -d "$user_home/.gradle/caches" ]]; then
|
||
local gradle_cache_size=$(du -sm "$user_home/.gradle/caches" 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $gradle_cache_size -gt 200 ]]; then
|
||
additional_opportunities="${additional_opportunities} Gradle build cache: ${gradle_cache_size}MB (development profile)\n"
|
||
fi
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Check system-level opportunities
|
||
if [[ -d /var/lib/flatpak ]]; then
|
||
local flatpak_size=$(du -sm /var/lib/flatpak 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $flatpak_size -gt 1000 ]]; then
|
||
additional_opportunities="${additional_opportunities} Flatpak apps: ${flatpak_size}MB (consider tmpfs for .cache)\n"
|
||
fi
|
||
fi
|
||
|
||
# Check package cache
|
||
if [[ -d /var/cache/apt ]]; then
|
||
local apt_cache_size=$(du -sm /var/cache/apt 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $apt_cache_size -gt 0 ]]; then
|
||
cache_analysis="${cache_analysis} Package cache: ${apt_cache_size}MB\n"
|
||
total_cache_size=$((total_cache_size + apt_cache_size))
|
||
fi
|
||
fi
|
||
|
||
# Check temp directories
|
||
local tmp_size=$(du -sm /tmp 2>/dev/null | cut -f1 || echo 0)
|
||
if [[ $tmp_size -gt 100 ]]; then
|
||
cache_analysis="${cache_analysis} Temp files: ${tmp_size}MB\n"
|
||
fi
|
||
|
||
if [[ $total_cache_size -gt 0 ]]; then
|
||
echo " 📊 Found cacheable data:"
|
||
echo -e "$cache_analysis"
|
||
echo " 💡 Total cache size: ${total_cache_size}MB"
|
||
|
||
# Recommend profile based on cache size and RAM
|
||
local recommended_profile="medium"
|
||
if [[ $ram_gb -ge 16 ]] && [[ $total_cache_size -gt 2000 ]]; then
|
||
recommended_profile="large"
|
||
echo " 📈 Recommended: Large profile (${ram_gb}GB RAM, ${total_cache_size}MB cache)"
|
||
elif [[ $ram_gb -le 8 ]] || [[ $total_cache_size -lt 1000 ]]; then
|
||
recommended_profile="small"
|
||
echo " 📈 Recommended: Small profile (${ram_gb}GB RAM, ${total_cache_size}MB cache)"
|
||
else
|
||
echo " 📈 Recommended: Medium profile (${ram_gb}GB RAM, ${total_cache_size}MB cache)"
|
||
fi
|
||
else
|
||
echo " 📊 No significant cache data found"
|
||
echo " 💡 tmpfs can still improve performance for future cache usage"
|
||
fi
|
||
|
||
# Check for additional opportunities regardless of current setup
|
||
if [[ -n "$additional_opportunities" ]]; then
|
||
echo ""
|
||
echo " 🎯 Additional Optimization Opportunities:"
|
||
echo -e "$additional_opportunities"
|
||
fi
|
||
|
||
# Determine if changes are needed
|
||
if [[ $tmpfs_count -gt 0 ]]; then
|
||
# Already configured - check if improvements are possible
|
||
local current_mounts=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l)
|
||
local recommended_mounts=4
|
||
|
||
# Check if KDE is detected and we don't have a KDE-specific mount
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
if ! mount | grep -q "tmpfs-cache/kde"; then
|
||
recommended_mounts=5
|
||
echo " 💡 KDE environment detected - could add dedicated KDE cache mount"
|
||
fi
|
||
fi
|
||
|
||
# Check if development mount exists
|
||
if ! mount | grep -q "tmpfs-cache/development" && [[ $total_cache_size -gt 500 ]]; then
|
||
echo " 💡 Development caches detected - could add dedicated development mount"
|
||
recommended_mounts=$((recommended_mounts + 1))
|
||
fi
|
||
|
||
if [[ $current_mounts -lt $recommended_mounts ]] || [[ $total_cache_size -gt 3000 ]]; then
|
||
echo " ⚠️ Current setup could be enhanced"
|
||
needs_changes=true
|
||
read -p " Would you like to enhance your tmpfs setup? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_TMPFS=true
|
||
else
|
||
SETUP_TMPFS=false
|
||
fi
|
||
else
|
||
echo " ✅ Current tmpfs setup is optimal for detected cache usage"
|
||
SETUP_TMPFS=false
|
||
fi
|
||
else
|
||
# Not configured at all
|
||
needs_changes=true
|
||
read -p " Would you like to set up tmpfs caches? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_TMPFS=true
|
||
else
|
||
SETUP_TMPFS=false
|
||
fi
|
||
fi
|
||
echo ""
|
||
|
||
# === KERNEL PARAMS CHECK ===
|
||
echo "⚙️ Kernel Parameters Analysis:"
|
||
if [[ -f /etc/sysctl.d/99-system-optimization.conf ]]; then
|
||
local swappiness=$(sysctl -n vm.swappiness 2>/dev/null)
|
||
local dirty_ratio=$(sysctl -n vm.dirty_ratio 2>/dev/null)
|
||
echo " ✅ Configuration exists"
|
||
echo " 📊 Current: swappiness=$swappiness, dirty_ratio=$dirty_ratio"
|
||
|
||
# Check if optimal
|
||
local opt_swap=5
|
||
local opt_dirty=5
|
||
if [[ $ram_gb -ge 16 ]]; then
|
||
opt_swap=1; opt_dirty=3
|
||
elif [[ $ram_gb -le 4 ]]; then
|
||
opt_swap=10; opt_dirty=10
|
||
fi
|
||
|
||
echo " 📊 Optimal: swappiness=$opt_swap, dirty_ratio=$opt_dirty"
|
||
|
||
if [[ "$swappiness" != "$opt_swap" ]] || [[ "$dirty_ratio" != "$opt_dirty" ]]; then
|
||
echo " ⚠️ Parameters could be optimized"
|
||
needs_changes=true
|
||
read -p " Would you like to optimize kernel parameters? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_KERNEL=true
|
||
else
|
||
SETUP_KERNEL=false
|
||
fi
|
||
else
|
||
echo " ✅ Parameters are optimal"
|
||
SETUP_KERNEL=false
|
||
fi
|
||
else
|
||
echo " ❌ Not optimized"
|
||
needs_changes=true
|
||
read -p " Would you like to optimize kernel parameters? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_KERNEL=true
|
||
else
|
||
SETUP_KERNEL=false
|
||
fi
|
||
fi
|
||
echo ""
|
||
|
||
# === SERVICE CHECK ===
|
||
echo "🔄 Systemd Service Analysis:"
|
||
if systemctl is-enabled system-optimization.service &>/dev/null; then
|
||
echo " ✅ Service is installed and enabled"
|
||
SETUP_SERVICE=false
|
||
else
|
||
echo " ❌ Service not installed"
|
||
needs_changes=true
|
||
read -p " Would you like to install the systemd service? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
SETUP_SERVICE=true
|
||
else
|
||
SETUP_SERVICE=false
|
||
fi
|
||
fi
|
||
echo ""
|
||
|
||
# Summary
|
||
if [[ $needs_changes == false ]]; then
|
||
success "🎉 All optimizations are already in great shape!"
|
||
echo ""
|
||
echo "📋 Current Optimization Details:"
|
||
echo "==============================="
|
||
|
||
# Show detailed zram info
|
||
if [[ -e /dev/zram0 ]] && swapon --show | grep -q zram0; then
|
||
local zram_size=$(swapon --show | grep zram0 | awk '{print $3}')
|
||
local zram_used=$(swapon --show | grep zram0 | awk '{print $4}')
|
||
echo ""
|
||
echo "🗜️ zram Compressed Swap:"
|
||
echo " 💾 Size: $zram_size (currently using: ${zram_used:-0B})"
|
||
echo " ⚡ Purpose: Compressed swap in RAM for better performance"
|
||
echo " 📈 Benefit: ~2-4x compression ratio reduces memory pressure"
|
||
echo " 🔧 Algorithm: $(cat /sys/block/zram0/comp_algorithm 2>/dev/null | grep -o '\[.*\]' | tr -d '[]' || echo 'lz4')"
|
||
fi
|
||
|
||
# Show detailed tmpfs info
|
||
local tmpfs_count=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l)
|
||
if [[ $tmpfs_count -gt 0 ]]; then
|
||
echo ""
|
||
echo "💾 tmpfs Cache System:"
|
||
echo " 📊 Active Mounts: $tmpfs_count cache filesystems in RAM"
|
||
echo ""
|
||
echo " 📁 Mount Details:"
|
||
mount | grep "tmpfs.*tmpfs-cache" | while read -r line; do
|
||
local mount_point=$(echo "$line" | awk '{print $3}')
|
||
local mount_name=$(basename "$mount_point")
|
||
local size_info=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2)
|
||
local df_info=$(df -h "$mount_point" 2>/dev/null | tail -1)
|
||
local used=$(echo "$df_info" | awk '{print $3}')
|
||
local use_percent=$(echo "$df_info" | awk '{print $5}')
|
||
|
||
printf " • %-12s: %8s (%s used, %s)\n" "$mount_name" "$size_info" "$used" "$use_percent"
|
||
|
||
# Explain what each mount is for
|
||
case "$mount_name" in
|
||
"browser")
|
||
echo " 📝 Purpose: Browser caches (Chrome, Firefox, etc.)"
|
||
echo " ⚡ Benefit: Faster page loading, reduced SSD wear"
|
||
;;
|
||
"ide")
|
||
echo " 📝 Purpose: IDE and editor caches (VS Code, JetBrains)"
|
||
echo " ⚡ Benefit: Faster project loading, syntax highlighting"
|
||
;;
|
||
"packages")
|
||
echo " 📝 Purpose: Package manager cache (APT, etc.)"
|
||
echo " ⚡ Benefit: Faster package operations, reduced downloads"
|
||
;;
|
||
"development")
|
||
echo " 📝 Purpose: Development tool caches (npm, pip, Docker)"
|
||
echo " ⚡ Benefit: Faster builds, dependency resolution"
|
||
;;
|
||
"kde")
|
||
echo " 📝 Purpose: KDE/Plasma desktop caches (Baloo, thumbnails)"
|
||
echo " ⚡ Benefit: Faster file indexing, desktop responsiveness"
|
||
;;
|
||
"thumbnails")
|
||
echo " 📝 Purpose: File manager thumbnail cache"
|
||
echo " ⚡ Benefit: Instant thumbnail generation"
|
||
;;
|
||
esac
|
||
echo ""
|
||
done
|
||
|
||
# Calculate total tmpfs allocation
|
||
local total_kb=0
|
||
while read -r line; do
|
||
local size_kb=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2 | sed 's/k$//')
|
||
total_kb=$((total_kb + size_kb))
|
||
done < <(mount | grep "tmpfs.*tmpfs-cache")
|
||
local total_mb=$((total_kb / 1024))
|
||
|
||
# Get RAM info with proper fallback and locale support
|
||
local ram_gb=$(free -g | awk '/^Mem:|^Speicher:/{print $2}')
|
||
local ram_mb=$(free -m | awk '/^Mem:|^Speicher:/{print $2}')
|
||
|
||
# Handle edge cases for RAM detection
|
||
if [[ $ram_gb -eq 0 && $ram_mb -gt 0 ]]; then
|
||
ram_gb=$((ram_mb / 1024))
|
||
[[ $ram_gb -eq 0 ]] && ram_gb=1 # Minimum 1GB for display
|
||
fi
|
||
|
||
# Calculate percentage safely
|
||
local ram_percent=0
|
||
if [[ $ram_gb -gt 0 ]]; then
|
||
ram_percent=$(( (total_mb * 100) / (ram_gb * 1024) ))
|
||
elif [[ $ram_mb -gt 0 ]]; then
|
||
ram_percent=$(( (total_mb * 100) / ram_mb ))
|
||
fi
|
||
|
||
echo " 📊 Total tmpfs allocation: ${total_mb}MB (${ram_percent}% of ${ram_gb}GB RAM)"
|
||
echo " 🚀 Performance gain: Cache operations run at RAM speed (~50-100x faster)"
|
||
echo " 💿 SSD protection: Reduces write cycles by ~60-80% for cached data"
|
||
fi
|
||
|
||
# Show kernel parameter details
|
||
if [[ -f /etc/sysctl.d/99-system-optimization.conf ]]; then
|
||
local swappiness=$(sysctl -n vm.swappiness 2>/dev/null)
|
||
local dirty_ratio=$(sysctl -n vm.dirty_ratio 2>/dev/null)
|
||
local dirty_bg_ratio=$(sysctl -n vm.dirty_background_ratio 2>/dev/null)
|
||
echo ""
|
||
echo "⚙️ Kernel Parameter Optimizations:"
|
||
echo " 🔧 vm.swappiness = $swappiness (how aggressively to use swap)"
|
||
echo " 📝 Purpose: $(if [[ $swappiness -le 5 ]]; then echo "Prefer RAM over swap for better performance"; else echo "Balanced RAM/swap usage"; fi)"
|
||
echo ""
|
||
echo " 🔧 vm.dirty_ratio = $dirty_ratio (% RAM for write cache)"
|
||
echo " 📝 Purpose: Controls when dirty pages are written to disk"
|
||
echo ""
|
||
echo " 🔧 vm.dirty_background_ratio = $dirty_bg_ratio (background write threshold)"
|
||
echo " 📝 Purpose: When background writing starts"
|
||
echo ""
|
||
|
||
# Use the ram_gb variable calculated above, or recalculate if needed
|
||
local ram_display_gb=${ram_gb:-$(free -g | awk '/^Mem:|^Speicher:/{print $2}')}
|
||
if [[ $ram_display_gb -eq 0 ]]; then
|
||
local ram_display_mb=$(free -m | awk '/^Mem:|^Speicher:/{print $2}')
|
||
ram_display_gb=$((ram_display_mb / 1024))
|
||
[[ $ram_display_gb -eq 0 ]] && ram_display_gb=1
|
||
fi
|
||
|
||
echo " ⚡ Combined benefit: Optimized memory management for your ${ram_display_gb}GB system"
|
||
fi
|
||
|
||
# Show service status
|
||
if systemctl is-enabled system-optimization.service &>/dev/null; then
|
||
echo ""
|
||
echo "🔄 Persistence Service:"
|
||
echo " ✅ system-optimization.service enabled"
|
||
echo " 📝 Purpose: Automatically recreates optimizations after reboot"
|
||
echo " 🔧 Restores: zram device, tmpfs mounts, bind mounts"
|
||
fi
|
||
|
||
echo ""
|
||
echo "💡 Quick Reference Commands:"
|
||
echo " ./tmpfs-info.sh # Detailed tmpfs status and configuration"
|
||
echo " ./quick-status-check.sh # Quick system overview"
|
||
echo " df -h /tmp/tmpfs-cache/* # Check tmpfs usage"
|
||
echo " swapon --show # Check zram status"
|
||
echo ""
|
||
|
||
# Check if applications are configured for tmpfs
|
||
local current_user=$(logname 2>/dev/null || echo $SUDO_USER)
|
||
local user_home=$(eval echo ~$current_user)
|
||
|
||
echo "📱 Application Configuration Status:"
|
||
local configured_browsers=0
|
||
local total_browsers=0
|
||
|
||
# Check each browser
|
||
if [[ -d "$user_home/.mozilla/firefox" ]]; then
|
||
total_browsers=$((total_browsers + 1))
|
||
if grep -q "tmpfs-cache" "$user_home/.mozilla/firefox"/*default*/prefs.js 2>/dev/null; then
|
||
echo " ✅ Firefox: Configured"
|
||
configured_browsers=$((configured_browsers + 1))
|
||
else
|
||
echo " ⚠️ Firefox: Not configured"
|
||
fi
|
||
fi
|
||
|
||
if [[ -d "$user_home/.config/BraveSoftware" ]]; then
|
||
total_browsers=$((total_browsers + 1))
|
||
if [[ -f "$user_home/.local/share/applications/brave-browser.desktop" ]] && \
|
||
grep -q "tmpfs-cache" "$user_home/.local/share/applications/brave-browser.desktop" 2>/dev/null; then
|
||
echo " ✅ Brave: Configured"
|
||
configured_browsers=$((configured_browsers + 1))
|
||
else
|
||
echo " ⚠️ Brave: Not configured"
|
||
fi
|
||
fi
|
||
|
||
if [[ -d "$user_home/.config/google-chrome" ]]; then
|
||
total_browsers=$((total_browsers + 1))
|
||
if [[ -f "$user_home/.local/share/applications/google-chrome.desktop" ]] && \
|
||
grep -q "tmpfs-cache" "$user_home/.local/share/applications/google-chrome.desktop" 2>/dev/null; then
|
||
echo " ✅ Chrome: Configured"
|
||
configured_browsers=$((configured_browsers + 1))
|
||
else
|
||
echo " ⚠️ Chrome: Not configured"
|
||
fi
|
||
fi
|
||
|
||
if [[ -d "$user_home/.config/chromium" ]]; then
|
||
total_browsers=$((total_browsers + 1))
|
||
if [[ -f "$user_home/.local/share/applications/chromium-browser.desktop" ]] && \
|
||
grep -q "tmpfs-cache" "$user_home/.local/share/applications/chromium-browser.desktop" 2>/dev/null; then
|
||
echo " ✅ Chromium: Configured"
|
||
configured_browsers=$((configured_browsers + 1))
|
||
else
|
||
echo " ⚠️ Chromium: Not configured"
|
||
fi
|
||
fi
|
||
|
||
# Check dev tools
|
||
local npm_configured=false
|
||
if command -v npm &>/dev/null; then
|
||
local npm_cache=$(sudo -u $current_user npm config get cache 2>/dev/null)
|
||
if [[ "$npm_cache" == *"tmpfs-cache"* ]]; then
|
||
echo " ✅ NPM: Configured"
|
||
npm_configured=true
|
||
else
|
||
echo " ⚠️ NPM: Not configured"
|
||
fi
|
||
fi
|
||
|
||
local pip_configured=false
|
||
if command -v pip3 &>/dev/null || command -v pip &>/dev/null; then
|
||
if [[ -f "$user_home/.config/pip/pip.conf" ]] && \
|
||
grep -q "tmpfs-cache" "$user_home/.config/pip/pip.conf" 2>/dev/null; then
|
||
echo " ✅ Pip: Configured"
|
||
pip_configured=true
|
||
else
|
||
echo " ⚠️ Pip: Not configured"
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
if [[ $configured_browsers -lt $total_browsers ]] || [[ $npm_configured == false ]] || [[ $pip_configured == false ]]; then
|
||
read -p " Would you like to configure/reconfigure your applications? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
echo ""
|
||
configure_applications_for_tmpfs
|
||
echo ""
|
||
success "Configuration complete! Restart your applications to use tmpfs caches."
|
||
fi
|
||
else
|
||
echo " ✅ Applications are configured to use tmpfs caches"
|
||
fi
|
||
echo ""
|
||
echo "🎯 Your system is fully optimized for maximum performance!"
|
||
exit 0
|
||
fi
|
||
|
||
# Show what will be done
|
||
local actions=()
|
||
[[ $SETUP_ZRAM == true ]] && actions+=("zram")
|
||
[[ $SETUP_TMPFS == true ]] && actions+=("tmpfs")
|
||
[[ $SETUP_KERNEL == true ]] && actions+=("kernel")
|
||
[[ $SETUP_SERVICE == true ]] && actions+=("service")
|
||
[[ $REMOVE_OVERLAYS == true ]] && actions+=("remove-overlays")
|
||
|
||
if [[ ${#actions[@]} -gt 0 ]]; then
|
||
echo "📋 Selected optimizations: ${actions[*]}"
|
||
echo ""
|
||
read -p "Proceed with these optimizations? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
log "User cancelled optimization"
|
||
exit 0
|
||
fi
|
||
else
|
||
log "No optimizations selected"
|
||
exit 0
|
||
fi
|
||
|
||
# Export variables for the optimization functions
|
||
export SETUP_ZRAM SETUP_TMPFS SETUP_KERNEL SETUP_SERVICE REMOVE_OVERLAYS
|
||
export SYSTEM_RAM_GB=$ram_gb
|
||
}
|
||
|
||
setup_zram() {
|
||
if [[ $SETUP_ZRAM != true ]]; then
|
||
return 0
|
||
fi
|
||
|
||
log "Configuring zram..."
|
||
|
||
# Calculate optimal size
|
||
local zram_size=$((SYSTEM_RAM_GB / 2))
|
||
[[ $zram_size -lt 2 ]] && zram_size=2
|
||
|
||
# Remove existing zram properly
|
||
if [[ -e /dev/zram0 ]]; then
|
||
log "Removing existing zram configuration..."
|
||
# Disable swap first
|
||
swapoff /dev/zram0 2>/dev/null || true
|
||
sleep 1
|
||
|
||
# Reset the device
|
||
echo 1 > /sys/block/zram0/reset 2>/dev/null || true
|
||
sleep 1
|
||
|
||
# Remove the device if possible
|
||
if [[ -e /sys/class/zram-control/hot_remove ]]; then
|
||
echo 0 > /sys/class/zram-control/hot_remove 2>/dev/null || true
|
||
fi
|
||
sleep 1
|
||
fi
|
||
|
||
# Unload and reload zram module for clean state
|
||
rmmod zram 2>/dev/null || true
|
||
sleep 1
|
||
|
||
# Configure new zram
|
||
log "Setting up new zram with ${zram_size}GB..."
|
||
modprobe zram num_devices=1
|
||
|
||
# Wait for device to be ready
|
||
local attempts=0
|
||
while [[ ! -e /dev/zram0 && $attempts -lt 10 ]]; do
|
||
sleep 1
|
||
((attempts++))
|
||
done
|
||
|
||
if [[ ! -e /dev/zram0 ]]; then
|
||
error "Failed to create zram device"
|
||
return 1
|
||
fi
|
||
|
||
# Configure the new device
|
||
echo "${zram_size}G" > /sys/block/zram0/disksize
|
||
mkswap /dev/zram0
|
||
swapon /dev/zram0
|
||
|
||
success "zram reconfigured with ${zram_size}GB"
|
||
}
|
||
|
||
remove_overlays() {
|
||
if [[ $REMOVE_OVERLAYS != true ]]; then
|
||
return 0
|
||
fi
|
||
|
||
log "Removing overlay filesystem mounts..."
|
||
|
||
# Get list of overlay mounts
|
||
local overlay_mounts=$(mount -t overlay | awk '{print $3}')
|
||
|
||
if [[ -z "$overlay_mounts" ]]; then
|
||
log "No overlay mounts found to remove"
|
||
return 0
|
||
fi
|
||
|
||
# Unmount each overlay
|
||
echo "$overlay_mounts" | while read -r mount_point; do
|
||
if [[ -n "$mount_point" ]]; then
|
||
log " Unmounting overlay: $mount_point"
|
||
if umount "$mount_point" 2>/dev/null; then
|
||
success " Successfully unmounted: $mount_point"
|
||
|
||
# Clean up overlay work directories if they exist in /tmp
|
||
local work_dir="/tmp/overlay-work$(basename "$mount_point")"
|
||
local upper_dir="/tmp/overlay-upper$(basename "$mount_point")"
|
||
|
||
if [[ -d "$work_dir" ]]; then
|
||
rm -rf "$work_dir"
|
||
log " Cleaned up work directory: $work_dir"
|
||
fi
|
||
|
||
if [[ -d "$upper_dir" ]]; then
|
||
rm -rf "$upper_dir"
|
||
log " Cleaned up upper directory: $upper_dir"
|
||
fi
|
||
else
|
||
warn " Failed to unmount: $mount_point (may be in use)"
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Remove any overlay entries from fstab
|
||
if [[ -f /etc/fstab ]] && grep -q "overlay" /etc/fstab; then
|
||
log "Removing overlay entries from /etc/fstab..."
|
||
cp /etc/fstab /etc/fstab.backup.$(date +%s)
|
||
grep -v "overlay" /etc/fstab > /etc/fstab.tmp && mv /etc/fstab.tmp /etc/fstab
|
||
success "Removed overlay entries from /etc/fstab"
|
||
fi
|
||
|
||
success "Overlay filesystem cleanup completed"
|
||
}
|
||
|
||
setup_tmpfs() {
|
||
if [[ $SETUP_TMPFS != true ]]; then
|
||
return 0
|
||
fi
|
||
|
||
log "Setting up tmpfs cache optimization..."
|
||
|
||
# Determine profile based on RAM
|
||
local profile="medium"
|
||
if [[ $SYSTEM_RAM_GB -ge 16 ]]; then
|
||
profile="large"
|
||
elif [[ $SYSTEM_RAM_GB -le 8 ]]; then
|
||
profile="small"
|
||
fi
|
||
|
||
# Create tmpfs directories
|
||
mkdir -p /tmp/tmpfs-cache/{browser,ide,packages,thumbnails,development,kde}
|
||
|
||
# Remove existing mounts if they exist
|
||
for dir in browser ide packages thumbnails development kde; do
|
||
if mount | grep -q "/tmp/tmpfs-cache/$dir"; then
|
||
umount "/tmp/tmpfs-cache/$dir" 2>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
# Set up tmpfs mounts based on profile
|
||
case "$profile" in
|
||
"large")
|
||
mount -t tmpfs -o size=4G tmpfs /tmp/tmpfs-cache/browser
|
||
mount -t tmpfs -o size=2G tmpfs /tmp/tmpfs-cache/ide
|
||
mount -t tmpfs -o size=3G tmpfs /tmp/tmpfs-cache/packages
|
||
mount -t tmpfs -o size=512M tmpfs /tmp/tmpfs-cache/thumbnails
|
||
mount -t tmpfs -o size=2G tmpfs /tmp/tmpfs-cache/development
|
||
# KDE-specific cache if detected
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
mount -t tmpfs -o size=1G tmpfs /tmp/tmpfs-cache/kde
|
||
fi
|
||
;;
|
||
"medium")
|
||
mount -t tmpfs -o size=2G tmpfs /tmp/tmpfs-cache/browser
|
||
mount -t tmpfs -o size=1G tmpfs /tmp/tmpfs-cache/ide
|
||
mount -t tmpfs -o size=2G tmpfs /tmp/tmpfs-cache/packages
|
||
mount -t tmpfs -o size=256M tmpfs /tmp/tmpfs-cache/thumbnails
|
||
mount -t tmpfs -o size=1G tmpfs /tmp/tmpfs-cache/development
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
mount -t tmpfs -o size=512M tmpfs /tmp/tmpfs-cache/kde
|
||
fi
|
||
;;
|
||
"small")
|
||
mount -t tmpfs -o size=1G tmpfs /tmp/tmpfs-cache/browser
|
||
mount -t tmpfs -o size=512M tmpfs /tmp/tmpfs-cache/ide
|
||
mount -t tmpfs -o size=1G tmpfs /tmp/tmpfs-cache/packages
|
||
mount -t tmpfs -o size=128M tmpfs /tmp/tmpfs-cache/thumbnails
|
||
mount -t tmpfs -o size=512M tmpfs /tmp/tmpfs-cache/development
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
mount -t tmpfs -o size=256M tmpfs /tmp/tmpfs-cache/kde
|
||
fi
|
||
;;
|
||
esac
|
||
|
||
# Bind mount package cache if apt is available
|
||
if [[ -d /var/cache/apt ]]; then
|
||
# Backup existing cache
|
||
if [[ ! -L /var/cache/apt ]] && [[ -d /var/cache/apt ]] && [[ ! -d /var/cache/apt.backup ]]; then
|
||
cp -a /var/cache/apt /var/cache/apt.backup
|
||
fi
|
||
|
||
# Create bind mount
|
||
mount --bind /tmp/tmpfs-cache/packages /var/cache/apt
|
||
fi
|
||
|
||
# Add fstab entries for persistence
|
||
local fstab_tmpfs="/etc/fstab.tmpfs"
|
||
local browser_size ide_size packages_size thumbnails_size development_size kde_size
|
||
|
||
case "$profile" in
|
||
"large")
|
||
browser_size="4G"
|
||
ide_size="2G"
|
||
packages_size="3G"
|
||
thumbnails_size="512M"
|
||
development_size="2G"
|
||
kde_size="1G"
|
||
;;
|
||
"medium")
|
||
browser_size="2G"
|
||
ide_size="1G"
|
||
packages_size="2G"
|
||
thumbnails_size="256M"
|
||
development_size="1G"
|
||
kde_size="512M"
|
||
;;
|
||
"small")
|
||
browser_size="1G"
|
||
ide_size="512M"
|
||
packages_size="1G"
|
||
thumbnails_size="128M"
|
||
development_size="512M"
|
||
kde_size="256M"
|
||
;;
|
||
esac
|
||
|
||
cat > "$fstab_tmpfs" << EOF
|
||
# tmpfs cache mounts - Generated $(date)
|
||
# Profile: $profile for ${SYSTEM_RAM_GB}GB RAM
|
||
tmpfs /tmp/tmpfs-cache/browser tmpfs size=${browser_size},noatime,nosuid,nodev 0 0
|
||
tmpfs /tmp/tmpfs-cache/ide tmpfs size=${ide_size},noatime,nosuid,nodev 0 0
|
||
tmpfs /tmp/tmpfs-cache/packages tmpfs size=${packages_size},noatime,nosuid,nodev 0 0
|
||
tmpfs /tmp/tmpfs-cache/thumbnails tmpfs size=${thumbnails_size},noatime,nosuid,nodev 0 0
|
||
tmpfs /tmp/tmpfs-cache/development tmpfs size=${development_size},noatime,nosuid,nodev 0 0
|
||
EOF
|
||
|
||
# Add KDE-specific mount if KDE is detected
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
echo "tmpfs /tmp/tmpfs-cache/kde tmpfs size=${kde_size},noatime,nosuid,nodev 0 0" >> "$fstab_tmpfs"
|
||
fi
|
||
|
||
success "tmpfs cache optimization enabled ($profile profile)"
|
||
|
||
# Automatically configure detected applications
|
||
configure_applications_for_tmpfs
|
||
|
||
# Show summary of what was configured
|
||
echo ""
|
||
echo "📋 tmpfs Setup Complete:"
|
||
echo "======================="
|
||
echo ""
|
||
echo "🔧 Created tmpfs mount points:"
|
||
mount | grep "tmpfs.*tmpfs-cache" | while read -r line; do
|
||
mount_point=$(echo "$line" | awk '{print $3}')
|
||
size=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2)
|
||
echo " 📁 $mount_point - Size: $size"
|
||
done
|
||
|
||
echo ""
|
||
echo "⚡ Performance Benefits:"
|
||
echo " • <20> Faster cache access (RAM speed vs SSD)"
|
||
echo " • 💿 Reduced SSD wear and tear"
|
||
echo " • 🧹 Automatic cleanup on reboot"
|
||
echo " • 🔋 Lower power consumption for cache operations"
|
||
}
|
||
|
||
configure_applications_for_tmpfs() {
|
||
log "Auto-configuring applications to use tmpfs caches..."
|
||
echo ""
|
||
|
||
local configured_count=0
|
||
local current_user=$(logname 2>/dev/null || echo $SUDO_USER)
|
||
local user_home=$(eval echo ~$current_user)
|
||
|
||
# Browser Configuration
|
||
echo "🌐 Configuring Browsers:"
|
||
|
||
# Firefox
|
||
for firefox_profile in "$user_home"/.mozilla/firefox/*.default* "$user_home"/.mozilla/firefox/*.default-release*; do
|
||
if [[ -d "$firefox_profile" ]]; then
|
||
local prefs_file="$firefox_profile/prefs.js"
|
||
if [[ -f "$prefs_file" ]]; then
|
||
# Backup original
|
||
cp "$prefs_file" "$prefs_file.backup.$(date +%s)" 2>/dev/null || true
|
||
|
||
# Remove old cache settings
|
||
sed -i '/browser.cache.disk.parent_directory/d' "$prefs_file" 2>/dev/null || true
|
||
|
||
# Add new cache location
|
||
echo 'user_pref("browser.cache.disk.parent_directory", "/tmp/tmpfs-cache/browser/firefox");' >> "$prefs_file"
|
||
|
||
# Create cache directory
|
||
mkdir -p /tmp/tmpfs-cache/browser/firefox
|
||
chown -R $current_user:$current_user /tmp/tmpfs-cache/browser/firefox
|
||
|
||
success " ✅ Firefox configured to use tmpfs cache"
|
||
((configured_count++))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Brave Browser
|
||
if [[ -d "$user_home/.config/BraveSoftware" ]]; then
|
||
mkdir -p /tmp/tmpfs-cache/browser/brave
|
||
mkdir -p "$user_home/.local/share/applications"
|
||
chown -R $current_user:$current_user /tmp/tmpfs-cache/browser/brave
|
||
|
||
local brave_desktop="$user_home/.local/share/applications/brave-browser.desktop"
|
||
cat > "$brave_desktop" << 'BRAVEEOF'
|
||
[Desktop Entry]
|
||
Version=1.0
|
||
Name=Brave Browser (tmpfs optimized)
|
||
Exec=brave-browser --disk-cache-dir=/tmp/tmpfs-cache/browser/brave %U
|
||
StartupNotify=true
|
||
Terminal=false
|
||
Icon=brave-browser
|
||
Type=Application
|
||
Categories=Network;WebBrowser;
|
||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
|
||
BRAVEEOF
|
||
chown $current_user:$current_user "$brave_desktop" 2>/dev/null || true
|
||
chmod +x "$brave_desktop" 2>/dev/null || true
|
||
success " ✅ Brave Browser configured to use tmpfs cache"
|
||
((configured_count++))
|
||
fi
|
||
|
||
# Google Chrome
|
||
if [[ -d "$user_home/.config/google-chrome" ]]; then
|
||
mkdir -p /tmp/tmpfs-cache/browser/google-chrome
|
||
mkdir -p "$user_home/.local/share/applications"
|
||
chown -R $current_user:$current_user /tmp/tmpfs-cache/browser/google-chrome
|
||
|
||
local chrome_desktop="$user_home/.local/share/applications/google-chrome.desktop"
|
||
cat > "$chrome_desktop" << 'CHROMEOF'
|
||
[Desktop Entry]
|
||
Version=1.0
|
||
Name=Google Chrome (tmpfs optimized)
|
||
Exec=google-chrome --disk-cache-dir=/tmp/tmpfs-cache/browser/google-chrome %U
|
||
StartupNotify=true
|
||
Terminal=false
|
||
Icon=google-chrome
|
||
Type=Application
|
||
Categories=Network;WebBrowser;
|
||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
|
||
CHROMEOF
|
||
chown $current_user:$current_user "$chrome_desktop" 2>/dev/null || true
|
||
chmod +x "$chrome_desktop" 2>/dev/null || true
|
||
success " ✅ Google Chrome configured to use tmpfs cache"
|
||
((configured_count++))
|
||
fi
|
||
|
||
# Chromium
|
||
if [[ -d "$user_home/.config/chromium" ]]; then
|
||
mkdir -p /tmp/tmpfs-cache/browser/chromium
|
||
mkdir -p "$user_home/.local/share/applications"
|
||
chown -R $current_user:$current_user /tmp/tmpfs-cache/browser/chromium
|
||
|
||
local chromium_desktop="$user_home/.local/share/applications/chromium-browser.desktop"
|
||
cat > "$chromium_desktop" << 'CHROMIUMEOF'
|
||
[Desktop Entry]
|
||
Version=1.0
|
||
Name=Chromium (tmpfs optimized)
|
||
Exec=chromium --disk-cache-dir=/tmp/tmpfs-cache/browser/chromium %U
|
||
StartupNotify=true
|
||
Terminal=false
|
||
Icon=chromium
|
||
Type=Application
|
||
Categories=Network;WebBrowser;
|
||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
|
||
CHROMIUMEOF
|
||
chown $current_user:$current_user "$chromium_desktop" 2>/dev/null || true
|
||
chmod +x "$chromium_desktop" 2>/dev/null || true
|
||
success " ✅ Chromium configured to use tmpfs cache"
|
||
((configured_count++))
|
||
fi
|
||
|
||
# Development Tools Configuration
|
||
echo ""
|
||
echo "💻 Configuring Development Tools:"
|
||
|
||
# NPM
|
||
if command -v npm &>/dev/null; then
|
||
sudo -u $current_user npm config set cache /tmp/tmpfs-cache/development/npm 2>/dev/null && \
|
||
success " ✅ NPM cache configured" && ((configured_count++))
|
||
fi
|
||
|
||
# Pip
|
||
if command -v pip3 &>/dev/null || command -v pip &>/dev/null; then
|
||
mkdir -p "$user_home/.config/pip"
|
||
cat > "$user_home/.config/pip/pip.conf" << 'PIPEOF'
|
||
[global]
|
||
cache-dir = /tmp/tmpfs-cache/development/pip
|
||
PIPEOF
|
||
chown $current_user:$current_user "$user_home/.config/pip/pip.conf" 2>/dev/null || true
|
||
success " ✅ Pip cache configured" && ((configured_count++))
|
||
fi
|
||
|
||
# KDE/Plasma Configuration
|
||
if [[ "$XDG_CURRENT_DESKTOP" == *"KDE"* ]] || [[ "$DESKTOP_SESSION" == *"plasma"* ]]; then
|
||
echo ""
|
||
echo "🖥️ Configuring KDE/Plasma:"
|
||
|
||
# Link thumbnails
|
||
if [[ -d "$user_home/.cache/thumbnails" ]]; then
|
||
mv "$user_home/.cache/thumbnails" "$user_home/.cache/thumbnails.backup.$(date +%s)" 2>/dev/null || true
|
||
fi
|
||
mkdir -p /tmp/tmpfs-cache/kde/thumbnails
|
||
ln -sf /tmp/tmpfs-cache/kde/thumbnails "$user_home/.cache/thumbnails"
|
||
chown -R $current_user:$current_user /tmp/tmpfs-cache/kde/thumbnails
|
||
success " ✅ KDE thumbnail cache linked to tmpfs"
|
||
((configured_count++))
|
||
fi
|
||
|
||
echo ""
|
||
if [[ $configured_count -gt 0 ]]; then
|
||
success "🎉 Automatically configured $configured_count applications!"
|
||
echo ""
|
||
log "💡 Changes will take effect when you restart the configured applications"
|
||
else
|
||
log "ℹ️ No applications detected for automatic configuration"
|
||
echo " You can manually configure other applications to use:"
|
||
echo " • Browser cache: /tmp/tmpfs-cache/browser/"
|
||
echo " • Dev tools: /tmp/tmpfs-cache/development/"
|
||
echo " • IDE cache: /tmp/tmpfs-cache/ide/"
|
||
fi
|
||
}
|
||
|
||
tune_kernel() {
|
||
if [[ $SETUP_KERNEL != true ]]; then
|
||
return 0
|
||
fi
|
||
|
||
log "Optimizing kernel parameters..."
|
||
|
||
local sysctl_conf="/etc/sysctl.d/99-system-optimization.conf"
|
||
|
||
# Determine optimal values
|
||
local swappiness=5
|
||
local dirty_ratio=5
|
||
local profile="desktop"
|
||
|
||
if [[ $SYSTEM_RAM_GB -ge 16 ]]; then
|
||
swappiness=1
|
||
dirty_ratio=3
|
||
profile="high-memory"
|
||
elif [[ $SYSTEM_RAM_GB -le 4 ]]; then
|
||
swappiness=10
|
||
dirty_ratio=10
|
||
profile="low-memory"
|
||
fi
|
||
|
||
cat > "$sysctl_conf" << EOF
|
||
# System Optimization - Generated $(date)
|
||
# Profile: $profile for ${SYSTEM_RAM_GB}GB RAM
|
||
|
||
# Memory management
|
||
vm.swappiness = $swappiness
|
||
vm.dirty_ratio = $dirty_ratio
|
||
vm.dirty_background_ratio = $((dirty_ratio / 2))
|
||
vm.vfs_cache_pressure = 50
|
||
|
||
# Network optimizations
|
||
net.core.rmem_max = 16777216
|
||
net.core.wmem_max = 16777216
|
||
|
||
# General performance
|
||
kernel.sched_autogroup_enabled = 1
|
||
EOF
|
||
|
||
# Apply immediately
|
||
sysctl -p "$sysctl_conf"
|
||
success "Kernel parameters optimized ($profile profile)"
|
||
}
|
||
|
||
create_service() {
|
||
if [[ $SETUP_SERVICE != true ]]; then
|
||
return 0
|
||
fi
|
||
|
||
log "Creating systemd service..."
|
||
|
||
# Create startup script
|
||
cat > /usr/local/bin/system-optimization-startup.sh << 'EOF'
|
||
#!/bin/bash
|
||
# Recreate optimizations after reboot
|
||
|
||
# Ensure zram if not present
|
||
if [[ ! -e /dev/zram0 ]]; then
|
||
ram_gb=$(free -g | awk '/^Mem:|^Speicher:/{print $2}')
|
||
zram_size=$((ram_gb / 2))
|
||
[[ $zram_size -lt 2 ]] && zram_size=2
|
||
|
||
modprobe zram num_devices=1 2>/dev/null || true
|
||
if [[ -e /sys/block/zram0/disksize ]]; then
|
||
echo "${zram_size}G" > /sys/block/zram0/disksize
|
||
mkswap /dev/zram0
|
||
swapon /dev/zram0
|
||
fi
|
||
fi
|
||
|
||
# Recreate tmpfs mounts if configured
|
||
if [[ -f /etc/fstab.tmpfs ]]; then
|
||
# Create directories
|
||
mkdir -p /tmp/tmpfs-cache/{browser,ide,packages,thumbnails,development,kde}
|
||
|
||
# Mount tmpfs filesystems
|
||
while IFS= read -r line; do
|
||
if [[ $line =~ ^tmpfs ]]; then
|
||
# Parse the fstab line and mount
|
||
eval "mount $line" 2>/dev/null || true
|
||
fi
|
||
done < /etc/fstab.tmpfs
|
||
|
||
# Restore package cache bind mount
|
||
if [[ -d /var/cache/apt ]] && [[ -d /tmp/tmpfs-cache/packages ]]; then
|
||
mount --bind /tmp/tmpfs-cache/packages /var/cache/apt 2>/dev/null || true
|
||
fi
|
||
fi
|
||
EOF
|
||
|
||
chmod +x /usr/local/bin/system-optimization-startup.sh
|
||
|
||
# Create systemd service
|
||
cat > /etc/systemd/system/system-optimization.service << EOF
|
||
[Unit]
|
||
Description=System Performance Optimization
|
||
After=multi-user.target
|
||
|
||
[Service]
|
||
Type=oneshot
|
||
ExecStart=/usr/local/bin/system-optimization-startup.sh
|
||
RemainAfterExit=yes
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
systemctl daemon-reload
|
||
systemctl enable system-optimization.service
|
||
|
||
success "Systemd service created and enabled"
|
||
}
|
||
|
||
show_final_status() {
|
||
echo ""
|
||
echo "🎉 Optimization Complete!"
|
||
echo "========================"
|
||
echo ""
|
||
|
||
# Show current status with more details
|
||
echo "📊 Current Optimization Status:"
|
||
|
||
# zram with usage info
|
||
if [[ -e /dev/zram0 ]] && swapon --show | grep -q zram0; then
|
||
local zram_size=$(swapon --show | grep zram0 | awk '{print $3}')
|
||
local zram_used=$(swapon --show | grep zram0 | awk '{print $4}')
|
||
echo " 🗜️ zram: $zram_size (used: ${zram_used:-0B})"
|
||
fi
|
||
|
||
# tmpfs with detailed mount info
|
||
local tmpfs_count=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l)
|
||
echo " 💾 tmpfs: $tmpfs_count cache mounts active"
|
||
if [[ $tmpfs_count -gt 0 ]]; then
|
||
local total_tmpfs_size=0
|
||
echo " 📁 Active mounts:"
|
||
mount | grep "tmpfs.*tmpfs-cache" | while read -r line; do
|
||
local mount_point=$(echo "$line" | awk '{print $3}' | sed 's|/tmp/tmpfs-cache/||')
|
||
local size_kb=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2 | sed 's/k$//')
|
||
local size_mb=$((size_kb / 1024))
|
||
local usage=$(df "$line" 2>/dev/null | tail -1 | awk '{print $5}' || echo "0%")
|
||
printf " • %-12s: %4dMB (%s used)\n" "$mount_point" "$size_mb" "$usage"
|
||
done
|
||
|
||
# Calculate total allocated tmpfs space
|
||
local total_kb=0
|
||
while read -r line; do
|
||
local size_kb=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2 | sed 's/k$//')
|
||
total_kb=$((total_kb + size_kb))
|
||
done < <(mount | grep "tmpfs.*tmpfs-cache")
|
||
local total_mb=$((total_kb / 1024))
|
||
echo " 📊 Total tmpfs allocated: ${total_mb}MB"
|
||
fi
|
||
|
||
# overlay status
|
||
local overlay_count=$(mount -t overlay | wc -l)
|
||
if [[ $overlay_count -eq 0 ]]; then
|
||
echo " 🗂️ overlays: None (optimal for desktop systems)"
|
||
else
|
||
echo " ⚠️ overlays: $overlay_count mounts found (consider removal)"
|
||
fi
|
||
|
||
# kernel with current values
|
||
if [[ -f /etc/sysctl.d/99-system-optimization.conf ]]; then
|
||
local swappiness=$(sysctl -n vm.swappiness 2>/dev/null)
|
||
local dirty_ratio=$(sysctl -n vm.dirty_ratio 2>/dev/null)
|
||
echo " ⚙️ kernel: swappiness=$swappiness, dirty_ratio=$dirty_ratio"
|
||
fi
|
||
|
||
# service status
|
||
if systemctl is-enabled system-optimization.service &>/dev/null; then
|
||
echo " 🔄 service: enabled (will restore tmpfs on reboot)"
|
||
fi
|
||
|
||
echo ""
|
||
echo "🎯 Next Steps:"
|
||
echo " 1. 🔄 Restart configured applications (browsers, IDEs) to use new cache locations"
|
||
echo " 2. 📊 Monitor cache usage: df -h | grep tmpfs-cache"
|
||
echo " 3. 🔍 Check status anytime: ./quick-status-check.sh"
|
||
echo " 4. <20> Optional: Reboot to verify all optimizations persist"
|
||
echo ""
|
||
echo "💡 Useful Commands:"
|
||
echo " • Check tmpfs usage: df -h /tmp/tmpfs-cache/*"
|
||
echo " • Monitor performance: iotop -ao"
|
||
echo " • View mount details: mount | grep tmpfs-cache"
|
||
echo ""
|
||
echo "🔧 Changes applied successfully!"
|
||
if [[ $tmpfs_count -gt 0 ]]; then
|
||
# Calculate total tmpfs space for the final message
|
||
local final_total_kb=0
|
||
while read -r line; do
|
||
local size_kb=$(echo "$line" | grep -o 'size=[^,]*' | cut -d= -f2 | sed 's/k$//')
|
||
final_total_kb=$((final_total_kb + size_kb))
|
||
done < <(mount | grep "tmpfs.*tmpfs-cache")
|
||
local final_total_mb=$((final_total_kb / 1024))
|
||
echo "🚀 Your system now has ${final_total_mb}MB of high-speed cache storage in RAM!"
|
||
fi
|
||
}
|
||
|
||
main() {
|
||
echo "🚀 Interactive System Optimizer"
|
||
echo "==============================="
|
||
echo ""
|
||
|
||
check_root
|
||
|
||
# Setup directories
|
||
mkdir -p "$(dirname "$LOG_FILE")" "$BACKUP_DIR"
|
||
touch "$LOG_FILE" 2>/dev/null || true
|
||
|
||
# Analyze and get user input
|
||
analyze_and_prompt
|
||
|
||
# Apply selected optimizations
|
||
remove_overlays
|
||
setup_zram
|
||
setup_tmpfs
|
||
tune_kernel
|
||
create_service
|
||
|
||
# Show results
|
||
show_final_status
|
||
|
||
log "Optimization completed successfully"
|
||
}
|
||
|
||
main "$@" |