autoNAS / scripts / autonas-boot-scan.sh
Newer Older
232 lines | 9.035kb
Bogdan Timofte authored 3 months ago
1
#!/bin/bash
2

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

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

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

            
17
# Main boot scan function
18
boot_scan() {
19
    log_message "AutoNAS boot scan started" "info"
20

            
21
    if [ ! -f "$CONFIG_FILE" ]; then
22
        log_message "No configuration file found at $CONFIG_FILE - boot scan skipped" "info"
23
        return 0
24
    fi
25

            
26
    local total_disks=0
27
    local processed_disks=0
28
    local attached_disks=0
29
    local already_mounted=0
30

            
31
    # Read configuration file and process each disk
32
    while IFS=':' read -r uuid name ip interface mount_point nfs_options; do
33
        # Skip empty lines and comments
34
        [[ -z "$uuid" || "$uuid" =~ ^[[:space:]]*# ]] && continue
35

            
36
        total_disks=$((total_disks + 1))
37

            
38
        log_message "Checking configured disk: $name (UUID: $uuid)" "info"
39

            
40
        # Check if UUID exists as a device
41
        if check_uuid_exists "$uuid"; then
42
            processed_disks=$((processed_disks + 1))
43

            
44
            # Check mount status
45
            case $(is_disk_mounted "$uuid" "$mount_point"; echo $?) in
46
                0)
47
                    log_message "Disk $name already mounted correctly at $mount_point" "info"
48
                    already_mounted=$((already_mounted + 1))
49
                    ;;
50
                1)
51
                    log_message "Disk $name mounted elsewhere, attempting AutoNAS attach" "info"
52
                    if handle_attach "$uuid"; then
53
                        attached_disks=$((attached_disks + 1))
54
                        log_message "Successfully attached disk $name via AutoNAS" "info"
55
                    else
56
                        log_message "Failed to attach disk $name" "warning"
57
                    fi
58
                    ;;
59
                2)
60
                    log_message "Disk $name not mounted, attaching via AutoNAS" "info"
61
                    if handle_attach "$uuid"; then
62
                        attached_disks=$((attached_disks + 1))
63
                        log_message "Successfully attached disk $name via AutoNAS" "info"
64
                    else
65
                        log_message "Failed to attach disk $name" "warning"
66
                    fi
67
                    ;;
68
            esac
69
        else
70
            log_message "Disk $name (UUID: $uuid) not present - skipping" "debug"
71
        fi
72

            
73
    done < "$CONFIG_FILE"
74

            
75
    # Summary report
76
    log_message "AutoNAS boot scan completed:" "info"
77
    log_message "  - Total configured disks: $total_disks" "info"
78
    log_message "  - Present disks processed: $processed_disks" "info"
79
    log_message "  - Already mounted correctly: $already_mounted" "info"
80
    log_message "  - Newly attached: $attached_disks" "info"
81

            
82
    if [ $attached_disks -gt 0 ] || [ $already_mounted -gt 0 ]; then
83
        log_message "AutoNAS boot scan successful - ${attached_disks} disks attached, ${already_mounted} already mounted" "info"
84
    else
85
        log_message "AutoNAS boot scan completed - no disks required processing" "info"
86
    fi
