From 22564dd26b33cd605b00799d27ad8ffabd99f79a Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 15 Jun 2026 16:11:12 +0100 Subject: [PATCH] [settings] Allow system time to be modified via builtin/unixtime Allow the system time offset to be modified by writing a new time value to builtin/unixtime, e.g.: set builtin/unixtime 0x10d1a884 As with the NTP client, this does not attempt to write to the underlying clock source (e.g. the RTC clock). Only the internal system time offset is updated. Any system time offset may be reset by clearing the setting: clear builtin/unixtime This will reset the system time offset to zero and so can be used to undo the effect of a previous "set builtin/unixtime" or "ntp" command. Requested-by: Christian I. Nilsson Signed-off-by: Michael Brown --- src/core/settings.c | 32 +++++++++++++++++++++++++++++++- src/include/ipxe/time.h | 9 +++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/core/settings.c b/src/core/settings.c index 3e2ebd695..2e5760330 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -2630,13 +2630,42 @@ static int unixtime_fetch ( void *data, size_t len ) { uint32_t content; /* Return current time */ - content = htonl ( time(NULL) ); + content = htonl ( time ( NULL ) ); if ( len > sizeof ( content ) ) len = sizeof ( content ); memcpy ( data, &content, len ); return sizeof ( content ); } +/** + * Store current time setting + * + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data + * @ret rc Return status code + */ +static int unixtime_store ( const void *data, size_t len ) { + unsigned long value; + int check_len; + int rc; + + /* Get intended current time */ + check_len = numeric_setting_value ( 0, data, len, &value ); + if ( check_len < 0 ) { + rc = check_len; + return rc; + } + + /* Adjust or restore system clock, as applicable */ + if ( len ) { + time_adjust ( value - time ( NULL ) ); + } else { + time_restore(); + } + + return 0; +} + /** Current time setting */ const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = { .name = "unixtime", @@ -2648,6 +2677,7 @@ const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = { /** Current time built-in setting */ struct builtin_setting unixtime_builtin_setting __builtin_setting = { .setting = &unixtime_setting, + .store = unixtime_store, .fetch = unixtime_fetch, }; diff --git a/src/include/ipxe/time.h b/src/include/ipxe/time.h index 1b6f5daff..09f92ac7d 100644 --- a/src/include/ipxe/time.h +++ b/src/include/ipxe/time.h @@ -71,4 +71,13 @@ time_adjust ( signed long delta ) { time_offset += delta; } +/** + * Clear system clock adjustment + * + */ +static inline __attribute__ (( always_inline )) void time_restore ( void ) { + + time_offset = 0; +} + #endif /* _IPXE_TIME_H */