Skip to content

Commit 12b57fe

Browse files
author
Alex J Lennon
committed
fix: Improve cleanup to handle busy filesystems and loop devices
- Use absolute paths for mounting/unmounting to avoid directory confusion - Fix loop device parsing using awk instead of cut for better field extraction - Add process detection with lsof and fuser to identify busy resources - Force unmount remaining mount points before directory cleanup - Add permission changes to handle read-only files - Use findmnt to locate and unmount remaining mount points - Multiple cleanup attempts with better error handling - Prevent 'device busy' errors from blocking cleanup Fixes cleanup failures that left mounted filesystems and work directories.
1 parent 4ef99f0 commit 12b57fe

File tree

1 file changed

+60
-20
lines changed

1 file changed

+60
-20
lines changed

wic-editor.sh

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,13 @@ ask_confirmation() {
158158
fi
159159

160160
if [ "$default" = "y" ]; then
161-
read -r -p "$message [Y/n]: " response
161+
read -r -p "$message [Y/n]: " response < /dev/tty
162162
case "$response" in
163163
[nN]|[nN][oO]) return 1 ;;
164164
*) return 0 ;;
165165
esac
166166
else
167-
read -r -p "$message [y/N]: " response
167+
read -r -p "$message [y/N]: " response < /dev/tty
168168
case "$response" in
169169
[yY]|[yY][eE][sS]) return 0 ;;
170170
*) return 1 ;;
@@ -179,7 +179,7 @@ select_partition_interactive() {
179179
list_partitions "$loop_device"
180180

181181
echo "Which partition would you like to modify?"
182-
read -r -p "Enter partition number: " partition_choice
182+
read -r -p "Enter partition number: " partition_choice < /dev/tty
183183

184184
# Validate partition choice
185185
partition_device="${loop_device}p${partition_choice}"
@@ -474,7 +474,7 @@ handle_file_conflict() {
474474
return 0
475475
fi
476476

477-
read -r -p " Choose option [1-4]: " choice
477+
read -r -p " Choose option [1-4]: " choice < /dev/tty
478478
case "$choice" in
479479
1)
480480
echo " Action: Overwriting existing file"
@@ -497,8 +497,11 @@ handle_file_conflict() {
497497
echo " Aborting operation"
498498
return 1 # Return instead of exit to allow cleanup
499499
;;
500+
"")
501+
echo " No input received. Please choose 1-4."
502+
;;
500503
*)
501-
echo " Invalid option. Please choose 1-4."
504+
echo " Invalid option '$choice'. Please choose 1-4."
502505
;;
503506
esac
504507
done
@@ -768,15 +771,26 @@ echo "Starting filesystem sync and unmount..."
768771
sync
769772

770773
echo "Unmounting filesystem..."
771-
echo "Unmounting: $WORK_DIR/$MOUNT_DIR"
772-
if ! umount "$WORK_DIR/$MOUNT_DIR"; then
773-
echo "Warning: Failed to unmount cleanly, forcing unmount..."
774-
umount -f "$WORK_DIR/$MOUNT_DIR" || umount -l "$WORK_DIR/$MOUNT_DIR" || true
774+
# Use absolute path to avoid directory confusion
775+
MOUNT_PATH="$(pwd)/$WORK_DIR/$MOUNT_DIR"
776+
echo "Unmounting: $MOUNT_PATH"
777+
778+
if mountpoint -q "$MOUNT_PATH" 2>/dev/null; then
779+
if ! umount "$MOUNT_PATH"; then
780+
echo "Warning: Failed to unmount cleanly, forcing unmount..."
781+
umount -f "$MOUNT_PATH" || umount -l "$MOUNT_PATH" || true
782+
fi
783+
else
784+
echo "Mount point not found or already unmounted"
775785
fi
776786

777787
# Verify unmount
778-
if mountpoint -q "$WORK_DIR/$MOUNT_DIR" 2>/dev/null; then
788+
if mountpoint -q "$MOUNT_PATH" 2>/dev/null; then
779789
echo "Warning: Mount point still active after unmount attempt"
790+
# Try to find what's using it
791+
echo "Processes using the mount point:"
792+
lsof "$MOUNT_PATH" || true
793+
fuser -v "$MOUNT_PATH" || true
780794
else
781795
echo "Filesystem unmounted successfully"
782796
fi
@@ -834,35 +848,61 @@ LOOP_DEVICE="" # Clear variable to prevent cleanup from trying again
834848
# Step 12: Final cleanup
835849
echo "Final cleanup..."
836850

837-
# Go back to the work directory for cleanup
838-
cd "$WORK_DIR"
851+
# Go back to original directory
852+
cd ..
839853

840854
# Force cleanup any remaining loop devices pointing to our working file
841855
echo "Checking for remaining loop devices..."
842-
remaining_loops=$(losetup -l 2>/dev/null | grep "working.wic" | cut -d: -f1)
856+
remaining_loops=$(losetup -l 2>/dev/null | grep "working.wic" | awk '{print $1}')
843857
if [ -n "$remaining_loops" ]; then
844-
echo "Found remaining loop devices: $remaining_loops"
858+
echo "Found remaining loop devices:"
859+
echo "$remaining_loops"
845860
for loop in $remaining_loops; do
846-
echo "Detaching remaining loop device: $loop"
847-
losetup -d "$loop" || true
861+
if [ -n "$loop" ] && [ "$loop" != "LOOP" ]; then
862+
echo "Detaching remaining loop device: $loop"
863+
losetup -d "$loop" 2>/dev/null || true
864+
fi
848865
done
849866
else
850867
echo "No remaining loop devices found"
851868
fi
852869

853-
# Go back to original directory
854-
cd ..
870+
# Force unmount any remaining mount points
871+
MOUNT_PATH="$(pwd)/$WORK_DIR/$MOUNT_DIR"
872+
if mountpoint -q "$MOUNT_PATH" 2>/dev/null; then
873+
echo "Force unmounting remaining mount point: $MOUNT_PATH"
874+
umount -f "$MOUNT_PATH" 2>/dev/null || umount -l "$MOUNT_PATH" 2>/dev/null || true
875+
fi
855876

856877
# Remove work directory
857878
if [ -d "$WORK_DIR" ]; then
858879
echo "Removing work directory: $WORK_DIR"
859880
echo "Contents before removal:"
860881
ls -la "$WORK_DIR/" || true
882+
883+
# Try to remove read-only files if any
884+
chmod -R u+w "$WORK_DIR" 2>/dev/null || true
885+
861886
rm -rf "$WORK_DIR"
862887
if [ -d "$WORK_DIR" ]; then
863888
echo "Warning: Work directory still exists after removal attempt"
864-
echo "Attempting force removal..."
865-
rm -rf "$WORK_DIR" || true
889+
echo "Attempting force removal with lazy unmount..."
890+
891+
# Find and unmount any remaining mount points
892+
if command -v findmnt &> /dev/null; then
893+
findmnt -t ext4,ext3,ext2,vfat | grep "$WORK_DIR" | awk '{print $1}' | while read -r mount_point; do
894+
echo "Force unmounting: $mount_point"
895+
umount -l "$mount_point" 2>/dev/null || true
896+
done
897+
fi
898+
899+
# Try again
900+
rm -rf "$WORK_DIR" 2>/dev/null || true
901+
902+
if [ -d "$WORK_DIR" ]; then
903+
echo "Error: Unable to remove work directory. Manual cleanup may be required."
904+
echo "You can manually run: sudo rm -rf $WORK_DIR"
905+
fi
866906
else
867907
echo "Work directory successfully removed"
868908
fi

0 commit comments

Comments
 (0)