RustROS · 2026-10-26 · 主线 872016e
M4 报告:网络系统调用
M4 做完了:进程能用套接字(TCP、UDP、Unix 域),在 Debian 13 根目录里 apt-get update、apt-get install curl 都能完成,curl 通过 HTTPS 取回网页。进程的 TCP 连接在替换协议栈、文件系统层和系统调用模块时不断。
回归测试(KVM 测试机)46 项全部通过新增 net 测试;debian 测试加上域名解析、apt、curl 和 LTP 的套接字测试
LTP 套接字测试32 通过4 个已知未通过(见下文),7 个需要内核配置文件或 ip 工具,不在这里跑
进程的 TCP62 MB/s到本机;经 QEMU 用户网络到测试机的回显服务器每个方向约 18 MB/s
转发18.8 / 18.3 Gbit/sTCP 单流 / 4 流;64 B 单流 358、16 流 383 kpps(嵌套虚拟机上波动约 15%)
设计套接字放在哪里
- 网络套接字在内核的网络协议栈里(属于"进程"这个所有者);进程的描述符是 VFS 里代表它的一个句柄。所以 fork、dup、close、poll、select、epoll 对套接字和对文件、管道完全一样,最后一个句柄关闭时协议栈里的套接字才关闭。
- Unix 域套接字(流、数据报、seqpacket,路径名或抽象名字)完全在 VFS 里,和管道一样随 VFS 模块热替换交接(连接、等待 accept 的连接、未读的数据都在)。eventfd 和 flock 锁也在 VFS 里。
- 阻塞:协议栈从不阻塞;会等待的调用由系统调用模块阻塞(非阻塞描述符、MSG_DONTWAIT 返回 EAGAIN,SO_RCVTIMEO/SO_SNDTIMEO 有超时)。内核只多了一件事:进程的套接字有变化时,让在等的调用重做一次。内核文件大小没有变化。
- 本机:127.0.0.0/8 可以绑定和连接,目的地址 0.0.0.0 就是本机(和 Linux 一样)。
验收测试里做了什么
| 测试 | 内容 |
| net(新) | Unix 域:一对套接字传 300 KB、命名监听者的连接和应答、数据报保持边界;本机 UDP、接收超时;本机 TCP 传 500 KB;非阻塞 accept 和 epoll 等连接;连接被拒(非阻塞和阻塞);1 MB 经 TCP 到测试机的回显服务器再回来;一个进程保持着 TCP 连接,期间替换 netstack、vfs、linux 三个模块,前后数据都正确,对方关闭后进程读到结束,套接字随进程关闭 |
| debian | getent 解析 deb.debian.org;apt-get update;apt-get install curl(下载、解包、执行各包的配置脚本,含 ca-certificates);curl 以 HTTPS 取 https://deb.debian.org/debian/ 得到 200;LTP 的 socket、bind、listen、accept、connect、send/recv 各形式、getsockopt/setsockopt、shutdown 等测试 |
发现为跑通 apt 和 curl 补上的
- glibc 解析域名失败:它给 UDP 套接字设 IP_RECVERR,协议栈原来拒绝未知选项,解析器就放弃了。现在常见的、在这里没有作用的选项都接受并保存。
- debconf 报"被别的进程锁住":缺 flock,ca-certificates 的配置脚本因此失败。现在 flock 有真正的共享 / 独占语义。
- curl 的解析线程起不来:缺 eventfd。已补上。
- LTP 找到的:不能绑定 127.0.0.1、不能连 0.0.0.0(这两项影响最大,很多程序依赖本机回环);各种错误号的细节(未连接的 TCP 发送是 EPIPE、UDP 上 accept 是 EOPNOTSUPP、带 MSG_OOB 的接收是 EINVAL、空指针的地址长度是 EFAULT 等)。
遗留还没有的
| 缺口 | 影响 | 打算 |
| 终端(伪终端) | apt 想用伪终端显示 dpkg 的输出,失败后自动退回不用终端;交互式 bash、docker exec -it 需要 | M5 |
| System V IPC(信号量、共享内存、消息队列) | PostgreSQL 等需要;LTP sendmsg02 | 容器跑数据库前补上 |
| IPv6、netlink | 协议栈还没有 IPv6;ip 一类工具要 netlink | 按需 |
| 传递描述符(SCM_RIGHTS)、MSG_MORE、组播 | 少数程序用到;LTP send02、accept02 | 按需 |
| 每个进程(容器)自己的协议栈实例 | 现在进程都用主机的协议栈(即 host 模式) | N(容器网络) |
下一步
先发布 M4 并更新两台机器(模块接口有变化,所有模块重装)。之后已确认、还没做的有:TLS 共享模块(M3 后的一小步,M4 先做了)、进程的最低 CPU 份额(应用改成用户态进程之前要有),以及按里程碑顺序的 N(容器网络)。另有一项待你决定:内核瘦身评估(把开机后很少用、或会常改的部分移到模块里,让更多更新可以热更新、不用重启)。