Systemd:为什么 /tmp 或 /run 中的文件几秒钟后就会被删除?

Systemd:为什么 /tmp 或 /run 中的文件几秒钟后就会被删除?

我正在使用 systemd 使用 Kerberos 挂载 Windows 共享。为了使其工作,我首先运行kinit.service 文件以创建 Kerberos 凭据缓存 (ccache)。.service 以 root 身份运行,因为 ccache 需要由 root 拥有(journalctl -xe这对我来说很有帮助),因为 mount.cifs 需要 root。.mount(和 .automount)使用 ccache 执行 Kerberized 挂载。当我以交互方式创建 ccache 时,它​​运行良好。但是,当在服务单元内运行时,ccache 很快就会被删除,并且(自动)挂载失败。无论我将其保存到 /tmp 还是 /run/user/0 都没有关系。

  1. 为什么/tmp或/run下的文件会被自动删除?
  2. 这些 ccache 文件的首选位置是什么?有PrivateTmp更好的解决方案吗?如果是这样,我该如何在服务文件中引用该私有 tmp 目录?我试过了,但 systemctl 生成了一个错误。在挂载文件中使用相同的私有 tmp 的方法%T/krb5cc_root.ccache是什么?JoinsNamespaceOf

我在 Linux CentOS 7 上使用 systemd 219。下面是我的 .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下的文件会被自动删除?

因为你的服务启动一个立即退出的“守护进程”,因此在启动后的几秒钟内将服务标记为“已停止”,从而导致kdestroyExecStop= 运行。

  • 选项 2:更改 .service 定义以告诉 systemd 这是应该是立即退出的任务,使用以下选项:

    [Service]
    Type=oneshot
    RemainAfterExit=yes
    

    Type=oneshot模式还有一个额外的用处,因为它会让 systemd 等待 ExecStart= 完全完成,然后才将服务标记为“活动”,从而避免添加任意的sleep 2。换句话说,它让您After=kinit.service无需担心其他东西会“过早”启动。

  • 选项 1:将 kinit 替换k5starthttps://www.eyrie.org/~eagle/software/kstart/。这是一个真正的守护进程——一个长期运行的进程——并将被跟踪。它还将处理定期更新。

    -b如果您使用带有选项(“启动时分离”)的 k5start并Type=forking相应地将 .service 更改为模式,您也将获得相同的“延迟直至成功”行为。

(还有第三种选择,即让它gssproxy处理所有票证,但 CentOS 中的 cifs.upcall 尚不支持该选项。对于除挂载文件系统之外的其他用途,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 没有帮助,因为删除文件的不是外部任务,而是服务本身。

相关内容