mirror of
https://github.com/home-assistant/operating-system.git
synced 2025-07-18 10:36:32 +00:00
Fix journal-gatewayd returning duplicated lines when following logs (#4124)
When following logs in Home Assitant frontend, the last line may be duplicated over time when no new lines are added. This is because systemd-journal-gatewayd incorrectly processed the num_skip part of the Range header, always returning the last entry even when it should have been skipped. Backport the patch for Systemd that processes the header correctly. Fixes #4101
This commit is contained in:
parent
42a5e6becb
commit
4a4da64f31
@ -0,0 +1,73 @@
|
|||||||
|
From 56e744bc45713ef7575032cfdb20073013ec0a8d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= <sairon@sairon.cz>
|
||||||
|
Date: Tue, 24 Jun 2025 18:54:44 +0200
|
||||||
|
Subject: [PATCH] journal-gatewayd: fix handling of num_skip pointing beyond
|
||||||
|
the last entry
|
||||||
|
|
||||||
|
When `num_skip` is supplied to the `Range` header, journal-gatewayd
|
||||||
|
always returns the very last record even though it should have been
|
||||||
|
skipped. This is because the `sd_journal_next_skip` always returns
|
||||||
|
non-zero value on the first call, leading to one iteration of the
|
||||||
|
`request_reader_entries` returning the last record.
|
||||||
|
|
||||||
|
To avoid this unexpected behavior, check that the number of lines we
|
||||||
|
have skipped by is not lower than the requested skip value. If it is,
|
||||||
|
then it means there are lines which should not be returned now -
|
||||||
|
decrement the n_skip counter then and return from the function, closing
|
||||||
|
the stream if follow flag is not set.
|
||||||
|
|
||||||
|
Fixes #37954
|
||||||
|
---
|
||||||
|
(Backported for v256.x)
|
||||||
|
Signed-off-by: Jan Čermák <sairon@sairon.cz>
|
||||||
|
Upstream: https://github.com/systemd/systemd/pull/37955
|
||||||
|
---
|
||||||
|
src/journal-remote/journal-gatewayd.c | 16 ++++++++++++++--
|
||||||
|
test/units/TEST-04-JOURNAL.journal-gatewayd.sh | 6 ++++++
|
||||||
|
2 files changed, 20 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
|
||||||
|
index 0661ecb1cf..5bce48d485 100644
|
||||||
|
--- a/src/journal-remote/journal-gatewayd.c
|
||||||
|
+++ b/src/journal-remote/journal-gatewayd.c
|
||||||
|
@@ -181,9 +181,21 @@ static ssize_t request_reader_entries(
|
||||||
|
|
||||||
|
if (m->n_skip < 0)
|
||||||
|
r = sd_journal_previous_skip(m->journal, (uint64_t) -m->n_skip + 1);
|
||||||
|
- else if (m->n_skip > 0)
|
||||||
|
+ else if (m->n_skip > 0) {
|
||||||
|
r = sd_journal_next_skip(m->journal, (uint64_t) m->n_skip + 1);
|
||||||
|
- else
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_error_errno(r, "Failed to skip journal entries: %m");
|
||||||
|
+ return MHD_CONTENT_READER_END_WITH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ /* We skipped beyond the end, make sure entries between the cursor and n_skip offset
|
||||||
|
+ * from it are not returned. */
|
||||||
|
+ if (r < m->n_skip + 1) {
|
||||||
|
+ m->n_skip -= r;
|
||||||
|
+ if (m->follow)
|
||||||
|
+ return 0;
|
||||||
|
+ return MHD_CONTENT_READER_END_OF_STREAM;
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
r = sd_journal_next(m->journal);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
diff --git a/test/units/TEST-04-JOURNAL.journal-gatewayd.sh b/test/units/TEST-04-JOURNAL.journal-gatewayd.sh
|
||||||
|
index ef85dc17c6..b6dc860b63 100755
|
||||||
|
--- a/test/units/TEST-04-JOURNAL.journal-gatewayd.sh
|
||||||
|
+++ b/test/units/TEST-04-JOURNAL.journal-gatewayd.sh
|
||||||
|
@@ -82,6 +82,12 @@ timeout 5 curl -LSfs \
|
||||||
|
--header "Range: entries=:-20:10" \
|
||||||
|
http://localhost:19531/entries?follow >"$LOG_FILE"
|
||||||
|
jq -se "length == 10" "$LOG_FILE"
|
||||||
|
+# Test positive skip beyond the last entry
|
||||||
|
+curl -LSfs \
|
||||||
|
+ --header "Accept: application/json" \
|
||||||
|
+ --header "Range: entries=$TEST_CURSOR:1:1" \
|
||||||
|
+ http://localhost:19531/entries?SYSLOG_IDENTIFIER="$TEST_TAG" >"$LOG_FILE"
|
||||||
|
+jq -se "length == 0" "$LOG_FILE"
|
||||||
|
# Check if the specified cursor refers to an existing entry and return just that entry
|
||||||
|
curl -LSfs \
|
||||||
|
--header "Accept: application/json" \
|
Loading…
x
Reference in New Issue
Block a user