5

У меня есть приложение (работает как служба от имени root), которое создает файл PID в /var/run . Но мне интересно, не является ли это сейчас лучшей практикой?

В Linux - альтернативные места, где хранить pid-файл вместо /var /run, заданный в 2012 году, спрашивающий спрашивает, следует ли вообще помещать PID-файлы в /var/run . Это было, однако, в значительной степени до появления systemd и перехода операционных систем systemd с /var/run на just /run (как одна из systemd " Файловые системы API " и указанная в системных требованиях иерархии файлов).

Такие вещи, как спецификация XDG Base Directory от Lennart Poettering (и других), говорят о других местах для «пользовательских несущественных файлов времени выполнения и других файловых объектов (таких как сокеты, именованные каналы,…)». Так же, как и справочная страница по file-hierarchy systemd.

И то, что я читал в другом месте, создает у меня впечатление, что /var/run/user/$UID - это новое стандартное расположение для таких вещей в операционных системах systemd.

  • Ответы в https://unix.stackexchange.com/questions/162900/ говорят о «файлах, используемых для запуска процессов». Предполагается, что /var /run /user /0 будет подходящим местом, если программа запускается от имени пользователя root, но в этой публикации также говорится, что каталог удаляется /очищается, когда больше нет активных сеансов. Поскольку это услуга, действительно ли это правильное местоположение?
  • https://github.com/systemd/systemd/issues/735#issuecomment-126309537 показывает процесс, вызываемый systemd с аргументами командной строки --pid-file /run/user/1000/uzbl/event/pid
  • https://lists.debian.org/debian-user/2015/10/msg01315.html , рассылка в списке рассылки пользователей Debian, имеет одного человека, который говорит, что "Полный Freedesktop Monty" для файлов PID "указал [и] /run/user для этого ".

Можно найти много других примеров.

Так должно ли мое приложение быть изменено на использование /var/run/user/$UID? Так как это служба (без активного сеанса), pam_systemd очистит / удалит каталог? Или $XDG_RUNTIME_DIR? Это что-то специфичное для systemd? Или это новый стандарт для всех Unices?

Какова лучшая практика в настоящее время в операционных системах systemd? В общем ли это верно и для других (не системных, но Unix-подобных) операционных систем?

2 ответа2

5

Ты спрашиваешь:

Является ли /var /run /user /$ UID новым /var /run для файлов PID?

Короткий ответ - нет".

И длинный ответ по-прежнему "нет".

Или сказать это громко и ясно: традиционные PID-файлы не должны быть ниже /run/user/$UID/ (AKA /var/run/user/$UID/). Храните их в /run/ или /run/package/ как обычно, так как /run/user/$UID/ служит для сервисов сеансов совершенно иным образом.

FYI:

  • Как отметил @Daniel B, /var/run сегодня - это мягкая ссылка, которая указывает на /run . Это не относится к systemd и может быть найдено в большинстве систем сегодня. Если вы хотите сохранить совместимость со старыми системами, есть два решения: либо оставайтесь с /var/run/ вместо /run/ , либо попросите кого-нибудь создать мягкую ссылку для /run , указывающую на /var/run в таких старых системах.

  • Также обратите внимание, что /run/user/$UID/ относится к системам, в которых работает systemd-logind . Также это не поддерживается на старых системах.

Чтобы вдаваться в подробности для тех, кто еще не знает:

Существует 3 вида услуг: системные сервисы, пользовательские сервисы и сервисы сеансов. Все 3 типа могут работать в фоновом режиме или на переднем плане, так что это дает 6 вариантов.

Системные службы Foreground традиционно запускались с помощью /etc/inittab , в настоящее время с systemd они запускаются с помощью /etc/init/ . Системные службы Foreground обычно не нуждаются в файлах PID, так как они контролируются init , и могут вызываться в случае сбоя.