87
}
88

            
89
# Function to clean up orphaned mounts and NFS exports at boot
90
cleanup_boot_orphans() {
91
    log_message "Starting boot-time cleanup of orphaned mounts and exports..." "info"
92

            
93
    local cleaned_mounts=0
94
    local cleaned_exports=0
95

            
96
    # Get list of configured disks
97
    if [ ! -f "$CONFIG_FILE" ]; then
98
        log_message "No configuration file found - skipping orphan cleanup" "info"
99
        return 0
100
    fi
101

            
102
    local configured_uuids=$(grep -v "^#\|^$" "$CONFIG_FILE" | cut -d':' -f1 | sort)
103

            
104
    # Check mounted disks in /mnt/autonas/
105
    if [ -d "/mnt/autonas" ]; then
106
        for mount_dir in /mnt/autonas/*/; do
107
            [ ! -d "$mount_dir" ] && continue
108

            
109
            local mount_name=$(basename "$mount_dir")
110
            local is_configured=false
111

            
112
            # Check if this mount corresponds to a configured disk AND is physically present
113
            local config_uuid=""
114
            while IFS=':' read -r uuid name ip hostname mount_point nfs_options; do
115
                [ -z "$uuid" ] && continue
116
                if [ "$name" = "$mount_name" ]; then
117
                    config_uuid="$uuid"
118
                    # Check if the disk is physically present and mounted
119
                    if [ -n "$(blkid | grep "$uuid")" ] && mountpoint -q "$mount_dir"; then
120
                        is_configured=true
121
                    fi
122
                    break
123
                fi
124
            done < <(grep -v "^#\|^$" "$CONFIG_FILE")
125

            
126
            if [ "$is_configured" = false ]; then
127
                log_message "Found orphaned mount point: $mount_dir" "info"
128

            
129
                # Unmount if mounted
130
                if mountpoint -q "$mount_dir"; then
131
                    log_message "Unmounting orphaned mount: $mount_dir" "info"
132
                    umount "$mount_dir" 2>/dev/null || {
133
                        log_message "Failed to unmount $mount_dir - forcing" "warn"
134
                        umount -f "$mount_dir" 2>/dev/null || true
135
                    }
136
                fi
137

            
138
                # Remove empty directory
139
                if [ -d "$mount_dir" ] && [ -z "$(ls -A "$mount_dir" 2>/dev/null)" ]; then
140
                    rmdir "$mount_dir" 2>/dev/null && {
141
                        log_message "Removed orphaned mount directory: $mount_dir" "info"
142
                        ((cleaned_mounts++))
143
                    }
144
                fi
145
            fi
146
        done
147
    fi
148

            
149
    # Clean up orphaned NFS exports
150
    if [ -f "/etc/exports" ]; then
151
        local temp_file=$(mktemp)
152
        local skip_next=false
153
        local current_uuid=""
154

            
155
        while IFS= read -r line; do
156
            if [[ "$line" =~ ^#\ AutoNAS\ Export\ -\ UUID:([^[:space:]]+)\ NAME: ]]; then
157
                current_uuid="${BASH_REMATCH[1]}"
158
                local is_configured=false
159

            
160
                # Check if this UUID is configured AND physically present
161
                while IFS= read -r configured_uuid; do
162
                    [ -z "$configured_uuid" ] && continue
163
                    if [ "$configured_uuid" = "$current_uuid" ]; then
164
                        # Additional check: verify the disk is physically present
165
                        if [ -n "$(blkid | grep "$current_uuid")" ]; then
166
                            is_configured=true
167
                        fi
168
                        break
169
                    fi
170
                done <<< "$configured_uuids"
171

            
172
                if [ "$is_configured" = false ]; then
173
                    log_message "Found orphaned NFS export for UUID: $current_uuid" "info"
174
                    skip_next=true
175
                    ((cleaned_exports++))
176
                    continue
177
                else
178
                    echo "$line" >> "$temp_file"
179
                    skip_next=false
180
                fi
181
            elif [ "$skip_next" = true ]; then
Bogdan Timofte authored 2 weeks ago
182
                # Skip the export line for orphaned entry, or drop marked
183
                # exports whose path does not exist yet. This avoids keeping
184
                # stale subpath exports like /mnt/autonas/<disk>/@pve across
185
                # reboot before the backing disk is mounted again.
Bogdan Timofte authored 3 months ago
186
                skip_next=false
Bogdan Timofte authored 2 weeks ago
187

            
188
                local export_path
189
                export_path=$(awk '{print $1}' <<< "$line")
190

            
191
                if [ -z "$export_path" ] || [ ! -e "$export_path" ]; then
192
                    log_message "Removing AutoNAS export with missing path: $export_path" "info"
193
                    ((cleaned_exports++))
194
                    continue
195
                fi
196

            
197
                echo "$line" >> "$temp_file"
Bogdan Timofte authored 3 months ago
198
                continue
199
            else
200
                echo "$line" >> "$temp_file"
201
            fi
202
        done < /etc/exports
203

            
204
        # Replace exports file if we made changes
205
        if [ "$cleaned_exports" -gt 0 ]; then
206
            mv "$temp_file" /etc/exports
207
            # Reload NFS exports
208
            exportfs -ra 2>/dev/null || true
209
            log_message "Reloaded NFS exports after cleanup" "info"
210
        else
211
            rm -f "$temp_file"
212
        fi
213
    fi
214

            
215
    if [ "$cleaned_mounts" -gt 0 ] || [ "$cleaned_exports" -gt 0 ]; then
216
        log_message "Boot cleanup completed: $cleaned_mounts mount points, $cleaned_exports NFS exports removed" "info"
217
    else
218
        log_message "Boot cleanup completed: no orphaned entries found" "info"
219
    fi
220
}
221

            
222
# Wait for system to be ready
223
log_message "Waiting for system to stabilize..." "info"
224
sleep 5
225

            
226
# Clean up any orphaned mounts and exports first
227
cleanup_boot_orphans
228

            
229
# Run the boot scan
230
boot_scan
231

            
232
exit 0