Replace time.time with time.monotonic to avoid clock drift issues (#4492)

Using time.time() can be inaccurate if the system clock gets
updated in between calls.
This commit is contained in:
correctmost 2026-04-28 07:34:33 -04:00 committed by GitHub
parent 8a929f603f
commit c4d68855cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 9 deletions

View File

@ -189,10 +189,10 @@ class Installer:
if not skip_ntp:
info(tr('Waiting for time sync (timedatectl show) to complete.'))
started_wait = time.time()
started_wait = time.monotonic()
notified = False
while True:
if not notified and time.time() - started_wait > 5:
if not notified and time.monotonic() - started_wait > 5:
notified = True
warn(tr('Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/'))

View File

@ -46,12 +46,12 @@ class DownloadTimer:
self.previous_handler = signal.signal(signal.SIGALRM, self.raise_timeout) # type: ignore[assignment]
self.previous_timer = signal.alarm(self.timeout)
self.start_time = time.time()
self.start_time = time.monotonic()
return self
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None:
if self.start_time:
time_delta = time.time() - self.start_time
time_delta = time.monotonic() - self.start_time
signal.alarm(0)
self.time = time_delta
if self.timeout > 0:
@ -165,7 +165,7 @@ def build_icmp(payload: bytes) -> bytes:
def ping(hostname: str, timeout: int = 5) -> int:
watchdog = select.epoll()
started = time.time()
started = time.monotonic()
random_identifier = f'archinstall-{random.randint(1000, 9999)}'.encode()
# Create a raw socket (requires root, which should be fine on archiso)
@ -180,7 +180,7 @@ def ping(hostname: str, timeout: int = 5) -> int:
# Gracefully wait for X amount of time
# for a ICMP response or exit with no latency
while latency == -1 and time.time() - started < timeout:
while latency == -1 and time.monotonic() - started < timeout:
try:
for _fileno, _event in watchdog.poll(0.1):
response, _ = icmp_socket.recvfrom(1024)
@ -188,7 +188,7 @@ def ping(hostname: str, timeout: int = 5) -> int:
# Check if it's an Echo Reply (ICMP type 0)
if icmp_type == 0 and response[-len(random_identifier) :] == random_identifier:
latency = round((time.time() - started) * 1000)
latency = round((time.monotonic() - started) * 1000)
break
except OSError as e:
debug(f'Error: {e}')

View File

@ -29,11 +29,11 @@ class Pacman:
if pacman_db_lock.exists():
warn(tr('Pacman is already running, waiting maximum 10 minutes for it to terminate.'))
started = time.time()
started = time.monotonic()
while pacman_db_lock.exists():
time.sleep(0.25)
if time.time() - started > (60 * 10):
if time.monotonic() - started > (60 * 10):
error(tr('Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall.'))
sys.exit(1)