Mount: New Order

18 марта 2020

Исторически в Unix/Linux монтирование разделов, перечисленных в /etc/fstab, было принято производить в два этапа:

  • сначала монтируются локальные разделы, т.е. расположенные на устройствах, физически установленных в данном компьютере;
  • затем инициализируется сеть и монтируются сетевые разделы (NFS, CIFS и т.д.);
  • внутри каждого этапа строки в /etc/fstab выполняются по порядку, но для повышения скорости все команды монтирования запускаются в фоне, т.е. без ожидания, пока завершатся предыдущие, поэтому фактически они выполняются независимо и почти одновременно.

В современном мире такой подход работать перестал.

Появились многочисленные типы локальных разделов, которые располагаются не непосредственно на устройствах, а на других локальных разделах, например:

  • loop — файловые системы, хранящиеся в файле-образе (например, зашифрованные);
  • bind — часть дерева каталогов, дополнительно смонтированная в другое место дерева;
  • unionfs, aufs и overlayfs — файлы для чтения поочередно ищутся в нескольких каталогах, а запись производится в один или несколько из них.

Монтировать такие разделы следует только после того, как успешно смонтировались разделы, на которых находятся необходимые для них данные. Предположим, что /etc/fstab выглядит так:

/dev/sdb      /mnt/disk  xfs  defaults       0  0
/mnt/disk/1c  /mnt/1c    none defaults,bind  0  0

В этом примере /mnt/1c с большой вероятностью не смонтируется при старте системы, потому что XFS может потратить на монтирование несколько секунд, т.е. /mnt/1c попытается смонтироваться в тот момент, когда /mnt/disk ещё пуст и /mnt/disk/1c отсутствует.

Данную проблему трудно понять, потому что трудно вопроизвести:
к тому моменту, когда мы получим возможность запустить "mount -a" вручную, /mnt/disk уже успеет смонтироваться, поэтому /mnt/disk/1c будет присутствовать в дереве каталогов и /mnt/1c смонтируется без ошибок.

Пример сообщений из реальной жизни для AUFS (XFS на 40-терабайтном /mnt/hdd в это время ударными темпами проигрывала журнал транзакций после перезагрузки по питанию):

[    6.325036] aufs opt_add:809:mount[736]: lookup failed /mnt/ssd/hot_logs/nginx (-2)
[    6.325060] aufs opt_add:809:mount[746]: lookup failed /mnt/hdd/old_logs/nginx (-2)

Система сообщает нам, что что-то пошло не так, но не в силах объяснить причины случившегося.

Таким образом, мы приходим к следующим выводам:

  • файловые системы (ФС) должны монтироваться в определённом порядке;
  • mount не всегда способен правильно определить этот порядок;
  • поэтому требуется возможность явно указывать зависимости между ФС — т.е. примерно так же, как в большинстве существующих систем инициализации (Systemd, OpenRC и т.д.) указываются зависимости между сервисами.

Хорошая новость — в Systemd такая возможность есть.

Плохая новость (хотя новость ли это?) — она реализована так же, как всё остальное в Systemd, т.е. методом грубой силы, без свойственного unix way изящества.

Порядок настройки зависимостей ФС через /etc/fstab:

  • во флаги монтирования добавляется "noauto", чтобы "mount -a" больше не пытался монтировать её самостоятельно;
  • также во флаги добавляется "x-systemd.automount", чтобы ею начал управлять Systemd;
  • также во флаги добавляется одна или несколько директив "x-systemd.requires-mounts-for=/точка/монтирования" с перечислением всех ФС, монтирование которых должно быть успешно завершено перед монтированием данной.

Верхний пример после внесения исправлений становится таким:

/dev/sdb      /mnt/disk  xfs  defaults       0  0
/mnt/disk/1c  /mnt/1c    none defaults,bind,noauto,x-systemd.automount,x-systemd.requires-mounts-for=/mnt/disk  0  0

Автоматически настройки из /etc/fstab в Systemd не загружаются.
Для их чтения необходимо выполнить "systemctl daemon-reload".
После этого в каталоге /run/systemd/generator должны появиться несколько файлов с расширениями .mount и .automount.
Рекомендуется ознакомиться с их содержимым.

При желании можно (а) перенести их в /etc/systemd/system и (б) закомментировать исходные строки в /etc/fstab.

Разумеется, смонтировать их вручную командой mount после этого станет невозможно и потребуется всегда использовать для этой цели systemctl, но для кого-то может оказаться удобнее редактировать mount-файлы вместо длинных строк в fstab.



← Назад в Блог

Подпишитесь на новые статьи: