Skip to content

[Request]: ListProcesses RPC on vminitd to enumerate guest processes (enables docker top / container top) #811

Description

@cap10morgan

Feature or enhancement request details

Problem

There is currently no way to enumerate the processes running inside a container without executing a binary in the guest. SandboxContext exposes full per-process lifecycle control (CreateProcess, StartProcess, KillProcess, WaitProcess) and cgroup-level ContainerStatistics, but nothing that lists what is actually running.

Every comparable runtime exposes this: containerd's task service has ListPids, and runc ps exists for the same reason. The gap is felt concretely by Docker-API bridges over Apple's container stack (e.g. socktainer, used by Whalebridge): docker top cannot be implemented correctly. The only available workaround is exec'ing ps inside the container, which:

  • fails outright for images that don't ship ps or a shell (distroless, scratch + static binary — increasingly the norm for production images), and
  • perturbs the very thing it measures (each invocation creates a process in the container).

A native RPC would also give container itself a natural user-facing feature (container top or container ps-style process inspection), independent of the Docker-bridge use case.

Proposed shape

A read-only RPC on SandboxContext, implemented in vminitd by walking the guest's /proc (vminitd already reads guest kernel state for ContainerStatistics, so this fits its existing role):

rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse);

message ListProcessesRequest {
  string container_id = 1;
}

message ListProcessesResponse {
  repeated ProcessInfo processes = 1;
}

message ProcessInfo {
  int32 pid = 1;
  int32 ppid = 2;
  uint32 uid = 3;
  string command = 4;          // /proc/<pid>/cmdline, argv joined; fallback to comm
  uint64 start_time_ticks = 5; // field 22 of /proc/<pid>/stat
  uint64 utime_ticks = 6;
  uint64 stime_ticks = 7;
  uint64 rss_bytes = 8;
}

Structured fields (rather than pre-rendered ps text) let each consumer format for its own surface — Docker's /containers/{id}/top response, a CLI table, etc. Scoping by the container's cgroup (/sys/fs/cgroup/.../cgroup.procs as the pid source, then per-pid /proc reads) keeps the result correct when multiple containers share a sandbox.

Compatibility note

Since vminitd ships inside the init filesystem image, host and guest versions can skew; callers would need to treat UNIMPLEMENTED from an older guest as "not supported" and degrade gracefully. Happy to follow whatever convention the project already uses for protocol additions.

I'm open to contributing the implementation (vminitd + proto here, plus the plumbing/CLI surface in apple/container as a follow-up) if maintainers are receptive to the direction — flagging the design here first for feedback.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions