mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-06 13:17:44 +03:00
time-util: introduce common implementation of TFD_TIMER_CANCEL_ON_SET client code
We now use pretty much the same code at three places, let's unify that.
This commit is contained in:
parent
bbf5fd8e41
commit
4f811d27d6
@ -1463,3 +1463,27 @@ bool in_utc_timezone(void) {
|
||||
|
||||
return timezone == 0 && daylight == 0;
|
||||
}
|
||||
|
||||
int time_change_fd(void) {
|
||||
|
||||
/* We only care for the cancellation event, hence we set the timeout to the latest possible value. */
|
||||
static const struct itimerspec its = {
|
||||
.it_value.tv_sec = TIME_T_MAX,
|
||||
};
|
||||
|
||||
_cleanup_close_ int fd;
|
||||
|
||||
assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
|
||||
|
||||
/* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever CLOCK_REALTIME makes a jump relative to
|
||||
* CLOCK_MONOTONIC. */
|
||||
|
||||
fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
|
||||
return -errno;
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
@ -185,3 +185,5 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
|
||||
#else
|
||||
#error "Yuck, time_t is neither 4 nor 8 bytes wide?"
|
||||
#endif
|
||||
|
||||
int time_change_fd(void);
|
||||
|
@ -353,14 +353,7 @@ static void manager_close_idle_pipe(Manager *m) {
|
||||
static int manager_setup_time_change(Manager *m) {
|
||||
int r;
|
||||
|
||||
/* We only care for the cancellation event, hence we set the
|
||||
* timeout to the latest possible value. */
|
||||
struct itimerspec its = {
|
||||
.it_value.tv_sec = TIME_T_MAX,
|
||||
};
|
||||
|
||||
assert(m);
|
||||
assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
|
||||
|
||||
if (m->test_run_flags)
|
||||
return 0;
|
||||
@ -368,18 +361,9 @@ static int manager_setup_time_change(Manager *m) {
|
||||
m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
|
||||
m->time_change_fd = safe_close(m->time_change_fd);
|
||||
|
||||
/* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
|
||||
* CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
|
||||
|
||||
m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
|
||||
m->time_change_fd = time_change_fd();
|
||||
if (m->time_change_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create timerfd: %m");
|
||||
|
||||
if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
|
||||
log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
|
||||
m->time_change_fd = safe_close(m->time_change_fd);
|
||||
return 0;
|
||||
}
|
||||
return log_error_errno(m->time_change_fd, "Failed to create timer change timer fd: %m");
|
||||
|
||||
r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
|
||||
if (r < 0)
|
||||
|
@ -115,16 +115,15 @@ static int inotify_handler(sd_event_source *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clock_state_update(ClockState *sp,
|
||||
sd_event *event) {
|
||||
static const struct itimerspec its = {
|
||||
.it_value.tv_sec = TIME_T_MAX,
|
||||
};
|
||||
int r;
|
||||
struct timex tx = {};
|
||||
static int clock_state_update(
|
||||
ClockState *sp,
|
||||
sd_event *event) {
|
||||
|
||||
char buf[MAX((size_t)FORMAT_TIMESTAMP_MAX, STRLEN("unrepresentable"))];
|
||||
usec_t t;
|
||||
struct timex tx = {};
|
||||
const char * ts;
|
||||
usec_t t;
|
||||
int r;
|
||||
|
||||
clock_state_release_timerfd(sp);
|
||||
|
||||
@ -151,19 +150,14 @@ static int clock_state_update(ClockState *sp,
|
||||
* it synchronized. When an NTP source is selected it sets the clock again with clock_adjtime(2) which marks it
|
||||
* synchronized and also touches /run/systemd/timesync/synchronized which covers the case when the clock wasn't
|
||||
* "set". */
|
||||
r = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||
|
||||
r = time_change_fd();
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to create timerfd: %m");
|
||||
log_error_errno(r, "Failed to create timerfd: %m");
|
||||
goto finish;
|
||||
}
|
||||
sp->timerfd_fd = r;
|
||||
|
||||
r = timerfd_settime(sp->timerfd_fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, NULL);
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to set timerfd conditions: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = adjtimex(&tx);
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to read adjtimex state: %m");
|
||||
|
@ -224,11 +224,6 @@ static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents
|
||||
|
||||
/* wake up when the system time changes underneath us */
|
||||
static int manager_clock_watch_setup(Manager *m) {
|
||||
|
||||
struct itimerspec its = {
|
||||
.it_value.tv_sec = TIME_T_MAX
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -236,12 +231,9 @@ static int manager_clock_watch_setup(Manager *m) {
|
||||
m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
|
||||
safe_close(m->clock_watch_fd);
|
||||
|
||||
m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
|
||||
m->clock_watch_fd = time_change_fd();
|
||||
if (m->clock_watch_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create timerfd: %m");
|
||||
|
||||
if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
|
||||
return log_error_errno(errno, "Failed to set up timerfd: %m");
|
||||
return log_error_errno(m->clock_watch_fd, "Failed to create timerfd: %m");
|
||||
|
||||
r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
|
||||
if (r < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user