как узнать, какие процессы препятствуют размонтированию устройства?

<p>иногда я хотел бы отключить <strong>sb-устройство</strong> с помощью <code>umount /run/media/thedrive</code>, но я получаю <code>drive is busy</code> ошибка.</p><p>как узнать, какие процессы или программы обращаются к устройству?</p>

<p>используйте <code>lsof | grep /media/whatever</code> чтобы узнать, что использует крепление.</p><p>также рассмотрим <code>umount -l</code> (отложенная установка), чтобы новые процессы не могли использовать диск во время очистки.</p>

<p>в большинстве случаев лучше всего использовать команду <a href="http://people.freebsd.org/~abe/">lsof</a> ("<strong> l </strong> i <strong> s </strong> t <strong> o </strong> ручка <strong> f </strong> īles").</p><pre><code>lsof +f -- /media/usb0 </code></pre><p>где <code>/media/usb0</code> - это точка монтирования usb-накопителя или другой файловой системы для размонтирования. <code>+f --</code> говорит lsof обрабатывать последующий аргумент как точку монтирования; обычно, но не всегда, это происходит самостоятельно, так что <code>lsof /media/usb0</code> также работает. он находит открытые файлы (даже несвязанные), отображенные в память файлы, текущие каталоги и некоторые другие неясные варианты использования. вам нужно будет выполнить команду от имени пользователя root, чтобы получить информацию о процессах других пользователей (и я думаю, что есть единицы, где <code>lsof</code> должен запускаться от имени пользователя root).</p><p>есть способы, которые lsof не найдет; это необычно на съемных носителях. они включают:</p><ul> <li>точки монтирования: вы не можете размонтировать <code>/foo</code> если <code>/foo/bar</code> это точка монтирования.</li> <li>монтировать устройства: вы не можете размонтировать <code>/foo</code> если <code>/foo/bar</code> - это смонтированное блочное устройство или обычный файл, смонтированный в цикле, или, если это источник монтирования в linux.</li> <li>экспорт nfs: lsof не обнаружит, что дерево экспортируется сервером nfs ядра.</li> </ul><p>еще одна команда, которая может использоваться в крайнем случае, - это fuser, который перечисляет только pid процессов с открытыми файлами на устройстве:</p><pre><code>fuser -m /media/usb0 </code></pre>

<h3>открытые файлы</h3><p>процессы с открытыми файлами являются обычными виновниками. показать их:</p><pre>\_<code>lsof +f -- <mountpoint or device> </code>\_</pre><p>преимущество использования \_<code>/dev/<device></code>\_, а не \_<code>/mountpoint</code>\_: точка монтирования исчезнет после \_<code>umount -l</code>\_ или может быть скрыта при наложенном монтировании.</p><p><code>fuser</code> также можно использовать, но, на мой взгляд, <code>lsof</code> имеет более полезный вывод. однако <code>fuser</code> полезно, когда дело доходит до уничтожения процессов, вызывающих ваши драмы, чтобы вы могли продолжить свою жизнь.</p><p>вывести список файлов на \_<code><mountpoint></code>\_ (см. предостережение выше):</p><pre>\_<code>fuser -vmm <mountpoint> </code>\_</pre><p>интерактивно уничтожать только процессы с открытыми для записи файлами:</p><pre>\_<code>fuser -vmmkiw <mountpoint> </code>\_</pre><p>после перемонтирования только для чтения (\_<code>mount -o remount,ro <mountpoint></code>\_) безопасно (r) убить все оставшиеся процессы:</p><pre>\_<code>fuser -vmmk <mountpoint> </code>\_</pre><h3>точки монтирования</h3><p>виновником может быть само ядро. другая файловая система, смонтированная в файловой системе, которую вы пытаетесь <code>umount</code>, вызовет горе. проверить с:</p><pre>\_<code>mount | grep <mountpoint>/ </code>\_</pre><p>для петлевых монтировок ( <a href="https://unix.stackexchange.com/questions/3109/how-do-i-find-out-which-processes-are-preventing-unmounting-of-a-device/386960#comment689190\_386960">спасибо стивену китту</a> ) также проверьте вывод:</p><pre>\_<code>losetup -la </code>\_</pre><h3>анонимные иноды (linux)</h3><p> <a href="https://stackoverflow.com/q/4508998/5353461">анонимные inode</a> может быть создано:</p><ul> <li>временные файлы (<code>open</code> с \_<code>o\_tmpfile</code>\_)</li> <li> <a href="https://en.wikipedia.org/wiki/inotify">inotify</a> часы</li> <li>[eventfd]</li> <li>[eventpoll]</li> <li>[timerfd]</li> </ul><p>это самый неуловимый тип покемонов, и он отображается в столбце <code>lsof</code> <code>type</code> как \_<code>a\_inode</code>\_ (который недокументирован в человеке <a href="http://man7.org/linux/man-pages/man8/lsof.8.html"><code>lsof</code>) страница</a> ).</p><p>они не будут отображаться в \_<code>lsof +f -- /dev/<device></code>\_, поэтому вам необходимо:</p><pre>\_<code>lsof | grep a\_inode </code>\_</pre><p>для процессов уничтожения, содержащих анонимные inode, смотрите: <a href="https://unix.stackexchange.com/q/386877/143394">список текущих наблюдений inotify (путь, pid)</a> .</p><h3><code>inotify</code> часы (linux)</h3><p> <a href="https://stackoverflow.com/questions/45951874/system-call-interface-to-proc-information#comment78876871\_45951874">этот комментарий</a> объясняет, почему <code>inotify</code> <em> не должен </em> предотвращать размонтирование, но <a href="https://sort.symantec.com/public/documents/sfha/5.1sp1/linux/productguides/html/sf\_notes/ch01s09s04s12.htm">это примечание</a> описывает ситуации, в которых он <em> будет </em>:</p><blockquote> <p>размонтирование может зависнуть в вызове <code>vx\_softcnt\_flush()</code>. зависание происходит из-за того, что отслеживание inotify увеличивает значение переменной \_<code>i\_count</code>\_ и заставляет \_<code>v\_os\_hold value</code>\_ оставаться повышенным до тех пор, пока наблюдатель inotify не освободит удержание.</p> </blockquote>

<p>вы можете использовать <code>lsof</code>, как сказал питер, или если вы уверены, что просто хотите убить все эти вещи и размонтировать его, вы можете сделать что-то вроде:</p><pre><code>fuser -mk /mnt/path umount /mnt/path </code></pre>

<p>если вы используете gnome, отключение через nautilus отобразит сообщение о том, какой процесс все еще использует диск, и файл, который он использует.</p><p><img src="https://i.stack.imgur.com/uw1km.png" alt="alt text"></p>

<p>для (как минимум) openbsd:</p><pre><code>$ fstat /mnt/mountpoint например (используя doas для выполнения fstat в качестве пользователя root, в противном случае мы бы видели только наши собственные процессы):$ doas fstat /usr/ports user cmd pid fd mount inum mode r/w sz|dv name \_pbuild make 15172 wd /usr/ports 3923598 drwxrwxr-x r 1536 /usr/ports/ \_pbuild make 40034 wd /usr/ports 3923598 drwxrwxr-x r 1536 /usr/ports/ </code></pre><p>в этом случае я не смог бы размонтировать <code>/usr/ports</code> до пользователя <code>\_pbuild</code> завершил выполнение этих двух процессов <code>make</code>.</p>