|
| 1 | +#!/bin/sh |
| 2 | +set -eu |
| 3 | + |
| 4 | +# In vz, the VM lacks an RTC when booting with a kernel image (see: https://developer.apple.com/forums/thread/760344). |
| 5 | +# This causes incorrect system time until NTP synchronizes it, leading to TLS errors. |
| 6 | +# To avoid TLS errors, this script waits for NTP synchronization if RTC is unavailable. |
| 7 | +test ! -c /dev/rtc0 || exit 0 |
| 8 | + |
| 9 | +# This script is intended for services running with systemd. |
| 10 | +command -v systemctl >/dev/null 2>&1 || exit 0 |
| 11 | + |
| 12 | +echo_with_time_usec() { |
| 13 | + time_usec=$(timedatectl show --property=TimeUSec) |
| 14 | + echo "${time_usec}, ${1}" |
| 15 | +} |
| 16 | + |
| 17 | +# For the first boot, where the above setting is not yet active, wait for NTP synchronization here. |
| 18 | +max_retry=60 retry=0 |
| 19 | +until ntp_synchronized=$(timedatectl show --property=NTPSynchronized --value) && [ "${ntp_synchronized}" = "yes" ] || |
| 20 | + [ "${retry}" -gt "${max_retry}" ]; do |
| 21 | + if [ "${retry}" -eq 0 ]; then |
| 22 | + # If /dev/rtc is not available, the system time set during the Linux kernel build is used. |
| 23 | + # The larger the difference between this system time and the NTP server time, the longer the NTP synchronization will take. |
| 24 | + # By setting the system time to the modification time of the reference file, which is likely to be closer to the actual time, |
| 25 | + reference_file="${LIMA_CIDATA_MNT:-/mnt/lima-cidata}/user-data" |
| 26 | + [ -f "${reference_file}" ] || reference_file="${0}" |
| 27 | + |
| 28 | + # the NTP synchronization time can be shortened. |
| 29 | + echo_with_time_usec "Setting the system time to the modification time of ${reference_file}." |
| 30 | + |
| 31 | + # To set the time to a specified time, it is necessary to stop systemd-timesyncd. |
| 32 | + systemctl stop systemd-timesyncd |
| 33 | + |
| 34 | + # Since `timedatectl set-time` fails if systemd-timesyncd is not stopped, |
| 35 | + # ensure that it is completely stopped before proceeding. |
| 36 | + until pid_of_timesyncd=$(systemctl show systemd-timesyncd --property=MainPID --value) && [ "${pid_of_timesyncd}" -eq 0 ]; do |
| 37 | + echo_with_time_usec "Waiting for systemd-timesyncd to stop..." |
| 38 | + sleep 1 |
| 39 | + done |
| 40 | + |
| 41 | + # Set the system time to the modification time of the reference file. |
| 42 | + modification_time=$(stat -c %y "${reference_file}") |
| 43 | + echo_with_time_usec "Setting the system time to ${modification_time}." |
| 44 | + timedatectl set-time "${modification_time}" |
| 45 | + |
| 46 | + # Restart systemd-timesyncd |
| 47 | + systemctl start systemd-timesyncd |
| 48 | + else |
| 49 | + echo_with_time_usec "Waiting for NTP synchronization..." |
| 50 | + fi |
| 51 | + retry=$((retry + 1)) |
| 52 | + sleep 1 |
| 53 | +done |
| 54 | +# Print the result of NTP synchronization |
| 55 | +ntp_message=$(timedatectl show-timesync --property=NTPMessage) |
| 56 | +if [ "${ntp_synchronized}" = "yes" ]; then |
| 57 | + echo_with_time_usec "NTP synchronization complete." |
| 58 | + echo "${ntp_message}" |
| 59 | +else |
| 60 | + echo_with_time_usec "NTP synchronization timed out." |
| 61 | + echo "${ntp_message}" |
| 62 | + exit 1 |
| 63 | +fi |
0 commit comments