以下指令用于分析 syscall 功能和最终测试。在并行实现这些功能的过程中不必每次都按这个流程走。
- 在 ZLMediaKit 提供的文档 下载并编译项目,获取可执行文件
MediaServer
- 将
MediaServer
及同目录下其他文件、所需的动态库一并放到文件系统镜像中 - 启动后执行
./MediaServer -h
命令
通过 ./MediaServer -h
可获取启动帮助。使用 strace 追踪后,发现值得注意的有以下参数(原输出文件)。这些任务需要各位在 Starry 中添加功能,使得内核在同样的 syscall 参数输入下的输出与 strace 的输出一致。
-
启动时需要动态库:
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libssl.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcrypto.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
除了 libc.so 外,Starry 应该目前都没有,可以都暴力复制一份到文件镜像里。
-
arch_prctl(ARCH_SET_FS, 0x7feda6bbf780) = 0
在 Arceos 的crates/percpu/src/imp.rs:97
有相关描述,但没有落实到 syscall 层面,只是 unikernel 用。 -
futex(0x7feda711c77c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
。FUTEX_WAKE_PRIVATE
直接给它当成FUTEX_WAKE
处理,在futex
里加一句就行 -
pipe2([3, 4], O_CLOEXEC) = 0
。目前 Starry 只有第一个参数(俩fd),没有pipe(2) - Linux manual page所规定的第二个参数 CLOEXEC,需要加上。这个参数在modules/axfs/src/api/port.rs
里就有定义,syscall_fcntl64
里也有应用,依葫芦画瓢就行。 -
clone3({flags=CLONE_VM|CLONE_VFORK, exit_signal=SIGCHLD, stack=0x7feda7606000, stack_size=0x9000}, 88) = 11122
需要支持 CLONE_VFORK 参数。具体来说,这个 clone 结束之后应直接运行子进程并阻塞父进程,直到子进程执行exec
或者exit
,父进程才可继续执行。可能需要在struct Process
里加一个状态位,表示该进程是否因为 vfork 被阻塞,然后要执行的时候检查一下,进程进 sys_exec 和 sys_exit 的时候把父进程的这个状态位消一下。 -
wait4(11122, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 11122
。目前内核的syscall_wait4
的 Option 只处理了 WNOHANG,没处理以上两个。看看是否需要添加,也有可能不用管也行。 -
readlink("/proc/self/exe", "/home/ZLMediaKit/"..., 8193) = 63
需要在 Procfs 里加一个目录/self/exe
,参见modules/axfs/src/mounts.rs: procfs
等信息。这条调用等于是读取“当前运行的程序在哪个目录下”,需要在struct Process
里加入“创建进程时可执行文件在哪个目录,是什么名字”这条信息,也即把syscall_exec
传入的信息保存到创建的进程中。这样才可以在访问readlink("/proc/self/exe"
的时候拿到这个信息。 -
prctl(PR_GET_NAME, "MediaServer") = 0
,只需要考虑这里用到的PR_GET_NAME
这个参数,获取进程名,很好加的 -
newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0
我在另一篇写过在内核中添加特殊文件的大致流程 -
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
这个也很简单,和上面的类似。注意这之后 ZLMediaKit 会读这个文件获取系统支持的核心数,从而决定之后运行时开几个线程。
简单的可能需要5分钟,长的可能需要1~2小时,发现有额外需要添加的功能再讨论。不要领一个任务做一整天。