diff --git a/README.md b/README.md index 3e5e116..743443d 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,31 @@ This repository provides automated system tuning based on hardware detection, usage patterns, and best practices for tmpfs, overlay filesystems, and kernel parameter optimization. +## ✨ **NEW: One-Button Optimizer** + +🎯 **Quick Start:** `sudo ./one-button-optimizer.sh` + +The **one-button optimizer** is an intelligent, interactive system optimizer that: + +- 🔍 **Analyzes current optimizations** and detects suboptimal configurations +- 🤔 **Prompts for user choice** on each optimization +- 🎯 **Applies only selected optimizations** - no forced changes +- ✅ **Recognizes existing optimal configurations** and leaves them alone +- ⚙️ **Handles mixed scenarios** where some optimizations exist but aren't ideal + +### Quick Tools + +- `./one-button-optimizer.sh` - **Main interactive optimizer** (recommended) +- `./quick-status-check.sh` - **Quick system status** overview (no changes) +- `./launcher.sh` - **Auto-sudo launcher** for the optimizer + ## 🎯 Features - **Hardware Detection**: Automatically detects RAM, CPU, storage configuration -- **Usage Analysis**: Identifies frequently accessed files and directories +- **Usage Analysis**: Identifies frequently accessed files and directories - **Intelligent Tuning**: Applies optimizations based on system characteristics +- **Interactive Mode**: User control over what gets optimized +- **Suboptimal Detection**: Finds and offers to fix existing but suboptimal configs - **Modular Design**: Easy to customize and extend - **Safe Deployment**: Backup and rollback capabilities - **Multi-Distribution**: Works across different Linux distributions @@ -16,6 +36,7 @@ This repository provides automated system tuning based on hardware detection, us ## 🏗️ Components ### Core Scripts +- `one-button-optimizer.sh` - **🆕 Interactive one-button optimizer** - `tune-system.sh` - Main tuning orchestrator - `system-analyzer.sh` - Hardware and usage analysis - `optimizer.sh` - Apply specific optimizations diff --git a/launcher.sh b/launcher.sh new file mode 100755 index 0000000..b26f928 --- /dev/null +++ b/launcher.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# One-Button System Optimizer Launcher +# Simple launcher that checks for root and runs the optimization + +SCRIPT_PATH="/tmp/optimize-system.sh" + +echo "🚀 One-Button Linux System Optimizer" +echo "=====================================" +echo "" + +# Check if optimization script exists +if [[ ! -f "$SCRIPT_PATH" ]]; then + echo "❌ Optimization script not found at $SCRIPT_PATH" + exit 1 +fi + +# Check if running as root +if [[ $EUID -eq 0 ]]; then + # Already root, run directly + exec "$SCRIPT_PATH" +else + # Not root, use sudo + echo "🔐 Root privileges required for system optimization" + echo "You will be prompted for your password..." + echo "" + exec sudo "$SCRIPT_PATH" +fi \ No newline at end of file diff --git a/one-button-optimizer.sh b/one-button-optimizer.sh new file mode 100755 index 0000000..ba930e6 --- /dev/null +++ b/one-button-optimizer.sh @@ -0,0 +1,433 @@ +#!/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 " 📁 Some 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" + SETUP_TMPFS=false + else + echo " ❌ Not configured" + 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!" + 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") + + 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 + 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" +} + +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 +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 + echo "📊 Current Status:" + + # zram + if [[ -e /dev/zram0 ]] && swapon --show | grep -q zram0; then + local zram_size=$(swapon --show | grep zram0 | awk '{print $3}') + echo " 🗜️ zram: $zram_size" + fi + + # tmpfs + local tmpfs_count=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l) + echo " 💾 tmpfs: $tmpfs_count cache mounts" + + # kernel + if [[ -f /etc/sysctl.d/99-system-optimization.conf ]]; then + local swappiness=$(sysctl -n vm.swappiness 2>/dev/null) + echo " ⚙️ kernel: swappiness=$swappiness" + fi + + # service + if systemctl is-enabled system-optimization.service &>/dev/null; then + echo " 🔄 service: enabled" + fi + + echo "" + echo "🔧 Changes applied successfully!" + echo "🔄 Reboot recommended for optimal performance" +} + +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 + setup_zram + tune_kernel + create_service + + # Show results + show_final_status + + log "Optimization completed successfully" +} + +main "$@" \ No newline at end of file diff --git a/quick-status-check.sh b/quick-status-check.sh new file mode 100755 index 0000000..1027304 --- /dev/null +++ b/quick-status-check.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# Quick test version to see current status + +echo "🔍 Current System Status Check" +echo "==============================" + +# Get RAM info +ram_gb=$(free -g | awk '/^Mem:|^Speicher:/{print $2}') +echo "RAM: ${ram_gb}GB" + +# Check zram +echo "" +echo "🗜️ zram Status:" +if [[ -e /dev/zram0 ]] && swapon --show | grep -q zram0; then + zram_size=$(swapon --show | grep zram0 | awk '{print $3}') + echo " ✅ Active: $zram_size" + + # Calculate optimal + if [[ $ram_gb -ge 8 ]]; then + optimal_size=$((ram_gb / 2)) + else + optimal_size=$((ram_gb * 3 / 4)) + fi + [[ $optimal_size -lt 2 ]] && optimal_size=2 + + echo " 📊 Optimal: ${optimal_size}GB" + + zram_size_gb=$(echo "$zram_size" | sed 's/[^0-9.]//g' | cut -d. -f1) + if [[ $zram_size_gb -lt $((optimal_size - 1)) ]] || [[ $zram_size_gb -gt $((optimal_size + 2)) ]]; then + echo " ⚠️ Size could be optimized" + else + echo " ✅ Size is optimal" + fi +else + echo " ❌ Not configured" +fi + +# Check tmpfs +echo "" +echo "💾 tmpfs Cache Status:" +tmpfs_count=$(mount | grep "tmpfs.*tmpfs-cache" | wc -l) +if [[ $tmpfs_count -gt 0 ]]; then + echo " ✅ Active: $tmpfs_count mounts" + echo " 📁 Mounted caches:" + mount | grep "tmpfs.*tmpfs-cache" | awk '{print " " $3 " (" $6 ")"}' | tr -d '()' | head -5 + [[ $tmpfs_count -gt 5 ]] && echo " ... and $((tmpfs_count - 5)) more" +else + echo " ❌ Not configured" +fi + +# Check kernel params +echo "" +echo "⚙️ Kernel Parameters:" +if [[ -f /etc/sysctl.d/99-system-optimization.conf ]]; then + echo " ✅ Optimization config exists" + swappiness=$(sysctl -n vm.swappiness 2>/dev/null) + dirty_ratio=$(sysctl -n vm.dirty_ratio 2>/dev/null) + echo " 📊 Current: swappiness=$swappiness, dirty_ratio=$dirty_ratio" + + # Calculate optimal for this system + if [[ $ram_gb -ge 16 ]]; then + opt_swap=1; opt_dirty=3 + elif [[ $ram_gb -le 4 ]]; then + opt_swap=10; opt_dirty=10 + else + opt_swap=5; opt_dirty=5 + fi + echo " 📊 Optimal: swappiness=$opt_swap, dirty_ratio=$opt_dirty" + + if [[ "$swappiness" != "$opt_swap" ]] || [[ "$dirty_ratio" != "$opt_dirty" ]]; then + echo " ⚠️ Could be optimized" + else + echo " ✅ Optimally configured" + fi +else + echo " ❌ Not optimized" +fi + +# Check systemd service +echo "" +echo "🔄 Systemd Service:" +if systemctl is-enabled system-optimization.service &>/dev/null; then + if systemctl is-active system-optimization.service &>/dev/null; then + echo " ✅ Active and enabled" + else + echo " ⚠️ Enabled but not active" + fi +elif [[ -f /etc/systemd/system/system-optimization.service ]]; then + echo " ⚠️ Installed but not enabled" +else + echo " ❌ Not installed" +fi + +echo "" +echo "✨ Analysis complete!" \ No newline at end of file