ptys 无法在 lxc 下的 chroot 中工作

ptys 无法在 lxc 下的 chroot 中工作

我正在尝试在 lxc 下使用 chroots 进行开发。我在 lxc 容器配置中启用了“嵌套”选项,并将安装的 proc 和 devpts 绑定到我的 chroot 中,就像 chroot 位于普通 Linux 机器上一样。

不幸的是,当我尝试在 chroot 中使用需要 ptys 的东西(例如“script”命令)时,我收到如下错误

root@manualdev:~# chroot /chroots/jessie-staging/
root@manualdev:/# script
script: openpty failed: No such file or directory
Terminated
root@manualdev:/#

系统信息:

  • 主机内核是 4.4.0-79-generic
  • 主机发行版是 Ubuntu xenial
  • 主机架构为arm64
  • 容器发行版是 Debian Stretch
  • 容器和chroot架构是armhf
  • Chroot 发行版是 Raspbian(使用 jessie、stretch 和 buster 进行测试)

答案1

解决这个问题的方法(通过有根据的猜测发现)是在 chroot 中执行以下命令。

rm /dev/ptmx
ln -s /dev/pts/ptmx /dev/ptmx

我不是 100% 确定,但我相信需要这样做的原因是 lxc 对 /dev/pts 使用“多实例模式”。根据文档https://github.com/torvalds/linux/blob/v4.4/Documentation/filesystems/devpts.txt

如果 CONFIG_DEVPTS_MULTIPLE_INSTANCES=y 并指定了 'newinstance' 选项,则挂载被视为处于多实例模式,并创建 devpts fs 的新实例。在此实例中创建的任何 pty 都独立于其他 devpt 实例中的 pty。与单实例模式一样,/dev/pts/ptmx 节点也存在。要有效使用多实例模式,必须使用符号链接或绑定安装将 /dev/ptmx 的打开重定向到“/dev/pts/ptmx”。

查看该文件的更新版本,似乎更新的内核可能不需要这样做。

答案2

需要安装管理伪终端的 devpts 文件系统:

魔法命令是:

(以 root 身份)# mount -t devpts devpts /dev/pts

这是一个检查伪终端系统是否正常工作的会话:

root@e7440:/me/media/20230104a# mount |grep pts # Check, yup no devpts mounted
root@e7440:/me/media/20230104a# ls -lai /dev/pt*   # /dev/ptmx exists, but /dev/pts is empty
233300 crw-rw-rw- 1 root root 5, 2 Jan  4 23:07 /dev/ptmx

/dev/pts:
total 8
237675 drwxr-xr-x 2 root root 4096 Jan  4 23:04 .
229757 drwxr-xr-x 4 root root 4096 Jan  3 14:31 ..
root@e7440:/me/media/20230104a# mount -t devpts devpts /dev/pts
root@e7440:/me/media/20230104a# mount |grep pts
devpts on /dev/pts type devpts (rw)
root@e7440:/me/media/20230104a# # Let's test the pty system using the script command.
root@e7440:/me/media/20230104a# # the script command will log the shell to its_alive.txt
root@e7440:/me/media/20230104a# script its_alive.txt
Script started, file is its_alive.txt
root@e7440:/me/media/20230104a# ls -lai /dev/pt*  # Now after the mount, things have changed!
233300 crw-rw-rw- 1 root root 5, 2 Jan  4 23:08 /dev/ptmx

/dev/pts:
total 4
     1 drwxr-xr-x 2 root root      0 Jan  4 23:08 .
229757 drwxr-xr-x 4 root root   4096 Jan  3 14:31 ..
     3 crw------- 1 root root 136, 0 Jan  4 23:08 0
     2 c--------- 1 root root   5, 2 Jan  4 23:08 ptmx
root@e7440:/me/media/20230104a# # Note the 0 entry! That's the pty we are using to log this with the script command!
root@e7440:/me/media/20230104a# # Also note it is using inode 3 on the devpts  file system instance
root@e7440:/me/media/20230104a# # And that it is a 'c' a character device node.
root@e7440:/me/media/20230104a# mount |grep pts
devpts on /dev/pts type devpts (rw)
root@e7440:/me/media/20230104a# umount /dev/pts  # Let's go back to no ptys, but wait ...
umount: /dev/pts: target is busy
        (In some cases useful info about processes that
         use the device is found by lsof(8) or fuser(1).)
root@e7440:/me/media/20230104a# # Naughty!  We're using a pty, so we can't get rid of ptys
root@e7440:/me/media/20230104a# exit   # We are leaving the script session so its_alive.txt will get closed.
exit
Script done, file is its_alive.txt
root@e7440:/me/media/20230104a# #### Now we can get rid of ptys entirely as no ptys are in use
root@e7440:/me/media/20230104a# ls -lai /dev/pt*
233300 crw-rw-rw- 1 root root 5, 2 Jan  4 23:09 /dev/ptmx

/dev/pts:
total 4
     1 drwxr-xr-x 2 root root    0 Jan  4 23:08 .
229757 drwxr-xr-x 4 root root 4096 Jan  3 14:31 ..
     2 c--------- 1 root root 5, 2 Jan  4 23:08 ptmx
root@e7440:/me/media/20230104a# ### See no 0 entry (but the /dev/pts/ptmx is there because devpts is mounted)
root@e7440:/me/media/20230104a# mount |grep pts
devpts on /dev/pts type devpts (rw)
root@e7440:/me/media/20230104a# umount /dev/pts
root@e7440:/me/media/20230104a# mount |grep pts
root@e7440:/me/media/20230104a# ls -lai /dev/pt*
233300 crw-rw-rw- 1 root root 5, 2 Jan  4 23:09 /dev/ptmx

/dev/pts:
total 8
237675 drwxr-xr-x 2 root root 4096 Jan  4 23:04 .
229757 drwxr-xr-x 4 root root 4096 Jan  3 14:31 ..
root@e7440:/me/media/20230104a# # Let's see that our session log exists
root@e7440:/me/media/20230104a# ls -l its*
-rwxr-xr-x 1 root root 1025 Jan  4 23:09 its_alive.txt
root@e7440:/me/media/20230104a# # Let's see the session log contents
root@e7440:/me/media/20230104a# grep -n "^"  its_alive.txt  #Line numbers, please!
1:Script started on Wed Jan  4 23:08:47 2023
2:root@e7440:/me/media/20230104a# ls -lai /dev/pt*
3:233300 crw-rw-rw- 1 root root 5, 2 Jan  4 23:08 /dev/ptmx
4:
5:/dev/pts:
6:total 4
7:     1 drwxr-xr-x 2 root root      0 Jan  4 23:08 .
8:229757 drwxr-xr-x 4 root root   4096 Jan  3 14:31 ..
9:     3 crw------- 1 root root 136, 0 Jan  4 23:08 0
10:     2 c--------- 1 root root   5, 2 Jan  4 23:08 ptmx
11:root@e7440:/me/media/20230104a# # Note the 0 entry! That's the pty we are using to log this with the script command!
12:root@e7440:/me/media/20230104a# mount |grep pts
13:devpts on /dev/pts type devpts (rw)
14:root@e7440:/me/media/20230104a# umount /dev/pts
15:umount: /dev/pts: target is busy
16:        (In some cases useful info about processes that
17:         use the device is found by lsof(8) or fuser(1).)
18:root@e7440:/me/media/20230104a# # Naughty!  We're using a pty
19:root@e7440:/me/media/20230104a# exit
20:exit
21:
22:Script done on Wed Jan  4 23:09:46 2023
root@e7440:/me/media/20230104a#  # Yup, life is good!

资料来源:

相关内容