summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2024-06-18 17:27:36 +0200
committerGitHub <noreply@github.com>2024-06-18 17:27:36 +0200
commit07748c53df5a72111d8b3eef49d275210d6018cd (patch)
tree2c71433e22be94d1c57c57b4e0d6cbe40c4bcc8d
parentrepart: fix memory leak (diff)
parentlogs-show: use _SOURCE_MONOTONIC_TIMESTAMP when _SOURCE_BOOTTIME_TIMESTAMP fi... (diff)
downloadsystemd-07748c53df5a72111d8b3eef49d275210d6018cd.tar.xz
systemd-07748c53df5a72111d8b3eef49d275210d6018cd.zip
Merge pull request #33386 from yuwata/journal-timestamp
journal: fix _SOURCE_MONOTONIC_TIMESTAMP field
-rw-r--r--src/journal/journald-kmsg.c14
-rw-r--r--src/libsystemd/sd-journal/journal-def.h6
-rw-r--r--src/shared/logs-show.c26
3 files changed, 34 insertions, 12 deletions
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index 78f6e1fef3..4123fda5f9 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -253,9 +253,17 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
}
}
- char source_time[STRLEN("_SOURCE_MONOTONIC_TIMESTAMP=") + DECIMAL_STR_MAX(unsigned long long)];
- xsprintf(source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec);
- iovec[n++] = IOVEC_MAKE_STRING(source_time);
+ char source_boot_time[STRLEN("_SOURCE_BOOTTIME_TIMESTAMP=") + DECIMAL_STR_MAX(unsigned long long)];
+ xsprintf(source_boot_time, "_SOURCE_BOOTTIME_TIMESTAMP=%llu", usec);
+ iovec[n++] = IOVEC_MAKE_STRING(source_boot_time);
+
+ /* Historically, we stored the timestamp 'usec' as _SOURCE_MONOTONIC_TIMESTAMP, so we cannot remove
+ * the field as it is already used in other projects. So, let's store the correct timestamp here by
+ * mapping the boottime to monotonic. Then, the existence of _SOURCE_BOOTTIME_TIMESTAMP indicates
+ * the reliability of _SOURCE_MONOTONIC_TIMESTAMP field. */
+ char source_monotonic_time[STRLEN("_SOURCE_MONOTONIC_TIMESTAMP=") + DECIMAL_STR_MAX(unsigned long long)];
+ xsprintf(source_monotonic_time, "_SOURCE_MONOTONIC_TIMESTAMP="USEC_FMT, map_clock_usec(usec, CLOCK_BOOTTIME, CLOCK_MONOTONIC));
+ iovec[n++] = IOVEC_MAKE_STRING(source_monotonic_time);
iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=kernel");
diff --git a/src/libsystemd/sd-journal/journal-def.h b/src/libsystemd/sd-journal/journal-def.h
index 1b10f24aa9..c972fe98ce 100644
--- a/src/libsystemd/sd-journal/journal-def.h
+++ b/src/libsystemd/sd-journal/journal-def.h
@@ -44,9 +44,9 @@ typedef enum ObjectType {
/* Object flags (note that src/basic/compress.h uses the same values for the compression types) */
enum {
- OBJECT_COMPRESSED_XZ = 1 << 0,
- OBJECT_COMPRESSED_LZ4 = 1 << 1,
- OBJECT_COMPRESSED_ZSTD = 1 << 2,
+ OBJECT_COMPRESSED_XZ = 1 << 0,
+ OBJECT_COMPRESSED_LZ4 = 1 << 1,
+ OBJECT_COMPRESSED_ZSTD = 1 << 2,
_OBJECT_COMPRESSED_MASK = OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD,
};
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index e122a4b111..34f9411fcf 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -443,6 +443,7 @@ static void parse_display_realtime(
sd_journal *j,
const char *source_realtime,
const char *source_monotonic,
+ const char *source_boottime,
usec_t *ret) {
usec_t t, s, u;
@@ -450,6 +451,11 @@ static void parse_display_realtime(
assert(j);
assert(ret);
+ if (!source_boottime)
+ /* _SOURCE_MONOTONIC_TIMESTAMP field is usable only when _SOURCE_BOOTTIME_TIMESTAMP exists,
+ * as previously the timestamp was in CLOCK_BOOTTIME. */
+ source_monotonic = NULL;
+
/* First, try _SOURCE_REALTIME_TIMESTAMP. */
if (source_realtime && safe_atou64(source_realtime, &t) >= 0 && VALID_REALTIME(t)) {
*ret = t;
@@ -477,6 +483,7 @@ static void parse_display_timestamp(
sd_journal *j,
const char *source_realtime,
const char *source_monotonic,
+ const char *source_boottime,
dual_timestamp *ret_display_ts,
sd_id128_t *ret_boot_id) {
@@ -488,6 +495,11 @@ static void parse_display_timestamp(
assert(ret_display_ts);
assert(ret_boot_id);
+ if (!source_boottime)
+ /* _SOURCE_MONOTONIC_TIMESTAMP field is usable only when _SOURCE_BOOTTIME_TIMESTAMP exists,
+ * as previously the timestamp was in CLOCK_BOOTTIME. */
+ source_monotonic = NULL;
+
if (source_realtime && safe_atou64(source_realtime, &t) >= 0 && VALID_REALTIME(t))
source_ts.realtime = t;
@@ -527,7 +539,7 @@ static int output_short(
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL,
*message = NULL, *priority = NULL, *transport = NULL,
*config_file = NULL, *unit = NULL, *user_unit = NULL, *documentation_url = NULL,
- *realtime = NULL, *monotonic = NULL;
+ *realtime = NULL, *monotonic = NULL, *boottime = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0,
priority_len = 0, transport_len = 0, config_file_len = 0,
unit_len = 0, user_unit_len = 0, documentation_url_len = 0;
@@ -550,6 +562,7 @@ static int output_short(
PARSE_FIELD_VEC_ENTRY("DOCUMENTATION=", &documentation_url, &documentation_url_len),
PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, NULL ),
PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, NULL ),
+ PARSE_FIELD_VEC_ENTRY("_SOURCE_BOOTTIME_TIMESTAMP=", &boottime, NULL ),
};
size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0};
@@ -596,11 +609,11 @@ static int output_short(
audit = streq_ptr(transport, "audit");
if (IN_SET(mode, OUTPUT_SHORT_MONOTONIC, OUTPUT_SHORT_DELTA)) {
- parse_display_timestamp(j, realtime, monotonic, &display_ts, &boot_id);
+ parse_display_timestamp(j, realtime, monotonic, boottime, &display_ts, &boot_id);
r = output_timestamp_monotonic(f, mode, &display_ts, &boot_id, previous_display_ts, previous_boot_id);
} else {
usec_t usec;
- parse_display_realtime(j, realtime, monotonic, &usec);
+ parse_display_realtime(j, realtime, monotonic, boottime, &usec);
r = output_timestamp_realtime(f, j, mode, flags, usec);
}
if (r < 0)
@@ -733,11 +746,12 @@ static int output_short(
static int get_display_realtime(sd_journal *j, usec_t *ret) {
const void *data;
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *boottime = NULL;
size_t length;
const ParseFieldVec message_fields[] = {
PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, NULL),
PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, NULL),
+ PARSE_FIELD_VEC_ENTRY("_SOURCE_BOOTTIME_TIMESTAMP=", &boottime, NULL),
};
int r;
@@ -749,13 +763,13 @@ static int get_display_realtime(sd_journal *j, usec_t *ret) {
if (r < 0)
return r;
- if (realtime && monotonic)
+ if (realtime && monotonic && boottime)
break;
}
if (r < 0)
return r;
- (void) parse_display_realtime(j, realtime, monotonic, ret);
+ (void) parse_display_realtime(j, realtime, monotonic, boottime, ret);
/* Restart all data before */
sd_journal_restart_data(j);