Вопрос или проблема
Я хочу узнать, какой самый простой способ определить (без привилегий root), замонтирован ли блочное устройство (скажем, sdb
) или какая-либо его часть (и какая именно часть).
Проверка /proc/mounts
на наличие sdb недостаточна, потому что sdb
или один из его разделов может быть использован LVM. Вы можете проверить /sys/block/sdb/sdb*/holders/
, но там будут записи dm-x
, которые необходимо разрешать до имен /dev/mapper
, чтобы проверить /proc/mounts
. Это возможно, но если есть более простое решение… (которое не требует привилегий root).
По сути, это вопрос проверки множества пограничных случаев.
- Диск может появиться в /proc/mounts
- Диск может использоваться как swap (используйте /proc/swaps)
- Диск может быть частью активного LVM pv (используйте pvdisplay)
- Диск может быть частью группы RAID через dm-mapper (используйте /proc/mdstat)
- Диск может быть напрямую доступен приложением (например, Oracle поддерживает запись напрямую на диск или раздел вместо файловой системы) (используйте fuser)
- Диск может быть напрямую доступен виртуальной машиной (используйте fuser)
- Диск может быть ссылаем устройством loopback (например:
mount /dev/sda -o offset=1M /foo
) (используйте losetup -a)
Это лишь примеры, которые я придумал за полторы минуты размышлений. Уверен, есть еще дюжина других.
Этот последний пример, думаю, самый интересный и мало кто знает о нем. Он позволяет монтировать файловую систему без использования разделов. Просто укажите начальное смещение, и Linux прозрачно создаст loopback устройство. Приведенный выше пример дает следующее:
# cat /proc/mounts
...
/dev/loop0 /foo ext4 relatime,data=ordered 0 0
# losetup -a
/dev/loop0 [0005]:2048 (/dev/sda), offset 1048576
Зачем это делать? Обычно это связано с ситуациями, когда изначально всё было ужасно неправильно.
Также имейте в виду, что с функцией неймспейсов, теперь входящей в mainline (см. unshare), разные процессы могут иметь разное представление о том, что смонтировано, а что нет. Здесь вещи начинают немного “краснопиллеветь”.
По крайней мере для устройств device-mapper (включая cryptsetup и LVM тома) существует “Open count”, отображаемый командой dmsetup info
. Это берется из DM_TABLE_STATUS
ioctl и также, по-видимому, является основой для флага o
(open), показанного в lvs
. Это кажется довольно всеобъемлющим: например, в dom0 моей системы Qubes OS 4.0 (основанной на Fedora 25), она обнаружила использование xen_blkback
, которое не упоминается ни в одном из других ответов здесь или не обнаружено lsblk
.
К сожалению, в быстром исследовании я не смог найти аналога этого для произвольных блочных устройств.
Существует гораздо больше способов монтирования устройств, все они могут комбинироваться, так что, как часто бывает, вам придется разобраться самостоятельно.
т.е. что используется lvm: pvdisplay
Поэтому вам нужно включить также nfs, cifs, raid, loop, crypt и так далее.
Хорошей отправной точкой всегда является /proc/mounts
, как вы уже упомянули.
Попробуйте получить эксклюзивную блокировку на блочное устройство. Если что-либо из него замонтировано где-либо, используется как swap, luks или lvm, вам не удастся получить эксклюзивную блокировку:
python3 -c "import os,sys; os.open(sys.argv[1], os.O_WRONLY | os.O_EXCL)" /dev/sda
Потому что, как отмечали другие: да, может быть масса разных странных способов, как блочное устройство может быть “в использовании”.
Ответ или решение
Определение текущего состояния блочного устройства, например, такого как sdb
, может быть сложной задачей без привилегий root, учитывая разнообразие способов использования этих устройств в современной системе Linux. В данной ситуации мы рассмотрим несколько подходов, которые помогут выяснить, смонтировано ли устройство или используется ли его часть.
Теория
-
Проверка монтирования: Первым шагом можно проверить, отображается ли устройство или его разделы в
/proc/mounts
. Этот файл содержит список всех активных монтирований файловой системы. -
Использование в качестве swap: Некоторые устройства могут использоваться как swap-раздел. Это можно проверить через
/proc/swaps
. -
Logical Volume Manager (LVM): Устройство может быть частью LVM. Выявить это можно с помощью команды
pvdisplay
, которая отображает физические объемы. -
Устройства Device Mapper: Если устройство используется в конфигурациях, таких как RAID или шифрование, информация об этом может содержаться в
/proc/mdstat
. Такжеdmsetup info
может предоставить детали о том, используется ли устройство. -
Прямой доступ приложениями: Некоторые приложения имеют возможность напрямую работать с блочными устройствами. Для их обнаружения можно использовать команду
fuser
. -
Использование виртуальными машинами: Аналогично, виртуальные машины могут иметь прямой доступ к устройствам, выявить это можно также с помощью
fuser
. -
Устройства Loopback: Иногда блочные устройства монтируются через loopback, что можно обнаружить через команду
losetup -a
.
Пример
Рассмотрим пример использования loopback-устройства. Если запустить следующую команду:
losetup -a
можно увидеть такие записи, как /dev/loop0
, указывающие на блочное устройство, использованное как loopback.
Применение
Помимо перечисленных методов, можно попробовать получить эксклюзивную блокировку на устройстве:
python3 -c "import os,sys; os.open(sys.argv[1], os.O_WRONLY | os.O_EXCL)" /dev/sda
Если это устройство уже используется (будь то монтировано, используется в LVM или другими способами), запрос блокировки завершится ошибкой.
Кроме того, необходимо учитывать, что с введением механизмов изоляции, таких как unshare
, различные процессы могут иметь разные представления о состоянии монтирования, что добавляет уровни сложности.
Заключение
Решение вопроса о состоянии блочного устройства требует учета множества факторов и проверки через различные механизмы, от простых файлов в /proc
до более сложных конфигураций, таких как LVM и передачи виртуальным машинам. Такой комплексный подход позволяет получить полное представление о текущем использовании устройства.