Фоновые системные службы традиционно запускались сценариями уровня запуска /etc/rc.d/ . Обычно им нужны PID-файлы, потому что они работают в фоновом режиме, поэтому нет никакого контроля над тем, работают они или нет. PID-файлы очень подвержены ошибкам (поскольку нет гарантии, что PID останется свободным после прекращения работы службы) и используются для повторного поиска запущенных служб, когда rc-скрипт должен завершить работу службы. Эти PID-файлы традиционно находятся в /var/run и в настоящее время находятся в /run/package/ (или, если в пакете только один файл, в /run/package.pid).

Пользовательские сервисы - это сервисы, которые запускаются пользователем и должны жить вне сеанса пользователя. Например, сервер Minecraft или что-то вроде долгоживущего процесса запроса SAP, который запускается по требованию с помощью кратковременного сеанса. Они немного отличаются от системных служб, поскольку не могут использовать /run/ . Вместо этого им нужно использовать /tmp/ или какой-либо каталог ниже $HOME (что проблематично, если $HOME является сетевым ресурсом, общим для нескольких компьютеров).

Пользовательские службы Foreground иногда немного проблематичны, потому что им часто нужен tty , поэтому, если пользователь выходит из системы, он завершается. Следовательно, существует множество способов оставить их в живых после ухода пользователя, например nohup или screen . Но даже могут быть некоторые экзотические варианты, такие как socat tcp-connect:host:port exec:service.sh,pty .

Другим вариантом приоритетных пользовательских услуг являются задания cron, которые живут в crontab пользователя. Однако эти cronjobs также могут быть фоновыми службами, например, если они не должны работать параллельно, даже если один процесс превышает время, когда выполняется следующий вызов cron.

У фоновых пользовательских сервисов та же проблема, что и у фоновых системных сервисов, поскольку они должны отслеживать, какая из них уже запущена, и контролировать уже запущенные. В прошлом это приводило к различным проблемам и исправлениям таких вещей, как атаки через каталоги и тому подобное, из-за необходимости использовать /tmp где каждый может создавать файлы и каталоги.

Однако это еще не изменилось, поскольку /run/user/$UID/ не предназначено для таких пользовательских служб. Он был разработан для решения еще более сложной проблемы со службами сеансов.

Служба сеанса - это служба, которая обычно запускается при входе пользователя в систему и останавливается при выходе пользователя из системы. Это звучит просто, но набирает обороты, если для одного пользователя разрешено более одного сеанса. Трудный вопрос, который нужно решить: "когда сессия действительно заканчивается"?

Сессия начинается с первого входа в систему. Это легко понять. Но это не обязательно заканчивается, когда этот логин выходит из системы! Таким образом, сервис сеанса может быть запущен при первом входе в систему (или позже), но довольно часто необходимо продолжать работать до тех пор, пока не выйдет последний сеанс пользователя.

Услуги переднего плана обычно являются простым вариантом. Как и сервис X-Window dbus который запускается и заканчивается графическим логином. Но если вы начнете печатать гигантский PDF-файл, вы наверняка захотите, чтобы эта работа либо успешно завершилась, либо была завершена без остатков мусора, верно?

Службы сеансов такого типа либо должны продолжать работать в фоновом режиме, либо должен быть какой-то способ очистки после сбоя службы, если что-то неожиданно умирает. И вещи часто умирают в нашем мобильном мире. Подумай о своем мониторе. Вы можете подключить и отключить монитор в любое время. Нет необходимости перезагружать компьютер. Но что произойдет, если вы отключите все экраны? Ну, X11 умирает, конечно. Для некоторых пользовательских служб, запущенных в сеансе X11, это происходит неожиданно, возможно, в середине более длительной задачи.

Здесь пригодится /run/user/$UID/ , так как этот каталог автоматически стирается после завершения последнего сеанса пользователя. Таким образом, службы могут полагать, что за пользователем будет проведена очистка всего, что хранится в /run/user/$UID/ !

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

