Отключение отсоединяемых устройств (eSATA, USB-накопитель) в Linux

3450
solidstate

Отсоединяемое устройство, например, eSATA, USB-накопитель может быть внезапно извлечено (просто потянув за вилку).

Если в разделе есть дескрипторы открытых файлов, то эти разделы не будут размонтированы, то есть команда Linux umountне будет выполнена, даже если диск физически отсоединен.

Если при размонтировании происходит сбой, то при повторном подключении устройства mountпроизойдет сбой. Таким образом, вы должны выяснить, какие процессы используют диск и уничтожить их или закрыть все дескрипторы. Если вы не можете сделать это, вам придется перезагрузить компьютер, чтобы подключить диск. И я определенно не могу убить процесс, используя его.

Я не вижу опции «принудительное отключение», она есть -f, но только для NFS.

Это звучит очень странно, разве Linux не подходит для этого сценария, когда пользователь просто дергает диск? Кто-нибудь знает, как изящно справиться с этим сценарием в Linux?

Есть ли способ узнать, какие файловые дескрипторы открыты на определенном разделе / ​​устройстве или выборочно очистить и закрыть все файловые дескрипторы только для определенного устройства?

Примечание. lsofКоманда недоступна во встроенном Linux, который я использую (busybox).


«fuser» недоступен в моем встроенном Linux.

Я попробовал ленивый umount -l. Тем не менее, это не похоже на последовательную работу. Скажем, например, я держу дескриптор файла открытым (с "tail -f" на некотором файле на устройстве). Затем я отсоединяю диск и затем делаю «umount -l», и он монтируется. А затем я снова присоединяю диск и пытаюсь снова смонтировать его в той же точке монтирования, пока хвост все еще работает. Это не всегда работает. Иногда это удается, а иногда нет. Это заставляет меня чувствовать себя неловко, используя ленивую опцию, что если она оставляет файловую систему в несогласованном состоянии. А также не уверен, что этот ленивый вариант должен был использоваться для таких сценариев.

Я не могу убить процесс, у которого открыты дескрипторы файлов.


Кажется, если я смонтировал устройство на скажем / mnt / abc и если я отключил диск и затем снова подключил, Linux, кажется, повторно подключил файловую систему устройства к той же точке монтирования "/ mnt / abc", без каких-либо действий. размонтировать или смонтировать. И затем те же самые старые дескрипторы открытого файла, кажется, начинают работать после присоединения (по крайней мере, для операции чтения файла). Это моё наблюдение. Я не уверен, является ли это ожидаемым поведением. Однако, это также, кажется, не работает последовательно.

У меня был дескриптор открытого файла для чтения ("tail -f"), который я оставил открытым, затем я отсоединил и заново подключил, а затем изменил файл, который был привязан, и увидел, что вывод "tail -f" обновляется с изменениями. Однако, если я пытаюсь изменить файл после того, как устройство исчезло (оно выдает ошибку, как и ожидалось), и затем я снова присоединяюсь, файловая система устройства не будет правильно подключена к той же точке монтирования. В случае записи файла (пока устройства там не было), оно, похоже, не работает.

Есть ли какое-либо стандартное / согласованное поведение, которому следует Linux, когда диск внезапно извлекается без закрытия всех ручек и правильного размонтирования всех разделов?

4

4 ответа на вопрос

3
billc.cn

Вы можете написать bash-скрипт для сканирования всех файловых дескрипторов, перечисленных в /proc(предположим, что у вас есть), и списка / уничтожения процессов.

/proc/$m/fd/$nэто n-й дескриптор файла для PID m, представленный в виде символической ссылки. busyboxдействительно имеет поддержку readlink, так что вы должны быть в состоянии автоматизировать ее.

Редактировать: просто сказать, что это по существу повторная реализация lsof, но на самом деле это довольно просто.

Спасибо за ответ. Но из fd, представленного в / proc / $ m / fd, я могу узнать, к какому устройству или объему он принадлежит. Мне нужно это, мне нужно закрывать fds отсоединяемого устройства (eSATA) ТОЛЬКО при отключении, а не другие, которые могут быть сокетом fd или файловым дескриптором на внутреннем устройстве. solidstate 13 лет назад 0
Есть ли надежный способ узнать, какой дескриптор fd / файла (из / proc) принадлежит какому устройству и тому? solidstate 13 лет назад 0
Извините за ответ так поздно. Основной / (не очень надежный) способ сделать это - использовать `readlink`, чтобы получить путь, на который указывают fds, и сравнить их с точкой монтирования, указанной в` mount`. Например, что-то вроде `if readlink $ fd | grep ^ $ точка монтирования; тогда .... фи billc.cn 13 лет назад 0
Спасибо billc.cn. Но почему вы говорите, что это «не так надежно», что не так с этим подходом. Когда это может дать неправильные результаты? solidstate 13 лет назад 0
Проблема заключается в сравнении пути с точками монтирования. Если программа открыла файл по символической ссылке, это не будет работать. billc.cn 13 лет назад 0
Я уже проверил это. Если файл, открытый командой tail -f, является символической ссылкой, и если вы видите proc /Запись / fd fd будет указывать на фактический файл, а не на ссылку. Так что читайте ссылкувернет путь к фактическому файлу. И даже если это не так, я думаю, можно снова выполнить readlink по возвращенному пути в цикле, чтобы получить целевой файл. solidstate 13 лет назад 1
2
carlpett

Вы можете использовать lsofдля отображения открытых файлов в определенном каталоге с помощью lsof +D /path/to/mountpoint.

Спасибо за ответ. На самом деле lsof не доступен во встроенном Linux, который я использую. lsof недоступен в busybox. 13 лет назад 0
Из простых переходов по каталогам proc / ## / fd для каждого процесса - в наши дни почти наверняка есть файловая система / proc. Таким образом, вы можете либо перенести lsof, либо легко скопировать его функциональность. Скорее всего, он уже доступен как опция в busybox, которую вы просто не включили в своей сборке. Chris Stratton 10 лет назад 0
1
Justin Pearce

Ты пытался:

umount -l /path/to/mountpoint 
Или же

fuser -km /path/to/mountpoint 
?


Итак, мои предыдущие предложения не сработали. Я знаю, что это может быть глупо, но вы действительно пытались:

umount -f /path/to/mountpoint 

Согласно документации Busybox, это должна быть опция принудительного отключения (в качестве примера приведена NFS).

Если это не сработало, вы пробовали:

eject -s /dev/my-sata-or-usb-device 

Согласно OP, `fuser` недоступен, а` umount -l` не работает последовательно (см. Правки к вопросу) slhck 13 лет назад 0
Там не было, когда я писал, да. Ну, это убивает мои идеи. :( Justin Pearce 13 лет назад 0
Благодарю. извлечение недоступно. umount -f не работает (даже после физического отсоединения диска и наличия дескриптора открытого файла - «tail -f»), он говорит umount: невозможно принудительно umount / mnt / abc: устройство или ресурс занят solidstate 13 лет назад 0
У меня нет идей, извини. :( Justin Pearce 13 лет назад 0
0
arpl

Быстрое решение, когда вам не хватает lsof, find /proc/*/fd | xargs readlink | grep /mount_pointзаменит точку монтирования на фактическую точку монтирования. Это основано на ответе billc.cn выше.

Похожие вопросы