As you all know, I put multiple operating systems on either an attached USB SSD or, (more recently) on a large microSD device.
Because of the way pcmanfm (the file-browser) works, it auto-mounts mountable partitions outside the one currently in use. (And yes, I understand that this can be disabled, but it’s handy to have the other partitions mounted.)
However, there is some troubling logic in the “device_added” script - which manages both adding and removing removable devices.
If it detects any directory activity on anything in the /media/pi folder, it recurses the open folder and removes everything inside it.
(i.e. If I’m booted as O/S “A”, and I open O/S “B”'s root folder, it automatically starts removing things.)
An analysis of this behavior appears to center on the /bin/device_added.sh script. When it detects a change, it recurses the directory and instead of removing a stale directory once the device is removed, it:
- Tries to un-mount it. If the un-mount fails, it fails silently and continues to the next step which is:
- rm -r [the directory] which, if the directory didn’t un-mount because it was busy, it recursively deletes everything in that directory.
Here is the analysis of the issue with line numbers indicated:
/bin/device_added.sh
Lines 57-62 — remove_mount_points()
Changed:
rm -frd $target_link;
To:
rmdir "$target_link";
Reason:
Prevent recursive deletion. An actual directory is removed only if it
is empty.
Lines 69-74 — remove_mount_points()
Changed:
rm -r $target_link;
To:
rm -f "$target_link";
Reason:
This operation is intended to remove the USB-Drive symlink. Recursive
removal is unnecessary and potentially dangerous.
Lines 211-231 — cleanup_media_folder()
Changed:
umount "$entry" >>/tmp/scripts.log
echo "umount $entry: $?" >>/tmp/scripts.log
rm -r "$entry"
echo "rm $entry: $?" >>/tmp/scripts.log
To:
umount "$entry" >>/tmp/scripts.log 2>&1
umount_return=$?
echo "umount $entry: $umount_return" >>/tmp/scripts.log
if [ $umount_return -eq 0 ]
then
rmdir "$entry" >>/tmp/scripts.log 2>&1
echo "rmdir $entry: $?" >>/tmp/scripts.log
else
echo "NOT removing $entry because unmount failed" >>/tmp/scripts.log
fi
Reason:
The original code recursively removed the entry regardless of whether
the unmount succeeded. The replacement will never remove the entry if
the unmount fails, and uses rmdir instead of recursive deletion if the
unmount succeeds.
I am attaching a patch-file that details the specific differences.
Also note that I copied the “patched” file to “Sam” as well as there is a copy of the identical file in his user context.
I would like to know more about what this is supposed to be doing before I continue down this rabbit hole.
Also, it would be interesting to see, to what extent, this functionality might be present in Bullseye and Bookworm.
What say ye?
device_added.sh.patch.txt (2.1 KB)