Автомонтирование файловых систем с systemd

  • Tutorial
Среди множества функций, которые предоставляет systemd, есть одна, которую несправедливо забыли. Это функция автомонтирования. При настройке автомонтирования указанный каталог будет подмонтирован только после первого обращения к нему (точнее, прямо во время).

NFS over VPN


Конкретный пример: у меня есть удалённый сервер, на котором есть интересующий меня каталог. Я хочу иметь этот каталог локально на своей машине. Протокол доступа — nfs. Т.к. он не имеет шифрования, то разумным решением выглядит использование vpn-канала до сервера.

При этом я хочу монтировать его на ходу и отмонтировать через некоторое время, чтобы не испытывать странных затруднений из-за тупящей nfs при лежащей сети. Таймаут монтирования куда более гуманная ошибка, чем таймаут nfs на ls.

Как оно устроено


Systemd имеет специальный вид automount-юнитов, которые позволяют автоматически монтировать указанный каталог.

Важно: automount-юниты это не «mount-юниты с автомонтированием», они не могут иметь в себе параметры монтирования. Вместо этого, они (при обращении к каталогу) всего лишь вызывают mount-юнит для указанного каталога.

Соответственно, при конфигурации:

  • Опции монтирования, устройство (или сервер в случае NFS) указываются в mount-юните
  • Зависимости и install-секция указываются в automount-юните
  • Свзяка automount-юнита и mount-юнита происходит по параметру where

Это же можно заметить по структуре самих юнитов. У mount-юнита есть секция [Mount] в которой может быть множество параметров. У automount-юнита такой секции быть не должно, а вместо этого есть секция [Automount], в которой могут быть всего несколько параметров: Where, DirectoryMode и TimeoutIdleSec.

Практический пример


/etc/systemd/system/media-nfs.mount:
[Unit]
Description=NFS share
[Mount]
What=server.url.example.com:/srv/nfs_share
Where=/media/nfs
Type=nfs4
Options=rw
DirectoryMode=0755


/etc/systemd/system/media-nfs.automount:
[Unit]
Description=NFS share
Requires=openvpn@vpn.service
Requires=network-online.target
[Automount]
Where=/media/nfs
TimeoutIdleSec=301
[Install]
WantedBy=graphical.target

Наблюдение: при том, что для mount-юнита нормальное состояние это active (mounted), то для automount — active (running), как для сервиса.

Если же automount ещё не случился, то статус будет «active (waiting)».

После настройки automount'а нужно сделать (sudo) systemctl daemon-reload, и сделать ls /media/nfs (для примера выше) — после некоторой задержки от монтирования nfs'а, мы увидим содержимое файлов на удалённом сервере.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 29
  • +2
    Получается более гибкий (и наверно даже более понятный) вариант autofs.
    Спасибо!
    • 0
      А «обычные» mount'ы свежие дистрибы уже используют по дефолту?
      • 0

        Через генератор из fstab'а — используют точно. Чтобы именно генерировали сами — не видел. Я пришел к тому, что часть разделов пишутся не в fstab, а в /etc/systemd/system/*.mount, чтобы не ломать систему по недоступности сети до СХД.

      • 0
        Вроде бы, нет. Есть генераторы (специальный фиче-хак для создания динамических юнитов, в частности, для парсинга fstab), но это всё костыли переходного периода.

        В принципе, за вычетом root'а, остальное можно смело писать. С root'ом всё чуть сложнее — и вопрос взаимодействия системы с содержимым в initrd надо внимательно смотреть, потому что можно случайно с кривым конфигом после мелкого изменения остаться.
      • +1

        Даже просто mount-unit'ы уменьшают количество боли и печали. Например, при использовании разделов на iscsi, которые не нужны при загрузке, но нужны при работе. Если такой раздел прописан в fstab'е, а доступа к target'у нет, то большинство систем ведут себя крайне неприятно, от остановки загрузки (и не запущенного sshd) до ухода в emergency/single, что при работой с сервером по ssh крайне неприятно.

        • 0
          Просто меня systemd-шные mount-ы тоже боль причинили — внезапно взяли и отмонтировались:

          systemd[1]: Mounting /data/ssd…
          systemd[1]: Mounted /data/ssd.
          systemd[1]: Unmounting /data/ssd…
          umount[3616]: umount: /data/ssd: not mounted
          systemd[1]: data-ssd.mount mount process exited, code=exited status=32
          systemd[1]: Unmounted /data/ssd.
          systemd[1]: Unit data-ssd.mount entered failed state.

          • +2
            Ну, тут systemd ничем помочь не может — надо смотреть почему случилось. systemctl status, или даже dmesg. Возможно, ошибка на блочном уровне, может, даже дисконнект на уровне кабеля. Или баг где-то ниже по стеку в Линуксе.
        • +1

          Спасибо!!! Вот есть у меня проблема, точнее была.
          Мак древнейший, на нём установлен debian 8. Мак задумывался как качалка, но он не подключал внешний диск с ntfs. В fstab прописывал, всякие проги устанавливал. Они подключали раздел с какой-то ошибкой. Но как ни странно ручьями нормально монтировалось.
          Сейчас прочёл статью, настроил юниты и оно работает! Неделю не работало, а теперь работает! Я очень рад. Спасибо огромнейшее за статью.

          • +2

            надо смотреть что за ошибка.


            Я для себя давно определил, что монтировать надо по uuid (/dev/disk/by-uuid/), тогда в случае с чехардой дисков (актуально для серверов и виртуалок) не будет прикола, что sdb больше не sdb, а sdc, в свою очередь, sdc теперь sdb.

            • +2

              Ну я же не совсем дурак) Я по uuid и монтировал. Вот только она сначала подключалась, а потом через какое-то время отключалась и всё. Дальше только с ручного. А теперь вот всё нормально работает.

          • 0

            А можно сделать ещё, чтобы перед уходом системы в suspend тоже размонтировалось?

            • 0
              Явного метода я не нашёл, наверное, можно в suspend-target'е потребовать остановки. Но я не уверен.
            • 0

              Возможно глупость спрашиваю :)
              А можно таким же образом смонтировать шару на самбе, но при этом ввести пароль интерактивно (т.е. у юзера запросить) при попытке доступа к дир-ии на локалхосте, куда должна смонтироваться шара?

              • 0
                Интерактивно — точно нет. Процессы запускаются системд отдельно от seat и не имеют доступа к пользовательской сессии.

                Чисто теоретически можно было бы подумать про что-то с pam, или auth agent, но я с трудом себе представляю как это сделать.
                • 0

                  Нагуглил systemd-ask-password, читаю…
                  Похоже, в этом systemd действительно пол OS найти можно :)

                  • 0

                    Да, это же набор разных кубиков для создания базового окружения, этих кубиков там выше крыши (более 70, IIRC). Правда, во многих дистрибутивах будет собрана не сильно большая часть.

                    • 0

                      В данном случае, это скорее в плюс systemd.
                      Доустановил systemd-gnome-ask-password-agent, запустил.
                      Вызвав systemd-ask-password выскакивает GUI-окно с запросом пароля.
                      В результате введенная строка печатается systemd-ask-password.
                      И вот дальше "затык". Как полученный пароль пробросить в параметры монтирования в


                      [Mount]
                      Options=...
                      

                      mount-юнита не ясно. Похоже, что никак.
                      Тут скорее концептуально было бы красивее и проще, если б сам systemd предусматривал бы интерактивный (с задаваемым таймаутом) запрос пароля из mount-юнита с помощью специальной директивы. Увы, я таковой не обнаружил.

              • 0

                Эх, вот если бы это счастье ещё и template-илось (кучка шар на одном сервере). Но увы.


                Ну и да, интересный вопрос как жить с асинхронными суспендами/выключениями сервера/клиента.

                • 0

                  А в чем проблема с использованием template unit'ов? Если в instance name можно запихать немного, то в EnvironmentFile вполне лезет почти всё, что нужно

                  • 0

                    В том что (https://www.freedesktop.org/software/systemd/man/systemd.automount.html):


                    Note that automount units cannot be templated, nor is it possible to add multiple names to an automount unit by creating additional symlinks to its unit file.

                    Как вы предлагаете использовать EnvironmentFile для подстановки разных What/Where, что-то не очень понял.

                    • 0

                      Тогда извините, не обратил внимания, что эта фича недоступна. Остаются генераторы, можно генерировать unit'ы в /run/systemd/system

                      • 0
                        Кстати, да, generator, который делает automount для каждого mount-юнита — это интересно.
                  • 0

                    С суспендами живёт замечательно, никак не хуже autofs.


                    Жаль только что каждые TimeoutIdleSec секунд на каждую смонтированную и занятую кем-то шару в журнал плюется сообщение о невозможности отмонтировать. Да и на успешное монтирование/отмонтирование журнал забивается.


                    Кто нибудь решал такую проблему или это надо в апстрим идти?

                  • 0
                    Что-то не хочет у меня это всё нормально работать с bind-ами.

                    Есть /mnt/sda, с automount. Монтируется при обращении.
                    Есть /opt/oh2 == bind to /mnt/sda/oh2 тоже с automount, BindsTo/After/PartOf на mnt-sda.mount.

                    При запуске opt-oh2.automount всё первый раз срабатывает. Но! Если отмонтируется /mnt/sda, то opt-oh2.automount переходит в 'inactive(dead)' и, соответственно, перестаёт работать. А OnFailure у automount нет…

                    Несколько дней гугления и вопрос на «Тостере» пока результат не дали :(
                    • 0
                      Выглядит как баг. Сконструировать минимальный кейс и заслать в багтрекер: https://github.com/systemd/systemd/issues
                      • 0
                        Для этого надо чуть более вменяемое описание зависимостей (Requires/Whants/BindsTo/PartOf), чем то, что лежит на freedesktop.org. Потому как я до конца не понимаю, как это вообще должно работать — как-то после «BindsTo несколько более строгое, чем Requires» и почти то же самое про PartOf, образуется равномерная каша в голове, не разбавляемая даже экспериментами.

                        Повожусь ещё несколько вечеров и либо буду сочинять баго-реквест, либо плюну и откачусь на симлинки…

                        Огорчает, что нет готового механизма «пнуть зависимых при изменении статуса» на случай _запуска_ .mount/.automount, только на случай его остановки :(
                        • +1
                          Лучше багрепорт. PartOf — отличная штука, если в ней есть дырки, то их лучше починить, чем плюнуть и забить.
                        • 0
                          Вдогонку из лога:

                          // #systemctl status mnt-bind_a.automount
                          ...
                          Active: inactive (dead)
                          ...
                          авг 02 23:54:24 x240 systemd[1]: Set up automount Test bind 1 auto.
                          авг 02 23:54:33 x240 systemd[1]: mnt-bind_a.automount: Got automount request for /mnt/bind_a, triggered by 24597 (mc)
                          авг 02 23:55:45 x240 systemd[1]: Unset automount Test bind 1 auto.

                          Вот, нижняя строчка вылезает при (авто-) отмонтировании «родителя»

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.