node: a cut launch with a network is still followed as running: pasta lives in a PID namespace of its own, so runs_own takes it for the job's process #68
Open
opened 2026-11-14 01:06:34 +00:00 by xemmerling
·
0 comments
No Branch/Tag specified
main
dev/schema-step-order
t-join-release
t-work-booking
t-ahead-deadlock-wip
t-hotfix-9ae
t-width-work
t-id-token-renew
t-claim-unkept
t-resume-live
t-run-record
t-all-lockfiles
t-relay-offset
t-blame-event
t-freer-links
t-load-tests
t-jobserver2
t-starved-timeout
t-client-pack
t-offline-config
t-test-plan
t-told-resume2
t-jobserver
t-told-resume
t-outbound2
t-crash-open-bench
t-told-once
guest-never-below-given
admit-page-cache-active
pooled-admission
driver-give-back
no-sizes
one-driver-per-check
archive/vm-root-share
archive/build-out-kept
archive/cargo-perf
archive/virtiofs-readdir-alloc
archive/vm-outputs-stream
archive/stable-verify-priority
archive/agents-1
archive/stack-parallel
archive/cpu-admission
archive/narrow-from-every-log
archive/old-t
archive/worker-store-gc
archive/failing-builds-kept
archive/vm-cargo-home
archive/lifecycle
archive/bench-own-cores
archive/place-test-binaries-nocopy
archive/vm-net-upload-stall
archive/booking-current-use
archive/archive-dep-out-dirs
archive/any-arch-shards
archive/prepare-stall-progress-ns20
archive/s2
archive/next-set-20
archive/store-full-waits
archive/fetch-caps-by-node
archive/vm-step-phases
archive/arm-only-for-arm
archive/deploy-all-workers
archive/lifecycle-staging
archive/lifecycle-1-wire
archive/fast-gate
archive/cargo-key-narrow
archive/log-leads-followup
archive/gate-limit
archive/prepare-stall-vm-bytes
archive/lifecycle-2-ends
archive/cache-hits-bind
archive/failing-reused
archive/oci-archive-direct
archive/prepare-stall-progress
archive/test-quarantine
archive/crash-safe-on-18
archive/build-script-etxtbsy
archive/old-release
archive/next-set-19c
archive/wait-reasons
archive/cache-put-best-effort
archive/hang-not-t-time
archive/shard-test-results
archive/vm-carry-on-17
archive/check-test-filter
archive/artifact-path-beneath
archive/stall-room-xfs
archive/build-dir-no-recopy
archive/cache-hits-link
archive/outputs-no-follow-on-copy
archive/outputs-no-follow
archive/next-set-19
archive/hang-detect
archive/stable-verify-stable-plan
archive/freer-target-only
archive/lease-pricing-narrow
archive/vm-outputs-once
archive/queue-place-starved
archive/publish-reads
archive/disk-warning-scratch
archive/outputs-no-copy
archive/wd-probe-3min
archive/watchdog-on-d65
archive/log-leads-with-excerpt
archive/queue-place
archive/prep-watchdog-progress
archive/cache-put-stack-room
archive/cache-put-stack
archive/place-by-pace
archive/nested-sync-helper
archive/next-set-18y
archive/archive-bins-by-env-19
archive/next-set-18
archive/disk-want-held
archive/young-booking-back
archive/flaky-tests-1027b
archive/next-set-17
archive/prep-start-at-close
archive/unpack-error-on-17
archive/server-memory-high
archive/vm-start-held
archive/vm-carry-on-14
archive/space-trim-registry-room
archive/file-cache-ns16
archive/unpack-error-final
archive/crash-safe-worker
archive/server-space-trim
archive/status-big-runs
archive/nested-tmp-volatile
archive/publish-refresh
archive/gc-cache-quiet-reads
archive/next-set-16
archive/vm14-proof
archive/csw-node-kill
archive/unpack-link
archive/vm-tests-15
archive/seccomp-allow-field
archive/flaky-tests-1027-ns15
archive/shard-fail-fast
archive/server-node-check
archive/live-log-restart
archive/unpack-no-orphans
archive/flaky-tests-1027
archive/fetch-share-images
archive/fetch-images-red4
archive/forget-cached
archive/put-file-once-ns15
archive/recheck-rank-15
archive/fetch-images-red3
archive/unpack-no-orphans-red2
archive/fetch-io-pass-followups
archive/sandbox-no-fallback-ns15
archive/unpack-no-orphans-red
archive/archive-bins-by-env-ns15
archive/ns15-proof
archive/next-set-15
archive/archive-bins-by-env
archive/vm-guest-panic-15
archive/sandbox-no-fallback
archive/recheck-rank
archive/placement-ahead-bound
archive/carry-keeps-listing
archive/registry-parallel-pull
archive/sandbox-tests-15
archive/attempt-log-live-15
archive/follow-progress-16
archive/follow-progress-15
archive/ns15-archive-base
archive/fetch-io-max-on-13
archive/fetch-images-red2
archive/transient-build-fail-15
archive/test-ended-early-15
archive/archive-keep-cleanup
archive/main-merge-14
archive/sandbox-clone3-fallback
archive/vm-carry-on-13
archive/fetch-io-sweep-15
archive/vm-root-disk-fixes
archive/vm-guest-panic
archive/follow-progress-14
archive/archive-keep-on-demand
archive/vm-exit-unseen
archive/file-cache-share
archive/bwrap-root-userns
archive/transient-build-fail
archive/fetch-io-max
archive/file-cache-guard-11
archive/fetch-io-sweep
archive/archive-build-dir-skip
archive/next-set-14
archive/wrapper-one-read
archive/archive-tmp-links
archive/attempt-log-live
archive/fetch-share-and-order
archive/vm-hang-io-wait
archive/vm-carry-fixes
archive/image-cancel
archive/test-ended-early
archive/sim-on-train3-bundle
archive/hits-layer-wip
archive/t-old-putfile
archive/archive-links
archive/stall-on-13
archive/carried-prep-completes
archive/put-file-once
archive/preview-14
archive/follow-progress
archive/gc-reads-dont-protect
archive/admission-replay-people
archive/people-pickup
archive/gc-pass-visible
archive/hits-layer
archive/own-build-priced
archive/compact-stamps-followup
archive/prepare-timing
archive/sim-on-train3
archive/next-set-13
archive/next-set-12b
archive/sim-on-next-set-12
archive/deploy-doc-no-kill
archive/next-set-12
archive/attempt-logs-real
archive/sim-tests-green
archive/shard-label-index
archive/young-booking
archive/next-set-11
archive/data-dir-config-env
archive/vm-sync-not-host-store
archive/attempt-logs
archive/wrapper-ro
archive/tests-wait-on-events
archive/blame-git-optional-needs
archive/job-file-headroom-impl
archive/next-set-10
archive/blame-verdict-fresh-parent
archive/compact-touched-stamps
archive/interactive-incremental-off
archive/follow-lost-lines-counted
archive/evict-test
archive/next-set-trial
archive/keys-cover-output-bytes
archive/file-cache-guard
archive/blame-after-parent
archive/test-filter-matching-nothing-fails
archive/s1-on-d96
archive/draining-node-queues
archive/tprev-checks-prod-next
archive/s1-dead
archive/follow-live-run
archive/guard-stopped-setup-text
archive/io-error-cause
archive/source-layer-whole
archive/clippy-groups
archive/worker-silence-grace
archive/price-touched
archive/prod-next
archive/batch1
archive/s1-on-prod-next
archive/vmcache/sandbox-copyup-pin
archive/s1-xfs-store
archive/warm-script-builds
archive/vmcache/setup-tag-digest
archive/vmcache/setup-should-fixes
archive/vmcache/setup-any-arch
archive/guard-livelock
archive/host-budget
archive/wire-format-test
archive/admission-replay
archive/switch-safe
archive/stall-window
archive/upgrade-carries-preparing
archive/static-init
archive/switch-proof-b
archive/carry-tokens
archive/seals-together
archive/switch-safe-storage
archive/switch-safe-worker
archive/batch-b-prev
archive/vmcache/batch-b
archive/carry-vm-helpers
archive/small-llvm-args-failed-log
archive/batch-a
archive/stall-hotfix
archive/prev-pacing
archive/u-try-wip
archive/u-try
archive/u-try-wip2
archive/flatten-verify
archive/poll-free
archive/flatten-tiers
archive/hotfix-cross
archive/pool-stall
archive/disk-pacing
archive/u-builds-from-graph
archive/mac-idle
archive/ship-direct
archive/vmcache/shards
archive/soft-margin
archive/behind-no-target
archive/filtered-binaries
archive/vmcache/setup-layers
archive/direct-off-prev
archive/probe-budget
archive/vm-helper-exit
archive/jobs-soft-bound
archive/vmcache/vm-disks
archive/vmcache/failure-outputs
archive/narrowed-not-verdict
archive/scratch-direct-off
archive/handover-holds
archive/memory-lines
archive/drain-destroys
archive/pool-size
archive/drain-own-frees
archive/test-schema-drop
archive/deploy-disk
archive/deploy-disk-lines
archive/clone-aware-freeing
archive/absolute-headroom
archive/zfs-pool-size
archive/u-int5
archive/u-load
archive/u-warn
archive/u-steer
archive/revert-stall-once
archive/guard-headroom
archive/u-int3
archive/u-readsets
archive/u-hermetic
archive/mem-virtio
archive/u-buildjobs
archive/u-waits
archive/u-three
archive/u-zfs-stall
archive/u-config
archive/u-lean
archive/u-e2e
archive/u-integrate2
archive/u-jobenv
archive/u-cache-blobs
archive/u-observe2
archive/u-sched-nospread
archive/u-node-bound
archive/u-sched-oom
archive/u-review-store
archive/u-observe
archive/u-review-engine
archive/u-review-srv
archive/u-review-node
archive/u-review-sched
archive/preempt-measured
archive/u-integrate
archive/u-eng
archive/lock-off-runtime
archive/u-vm
archive/u-gone
archive/u-offline
archive/ready-starve
archive/u-notices
archive/heads-never-superseded
archive/u-learn
archive/int
archive/u-graph
archive/u-umount
archive/supersede-followed
archive/preparing-booking
archive/u-xdev
archive/u-env
archive/u-poll
archive/u-wrap
archive/u-room
archive/u-wrap-try
archive/u-fixed
archive/unstall
archive/u-fix3
archive/u-cwd
archive/resume-supersedes
archive/server-heap
archive/u-harness
archive/u-macos
archive/u-node
archive/u-eng2
archive/u-leader
archive/u-cutover
archive/u-cache
archive/u-sched
archive/u-engine
archive/chore/agpl-license
archive/note-x86-disk-room
archive/pass-cost
archive/prod-defects
archive/clippy-false-greens
archive/t-pace-variance-prototype
archive/outputs-reattach
archive/fix-retry-needs
archive/no-supersede-uncached
archive/fix/promoted-view-mtime
archive/rb-merge
archive/ft-sched
archive/ft-node
archive/ft-engine
archive/fx-sim
archive/fx2-mem
archive/fx2-store
archive/fx2-ci
archive/fx-work
archive/fx-ci
archive/fx-sched
archive/fx-req
archive/fx-store
archive/fx-cache
archive/rb-storage
archive/rb-scheduling
archive/rb-sweep
archive/rb-tracking
archive/rb-workers
archive/rb-client
archive/rb-profiles
archive/rebuild
archive/batch-deploy
archive/fix-roll
archive/work
archive/fix-busy
archive/fix-perf
archive/fix-suite
archive/fix-spread
archive/fix-sig
archive/fix-wait
archive/fix-init
archive/sizing
archive/fix-drift
archive/delivery
archive/fix-snap
archive/fix-own
archive/fix-rollout
archive/fix-hang
archive/fix-tree
archive/images
archive/fill
archive/sched-gate-preparing-after
archive/takeover-sim
archive/image-d244b22
archive/image-ce8a09e
archive/image-c9ff4f7
archive/image-489bec9
archive/image-7e07ffb
archive/image-583ea93
archive/image-8e1cd2c
archive/image-fbf0a9c
archive/image-6924e11
archive/image-29cabc3
archive/image-97ebb0e
archive/image-d0e23ac
archive/image-319fce9
archive/image-4f689e1
archive/image-feacbcd
archive/image-d5d9446
archive/image-6b86940
archive/fix/dedup-priority-promotion
archive/image-a5b0fe3
archive/image-462afb1
archive/image-f39d42c
archive/image-6e71fb4
archive/image-0c62329
archive/resources
archive/image-112b6a6
archive/image-8b06530
archive/image-5ae7cd8
archive/fmt-fix-in-t-toml
archive/image-arm64
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
tilo/t#68
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A job whose launch was cut is meant to be told from a running one by whether a process of its own is in its cgroup (
JobCgroup::runs_own,7f174964, mine, 2026-11-12). The rule readsNSpid: a process named in more PID namespaces than the node's is the job's own. That rule takes pasta for the job's own process, so a networked job whose launch was cut is still followed as running until its stall bound, which is the case the commit set out to end (j319-1: its cgroup held pasta andt __observealone).Evidence
The test that covers it fails wherever it really runs.
node::sandbox::tests::a_job_s_own_process_is_told_from_what_its_launch_started_for_iton the forge's runner (run 1454, with the assertion printing what it saw):t-testing's
testcheck declaresrootmissing, so the test returns early there and has never run on a push (see #67).Production shows the same. Read-only sample of the worker on ci-x86-1 at 01:05Z 11-14, helper and job processes by name and by how many PID namespaces they are named in (the node's is 1):
passt.avx2pastapasst.avx2passtvirtiofsdvirtiofsdtilo-job-init(helpers)tilo-job-init(jobs' own)qemu-system-x86So every helper is in the node's namespace as the doc above
PidNssays, except pasta: all 85 running pastas are one namespace below it.Why. t starts pasta without
--foreground(pasta_argv,src/node/sandbox.rs) and relies on it returning once it has connected the namespace. Upstream'sisolate_prefork()at the snapshot t builds (passt-2026_10_02.cba3570, one unrelated patch) unshares a PID namespace for a pasta that goes to the background:if (!c->foreground || c->mode != MODE_PASTA) flags |= CLONE_NEWPID;. The doc abovePidNs(src/node/cgroup.rs) says pasta "runs in the node's own", which is not so.Effect
launch_cut(src/node/run/live.rs) returns nothing whenruns_ownis true. A job with a network whose worker died between itsstartedand its process therefore is not ended as lost at once and rerun; its follower reads the cgroup as populated and follows it to its stall bound (600 s), then it ends in an error. Planned upgrades are not affected: the launch gate (d925bedf) lets no launch be cut by an exit the worker chooses. It bites when a worker dies unplanned.What I am doing
One developer is taking it, on top of the #67 branch, where the failing test is the proof: pasta is told apart from the job's own processes by a fact that holds on a node (which one is being decided from the code and upstream's source, with the reasons written down), the doc is corrected, and the test passes on the forge's runner. Before it lands I prove an upgrade with running jobs on testing, since it changes what a worker reads of jobs an older worker started.
01:20Z 11-14: the fix, on trial (branch
dev/forge-ci, commitd5a910f8)Mechanism. Once pasta has connected, the launch records what lives below the node's PID namespace in the job's cgroup, by PID and start time, in the job's directory (
started-for.json). At that point that is pasta's daemon alone: the record is taken inNet::start, before the source server, beforestartedis written and before the job's own process is spawned, in a cgroup made for this launch.runs_ownthen counts a process below the node's namespace as the job's own unless its PID and start time are in that record.Why a running job is never read as lost. Every way the record can be wrong or missing leaves at least as many processes counted as the job's own as before:
Considered and not taken. pasta's own
--pidfile (needs a file bound into pasta's mount namespace and a changed argument, and still a start time); a cgroup of pasta's own below the job's (every reader of a job's cgroup would have to step around it); pasta in the foreground (it never returns once connected, so the launch would have to poll).Upgrade. It adds one file to a job's directory and changes no argument of pasta. Jobs an earlier worker started have no record and read as before; an earlier worker never reads the file. I prove this with running jobs on testing as soon as testing serves it, before it is promoted.
State. Reviewed. On the forge's runner as run 1456; t's own check set is running for it on testing.
01:32Z 11-14: the fix passes where the test really runs
Forge run 1456 on
d5a910f8: fmt and clippy pass; test 3,326 run, 3,326 passed, 42 skipped. It is the first greentestjob of the forge's workflow since at least 11-05.node::sandbox::tests::a_job_s_own_process_is_told_from_what_its_launch_started_for_itpassed with the runner's stock pasta, the one that lives in a PID namespace of its own.node::run::live::tests::a_job_whose_launch_was_cut_after_its_start_is_lost_and_never_followedpassed with pasta below the node's namespace and a record.node::run::live::tests::a_job_without_a_record_of_its_pasta_is_never_lostpassed: a job of an earlier worker, or one whose record cannot be read, staysRunning.Main moved to
445e458emeanwhile, so the candidate was rebuilt on it (95935ccd) and t's own check set is running for it on testing. After it lands: the upgrade with running jobs on testing, both ways, before any promote.01:38Z 11-14: landed as
95935ccdt's own check set on testing passed for it on main's head
445e458e(run r9d3662abef, 8 of 8), and it is on main as95935ccdsince 01:37:54Z. It is NOT promoted. Running now on testing: the upgrade with jobs under way (an earlier worker's jobs read by this one); then the reverse (this worker's jobs, withstarted-for.json, read by the earlier one). Please do not promote it before the result stands here.01:50Z 11-14: the way back holds; the fix seen at work
95935ccd): all 15 job directories of a forced check set heldstarted-for.json. One read[{"pid":615067,"start":66523111}], and that process waspasst.avx2with argv[0]pastaandNSpid: 615067 1: pasta's daemon and nothing else.445e458ewas deployed. The worker fetched it at 01:46:14Z and loggedre-attached to the jobs on disk jobs=14; reaped as unattachable 0,missing field0, ERROR lines 0, panics 0. The run (ra87c34c88a) ended with all 8 checks passed.01:57Z 11-14: the upgrade holds both ways with jobs under way
missing fieldstarted-for.json, read by445e458e(01:46:14Z)95935ccd(01:53:10Z)One thing in the way-back run I could not read to the end: of its 13
test/tjobs under way across the takeover, one (j386-11) endedfailby a normal end, and the check passed with every shard once and no failed or retried test in its log. The failed attempt's own output is not kept, so I cannot say what failed in it. The forward run had no such job.The forge's workflow is green for
95935ccd(run 1459). Testing serves it. It is not on production; nothing here stands in the way of a promote any more.02:48Z 11-14: the node protocol step under it (
a3c41636, 72 to 73), with jobs under wayMain's head
a3c41636raises the node protocol to 73, and a promote of main would carry this fix across that step. Testing had moved toa3c41636by itself at 02:34Z with no job on disk, so I ran both directions by hand there:missing field95935ccd(protocol 73 to 72)a3c41636(protocol 72 to 73)In both the worker logged "server speaks node protocol N, this node speaks M: it runs the server's build", kept a job's end and its output until the server took them, fetched the server's build and re-attached within two seconds. Testing serves
a3c41636again.One thing for whoever promotes
a3c41636: t's own run on it on testing (rb3566d100f, 02:28 to 02:33Z) failedtest/ton one test,drivers::cargo::tests_again::a_family_whose_own_wrapper_makes_cargo_refuse_is_answered_once("every verdict from the cache",src/drivers/cargo/tests_again.rs:919). The same commit passed that test on the forge's runner (run 1460) and in the whole check set of the way-back proof, which was built from a3c41636's sources. One failure against two passes, with no deploy on testing in that window; I have not found its cause.03:15Z 11-14: the next node protocol step (
1f4798be, 73 to 74), with jobs under wayMain moved to
1f4798beat 02:56Z, which raises the node protocol once more. t's own run on it on testing passed 15 of 15, and testing moved to it by itself at 03:03Z with no job on disk. Both directions by hand again:missing fielda3c41636(protocol 74 to 73)1f4798be(protocol 73 to 74)test/tfailed on one test, see belowTesting serves
1f4798beagain. Production is onc2d52b34with node protocol 72 and client protocol 64; main's head has node protocol 74 and the same client protocol, so a promote of main crosses two node steps at once. For people's clients: an oldertkeeps working against the newer server, since2ec12d3conly adds aninputsfield to results, left out when empty, andCheckResulttakes fields it does not know. The other way round, a newertthat sends--inputto a server before2ec12d3cis refused, becauseRunRequestrefuses unknown fields; without--inputnothing is sent and it works. The mismatch test is plain equality of the header with the build's own number (proto::speaks, raised inClient::check_protocols), so a worker two steps away takes the same path as one step away: it runs the server's build. Shown by runs here: each single step with its neighbour, both ways. Not shown by a run: the jump of two, and the way back toc2d52b34itself.The red check in the forward run is not one of the re-attached jobs. All 13 jobs that were under way across the takeover passed, as did the 13 across the way back. The job that failed (j394-8) was started by the newer worker ten seconds after it took over, and failed one test after 86 s:
drivers::cargo::tests_multi_tilo::a_tilos_sized_wave_runs_across_nodes_as_it_does_on_one, "CI's wave is handed out" (src/drivers/cargo/tests_multi_tilo.rs:307). On the forge's runner that test passes in 39 s.It is the third single test failure in
test/ton testing tonight, each a different test and each in a run that shared testing's one node with a restart or a second check set: an unread one at 01:48Z,drivers::cargo::tests_again::a_family_whose_own_wrapper_makes_cargo_refuse_is_answered_onceat 02:33Z ("every verdict from the cache"), and this one. The same sources passedtest/twhole in other runs and on the forge's runner each time. I read them as tests that fail under load on that node, not as an effect of the protocol steps; I have not found a cause in the code.