Setup installation

This commit is contained in:
2025-08-07 19:28:22 +02:00
parent e3f6363844
commit 17d74b261d
19 changed files with 6144 additions and 0 deletions

View File

@@ -0,0 +1,334 @@
#!/bin/bash
# ssd-safe-eject.sh - Safe Eject Extension für USB-C SSDs
# Zweck: Sichere Entfernung von USB-C SSDs mit vollständigem Sync und Hardware-Eject
set -e
# Konfiguration
MOUNT_POINT="/mnt/ssd-storage"
LOG_FILE="/var/log/ssd-mount.log"
# Farben für Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging-Funktion
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - SAFE-EJECT: $1" | sudo tee -a "$LOG_FILE"
echo -e "${BLUE}[SAFE-EJECT]${NC} $1"
}
log_success() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: $1" | sudo tee -a "$LOG_FILE"
echo -e "${GREEN}[✓]${NC} $1"
}
log_warning() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: $1" | sudo tee -a "$LOG_FILE"
echo -e "${YELLOW}[!]${NC} $1"
}
log_error() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: $1" | sudo tee -a "$LOG_FILE"
echo -e "${RED}[✗]${NC} $1"
}
# Schritt 1: Pre-Eject Validierung
validate_pre_eject() {
log_message "Validiere Pre-Eject Status..."
if ! mountpoint -q "$MOUNT_POINT"; then
log_warning "Keine SSD auf $MOUNT_POINT gemountet"
return 1
fi
mounted_device=$(df "$MOUNT_POINT" | tail -1 | awk '{print $1}')
log_success "Gemountetes Device identifiziert: $mounted_device"
# Prüfe ob Device USB-Device ist
device_base=$(echo "$mounted_device" | sed 's/[0-9]*$//')
if lsblk -o TRAN "$device_base" 2>/dev/null | grep -q usb; then
log_success "USB-Device bestätigt: $device_base"
echo "$mounted_device"
return 0
else
log_error "Device ist kein USB-Device - Safe-Eject nicht anwendbar"
return 1
fi
}
# Schritt 2: Aktive Prozesse prüfen
check_active_processes() {
local device="$1"
log_message "Prüfe aktive Prozesse auf $MOUNT_POINT..."
# Prozesse finden die das Mount-Point verwenden
active_processes=$(lsof "$MOUNT_POINT" 2>/dev/null || true)
if [ -n "$active_processes" ]; then
log_warning "Aktive Prozesse gefunden:"
echo "$active_processes"
echo ""
echo "Prozesse beenden? (y/n/s für skip)"
read -r response
case "$response" in
"y"|"Y")
log_message "Beende Prozesse..."
lsof -t "$MOUNT_POINT" 2>/dev/null | xargs -r sudo kill -TERM
sleep 2
# Prüfe erneut
remaining=$(lsof "$MOUNT_POINT" 2>/dev/null || true)
if [ -n "$remaining" ]; then
log_warning "Einige Prozesse laufen noch - Force Kill..."
lsof -t "$MOUNT_POINT" 2>/dev/null | xargs -r sudo kill -KILL
fi
log_success "Prozesse beendet"
;;
"s"|"S")
log_warning "Prozesse werden nicht beendet - Fortfahren auf eigene Gefahr"
;;
*)
log_message "Safe-Eject abgebrochen"
return 1
;;
esac
else
log_success "Keine aktiven Prozesse gefunden"
fi
return 0
}
# Schritt 3: Vollständiger Daten-Sync
perform_full_sync() {
log_message "Führe vollständigen Daten-Sync durch..."
# Globaler Sync
log_message "Globaler Sync..."
sync
# Warte auf Dirty Pages Flush
log_message "Warte auf Buffer-Flush..."
local timeout=30
local count=0
while [ $count -lt $timeout ]; do
dirty_pages=$(cat /proc/meminfo | grep "Dirty:" | awk '{print $2}')
writeback_pages=$(cat /proc/meminfo | grep "Writeback:" | awk '{print $2}')
if [ "$dirty_pages" -le 4 ] && [ "$writeback_pages" -le 4 ]; then
log_success "Buffer-Flush abgeschlossen (Dirty: ${dirty_pages}kB, Writeback: ${writeback_pages}kB)"
break
fi
if [ $((count % 5)) -eq 0 ]; then
log_message "Warte auf Buffer-Flush... (Dirty: ${dirty_pages}kB, Writeback: ${writeback_pages}kB)"
fi
sleep 1
count=$((count + 1))
done
if [ $count -ge $timeout ]; then
log_warning "Buffer-Flush Timeout erreicht - Fortfahren..."
fi
# Finaler Sync
log_message "Finaler Sync..."
sync
sleep 2
log_success "Vollständiger Sync abgeschlossen"
}
# Schritt 4: Filesystem Unmount
perform_unmount() {
local device="$1"
log_message "Unmounte Dateisystem: $device"
# Lazy Unmount falls normal unmount fehlschlägt
if ! sudo umount "$MOUNT_POINT" 2>/dev/null; then
log_warning "Normaler Unmount fehlgeschlagen - versuche Lazy Unmount..."
if sudo umount -l "$MOUNT_POINT" 2>/dev/null; then
log_success "Lazy Unmount erfolgreich"
else
log_error "Unmount fehlgeschlagen"
return 1
fi
else
log_success "Unmount erfolgreich"
fi
# Verifikation
if mountpoint -q "$MOUNT_POINT"; then
log_error "Mount-Point noch aktiv nach Unmount"
return 1
else
log_success "Mount-Point erfolgreich getrennt"
return 0
fi
}
# Schritt 5: Hardware-Eject
perform_hardware_eject() {
local device="$1"
local device_base=$(echo "$device" | sed 's/[0-9]*$//')
log_message "Hardware-Eject für Device: $device_base"
# Prüfe ob eject verfügbar ist
if ! command -v eject >/dev/null; then
log_warning "eject Befehl nicht verfügbar - installiere eject..."
sudo apt update && sudo apt install -y eject
fi
# Hardware-Eject durchführen
if sudo eject "$device_base" 2>/dev/null; then
log_success "Hardware-Eject erfolgreich: $device_base"
else
log_warning "Hardware-Eject fehlgeschlagen - möglicherweise nicht unterstützt"
# Alternative: USB-Device über sysfs deaktivieren
usb_device=$(udevadm info --query=path --name="$device_base" 2>/dev/null | sed 's|/block/.*||')
if [ -n "$usb_device" ]; then
log_message "Versuche USB-Device Deaktivierung über sysfs..."
if echo 1 | sudo tee "/sys$usb_device/remove" >/dev/null 2>&1; then
log_success "USB-Device über sysfs deaktiviert"
else
log_warning "USB-Device Deaktivierung fehlgeschlagen"
fi
fi
fi
}
# Schritt 6: Post-Eject Validierung
validate_post_eject() {
local device="$1"
local device_base=$(echo "$device" | sed 's/[0-9]*$//')
log_message "Post-Eject Validierung..."
# Prüfe ob Mount-Point noch aktiv
if mountpoint -q "$MOUNT_POINT"; then
log_error "Mount-Point noch aktiv - Safe-Eject unvollständig"
return 1
fi
# Prüfe ob Device noch sichtbar
sleep 3 # Kurze Wartezeit für System-Update
if [ -b "$device_base" ]; then
log_warning "Device noch im System sichtbar: $device_base"
log_message "Device kann möglicherweise manuell entfernt werden"
else
log_success "Device nicht mehr im System sichtbar"
fi
log_success "Post-Eject Validierung abgeschlossen"
return 0
}
# Safe-Eject Status anzeigen
show_eject_status() {
echo ""
echo "=== Safe-Eject Status ==="
if mountpoint -q "$MOUNT_POINT"; then
mounted_device=$(df "$MOUNT_POINT" | tail -1 | awk '{print $1}')
device_base=$(echo "$mounted_device" | sed 's/[0-9]*$//')
echo "✓ Gemountetes Device: $mounted_device"
echo "✓ Hardware Device: $device_base"
# USB-Status prüfen
if lsblk -o TRAN "$device_base" 2>/dev/null | grep -q usb; then
echo "✓ USB-Device: Ja"
echo "✓ Safe-Eject: Verfügbar"
else
echo "✗ USB-Device: Nein"
echo "✗ Safe-Eject: Nicht verfügbar"
fi
# Aktive Prozesse prüfen
active_count=$(lsof "$MOUNT_POINT" 2>/dev/null | wc -l)
if [ "$active_count" -gt 0 ]; then
echo "! Aktive Prozesse: $active_count"
else
echo "✓ Aktive Prozesse: Keine"
fi
else
echo "✗ Kein Device gemountet"
echo "✗ Safe-Eject: Nicht erforderlich"
fi
echo ""
}
# Hauptfunktion Safe-Eject
safe_eject_main() {
echo "=== USB-C SSD Safe-Eject ==="
echo "Version: 1.0"
echo ""
# Pre-Validierung
device=$(validate_pre_eject)
if [ $? -ne 0 ]; then
return 1
fi
echo "=== Safe-Eject Prozess gestartet für: $device ==="
echo ""
# Aktive Prozesse prüfen
if ! check_active_processes "$device"; then
return 1
fi
# Vollständiger Sync
perform_full_sync
# Unmount
if ! perform_unmount "$device"; then
return 1
fi
# Hardware-Eject
perform_hardware_eject "$device"
# Post-Validierung
validate_post_eject "$device"
echo ""
echo "=== Safe-Eject abgeschlossen ==="
echo "USB-C SSD kann jetzt sicher entfernt werden."
echo ""
return 0
}
# Hauptfunktion
main() {
case "${1:-eject}" in
"eject")
safe_eject_main
;;
"status")
show_eject_status
;;
*)
echo "Verwendung: $0 {eject|status}"
echo ""
echo "Befehle:"
echo " eject - Sichere SSD-Entfernung durchführen"
echo " status - Safe-Eject Status anzeigen"
;;
esac
}
# Script ausführen
main "$@"