Skip to content

Commit

Permalink
time-util: assume CLOCK_BOOTTIME always exists
Browse files Browse the repository at this point in the history
Let's raise our supported baseline a bit: CLOCK_BOOTTIME started to work
with timerfd in kernel 3.15 (i.e. back in 2014), let's require support
for it now.

This will raise our baseline only modestly from 3.13 → 3.15.
  • Loading branch information
poettering committed Mar 28, 2022
1 parent ec4954d commit ba4e042
Show file tree
Hide file tree
Showing 46 changed files with 122 additions and 176 deletions.
2 changes: 1 addition & 1 deletion README
Expand Up @@ -30,7 +30,7 @@ LICENSE:
LGPL-2.1-or-later for all code, exceptions noted in LICENSES/README.md

REQUIREMENTS:
Linux kernel >= 3.13
Linux kernel >= 3.15
Linux kernel >= 4.2 for unified cgroup hierarchy support
Linux kernel >= 4.10 for cgroup-bpf egress and ingress hooks
Linux kernel >= 4.15 for cgroup-bpf device hook
Expand Down
56 changes: 7 additions & 49 deletions src/basic/time-util.c
Expand Up @@ -77,7 +77,7 @@ triple_timestamp* triple_timestamp_get(triple_timestamp *ts) {

ts->realtime = now(CLOCK_REALTIME);
ts->monotonic = now(CLOCK_MONOTONIC);
ts->boottime = clock_boottime_supported() ? now(CLOCK_BOOTTIME) : USEC_INFINITY;
ts->boottime = now(CLOCK_BOOTTIME);

return ts;
}
Expand Down Expand Up @@ -150,9 +150,7 @@ triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u)

ts->realtime = u;
ts->monotonic = map_clock_usec_internal(u, nowr, now(CLOCK_MONOTONIC));
ts->boottime = clock_boottime_supported() ?
map_clock_usec_internal(u, nowr, now(CLOCK_BOOTTIME)) :
USEC_INFINITY;
ts->boottime = map_clock_usec_internal(u, nowr, now(CLOCK_BOOTTIME));

return ts;
}
Expand All @@ -170,23 +168,16 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
return ts;
}

dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u) {
clockid_t cid;
dual_timestamp* dual_timestamp_from_boottime(dual_timestamp *ts, usec_t u) {
usec_t nowm;

if (u == USEC_INFINITY) {
ts->realtime = ts->monotonic = USEC_INFINITY;
return ts;
}

cid = clock_boottime_or_monotonic();
nowm = now(cid);

if (cid == CLOCK_MONOTONIC)
ts->monotonic = u;
else
ts->monotonic = map_clock_usec_internal(u, nowm, now(CLOCK_MONOTONIC));

nowm = now(CLOCK_BOOTTIME);
ts->monotonic = map_clock_usec_internal(u, nowm, now(CLOCK_MONOTONIC));
ts->realtime = map_clock_usec_internal(u, nowm, now(CLOCK_REALTIME));
return ts;
}
Expand Down Expand Up @@ -1461,50 +1452,17 @@ int verify_timezone(const char *name, int log_level) {
return 0;
}

bool clock_boottime_supported(void) {
static int supported = -1;

/* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */

if (supported < 0) {
int fd;

fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
if (fd < 0)
supported = false;
else {
safe_close(fd);
supported = true;
}
}

return supported;
}

clockid_t clock_boottime_or_monotonic(void) {
if (clock_boottime_supported())
return CLOCK_BOOTTIME;
else
return CLOCK_MONOTONIC;
}

bool clock_supported(clockid_t clock) {
struct timespec ts;

switch (clock) {

case CLOCK_MONOTONIC:
case CLOCK_REALTIME:
return true;

case CLOCK_BOOTTIME:
return clock_boottime_supported();

case CLOCK_BOOTTIME_ALARM:
if (!clock_boottime_supported())
return false;
/* These three are always available in our baseline, and work in timerfd, as of kernel 3.15 */
return true;

_fallthrough_;
default:
/* For everything else, check properly */
return clock_gettime(clock, &ts) >= 0;
Expand Down
4 changes: 1 addition & 3 deletions src/basic/time-util.h
Expand Up @@ -82,7 +82,7 @@ usec_t map_clock_usec(usec_t from, clockid_t from_clock, clockid_t to_clock);
dual_timestamp* dual_timestamp_get(dual_timestamp *ts);
dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u);
dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u);
dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u);
dual_timestamp* dual_timestamp_from_boottime(dual_timestamp *ts, usec_t u);

