summaryrefslogtreecommitdiff
path: root/src/core/socket.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-10-26 17:39:14 +0100
committerLennart Poettering <lennart@poettering.net>2020-10-27 14:12:39 +0100
commit9b1915256cb33940a72a7c39444ebac7f906603b (patch)
tree5c1bea58246c3918e2067c3c3b7803b87157a318 /src/core/socket.c
parenta2b06dbe15871f41deb107ee30a784e8a1ceb951 (diff)
downloadsystemd-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.c46
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),