我想问一下当用户注销时,Linux系统上卡在‘D’不可中断睡眠状态的进程会造成什么影响。
如果磁盘睡眠中存在无法终止的用户进程,是否可以通过注销(而不是关闭或重新启动)来结束用户会话?或者系统是否会在注销尝试时冻结/崩溃?如果尽管进程卡住了,但注销成功,那么进程会发生什么?它会成为孤儿并重新成为父级吗?它会继续进行下一个用户会话吗?此外,如果进程在进入不可中断睡眠之前正在访问共享内存段,那么该共享内存和使用它的其他进程会发生什么?它们也会受到影响吗?Linux 系统如何处理这种情况?
这种状态很难故意重现,所以我无法找到自己测试的方法以了解答案。
如果之前在某个地方回答过类似的问题,我深表歉意;我曾尝试在各种 Linux 网站和留言板上搜索这些问题的答案,但大多数页面似乎只解释了什么是不间断睡眠以及如何防止/修复该问题。我没有找到任何资源来解释当用户会话结束时没有重新启动系统时,此类进程会发生什么。大多数资源只是建议重新启动系统以摆脱它。
答案1
“D”进程是无法终止的,常见情况是 NFS 文件句柄过期。如果进程在后台运行,则可能会发生注销,但这不会对休眠进程产生影响。
答案2
首先,感谢大家的回答!我做了一些测试,所以我会尝试回答我自己的问题。
我测试了 systemd(在 Ubuntu 上)和 upstart(在 Chromium OS 上)在注销时对不可中断进程的处理。我发现,使任意用户进程进入“D”睡眠状态的最简单方法是将其放入 freezer cgroup 子系统中,并将 freezer.status 更改为 FROZEN。(https://www.kernel.org/doc/Documentation/cgroup-v1/freezer-subsystem.txt) 之后,我尝试通过注销来结束用户会话。据我所知,对于 systemd 和 Chromium OS 版本的 upstart,注销时的预期行为是,在会话管理器退出之前应终止所有非 root 进程。
注销时发生的情况是用户会话干净地退出,在 Chromium OS 的情况下,cryptohome 似乎也顺利卸载(我在系统日志中没有发现任何表明卸载失败的内容)。正如预期的那样,冻结进程在两种情况下都幸免于注销,并且仍然在 top 中可见。它不使用任何资源,在重新登录帐户后无法以任何方式访问。重新登录帐户时也没有出现任何问题或错误。当我将 freezer.status 从 FROZEN 更改为 THAWED 时,该进程立即消失。我不确定当进程因不同原因进入“D”状态时,这种行为是否会有所不同,例如在尝试访问 NFS 时被阻止等,但我希望结果是相似的。