2

In the event an external hard-drive is physically disconnected and the device is mounted using device-mapper, no cleanup is made.

In particular:

  • the directory where the drive was mounted is empty
  • the mount is still present in mount(8)
  • the device-mapper devices are still present
  • the physical device is still present as /dev/sd*

In this scenario, without cleaning up the items above, the first three steps need manual cleanup (via umount, dmsetup remove and udevadm trigger --subsystem-match=block). Even then, the disk's sysfs directory is still present in /sys/bus/scsi/drivers/sd and you need to manually echo 1 > delete to make sure the SCSI device is unregistered. Without it, replugging the disk back in does not work.

So my question is - is there a program that can detect when a physical disk that's been device mapped is no longer responding and perform the necessary cleanup?

1 Answer 1

1

I am not aware of a program to do that for you however I had a device at one stage which would periodically end up in this state by suddenly disconnecting itself. It would reconnect fine after manually going through the steps you describe above, my solution relied on noticing that when it happened the mount point did show as empty though the system still believed something was mounted.

My solution, put a simple empty file onto the drive the presence of which could then be checked for by a shell script and automatically clean up. I no longer have the drive or the full shell script but I can give you a basic example how to create your own and you can add in the commands you had to run in order to clean up manually when you did that.

Note in this example I will use /mnt/externalhd as the mountpoint and presume that the file we are looking for is named .isonline in it's root filesystem. You could check for the presence of an existing file on the drive also assuming that it will not ever change during operation. Note that the if statement also checks for the /dev entry so we dont create a loop of cleanups while waiting for the device to reconnect, finding and using the disks correct /dev/disk/by-uuid/* entry would be more accurate however and essential if the order of connection of your devices may vary a problem I fortunately never had.

if [ ! -e /mnt/externalhd/.isonline ] && [ -e /dev/sdb ]; then {
   # This line optionally logs the disconnect to a file for your records.
   echo "`date '+%d %b %Y %H:%M:%S'` OFFLINE: /dev/sdb disconnected, cleaning up" >> /var/log/externalhd.log

   # Do whatever you need to do to clean up the bad unmount and enable reconnection

   # Optionally log the completion of the cleanup process
   echo "`date '+%d %b %Y %H:%M:%S'` CLEANUP: /dev/sdb cleanup process completed" >> /var/log/externalhd.log
}
fi

I hope that helps, I am a little fuzzy on the commands I had to run to complete the full cleanup and it seems that I deleted the old script when the drive itself finally died. Once you have the script set up with the commands you need to run to clean up your drive they will be the same ones you use when doing it manually though you should drop the sudo part from them.

The script can then be run via cron to do a regular check for a bad unmount and automatically clean up whenever one is detected. Assuming that the script is saved in /home/user/cleanumount then the following steps can add a cron job for it the example will run the check every 5 minutes.

First run the following command: sudo crontab -u root -e

You may be asked to select a text editor from a list by pressing a number from a menu if so simply choose your preferred editor by pressing the corresponding number.

Then add the following two lines to your crontab (The top line is an optional but recommended comment so you know what it does).

# Run /home/user/cleanumount every 5 minutes to cleanly unmount /dev/sdb after sudden disconnects
*/5 * * * *    /home/user/cleanumount

Then save your file and exit the text editor the new crontab will automatically be installed and loaded into the cron daemon.

In the event that 5 minutes is not frequent enough you can adjust the first part of the line, change it to a simple * to run every minute or for example */2 for every 2 minutes */3 for every 3 minutes and so on. More detailed information on the crontab can be found by running man 5 crontab

Hope you find that useful, that is unless some other clever person comes along with a nifty tool to make all this information I wrote out for you redundant if so fantastic :)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .