Merge nucleic/hazy-opal-yak-cjc0 into dev
This commit is contained in:
+34
-2
@@ -205,6 +205,36 @@ rebuild whenever a guest patch changes. Built locally, not in CI: the host frame
|
||||
into a never-accepted backlog. A failed pre-relay connection is also closed explicitly.
|
||||
Marked `[Nucleic vendored patch]`.
|
||||
|
||||
14. **Non-blocking, non-spinning guest I/O plane (`IOPair.swift`, `OSFile+Splice.swift`,
|
||||
`VsockProxy.swift`) — the root cause of the "control plane unresponsive / all sessions stall"
|
||||
wedge.** Every exec's stdio relay (`IOPair`) and every control-plane relay connection
|
||||
(`VsockProxy`) share ONE thread: `ProcessSupervisor.default`'s epoll poller. Three defects let
|
||||
a single slow peer freeze that thread — and with it every session's stdio AND the whole
|
||||
container's control plane at once (probes then read "accepts connections but never answers";
|
||||
before the manager-side recovery rework the host restarted the container over this, SIGKILLing
|
||||
every session):
|
||||
- **`IOPair` blocking write:** only *registered* fds get `O_NONBLOCK` (set by `Epoll.add`), and
|
||||
the relay registers only its READ fd — the write fd (e.g. the vsock socket carrying an exec's
|
||||
stdout to the host) stayed blocking. One slow-drained stream parked the poller thread in
|
||||
`write(2)`. The relay now sets the write fd non-blocking up front and implements real
|
||||
backpressure: a full destination stashes the remainder in a `pending` backlog, registers the
|
||||
write fd for EPOLLOUT, and suspends reads until the flush completes (throttling the producing
|
||||
process via its own pipe, not the shared thread). The old close-on-short-write path — dead
|
||||
while the fd was blocking, live and stdio-dropping once non-blocking — is subsumed by the
|
||||
backlog; genuine write errors still close the pair.
|
||||
- **`OSFile.splice` busy-spin:** when the destination was full (EAGAIN) and the source idle,
|
||||
the outer loop had no exit — it spun the poller thread at 100% until the peer drained (or
|
||||
forever if it never did). The flush leg's EAGAIN branch now returns partial progress; the
|
||||
un-flushed bytes stay in the transfer pipe and the destination's EPOLLOUT edge resumes the
|
||||
flush (both `VsockProxy` handlers already pump both directions on both events).
|
||||
- **`VsockProxy` registration race:** the client fd's epoll handler can fire — and splice
|
||||
toward the server fd — before the second registration makes that fd non-blocking; a full
|
||||
destination made that a genuinely blocking splice on the poller thread. Both fds are now set
|
||||
non-blocking before either is registered.
|
||||
All three are guest-side and INERT until the initfs image is rebuilt (`make vminit-image`, tag
|
||||
`0.34.0-nucleic4`) and `ContainerEngine.vminitReference` is bumped after runtime validation.
|
||||
Marked `[Nucleic vendored patch]`.
|
||||
|
||||
## Re-vendoring a newer upstream commit
|
||||
|
||||
1. `git clone` upstream (or copy `.build/checkouts/containerization` after bumping the URL pin
|
||||
@@ -222,9 +252,11 @@ rebuild whenever a guest patch changes. Built locally, not in CI: the host frame
|
||||
`Cgroup2Manager.swift` / `ManagedContainer.swift` / `ManagedProcess.swift`, patch #10
|
||||
(`Socket.acceptStream` transient-error tolerance + `isTransientAcceptError`), patch #11 (the
|
||||
`UnixSocketRelay` per-connection containment + fail-fast closes), patch #12 (the `VsockProxy`
|
||||
cleanup/`try!`/listener hardening in `vminitd/`), and patch #13 (the prompt-free
|
||||
cleanup/`try!`/listener hardening in `vminitd/`), patch #13 (the prompt-free
|
||||
`KeychainQuery` reads: `withoutInteractiveUI` + the `errSecInteractionNotAllowed` handling +
|
||||
the `save` duplicate retry). After re-applying any
|
||||
the `save` duplicate retry), and patch #14 (the non-blocking/non-spinning guest I/O plane:
|
||||
`IOPair` backpressure, the `OSFile.splice` EAGAIN return, and the `VsockProxy` pre-registration
|
||||
non-blocking fds — all in `vminitd/`). After re-applying any
|
||||
`vminitd/` patch, rebuild + publish the custom init image
|
||||
with `make vminit-image` + `make vminit-image-push`, and bump `ContainerEngine.vminitReference`.
|
||||
5. Update the commit hash above and in the root `Package.swift` comment.
|
||||
|
||||
Reference in New Issue
Block a user