Systemd: почему файлы в /tmp или /run удаляются через несколько секунд?

Systemd: почему файлы в /tmp или /run удаляются через несколько секунд?

Я использую systemd для монтирования общего ресурса Windows с помощью Kerberos. Чтобы это сработало, я сначала запускаю kinitфайл .service для создания кэша учетных данных Kerberos (ccache). .service запускается от имени root, поскольку ccache должен принадлежать root ( journalctl -xeмне это помогло), поскольку mount.cifs требует root. .mount (и .automount) используют ccache для выполнения монтирования Kerberos. Когда я создаю ccache в интерактивном режиме, это работает хорошо. Однако при запуске внутри сервисного модуля ccache быстро удаляется, и (автоматическое) монтирование завершается ошибкой. Неважно, сохраняю ли я его в /tmp или /run/user/0.

  1. Почему файлы в /tmp или /run автоматически удаляются?
  2. Какое предпочтительное расположение для этих файлов ccache? Есть ли PrivateTmpлучшее решение? Если да, то как мне сослаться на этот частный каталог tmp внутри файла службы? Я пробовал %T/krb5cc_root.ccache, но systemctl выдает ошибку. Есть ли JoinsNamespaceOfспособ использовать тот же частный tmp в файле монтирования?

Я использую systemd 219 на linux CentOS 7. Ниже мой юнит .service. Заранее спасибо!

[Unit]
Description=Kinit keytab for /mnt/windows_staging
After=network.target
Requires=network.target

[Service]
Restart=always
RestartSec=30
PrivateTmp=yes
User=root
Group=users
ExecStartPre=-/bin/mkdir -p /mnt/windows_staging
ExecStartPre=-/bin/mkdir -p /run/user/0
Environment=KRB5_KTNAME=/home/albertjan@domain/myproject/etc/keytabs/albertjan.keytab
Environment=KRB5CCNAME=/run/user/0/krb5cc_root.ccache
ExecStart=/bin/kinit albertjan -kt ${KRB5_KTNAME} -c ${KRB5CCNAME}
ExecStartPost=/bin/sleep 2
ExecStop=-/bin/kdestroy -c ${KRB5CCNAME}

[Install]
WantedBy=multi-user.target

решение1

Почему файлы в /tmp или /run автоматически удаляются?

Потому что ваша службазапускает «демон», который немедленно завершает работу, тем самым помечая службу как «остановленную» в течение нескольких секунд после запуска, что приводит к kdestroyзапуску метода ExecStop=.

  • Вариант 2: Измените определение .service, чтобы сообщить systemd, что этодолжно бытьзадача, которая немедленно завершается, используя следующие параметры:

    [Service]
    Type=oneshot
    RemainAfterExit=yes
    

    Режим Type=oneshotдополнительно полезен, поскольку заставит systemd ждать полного завершения ExecStart=, прежде чем служба будет помечена как «активная», избегая необходимости добавлять произвольный sleep 2. Другими словами, он позволяет вам использовать его, After=kinit.serviceне беспокоясь о том, что другие вещи начнутся «слишком рано».

  • Вариант 1: Заменить kinit на k5startдемон изhttps://www.eyrie.org/~eagle/software/kstart/. Это настоящий демон – долгосрочный процесс – и он будет отслеживаться как таковой. Он также будет обрабатывать периодическое обновление.

    Если вы используете k5start с -bопцией («Отсоединить при запуске») и соответствующим образом измените режим .service Type=forking, вы также получите такое же поведение «задержка до успешного завершения».

(Есть также третий вариант, позволяющий gssproxyобрабатывать все билеты, но cifs.upcall в CentOS пока его не поддерживает. Для других целей, помимо монтирования файловых систем, KRB5_CLIENT_KTNAMEможно разрешить самой программе получать билеты из keytab по мере необходимости, но в данном случае это не сработает.)

Какое предпочтительное место для этих файлов ccache?

Лично я бы остановился на /tmp/krb5cc_*или /run/user/<uid>/krb5cc_*. (Это единственные места, которые проверяет NFS rpc.gssd.)

Для SMB cifs.upcall будет искать системное расположение по умолчанию для UID, который выполняет монтирование (т. е. то, что определено в krb5.conf), что обычно происходит, /tmp/krb5cc_0когда это делает systemd. (Хотя cifs.upcall может извлечь KRB5CCNAME из среды вызывающего, это не поможет при задействовании автомонтирования, поскольку cifs.upcall будет видеть только systemd или autofsd в качестве вызывающего.)

Является ли PrivateTmp лучшим решением?

PrivateTmp не поможет, потому что ваш файл удаляет не внешняя задача, а сама служба.

Связанный контент