Don't let the boot-time ntpdate stall a VAX guest - #12
Merged
Conversation
ntpdate's rc.d script runs ntpdate(8) inline, so everything after it in
the boot sequence -- sshd included -- waits for it to return. In CI a
VAX guest sat at "Setting date via ntp." for a full hour, never reached
sshd, and failed the image test; the same commit passed on the next run,
so it flips a coin.
The QEMU ports don't have this problem because provision.sh switches
ntpdate off outright: QEMU seeds the emulated RTC from the host clock,
so the offset it would correct is already ~0. That reasoning doesn't
carry over to SIMH, whose KA655 has no battery-backed clock to seed --
the kernel rejects what it reads ("preposterous TOD clock time") and
falls back to the file system time. A VAX guest that never runs ntpdate
boots years in the past, and every HTTPS fetch then fails on
certificate validity instead.
So keep it and bound it. Neither of the two things in its path that can
block indefinitely is bounded by ntpdate's own retries:
- Resolving the pool names in the stock ntp.conf, which is what the
rc.d script falls back to when ntpdate_hosts is empty. An
unanswered DNS lookup has no deadline here at all, which is what
wedged the guest. ntpdate_hosts takes precedence over ntp.conf, so
numeric addresses keep DNS off the boot path entirely.
- A server that accepts the query and never answers, which -t bounds.
The addresses are Cloudflare's time service, whose anycast addresses are
documented as stable in a way a pool member's are not. ntpd still runs
afterwards and corrects drift over the life of the VM, so they only have
to be good enough for the initial step.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9LHkNMNNfDf2Fa1ieGT8g
jacob-carlborg
pushed a commit
that referenced
this pull request
Aug 14, 2026
Both sides added to the [Unreleased] changelog section. Keeps each: the VAX ntpdate fix from master (#12) alongside this branch's entries, with Fixed last, per Keep a Changelog's section order.
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.
ntpdate's rc.d script runsntpdate(8)inline, so everything after it in the boot sequence —sshdincluded — waits for it to return.In CI a VAX guest sat at
Setting date via ntp.for a full hour, never reachedsshd, and failedTest Image (vax). It is not deterministic: the same commit passed on the next run.Four VAX jobs on the same commit, showing the coin flip — and that a healthy boot reaches
sshdin ~2 minutes, not the ~15 the test's comment assumes:Why not just switch it off
That is what the QEMU ports do —
configure_time_syncinresources/provision.shsetsntpdate=NO, because QEMU seeds the emulated RTC from the host clock and the offset it would correct is already ~0.That reasoning does not carry over. SIMH's KA655 has no battery-backed clock to seed: the kernel rejects what it reads and falls back to the file system time.
A VAX guest that never runs
ntpdateboots years in the past, and every HTTPS fetch then fails on certificate validity instead. So it is kept, and bounded.What bounds it
Neither of the two things in its path that can block indefinitely is bounded by
ntpdate's own retries:ntp.conf, which is what the rc.d script falls back to whenntpdate_hostsis empty. An unanswered DNS lookup has no deadline here at all, and is what wedged the guest.ntpdate_hoststakes precedence overntp.conf, so numeric addresses keep DNS off the boot path entirely.-tbounds — a worst case of a few seconds per address rather than forever.The addresses are Cloudflare's time service, whose anycast addresses are documented as stable in a way a pool member's are not.
ntpdstill runs afterwards and corrects drift over the life of the VM, so they only have to be good enough for the initial step.Scope
Branched from
masterand independent of #11: this is a pre-existing flake, not something that PR introduced, and the fix touches only the VAX provisioner, which #11 does not. It is worth having before the next release tag, though —Create Releaseruns afterTest Image (vax), so a wedged VAX job fails the release job.Generated by Claude Code