Также обратите внимание, что сегодня у нас есть dbus . Таким образом, вам больше не нужно полагаться на PID-файлы, чтобы узнать, запущена какая-либо служба или нет. Это особенно верно для сервисов сессий, так как есть нечто, называемое "сессия", которое позволяет вам обрабатывать вещи немного лучше, например, использовать сегменты общей памяти или блокировать файлы, которые могут находиться в /run/user/$UID/ .

Вещи не легко. И чтобы сделать его еще более сложным, есть такие вещи, как screen , tmux или ssh (тот, который разветвляется от оболочки), у которых есть две стороны, одна сторона - пользовательская служба (т.е. Т.е. демон), другая сторона - это сервис сеанса (tty). Хотя они обычно связаны с сеансом, это не обязательно должно происходить постоянно. Например, если вы используете переадресацию порта ssh и выходите из своей оболочки, ssh остается открытым, пока не будет закрыт последний перенаправленный порт. Вы можете даже открыть новые порты, пока некоторые другие остаются активными. В случае такого "двойного" сервиса может пригодиться что-то вроде файла PID, и в этом случае он может даже находиться в каталоге /run/user/$UID/ .

(Обратите внимание, что cron можно использовать для открытия сеанса пользователя, поэтому, вероятно, /run/user/$UID/ доступен для cronjobs. Но если это так, /run/user/$UID/ снова получает право на очистку после завершения всех cronjobs. Возможно, это означает, что файлы, которые были переданы в другое место, исчезают, в отличие от того, когда они находятся в /tmp/ , так как только перезагрузка должна безоговорочно удалять файлы там.)

Подвести итог:

Если у вас есть правильно спроектированная служба, вам никогда не понадобятся простые PID-файлы в /run/user/$UID/ , потому что сервисы сеансов (единственный, использующий этот каталог) обычно имеют более лучший способ (сеанс), чтобы оставаться под контролем , даже если они работают в фоновом режиме.

Поэтому, если вы видите, что для вашей службы нужен файл PID, очень вероятно, что вы получите что-то вроде /run/package/ , /run/package.pid или /tmp/package-$UID/ .

Используйте /run/user/$UID/ если вы хотите, чтобы файл исчез, как только пользователь полностью выйдет из системы. Также обратите внимание, что пользователь root не всегда вошел в систему, поэтому, скорее всего, нет /run/user/0/ .

И, пожалуйста, никогда не создавайте каталоги прямо под /run/user/ самостоятельно!

Надеюсь, теперь все так хорошо и понятно. Но мне есть что признаться

Я соврал тебе. И я сделал это остроумно (но без злого умысла).

Поскольку сессия (с точки зрения systemd-logind ) не просто привязана к login . Да, конечно, что-то похожее на login , но все немного сложнее:

https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/

Тем не мение:

  • Для этой публикации здесь (короткая, но неправильная история) ответом на ваш вопрос будет "нет".

  • К счастью, с длинными (и верными) сведениями о сессиях (см. Ссылку), ответ по-прежнему остается "нет".

  • Только для очень немногих и очень особых случаев для очень четко определенной цели вы можете рассмотреть возможность помещения вашего файла PID в /run/user/$UID/ .

Хорошего дня.

0

В руководстве systemd.exec говорится о параметре RuntimeDirectory :

Принимает список имен каталогов. Если установлено, один или несколько каталогов с указанными именами будут созданы ниже /run (для системных служб) или ниже $XDG_RUNTIME_DIR (для пользовательских служб), когда модуль запущен, и удалены, когда модуль остановлен.

Кроме того, на справочной странице pam_systemd мы можем найти следующую информацию о $XDG_RUNTIME_DIR (выделено мной):

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

Используя эти два руководства, мы можем сделать вывод, что $XDG_RUNTIME_DIR (/run/user/$UID в моей установке Arch) не является правильным выбором для системных служб. Вместо этого они обычно помещаются /run (по крайней мере, в Arch и Gentoo). Также может быть возможным создать их в RuntimeDirectory как описано выше.

/var/run - это символическая ссылка на /run эти дни.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .