Среди множества функций, которые предоставляет 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'а, мы увидим содержимое файлов на удалённом сервере.
Поделиться с друзьями
-->

Комментарии (23)


  1. MagicGTS
    19.06.2017 22:38
    +2

    Получается более гибкий (и наверно даже более понятный) вариант autofs.
    Спасибо!


  1. pansa
    19.06.2017 23:11

    А «обычные» mount'ы свежие дистрибы уже используют по дефолту?


    1. grossws
      19.06.2017 23:14

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


      1. nazarpc
        19.06.2017 23:17

        В Ubuntu оно не работало у меня некоторое время назад и исправлять никто не спешит: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1617512


    1. amarao
      19.06.2017 23:31

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

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


  1. grossws
    19.06.2017 23:12
    +1

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


    1. pansa
      19.06.2017 23:24

      Просто меня 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.


      1. amarao
        19.06.2017 23:32
        +2

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


  1. bano-notit
    20.06.2017 01:09
    +1

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


    1. nikitasius
      20.06.2017 09:43
      +2

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


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


      1. bano-notit
        20.06.2017 16:52
        +2

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


  1. yktoo
    21.06.2017 11:33

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


    1. amarao
      22.06.2017 00:50

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


  1. bormental
    22.06.2017 17:50

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


    1. amarao
      22.06.2017 17:51

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

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


      1. bormental
        22.06.2017 19:40

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


        1. grossws
          22.06.2017 23:38

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


          1. bormental
            23.06.2017 00:46

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


            [Mount]
            Options=...
            

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


  1. evg_krsk
    22.06.2017 20:16

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


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


    1. grossws
      22.06.2017 23:39

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


      1. evg_krsk
        23.06.2017 10:29

        В том что (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, что-то не очень понял.


        1. grossws
          23.06.2017 15:35

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


          1. amarao
            23.06.2017 15:38

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