autoNAS / scripts / autonas-boot-scan.sh
5b5a565 3 months ago History
1 contributor
218 lines | 8.395kb
#!/bin/bash

# AutoNAS Boot Scanner - Detects and attaches configured disks at boot time
# This script runs at boot to handle disks that are already connected
# Uses autonas-core.sh for all business logic

# Load the AutoNAS core library
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/autonas-core.sh" || {
    echo "Error: Cannot load AutoNAS core library" >&2
    exit 1
}

# Set LOG_TAG for this component
LOG_TAG="autonas-boot-scanner"

# Main boot scan function
boot_scan() {
    log_message "AutoNAS boot scan started" "info"
    
    if [ ! -f "$CONFIG_FILE" ]; then
        log_message "No configuration file found at $CONFIG_FILE - boot scan skipped" "info"
        return 0
    fi
    
    local total_disks=0
    local processed_disks=0
    local attached_disks=0
    local already_mounted=0
    
    # Read configuration file and process each disk
    while IFS=':' read -r uuid name ip interface mount_point nfs_options; do
        # Skip empty lines and comments
        [[ -z "$uuid" || "$uuid" =~ ^[[:space:]]*# ]] && continue
        
        total_disks=$((total_disks + 1))
        
        log_message "Checking configured disk: $name (UUID: $uuid)" "info"
        
        # Check if UUID exists as a device
        if check_uuid_exists "$uuid"; then
            processed_disks=$((processed_disks + 1))
            
            # Check mount status
            case $(is_disk_mounted "$uuid" "$mount_point"; echo $?) in
                0)
                    log_message "Disk $name already mounted correctly at $mount_point" "info"
                    already_mounted=$((already_mounted + 1))
                    ;;
                1)
                    log_message "Disk $name mounted elsewhere, attempting AutoNAS attach" "info"
                    if handle_attach "$uuid"; then
                        attached_disks=$((attached_disks + 1))
                        log_message "Successfully attached disk $name via AutoNAS" "info"
                    else
                        log_message "Failed to attach disk $name" "warning"
                    fi
                    ;;
                2)
                    log_message "Disk $name not mounted, attaching via AutoNAS" "info"
                    if handle_attach "$uuid"; then
                        attached_disks=$((attached_disks + 1))
                        log_message "Successfully attached disk $name via AutoNAS" "info"
                    else
                        log_message "Failed to attach disk $name" "warning"
                    fi
                    ;;
            esac
        else
            log_message "Disk $name (UUID: $uuid) not present - skipping" "debug"
        fi
        
    done < "$CONFIG_FILE"
    
    # Summary report
    log_message "AutoNAS boot scan completed:" "info"
    log_message "  - Total configured disks: $total_disks" "info"
    log_message "  - Present disks processed: $processed_disks" "info"
    log_message "  - Already mounted correctly: $already_mounted" "info"
    log_message "  - Newly attached: $attached_disks" "info"
    
    if [ $attached_disks -gt 0 ] || [ $already_mounted -gt 0 ]; then
        log_message "AutoNAS boot scan successful - ${attached_disks} disks attached, ${already_mounted} already mounted" "info"
    else
        log_message "AutoNAS boot scan completed - no disks required processing" "info"
    fi
}

