Mount

如何插入 USB 驅動器?

  • February 9, 2018

問題

在我的 USB 驅動器 (/dev/sdd) 上使用以下命令後:

# physically plugging usb-drive in at /dev/sdd
> umount /dev/sdd1
> eject /dev/sdd

我無法撤消這最後一個操作。如何以程式方式再次安裝驅動器?

物理訪問設備不是一種選擇,重啟也不是。


你嘗試了什麼?

正如你將看到的,正常的東西是行不通的。

> mount /dev/sdd1
mount: /dev/sdd1: can't find in /etc/fstab.

我們可以看到/dev/sdd1不存在了:

> ls /dev/sdd*
/dev/sdd

因此,讓我們再次使用相同的實用程序嘗試撤消彈出:

> eject --trayclose /dev/sdd
> ls /dev/sdd*
/dev/sdd

這似乎沒有做任何事情,所以讓我們將 USB 驅動器綁定到驅動程序。

> 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

好的,所以 unbind 和 bind 起作用了。這不是問題,也不是解決方案。此外,該設備似乎仍處於通電狀態。讓我們嘗試觸發一些東西。

> udevadm trigger --name-match=/dev/sdd

這似乎也不能解決問題。現在讓我們再次嘗試讀取分區表,因為/dev/sdd存在但/dev/sdd1不存在。我發現了三種不同的方法來實現這一點:

> 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

還是沒有/dev/sdd1。也許嘗試重新掃描:

> echo 1 > /sys/block/sdd/device/rescan
> ls /dev/sdd*
/dev/sdd

還是什麼都沒有,讓我們驗證一下fdisk這件事是怎麼說的:

> fdisk -l | grep sdd

好吧,沒什麼。讓我們嘗試重置 USB 驅動器。

> 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

這使情況變得更糟,反複試驗失敗了。我放棄。我在這裡想念什麼?


*facepalm *為什麼eject

好吧,我實際上需要這個解決方案來解決另一個問題,即在發生 i/o 錯誤後 Linux 不想再掛載 USB 驅動器。由於以物理方式重新插入 USB 驅動器可以解決該問題,因此我需要知道如何以程式方式執行此操作。即使這不能解決我原來的問題,我也想知道如何撤消eject


編輯:更多細節

這是kernel.org 關於 usb hotplugging的另一個來源,說明應該發生什麼:

  • 找到可以處理該設備的驅動程序。這可能涉及載入核心模組;較新的驅動程序可以使用 module-init-tools 將其設備(和類)支持發佈到使用者實用程序。
  • 將驅動程序綁定到該設備。匯流排框架使用設備驅動程序的 probe() 常式來做到這一點。
  • 告訴其他子系統配置新設備。可能需要啟用列印隊列、啟動網路、安裝磁碟分區等等。在某些情況下,這些將是特定於驅動程序的操作。

看來最後一步可能還需要做。以 USB 驅動器“彈出”後狀態的更多資訊為後盾,表明 USB 驅動器已通電並且 Linux 可以與其通信:

> 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

如果設備不是 CDROM 驅動器,則eject回退到通用 SCSI“START STOP”命令,並設置選項“eject”。

可以使用“開始”選項發送相反的“開始停止” sg_start -s。sg_start 在大多數發行版上作為 sg3_utils 包的一部分提供。

在這種情況下,顯然sg_start -s足以重新啟動驅動器。 sg_start --load不是必需的。(這對我來說很有意義,因為我不認為這是發生了彈出)。

其他使用者聲稱這不起作用。用於小型快閃記憶體驅動器的 USB 驅動器控制器可能有點奇怪,因此如果某些驅動器拒絕此命令,我不會感到驚訝。

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

快閃記憶體 ROM 棒中的 USB 控制器通常會通過關閉設備電源並阻止任何進一步的互動來做出反應。這意味著它完全從 USB 子系統中消失,必須重新列舉才能再次訪問。

發送到 CD/DVD 驅動器時的相同命令將彈出磁碟,並且“START STOP”命令的現有“載入”選項將再次載入它。但這種解釋僅適用於具有可移動媒體的設備。

引用自:https://unix.stackexchange.com/questions/422880