Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Fixed
- Stop the boot-time `ntpdate` being able to stall a NetBSD/VAX guest
indefinitely. It runs inline in the boot sequence, ahead of `sshd`, and the
DNS lookup for the pool names in the stock `ntp.conf` has no deadline, so a
lookup that went unanswered left the guest sitting at `Setting date via
ntp.` It is now given numeric addresses, keeping DNS off the boot path, and
a per-query timeout

## [0.7.0] - 2026-08-09
### Added
Expand Down
36 changes: 36 additions & 0 deletions resources/post_install_vax.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# (no msdosfs on vax), so a key is not an option.
# - Enable sshd at boot
# - Set boot loader timeout to 0
# - Bound the boot-time ntpdate, which the VAX needs and cannot let hang
# - Set the hostname
# - Minimize the disk image (zero unused blocks so zstd compresses it well)
#
Expand Down Expand Up @@ -119,6 +120,40 @@ configure_boot_flags() {
fi
}

# ntpdate's rc.d script runs ntpdate(8) inline, so everything after it in the
# boot sequence -- sshd included -- waits for it to return.
#
# The QEMU ports simply switch it off (configure_time_sync in
# resources/provision.sh): QEMU seeds the emulated RTC from the host clock, so
# the offset it would correct is already ~0. That reasoning does not carry over
# here. SIMH's 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, so a VAX guest that never runs ntpdate boots years in the past
# and every HTTPS fetch fails on certificate validity instead.
#
# So keep it, but stop it being able to hang the boot. Two things in its path
# can block indefinitely, and neither is bounded by ntpdate's own retries:
#
# 1. Resolving the pool names in the stock /etc/ntp.conf, which is what the
# rc.d script falls back to when ntpdate_hosts is empty. A DNS lookup that
# goes unanswered has no deadline here at all -- this is what wedged the
# guest at "Setting date via ntp." for an hour in CI. ntpdate_hosts takes
# precedence over ntp.conf, so numeric addresses keep DNS off the boot
# path entirely.
# 2. A server that accepts the query and never answers. -t bounds each one,
# giving a worst case of a few seconds per address rather than forever.
#
# Cloudflare's time service is used because its addresses are anycast and
# documented as stable, which a pool member's address is not. ntpd still runs
# afterwards and corrects drift over the life of the VM, so these addresses
# only have to be good enough for the initial step.
configure_time_sync() {
cat <<'EOF' >> /mnt/etc/rc.conf
ntpdate_hosts="162.159.200.1 162.159.200.123"
ntpdate_flags="-t 5"
EOF
}

set_hostname() {
echo "hostname=${HOSTNAME}" >> /mnt/etc/rc.conf
}
Expand Down Expand Up @@ -179,6 +214,7 @@ configure_ssh
setup_passwordless_login
enable_sshd_at_boot
configure_boot_flags
configure_time_sync
set_hostname
install_packages
setup_sudo
Expand Down
Loading