新的 pam(_systemd) 会话是否需要新进程?

问题描述

作为实验,我正在编写一个小型 linux 显示管理器。作为参考,我使用了 lightdm,尤其是 https://github.com/canonical/lightdm/blob/master/src/session-child.c,以及 systemd 文档页面 https://www.freedesktop.org/wiki/Software/systemd/writing-display-managers/

一开始一直管理tty9,注销后重启由systemd处理(Restart=always)。

那么程序的作用是

Lightdm 为此使用了两个会话子进程,但为了简单起见,我尝试将其合二为一。

当我注释掉“欢迎者”的会话开始时,例如:https://github.com/TheJonny/textdm/blob/ba32d87f23816ef78763016b4c748a0875ae93f6/src/main.rs#L86,我能够登录并启动 weston(启动 X 服务器当前尚未完成)。如果我确实使用了欢迎程序的会话(启用了第 86 和 126 行),pam_systemd 将失败并显示调试消息

Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Asking logind to create session: uid=1001 pid=4084383 service=textdm type=wayland class=user desktop= seat=seat0 vtnr=9 tty>
Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Session limits: memory_max=n/a tasks_max=n/a cpu_weight=n/a io_weight=n/a runtime_max_sec=n/a
Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Not creating session: Already running in a session or user slice

loginctl里没有出现,没有设置$XDG_RUNTIME_DIR,然后weston启动失败。

所以我的问题是:这(仅)可以通过使用单独的进程来解决吗?是否有另一种方法可以完全拆除 pam_systemd 会话?

(我将 pam-client 绑定用于 Rust,https://docs.rs/pam-client/0.2.0/pam_client/struct.Context.html#method.open_session 应该调用 pam_open_session()pam_setcred(),并且 drop 应该关闭会话和凭据。)

解决方法

清理,我回答我的问题。

https://github.com/systemd/systemd/blob/756755d0fc5a0ef380416a54346b6438c3fb7ba5/src/login/pam_systemd.c#L1020

pam_systemd 故意泄漏管道文件描述符,并且 logind 延迟关闭会话,直到它关闭,也就是直到使用 pam_systemd 的进程退出。