|
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
|