# Function to clean up orphaned mounts and NFS exports at boot
cleanup_boot_orphans() {
    log_message "Starting boot-time cleanup of orphaned mounts and exports..." "info"
    
    local cleaned_mounts=0
    local cleaned_exports=0
    
    # Get list of configured disks
    if [ ! -f "$CONFIG_FILE" ]; then
        log_message "No configuration file found - skipping orphan cleanup" "info"
        return 0
    fi
    
    local configured_uuids=$(grep -v "^#\|^$" "$CONFIG_FILE" | cut -d':' -f1 | sort)
    
    # Check mounted disks in /mnt/autonas/
    if [ -d "/mnt/autonas" ]; then
        for mount_dir in /mnt/autonas/*/; do
            [ ! -d "$mount_dir" ] && continue
            
            local mount_name=$(basename "$mount_dir")
            local is_configured=false
            
            # Check if this mount corresponds to a configured disk AND is physically present
            local config_uuid=""
            while IFS=':' read -r uuid name ip hostname mount_point nfs_options; do
                [ -z "$uuid" ] && continue
                if [ "$name" = "$mount_name" ]; then
                    config_uuid="$uuid"
                    # Check if the disk is physically present and mounted
                    if [ -n "$(blkid | grep "$uuid")" ] && mountpoint -q "$mount_dir"; then
                        is_configured=true
                    fi
                    break
                fi
            done < <(grep -v "^#\|^$" "$CONFIG_FILE")
            
            if [ "$is_configured" = false ]; then
                log_message "Found orphaned mount point: $mount_dir" "info"
                
                # Unmount if mounted
                if mountpoint -q "$mount_dir"; then
                    log_message "Unmounting orphaned mount: $mount_dir" "info"
                    umount "$mount_dir" 2>/dev/null || {
                        log_message "Failed to unmount $mount_dir - forcing" "warn"
                        umount -f "$mount_dir" 2>/dev/null || true
                    }
                fi
                
                # Remove empty directory
                if [ -d "$mount_dir" ] && [ -z "$(ls -A "$mount_dir" 2>/dev/null)" ]; then
                    rmdir "$mount_dir" 2>/dev/null && {
                        log_message "Removed orphaned mount directory: $mount_dir" "info"
                        ((cleaned_mounts++))
                    }
                fi
            fi
        done
    fi
    
    # Clean up orphaned NFS exports
    if [ -f "/etc/exports" ]; then
        local temp_file=$(mktemp)
        local skip_next=false
        local current_uuid=""
        
        while IFS= read -r line; do
            if [[ "$line" =~ ^#\ AutoNAS\ Export\ -\ UUID:([^[:space:]]+)\ NAME: ]]; then
                current_uuid="${BASH_REMATCH[1]}"
                local is_configured=false
                
                # Check if this UUID is configured AND physically present
                while IFS= read -r configured_uuid; do
                    [ -z "$configured_uuid" ] && continue
                    if [ "$configured_uuid" = "$current_uuid" ]; then
                        # Additional check: verify the disk is physically present
                        if [ -n "$(blkid | grep "$current_uuid")" ]; then
                            is_configured=true
                        fi
                        break
                    fi
                done <<< "$configured_uuids"
                
                if [ "$is_configured" = false ]; then
                    log_message "Found orphaned NFS export for UUID: $current_uuid" "info"
                    skip_next=true
                    ((cleaned_exports++))
                    continue
                else
                    echo "$line" >> "$temp_file"
                    skip_next=false
                fi
            elif [ "$skip_next" = true ]; then
                # Skip the export line for orphaned entry
                skip_next=false
                continue
            else
                echo "$line" >> "$temp_file"
            fi
        done < /etc/exports
        
        # Replace exports file if we made changes
        if [ "$cleaned_exports" -gt 0 ]; then
            mv "$temp_file" /etc/exports
            # Reload NFS exports
            exportfs -ra 2>/dev/null || true
            log_message "Reloaded NFS exports after cleanup" "info"
        else
            rm -f "$temp_file"
        fi
    fi
    
    if [ "$cleaned_mounts" -gt 0 ] || [ "$cleaned_exports" -gt 0 ]; then
        log_message "Boot cleanup completed: $cleaned_mounts mount points, $cleaned_exports NFS exports removed" "info"
    else
        log_message "Boot cleanup completed: no orphaned entries found" "info"
    fi
}

# Wait for system to be ready
log_message "Waiting for system to stabilize..." "info"
sleep 5

# Clean up any orphaned mounts and exports first
cleanup_boot_orphans

# Run the boot scan
boot_scan

exit 0