TL;DR:
- Keeping an external drive dock active without using low-level commands which cause a reset and thus potential data loss.
- In Linux, how to remount an LVM drive which the kernel thinks is still mounted.
Some of us live on the wild side and use an external drive attached via USB as target for backups.
I ran into a problem with my dual-drive docking station while using two drives under Linux: one formatted to ext4 and the other utlising LVM.
It was a lot of trial and error, but eventually I figured out the following conditions:
- Drive is accessed often: no issues.
- Owing to inactivity, drive spins down but dock is still active. Other than delay to spin up, no issues.
- Owing to a long period of inactivity, the dock disconnects from the computer.
- Owing to an even longer inactivity, the dock goes into an extremely deep sleep state — the red light’s on (otherwise green), but it doesn’t respond to anything other than a power cycle of the dock.
The problems came in with dealing with stages 3 and 4.
Stage 3
Being disconnected, so the OS won’t see it until you unplug it and then re-plug it again. The problem comes in that the dock doesn’t disconnect — as far as the OS is concerned it is still connected, but now another dock makes its appearance. In the case of the ext4 volume it gets mounted to a new device file, but LVM throws its toys out of the cot because now a “new” drive presents itself with the same credentials as an existing one.
There are two things you can do here, either some incantations on the command line, or reboot. If you don’t want to reboot, run these, assuming that the VG is called vg-backup
, the LV is called lv-backup
, and the mount point is /mnt/backup
:
umount /dev/vg-backup/lv-backup
dmsetup remove -f vg--backup-lv--backup
pvscan --cache
vgscan
vgchange -an vg-backup
vgchange -ay vg-backup
mount /mnt/backup
If you’re going to put that in a script, it’s safest to add a sleep 1
between the lines.
Stage 4
This is a real problem, and the only thing you can do (well, in the case of my dock) is to cycle the dock’s power. Rebooting the machine doesn’t help, as the dock doesn’t see it and since its power stays on, its state stays unchanged.
The only solution is never to get to this point, and I address this with a cron
entry which runs a script that doesn’t use low-level commands which reset the connection in some way.
The simplest I found was to use hdparm
to query the drive’s current temperature, as almost everything else is cached by the OS, but it has to query the drive to get its current temperature. What makes it difficult is that I wanted a solution which would work without knowing the details of any of the drives in the dock (so I can’t use its UUID, for example).
My approach was to run “dmesg”, then search from the back for the dock device serial number (that’s when it was last seen as a new device). Then from there I’d search forward in time for text matching “[sd.]” (as a “grep” regular expression). Using that I could then query the correct drive. Once we have the device file it’s a one-liner.
Doing all of that leads to this rather inelegant code:
#!/bin/bash
DRIVE="/dev/\
`dmesg \
| tac \
| grep -B 20 DD564198838DA \
| head -21 \
| grep '\[sd.\]' \
| awk '{print $5}' \
| tr -d '\[\]' \
| sort \
| uniq \
| head -1`"
hdparm -H $DRIVE >/dev/null 2>&1
exit 0
There is a non-zero chance that the assignment of a previously (only just previously) discovered drive would pop up in the journal after the device serial number is recorded and before any related assignments are made, so there is room for improvement.
Put your own device’s serial number in after the grep -B 20
and before that line’s \
, save it, then call it as often as required. It’s a lot of work, but you’ll have to run something like lsusb -v | less
, then search for your device and use its iSerial
value.
Also, first run it in script form with and echo
before the hdparm
call, so you can be sure that the awk
line gets the correct field (it might not be field 5 on yours).