mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
time-set: adjust system clock if rtc is far in future
This commit is contained in:
parent
f121bd7818
commit
b10abe4bba
@ -722,6 +722,8 @@ if time_epoch == -1
|
|||||||
endif
|
endif
|
||||||
conf.set('TIME_EPOCH', time_epoch)
|
conf.set('TIME_EPOCH', time_epoch)
|
||||||
|
|
||||||
|
conf.set('CLOCK_VALID_RANGE_USEC_MAX', get_option('clock-valid-range-usec-max'))
|
||||||
|
|
||||||
foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1], # Also see login.defs(5).
|
foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1], # Also see login.defs(5).
|
||||||
['system-uid-max', 'SYS_UID_MAX', 999],
|
['system-uid-max', 'SYS_UID_MAX', 999],
|
||||||
['system-alloc-gid-min', 'SYS_GID_MIN', 1],
|
['system-alloc-gid-min', 'SYS_GID_MIN', 1],
|
||||||
|
@ -208,6 +208,8 @@ option('status-unit-format-default', type : 'combo',
|
|||||||
description : 'use unit name or description in messages by default')
|
description : 'use unit name or description in messages by default')
|
||||||
option('time-epoch', type : 'integer', value : '-1',
|
option('time-epoch', type : 'integer', value : '-1',
|
||||||
description : 'time epoch for time clients')
|
description : 'time epoch for time clients')
|
||||||
|
option('clock-valid-range-usec-max', type : 'integer', value : '473364000000000', # 15 years
|
||||||
|
description : 'maximum value in microseconds for the difference between RTC and epoch, exceeding which is considered an RTC error')
|
||||||
|
|
||||||
option('system-alloc-uid-min', type : 'integer', value : '-1',
|
option('system-alloc-uid-min', type : 'integer', value : '-1',
|
||||||
description : 'minimum system UID used when allocating')
|
description : 'minimum system UID used when allocating')
|
||||||
|
@ -83,6 +83,7 @@
|
|||||||
#include "switch-root.h"
|
#include "switch-root.h"
|
||||||
#include "sysctl-util.h"
|
#include "sysctl-util.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
#include "time-util.h"
|
||||||
#include "umask-util.h"
|
#include "umask-util.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -1598,11 +1599,18 @@ static void initialize_clock(void) {
|
|||||||
*/
|
*/
|
||||||
(void) clock_reset_timewarp();
|
(void) clock_reset_timewarp();
|
||||||
|
|
||||||
r = clock_apply_epoch();
|
ClockChangeDirection change_dir;
|
||||||
if (r < 0)
|
r = clock_apply_epoch(&change_dir);
|
||||||
log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
|
if (r > 0 && change_dir == CLOCK_CHANGE_FORWARD)
|
||||||
else if (r > 0)
|
|
||||||
log_info("System time before build time, advancing clock.");
|
log_info("System time before build time, advancing clock.");
|
||||||
|
else if (r > 0 && change_dir == CLOCK_CHANGE_BACKWARD)
|
||||||
|
log_info("System time is further ahead than %s after build time, resetting clock to build time.",
|
||||||
|
FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
|
||||||
|
else if (r < 0 && change_dir == CLOCK_CHANGE_FORWARD)
|
||||||
|
log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
|
||||||
|
else if (r < 0 && change_dir == CLOCK_CHANGE_BACKWARD)
|
||||||
|
log_error_errno(r, "Current system time is further ahead %s after build time, but cannot correct: %m",
|
||||||
|
FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_clock_update(void) {
|
static void apply_clock_update(void) {
|
||||||
|
@ -139,10 +139,15 @@ int clock_reset_timewarp(void) {
|
|||||||
|
|
||||||
#define EPOCH_FILE "/usr/lib/clock-epoch"
|
#define EPOCH_FILE "/usr/lib/clock-epoch"
|
||||||
|
|
||||||
int clock_apply_epoch(void) {
|
int clock_apply_epoch(ClockChangeDirection *ret_attempted_change) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
usec_t epoch_usec;
|
usec_t epoch_usec, now_usec;
|
||||||
|
|
||||||
|
/* NB: we update *ret_attempted_change in *all* cases, both
|
||||||
|
* on success and failure, to indicate what we intended to do! */
|
||||||
|
|
||||||
|
assert(ret_attempted_change);
|
||||||
|
|
||||||
if (stat(EPOCH_FILE, &st) < 0) {
|
if (stat(EPOCH_FILE, &st) < 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
@ -152,8 +157,15 @@ int clock_apply_epoch(void) {
|
|||||||
} else
|
} else
|
||||||
epoch_usec = timespec_load(&st.st_mtim);
|
epoch_usec = timespec_load(&st.st_mtim);
|
||||||
|
|
||||||
if (now(CLOCK_REALTIME) >= epoch_usec)
|
now_usec = now(CLOCK_REALTIME);
|
||||||
|
if (now_usec < epoch_usec)
|
||||||
|
*ret_attempted_change = CLOCK_CHANGE_FORWARD;
|
||||||
|
else if (now_usec > usec_add(epoch_usec, CLOCK_VALID_RANGE_USEC_MAX))
|
||||||
|
*ret_attempted_change = CLOCK_CHANGE_BACKWARD;
|
||||||
|
else {
|
||||||
|
*ret_attempted_change = CLOCK_CHANGE_NOOP;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, epoch_usec)) < 0)
|
if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, epoch_usec)) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
typedef enum ClockChangeDirection {
|
||||||
|
CLOCK_CHANGE_NOOP,
|
||||||
|
CLOCK_CHANGE_FORWARD,
|
||||||
|
CLOCK_CHANGE_BACKWARD,
|
||||||
|
_CLOCK_CHANGE_MAX,
|
||||||
|
_CLOCK_CHANGE_INVALID = -EINVAL,
|
||||||
|
} ClockChangeDirection;
|
||||||
|
|
||||||
int clock_is_localtime(const char* adjtime_path);
|
int clock_is_localtime(const char* adjtime_path);
|
||||||
int clock_set_timezone(int *ret_minutesdelta);
|
int clock_set_timezone(int *ret_minutesdelta);
|
||||||
int clock_reset_timewarp(void);
|
int clock_reset_timewarp(void);
|
||||||
int clock_get_hwclock(struct tm *tm);
|
int clock_get_hwclock(struct tm *tm);
|
||||||
int clock_set_hwclock(const struct tm *tm);
|
int clock_set_hwclock(const struct tm *tm);
|
||||||
int clock_apply_epoch(void);
|
int clock_apply_epoch(ClockChangeDirection *ret_attempted_change);
|
||||||
|
Loading…
Reference in New Issue
Block a user