Skip to content

fix(tools-image): fall back to BusyBox ionice for minimal user images - #210

Open
dushulin wants to merge 1 commit into
kvcache-ai:mainfrom
dushulin:feat/tools-image-ionice-fallback
Open

fix(tools-image): fall back to BusyBox ionice for minimal user images#210
dushulin wants to merge 1 commit into
kvcache-ai:mainfrom
dushulin:feat/tools-image-ionice-fallback

Conversation

@dushulin

Copy link
Copy Markdown

背景

envd 的进程 wrapper 硬编码调用 /usr/bin/ionice -c 2 -n 4 /usr/bin/nice -n N ...packages/envd/internal/services/process/handler/handler.go),只要用户 rootfs 里没有 /usr/bin/ionice,每一次进程 spawn 都会立刻失败并报 /usr/bin/ionice: not found。这在 Alpine/musl、distroless、FROM scratch、以及各类不带 util-linux 的 slim 镜像上都能稳定复现——envd 自身能起来,用户在 sandbox 里跑任何命令都会立刻挂掉。

相关上游 issue / PR:

方案

复用现有 nice(1) 兜底思路(tools-image/pivot-init):

  • 在 pivot_root 之后、envd 启动之前,如果用户 rootfs 里没有可执行的 /usr/bin/ionice,就把它软链到 /agentenv/bin/busybox。BusyBox 是 multi-call binary,通过 argv[0]=ionice 直接走 ionice applet。
  • [ ! -x /usr/bin/ionice ] guard 保证自带 util-linux 的镜像原样保留自己的 ionice,不会被覆盖。
  • 同时把 pivot-init 里的注释补上,说明现在同时兜底 nice/ionice
  • Dockerfile 里补两条 BusyBox applet 断言(nice + ionice),万一以后 upstream BusyBox 改默认配置或有人重编 BusyBox,能在镜像构建阶段就报错,不至于到 guest 里才发现。

与 util-linux ionice 的能力对齐

envd 调用的形式是 ionice -c 2 -n 4 <cmd>,用到的是 -c/-n 以及 exec 新进程的能力。BusyBox 的 ionice applet 覆盖 -c/-n/-p/-t 与 exec 语义,与 util-linux 落到同一个 ioprio_set(2) syscall,语义完全一致。util-linux 独有的 -P PGID-u UID envd 用不到;如果 sandbox 内部用户脚本自己在 fallback 镜像里手动调这两个 flag 会拿到 unknown option,这跟现有 nice fallback 面临的情况完全对称。

兼容性

  • 自带 util-linux 的镜像(大多数发行版基础镜像):[ ! -x ] guard 短路,/usr/bin/ionice 保留镜像原有实现,零回退。
  • 缺 ionice 的镜像(Alpine/musl/distroless 等):拿到 BusyBox 的 ionice,envd 能正常 spawn。
  • pivot-init 在每次 boot 都会跑一遍,symlink 是幂等的,pause/resume 或 snapshot 提交后 symlink 会跟着上层写走。

Test plan

  • docker build tools-image/ 通过,BusyBox applet 断言不报错
  • 用一个不带 util-linux 的 Alpine-based 用户镜像启动 sandbox,ionice -c 2 -n 4 echo ok 通过 envd wrapper 能正常输出 ok
  • 用一个自带 util-linux 的镜像启动 sandbox,readlink /usr/bin/ionice 仍指向镜像原有二进制(不是 /agentenv/bin/busybox
  • envd 的 process spawn 端到端在两种镜像上都正常,echo $? 返回 0

envd's process wrapper hardcodes `/usr/bin/ionice -c 2 -n 4 /usr/bin/nice -n N ...`,
so any user image without util-linux (Alpine/musl, distroless, FROM scratch,
various slim rootfs) fails every spawn with `/usr/bin/ionice: not found` even
though envd itself launches fine.

Mirror the existing nice(1) fallback: when the user rootfs has no executable
/usr/bin/ionice, symlink it to /agentenv/bin/busybox so the multi-call binary
serves the applet. Images that already ship util-linux keep their real
ionice(1) thanks to the [ ! -x ] guard. Also assert both nice and ionice
applets are compiled into the shipped BusyBox at image build time.

BusyBox ionice supports the -c/-n/-p/-t flags envd relies on (both call the
same ioprio_set(2) syscall); the util-linux-only -P/-u flags are not used by
envd.
@github-actions

Copy link
Copy Markdown
Contributor

OpenCodeReview: Review complete: 0 finding(s) across 2 selected item(s).

@yingdi-shan

Copy link
Copy Markdown
Collaborator

Thanks! We'll merge this PR once support for the tools image upgrade has been added. Otherwise, existing templates/snapshots will fail to resume.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants