Repository navigation
image: the SSH host keys are made from the boot's first dispatch - #248
Merged
Merged
Conversation
spin-machine-sshd-keygen.service is wanted by sysinit.target without default dependencies, so the keys exist before sshd-vsock.socket listens and the first login's sshd@ no longer waits for them before its banner. On the bench fleet, 20 boots of each interleaved (task boot:ssh-first, lab run 43483372488): the first SSH login 489/506 -> 468/494 ms p50/p95, accept to login 177 -> 154 ms. build.sh asserts the want and DefaultDependencies=no. Measured beside it and left out, the conclusions kept by the probes: masking sshd-socket-generator and systemd-run-generator (generators 5.3 -> 3.7 ms, login 489), and masking the eleven initial-transaction units whose condition always fails here (login 484); all three together 469. The ~32 ms with no unit running after the unit load is PID 1 loading the default target's units and building the initial transaction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #247, rebased onto main after #245 (the conflicts were both PRs adding to the same assertions and to ssh-first's rows; both kept).
Three image-side changes for the cold boot to the first SSH login, measured one by one and together against the image as built, judged on the first login over vsock.
Fleet (task boot:ssh-first, lab run 43483372488, release v20261113.02, 20 boots of each, interleaved, 2 vCPUs)
No row lost a login (0/20 each). Keys early alone had already measured 486 to 468 and 177 to 155 in lab run 43463472762. Only the keys moved the login, so this PR ships them and leaves the other two out.
Per item
spin-machine-sshd-keygen.servicenow hasDefaultDependencies=no,Conflicts=/Before=shutdown.targetandWantedBy=sysinit.target.optimize-systemd.shenables it with a link insysinit.target.wants. Thesshd@.service.d/keygen.confordering stays.build.shasserts the link andDefaultDependencies=noon the finished filesystem. In the built image, the keygen starts beforesysinit.targetand is done by then, and no unit fails.boot:ssh-firstandboot:logindpass on it locally. One consequence for consumers: a guest checkpointed after boot now always carries host keys, so the restorer has to hand each VM its own. That was already true whenever anything had logged in before the checkpoint.image/README.mdsays this.sshd-socket-generator,systemd-getty-generator,systemd-run-generatorandsystemd-ssh-generator. The rest are already masked.sshd-socket-generatoris the slowest: it loads libcrypto and writes nothing, because sshd_config is at its defaults. In a guest it took 3.5-23.5 ms, against about 1.5 ms for each systemd generator. The generators run in parallel, though. Masking it andsystemd-run-generatortook the generators phase from 5.3 to 3.7 ms p50 (laptop, 8 boots each), and on the fleet the login did not move (489). The fleet's generators phase is 6.5 ms. The ~44 ms before it is PID 1's own setup, not generators.UnitsLoadFinish, no unit runs for about 32 ms p50 on the fleet (lab run 43361486792). That time is PID 1 itself. systemd stampsUnitsLoadFinishafter it enumerates mounts, devices and slices, and only then loads the boot's units: coldplug, thenActivating default unit: default.target. That parses every unit filedefault.targetreaches, plus a stub for every name anAfter=/RequiresMountsFor=gives. It then builds the initial transaction (64 jobs) and garbage-collects the stubs before it dispatches the first job (systemd-ask-password.socket). This comes fromtask boot:tracewithsystemd.log_level=debug, which ends in "Loaded units and determined initial transaction". The gap only shrinks along with the transaction. Masking the 11 jobs whose condition fails on every boot here (pcr*, kmod-static-nodes, apparmor, the distribution's sshd-keygen, getty-static, getty@tty1) did not move the login (484). The explanation is now a comment inboot/waits_probe_test.go.boot/ssh_first_test.gokeeps one row, "as this branch", which applies keys early to older releases too. The experiment rows are gone and their results are in its comment. The probe gains an accept-to-login column.🤖 Generated with Claude Code