进程现在可以在伪终端上运行:交互式 bash、Ctrl-C、Ctrl-Z、jobs、fg 都和 Linux 上一样,apt 经终端显示 dpkg 的输出。管理端可以从开发机直接在机器上开一个终端运行程序(rustros-update.py run -t),以后的 docker exec -it 走同一条路。终端在可热替换的 VFS 模块里,会话进行中替换 vfs 和 linux 模块,bash 照常。
| 步骤 | 内容 | 验收 |
|---|---|---|
| M5.1 | VFS 里的伪终端:打开 /dev/ptmx 得到一对,从端在 /dev/pts/N(VFS 自己的 devpts,可以挂在容器的根目录里);行规程:规范模式的编辑(退格、删行、删词、^V、^D)、回显、^C ^\ ^Z 产生信号、^S ^Q、CR / NL 转换、非规范模式的 VMIN / VTIME、输出时 NL 变 CR NL;窗口大小(改了发 SIGWINCH);状态交接格式 4 | 16 个 VFS 单元测试(新增终端一项:行规程、信号、/dev/tty、挂断、交接) |
| M5.2 | 作业控制:会话和控制终端、前台进程组(tcsetpgrp);后台进程读终端收到 SIGTTIN 而停下,改设置收到 SIGTTOU;进程停止和继续(内核);wait 的 WUNTRACED / WCONTINUED、waitid;主端关闭时挂断(SIGHUP);/proc 里的 tty_nr;linux 模块的终端 ioctl | ptytest:解锁、ttyname、规范模式、回显、窗口大小、VTIME 超时;一个会话里:后台读被停下、设为前台并继续后读到输入、^C 结束前台任务、^Z 停下(waitid 看到)、SIGKILL 结束停下的进程、主端关闭时会话首进程被挂断 |
| M5.3 | 管理端在终端里运行程序:updater 的新命令(之后双向是加密、带 MAC、按方向计数的帧),内核的 Admin::spawn_tty / tty_io / tty_resize / tty_close;rustros-update.py run -t 把本地终端接上去(窗口大小跟着变,Ctrl-] 挂断) | 测试用同一个客户端(Term)驱动 Debian 的 bash |
| M5.4 | Debian 里的交互式 bash(按用户打字的方式驱动) | tty 是 /dev/pts/N;stty size 先 24 80,改窗口后 30 100;sleep 30 后 ^Z 显示 Stopped,jobs -l 列出,fg 后 ^C,$? 是 130;后台任务和 wait;cat 读到输入、^D 结束;apt 重装 curl 不再报 posix_openpt 失败;会话进行中替换 vfs 和 linux,bash 照常;exit 后状态 0 |
| M5.5 | 顺路的内核瘦身:控制台的命令处理 | 查过:命令处理已经在 rescue 和 shell 模块里,内核只剩按键解码和屏幕输出(设备机制),这次没有可移的 |
用法(开发机上):
tools/rustros-update.py HOST run -t build/user/chrootrun -- /debian /bin/bash -i
程序是本地的静态 ELF 文件(这里是在 /debian 根目录里执行 bash 的小程序);容器运行时(M7)以后按容器启动。
tty、take_signals、session_end,VfsHost::job / group_in;ProcHost::wait 带选项;Admin 加终端会话的四个调用;VFS 状态格式 4(旧格式仍能读)。| 缺口 | 打算 |
|---|---|
| 所有 devpts 挂载看到同一组终端(容器各自的终端编号空间) | M7a 容器隔离时 |
| /proc/<pid>/fd 的链接不是真实路径(ttyname 退回到扫 /dev/pts,能用) | 按需 |
| 终端的 packet 模式(TIOCPKT)、硬件流控、波特率 | 伪终端用不到;按需 |
| 物理控制台还不是终端(不能在串口上交互运行进程) | 需要时把控制台做成终端的主端 |
| updater 被替换时终端会话断开(程序收到 SIGHUP) | updater 在引导镜像里,随内核更新 |
是否发布 M5 并更新两台机器:内核变了,按老流程上传内核、重装所有模块、重启一次。之后按顺序是 M6(镜像:先导入 docker save 的 tar 和 OCI 布局,层解到 ext4 上;从仓库拉取在后)。