2

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
1

If the device is not a CDROM drive, eject falls back to a generic SCSI "START STOP" command, with option "eject" set.

It's possible to send the reverse, "START STOP" with the "start" option, using sg_start -s. sg_start is available as part of the sg3_utils package on most distributions.

Apparently sg_start -s was sufficient to restart the drive in this case. sg_start --load was not required. (This makes sense to me, because I don't see this as an eject having taken place).

Other users have claimed that this doesn't work. USB drive controllers particularly for small flash drives can be a bit weird, so I wouldn't be surprised if some drives refused this command.

https://unix.stackexchange.com/a/394961/29483

The USB controller in a flash ROM stick usually reacts by powering down the device and preventing any further interaction. That means it disappears completely from the USB subsystem, and must be re-enumerated to be able to accessed again.

The same command when send e.g. to a CD/DVD drive will eject the disk, and the also existing "load" option of the "START STOP" command will load it again. But this interpretation only applies to devices with removable media.

  • Gotcha, thanks! I learned some new valuable information. If you add the following to your answer, I will accept it: I needed to simply send the SCSI START signal again. So I found a utility to do this sg_start -s /dev/sdd, and it worked, I immediately saw the LED on the usb-drive flashing, and my file manager asked me if I wanted to mount it :) (on Arch Linux sg_start is part of the sg3_utils package) – Yeti Feb 9 '18 at 8:20
  • @Yeti updated. Thanks for your correction! I've always wondered about this. This answer applies to the eject command - "eject" buttons in the GUI tend to go through udisks and I think do unbind as well, which makes it a bit confusing. – sourcejedi Feb 9 '18 at 9:32
  • @Yeti it might be interesting to know what device it is. Am I right in guessing it is not a "memory stick"? – sourcejedi Feb 9 '18 at 9:38
  • I am sorry to disappoint you, it is just a regular Kingston flash/thumb drive. – Yeti Feb 9 '18 at 12:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.