diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-10-26 17:39:14 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-10-27 14:12:39 +0100 |
commit | 9b1915256cb33940a72a7c39444ebac7f906603b (patch) | |
tree | 5c1bea58246c3918e2067c3c3b7803b87157a318 /src/core/socket.c | |
parent | a2b06dbe15871f41deb107ee30a784e8a1ceb951 (diff) | |
download | systemd-9b1915256cb33940a72a7c39444ebac7f906603b.tar.gz |
core: add Timestamping= option for socket units
This adds a way to control SO_TIMESTAMP/SO_TIMESTAMPNS socket options
for sockets PID 1 binds to.
This is useful in journald so that we get proper timestamps even for
ingress log messages that are submitted before journald is running.
We recently turned on packet info metadata from PID 1 for these sockets,
but the timestamping info was still missing. Let's correct that.
Diffstat (limited to 'src/core/socket.c')
-rw-r--r-- | src/core/socket.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/core/socket.c b/src/core/socket.c index f71fa34300..f045eed5b5 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -629,6 +629,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { prefix, socket_fdname(s), prefix, yes_no(s->selinux_context_from_net)); + if (s->timestamping != SOCKET_TIMESTAMPING_OFF) + fprintf(f, + "%sTimestamping: %s\n", + prefix, socket_timestamping_to_string(s->timestamping)); + if (s->control_pid > 0) fprintf(f, "%sControl PID: "PID_FMT"\n", @@ -1051,6 +1056,14 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) { log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m"); } + if (s->timestamping != SOCKET_TIMESTAMPING_OFF) { + r = setsockopt_int(fd, SOL_SOCKET, + s->timestamping == SOCKET_TIMESTAMPING_NS ? SO_TIMESTAMPNS : SO_TIMESTAMP, + true); + if (r < 0) + log_unit_warning_errno(UNIT(s), r, "Failed to enable timestamping socket option, ignoring: %m"); + } + if (s->priority >= 0) { r = setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY, s->priority); if (r < 0) @@ -3409,6 +3422,39 @@ static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); +static const char* const socket_timestamping_table[_SOCKET_TIMESTAMPING_MAX] = { + [SOCKET_TIMESTAMPING_OFF] = "off", + [SOCKET_TIMESTAMPING_US] = "us", + [SOCKET_TIMESTAMPING_NS] = "ns", +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_timestamping, SocketTimestamping); + +SocketTimestamping socket_timestamping_from_string_harder(const char *p) { + SocketTimestamping t; + int r; + + if (!p) + return _SOCKET_TIMESTAMPING_INVALID; + + t = socket_timestamping_from_string(p); + if (t >= 0) + return t; + + /* Let's alternatively support the various other aliases parse_time() accepts for ns and µs here, + * too. */ + if (streq(p, "nsec")) + return SOCKET_TIMESTAMPING_NS; + if (STR_IN_SET(p, "usec", "µs")) + return SOCKET_TIMESTAMPING_US; + + r = parse_boolean(p); + if (r < 0) + return _SOCKET_TIMESTAMPING_INVALID; + + return r ? SOCKET_TIMESTAMPING_NS : SOCKET_TIMESTAMPING_OFF; /* If boolean yes, default to ns accuracy */ +} + const UnitVTable socket_vtable = { .object_size = sizeof(Socket), .exec_context_offset = offsetof(Socket, exec_context), |