triple_timestamp* triple_timestamp_get(triple_timestamp *ts);
triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u);
Expand Down Expand Up @@ -155,9 +155,7 @@ static inline bool timezone_is_valid(const char *name, int log_level) {
return verify_timezone(name, log_level) >= 0;
}

bool clock_boottime_supported(void);
bool clock_supported(clockid_t clock);
clockid_t clock_boottime_or_monotonic(void);

usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);

Expand Down
2 changes: 1 addition & 1 deletion src/core/timer.h
Expand Up @@ -64,7 +64,7 @@ struct Timer {
char *stamp_path;
};

#define TIMER_MONOTONIC_CLOCK(t) ((t)->wake_system && clock_boottime_supported() ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC)
#define TIMER_MONOTONIC_CLOCK(t) ((t)->wake_system ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC)

void timer_free_values(Timer *t);

Expand Down
2 changes: 1 addition & 1 deletion src/import/curl-util.c
Expand Up @@ -148,7 +148,7 @@ static int curl_glue_timer_callback(CURLM *curl, long timeout_ms, void *userdata
if (sd_event_source_set_enabled(g->timer, SD_EVENT_ONESHOT) < 0)
return -1;
} else {
if (sd_event_add_time_relative(g->event, &g->timer, clock_boottime_or_monotonic(), usec, 0, curl_glue_on_timer, g) < 0)
if (sd_event_add_time_relative(g->event, &g->timer, CLOCK_BOOTTIME, usec, 0, curl_glue_on_timer, g) < 0)
return -1;

(void) sd_event_source_set_description(g->timer, "curl-timer");
Expand Down
4 changes: 2 additions & 2 deletions src/libsystemd-network/lldp-neighbor.c
Expand Up @@ -333,9 +333,9 @@ void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) {
usec_t base;

/* Use the packet's timestamp if there is one known */
base = triple_timestamp_by_clock(&n->timestamp, clock_boottime_or_monotonic());
base = triple_timestamp_by_clock(&n->timestamp, CLOCK_BOOTTIME);
if (!timestamp_is_set(base))
base = now(clock_boottime_or_monotonic()); /* Otherwise, take the current time */
base = now(CLOCK_BOOTTIME); /* Otherwise, take the current time */

n->until = usec_add(base, n->ttl * USEC_PER_SEC);
} else
Expand Down
22 changes: 11 additions & 11 deletions src/libsystemd-network/sd-dhcp-client.c
Expand Up @@ -821,7 +821,7 @@ static int client_message_init(

/* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
refuse to issue an DHCP lease if 'secs' is set to zero */
r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
return r;
assert(time_now >= client->start_time);
Expand Down Expand Up @@ -1246,7 +1246,7 @@ static int client_timeout_resend(
assert(client);
assert(client->event);

r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
goto error;

Expand Down Expand Up @@ -1294,7 +1294,7 @@ static int client_timeout_resend(
}

r = event_reset_time(client->event, &client->timeout_resend,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
next_timeout, 10 * USEC_PER_MSEC,
client_timeout_resend, client,
client->event_priority, "dhcp4-resend-timer", true);
Expand Down Expand Up @@ -1394,12 +1394,12 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
assert(client->event);

if (client->start_delay > 0) {
assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
assert_se(sd_event_now(client->event, CLOCK_BOOTTIME, &usec) >= 0);
usec += client->start_delay;
}

r = event_reset_time(client->event, &client->timeout_resend,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
usec, 0,
client_timeout_resend, client,
client->event_priority, "dhcp4-resend-timer", true);
Expand Down Expand Up @@ -1440,7 +1440,7 @@ static int client_start_delayed(sd_dhcp_client *client) {
client->fd = r;

if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
client->start_time = now(clock_boottime_or_monotonic());
client->start_time = now(CLOCK_BOOTTIME);

return client_initialize_events(client, client_receive_message_raw);
}
Expand Down Expand Up @@ -1684,7 +1684,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
return 0;
}

r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
return r;
assert(client->request_sent <= time_now);
Expand Down Expand Up @@ -1717,7 +1717,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {

/* arm lifetime timeout */
r = event_reset_time(client->event, &client->timeout_expire,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
client->expire_time, 10 * USEC_PER_MSEC,
client_timeout_expire, client,
client->event_priority, "dhcp4-lifetime", true);
Expand All @@ -1733,7 +1733,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {

/* arm T2 timeout */
r = event_reset_time(client->event, &client->timeout_t2,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
client->t2_time, 10 * USEC_PER_MSEC,
client_timeout_t2, client,
client->event_priority, "dhcp4-t2-timeout", true);
Expand All @@ -1749,7 +1749,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {

/* arm T1 timeout */
r = event_reset_time(client->event, &client->timeout_t1,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
client->t1_time, 10 * USEC_PER_MSEC,
client_timeout_t1, client,
client->event_priority, "dhcp4-t1-timer", true);
Expand Down Expand Up @@ -1784,7 +1784,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client->attempt = 0;

r = event_reset_time(client->event, &client->timeout_resend,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
0, 0,
client_timeout_resend, client,
client->event_priority, "dhcp4-resend-timer", true);
Expand Down
4 changes: 2 additions & 2 deletions src/libsystemd-network/sd-dhcp-server.c
Expand Up @@ -987,7 +987,7 @@ static int server_ack_request(sd_dhcp_server *server, DHCPRequest *req, DHCPLeas
assert(req);
assert(address != 0);

r = sd_event_now(server->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(server->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
return r;

Expand Down Expand Up @@ -1039,7 +1039,7 @@ static int dhcp_server_cleanup_expired_leases(sd_dhcp_server *server) {

assert(server);

r = sd_event_now(server->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(server->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
return r;

Expand Down
14 changes: 7 additions & 7 deletions src/libsystemd-network/sd-dhcp6-client.c
Expand Up @@ -649,7 +649,7 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
assert(client);
assert(client->event);

r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
if (r < 0)
return r;

Expand Down Expand Up @@ -830,7 +830,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
FORMAT_TIMESPAN(client->retransmit_time, USEC_PER_SEC));

r = event_reset_time_relative(client->event, &client->timeout_resend,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
client->retransmit_time, 10 * USEC_PER_MSEC,
client_timeout_resend, client,
client->event_priority, "dhcp6-resend-timer", true);
Expand Down Expand Up @@ -872,12 +872,12 @@ static int client_start_transaction(sd_dhcp6_client *client, DHCP6State state) {
client->retransmit_count = 0;
client->transaction_id = random_u32() & htobe32(0x00ffffff);

r = sd_event_now(client->event, clock_boottime_or_monotonic(), &client->transaction_start);
r = sd_event_now(client->event, CLOCK_BOOTTIME, &client->transaction_start);
if (r < 0)
goto error;

r = event_reset_time(client->event, &client->timeout_resend,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
0, 0,
client_timeout_resend, client,
client->event_priority, "dhcp6-resend-timeout", true);
Expand Down Expand Up @@ -969,7 +969,7 @@ static int client_enter_bound_state(sd_dhcp6_client *client) {
} else {
log_dhcp6_client(client, "T1 expires in %s", FORMAT_TIMESPAN(lifetime_t1, USEC_PER_SEC));
r = event_reset_time_relative(client->event, &client->timeout_t1,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
lifetime_t1, 10 * USEC_PER_SEC,
client_timeout_t1, client,
client->event_priority, "dhcp6-t1-timeout", true);
Expand All @@ -983,7 +983,7 @@ static int client_enter_bound_state(sd_dhcp6_client *client) {
} else {
log_dhcp6_client(client, "T2 expires in %s", FORMAT_TIMESPAN(lifetime_t2, USEC_PER_SEC));
r = event_reset_time_relative(client->event, &client->timeout_t2,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
lifetime_t2, 10 * USEC_PER_SEC,
client_timeout_t2, client,
client->event_priority, "dhcp6-t2-timeout", true);
Expand All @@ -998,7 +998,7 @@ static int client_enter_bound_state(sd_dhcp6_client *client) {
log_dhcp6_client(client, "Valid lifetime expires in %s", FORMAT_TIMESPAN(lifetime_valid, USEC_PER_SEC));

r = event_reset_time_relative(client->event, &client->timeout_expire,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
lifetime_valid, USEC_PER_SEC,
client_timeout_expire, client,
client->event_priority, "dhcp6-lease-expire", true);
Expand Down
6 changes: 3 additions & 3 deletions src/libsystemd-network/sd-ipv4acd.c
Expand Up @@ -200,10 +200,10 @@ static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_u
if (random_usec > 0)
next_timeout += (usec_t) random_u64() % random_usec;

assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
assert_se(sd_event_now(acd->event, CLOCK_BOOTTIME, &time_now) >= 0);

return event_reset_time(acd->event, &acd->timer_event_source,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
time_now + next_timeout, 0,
ipv4acd_on_timeout, acd,
acd->event_priority, "ipv4acd-timer", true);
Expand Down Expand Up @@ -381,7 +381,7 @@ static int ipv4acd_on_packet(
if (ipv4acd_arp_conflict(acd, &packet, true)) {
usec_t ts;

assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &ts) >= 0);
assert_se(sd_event_now(acd->event, CLOCK_BOOTTIME, &ts) >= 0);

/* Defend address */
if (ts > acd->defend_window) {
Expand Down
4 changes: 2 additions & 2 deletions src/libsystemd-network/sd-lldp-rx.c
Expand Up @@ -69,7 +69,7 @@ static int lldp_rx_make_space(sd_lldp_rx *lldp_rx, size_t extra) {
goto remove_one;

if (t == USEC_INFINITY)
t = now(clock_boottime_or_monotonic());
t = now(CLOCK_BOOTTIME);

if (n->until > t)
break;
Expand Down Expand Up @@ -448,7 +448,7 @@ static int lldp_rx_start_timer(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *neighbor)
return event_source_disable(lldp_rx->timer_event_source);

return event_reset_time(lldp_rx->event, &lldp_rx->timer_event_source,
clock_boottime_or_monotonic(),
CLOCK_BOOTTIME,
n->until, 0,
on_timer_event, lldp_rx,
lldp_rx->event_priority, "lldp-rx-timer", true);
Expand Down
2 changes: 1 addition & 1 deletion src/libsystemd-network/sd-lldp-tx.c
Expand Up @@ -609,7 +609,7 @@ int sd_lldp_tx_start(sd_lldp_tx *lldp_tx) {
delay = lldp_tx_get_delay(lldp_tx);

r = sd_event_add_time_relative(lldp_tx->event, &lldp_tx->timer_event_source,
clock_boottime_or_monotonic(), delay, 0,
CLOCK_BOOTTIME, delay, 0,
on_timer_event, lldp_tx);
if (r < 0)
return r;
Expand Down

0 comments on commit ba4e042

Please sign in to comment.