Move two functions only used in pid1 from libshared to the binary

Anything that is part of src/shared becomes part of the shared library, which
is wasteful, because the library is linked into almost all binaries. The
library is also forms a separate link unit, so this prevents the function from
being inlined or such.

Also, move logging into the function. Now that it's not a library function,
there is no reason not to do that.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2024-06-12 10:08:23 +02:00
parent 455a2eb953
commit 4d47aa8c04
6 changed files with 64 additions and 71 deletions

56
src/core/clock-warp.c Normal file
View file

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/stat.h>
#include <sys/time.h>
#include "clock-util.h"
#include "clock-warp.h"
#include "errno-util.h"
int clock_reset_timewarp(void) {
static const struct timezone tz = {
.tz_minuteswest = 0,
.tz_dsttime = 0, /* DST_NONE */
};
/* The very first call to settimeofday() does time warp magic. Do a dummy call here, so the time
* warping is sealed and all later calls behave as expected. */
return RET_NERRNO(settimeofday(NULL, &tz));
}
void clock_apply_epoch(void) {
usec_t epoch_usec;
struct stat st;
int r;
r = RET_NERRNO(stat(EPOCH_CLOCK_FILE, &st));
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Cannot stat " EPOCH_CLOCK_FILE ": %m");
epoch_usec = (usec_t) TIME_EPOCH * USEC_PER_SEC;
} else
epoch_usec = timespec_load(&st.st_mtim);
usec_t now_usec = now(CLOCK_REALTIME);
bool advance;
if (now_usec < epoch_usec)
advance = true;
else if (CLOCK_VALID_RANGE_USEC_MAX > 0 && now_usec > usec_add(epoch_usec, CLOCK_VALID_RANGE_USEC_MAX))
advance = false;
else
return; /* Nothing to do. */
r = RET_NERRNO(clock_settime(CLOCK_REALTIME, TIMESPEC_STORE(epoch_usec)));
if (r < 0 && advance)
return (void) log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
else if (r < 0)
return (void) log_error_errno(r, "Current system time is further ahead than %s after build time, but cannot correct: %m",
FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
else if (advance)
log_info("System time was before build time, advanced clock.");
else
log_info("System time was further ahead than %s after build time, reset clock to build time.",
FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
}

5
src/core/clock-warp.h Normal file
View file

@ -0,0 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
int clock_reset_timewarp(void);
void clock_apply_epoch(void);

View file

@ -30,6 +30,7 @@
#include "cgroup-util.h"
#include "chase.h"
#include "clock-util.h"
#include "clock-warp.h"
#include "conf-parser.h"
#include "confidential-virt.h"
#include "copy.h"
@ -1705,18 +1706,7 @@ static void initialize_clock(void) {
*/
(void) clock_reset_timewarp();
ClockChangeDirection change_dir;
r = clock_apply_epoch(&change_dir);
if (r > 0 && change_dir == CLOCK_CHANGE_FORWARD)
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));
clock_apply_epoch();
}
static void apply_clock_update(void) {

View file

@ -143,6 +143,7 @@ core_includes = [includes, include_directories('.')]
systemd_sources = files(
'main.c',
'crash-handler.c',
'clock-warp.c',
)
systemd_executor_sources = files(

View file

@ -1,10 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdbool.h>
#include <time.h>
#include <linux/rtc.h>
#include <stdio.h>
#include <sys/ioctl.h>
@ -120,47 +116,3 @@ int clock_set_timezone(int *ret_minutesdelta) {
return 0;
}
int clock_reset_timewarp(void) {
static const struct timezone tz = {
.tz_minuteswest = 0,
.tz_dsttime = 0, /* DST_NONE */
};
/* The very first call to settimeofday() does time warp magic. Do a dummy call here, so the time
* warping is sealed and all later calls behave as expected. */
return RET_NERRNO(settimeofday(NULL, &tz));
}
int clock_apply_epoch(ClockChangeDirection *ret_attempted_change) {
usec_t epoch_usec, now_usec;
struct stat st;
/* 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_CLOCK_FILE, &st) < 0) {
if (errno != ENOENT)
log_warning_errno(errno, "Cannot stat " EPOCH_CLOCK_FILE ": %m");
epoch_usec = (usec_t) TIME_EPOCH * USEC_PER_SEC;
} else
epoch_usec = timespec_load(&st.st_mtim);
now_usec = now(CLOCK_REALTIME);
if (now_usec < epoch_usec)
*ret_attempted_change = CLOCK_CHANGE_FORWARD;
else if (CLOCK_VALID_RANGE_USEC_MAX > 0 && 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;
}
if (clock_settime(CLOCK_REALTIME, TIMESPEC_STORE(epoch_usec)) < 0)
return -errno;
return 1;
}

View file

@ -1,23 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <errno.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_set_timezone(int *ret_minutesdelta);
int clock_reset_timewarp(void);
int clock_get_hwclock(struct tm *tm);
int clock_set_hwclock(const struct tm *tm);
int clock_apply_epoch(ClockChangeDirection *ret_attempted_change);
#define EPOCH_CLOCK_FILE "/usr/lib/clock-epoch"
#define TIMESYNCD_CLOCK_FILE_DIR "/var/lib/systemd/timesync/"