Problem
After using the following command on my usb-drive (/dev/sdd):
# physically plugging usb-drive in at /dev/sdd
> umount /dev/sdd1
> eject /dev/sdd
I am unable to undo this last action. How do I mount the drive again, programmatically?
Physical access to the device is not an option, and neither is rebooting.
What did you try?
As you will see, the regular stuff won't work.
> mount /dev/sdd1
mount: /dev/sdd1: can't find in /etc/fstab.
We can see /dev/sdd1
does not exist anymore:
> ls /dev/sdd*
/dev/sdd
So let's try to undo eject by using the same utility again:
> eject --trayclose /dev/sdd
> ls /dev/sdd*
/dev/sdd
This does not seem to do anything, so let's bind the usb-drive to the driver.
> udevadm info /dev/sdd | grep DEVPATH
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/host6/target6:0:0/6:0:0:0/block/sdd
> echo -n "1-1:1.0" > /sys/bus/usb/drivers/usb-storage/unbind
> ls -d /sys/bus/usb/drivers/usb-storage/1-1\:1.0
ls: cannot access '/sys/bus/usb/drivers/usb-storage/1-1:1.0': No such file or directory
> echo -n "1-1:1.0" > /sys/bus/usb/drivers/usb-storage/bind
> ls -d /sys/bus/usb/drivers/usb-storage/1-1\:1.0
1-1:1.0
Ok, so the unbind and bind worked. This is not the problem nor solution. Also, the device still seems to be powered. Let's try to trigger something.
> udevadm trigger --name-match=/dev/sdd
This does not seem to solve the problem either. Now let's try to read the partition table again, because /dev/sdd
exists but /dev/sdd1
not. I found three different methods of achieving this:
> partprobe /dev/sdd
Error: Error opening /dev/sdd: No medium found
> hdparm -z /dev/sdd
/dev/sdd:
re-reading partition table
> partx -u /dev/sdd
partx: cannot open /dev/sdd: No medium found
> ls /dev/sdd*
/dev/sdd
Still no /dev/sdd1
. Maybe try some rescan:
> echo 1 > /sys/block/sdd/device/rescan
> ls /dev/sdd*
/dev/sdd
Still nothing, let's verify what fdisk
says about this:
> fdisk -l | grep sdd
Okay, nothing. Let's try to reset the usb-drive then.
> echo 0 > /sys/bus/usb/devices/1-1\:1.0/authorized
> echo 1 > /sys/bus/usb/devices/1-1\:1.0/authorized
> ls /dev/sdd*
ls: cannot access '/dev/sdd*': No such file or directory
This made it worse, trial and error failed. I give up. What am I missing here?
*facepalm* why eject
at all?!
Well, I need this solution for actually another problem, in which Linux does not want to mount the usb-drive anymore after i/o errors occurred. Since physically plugging the usb-drive back in works for that problem, I need to know how to do this programmatically. And even if this will not solve my original problem, I want to know how to undo eject
.
EDIT: More details
Here is an additional source from kernel.org on usb hotplugging, telling what should be happening:
- Find a driver that can handle the device. That may involve loading a kernel module; newer drivers can use module-init-tools to publish their device (and class) support to user utilities.
- Bind a driver to that device. Bus frameworks do that using a device driver’s probe() routine.
- Tell other subsystems to configure the new device. Print queues may need to be enabled, networks brought up, disk partitions mounted, and so on. In some cases these will be driver-specific actions.
It seems that the last step may still need to be done. Backed by further info on the state of the usb-drive after it is "ejected", showing that the usb-drive is powered and Linux can communicate with it:
> cat /sys/block/sdd/device/state
running
> cat /sys/block/sdd/device/power/runtime_status
active
> cat /sys/block/sdd/device/power/runtime_suspended_time
0
> cat /sys/block/sdd/device/power/control
on