From a81fe186c07163d9380b43d52e7ec79796ae8be4474827e9be5978f404638d56 Mon Sep 17 00:00:00 2001 From: Frederic Crozat Date: Tue, 18 Jun 2013 07:18:53 +0000 Subject: [PATCH] Accepting request 179368 from home:elvigia:branches:Base:System - 0001-journal-letting-interleaved-seqnums-go.patch and 0002-journal-remember-last-direction-of-search-and-keep-o.patch fix possible infinite loops in the journal code, related to bnc #817778 - 0001-journal-letting-interleaved-seqnums-go.patch and 0002-journal-remember-last-direction-of-search-and-keep-o.patch fix possible infinite loops in the journal code, related to bnc #817778 (forwarded request 179367 from elvigia) OBS-URL: https://build.opensuse.org/request/show/179368 OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=396 --- ...urnal-letting-interleaved-seqnums-go.patch | 74 +++++++++++ ...-last-direction-of-search-and-keep-o.patch | 122 ++++++++++++++++++ systemd-mini.changes | 8 ++ systemd-mini.spec | 6 + systemd.changes | 8 ++ systemd.spec | 6 + 6 files changed, 224 insertions(+) create mode 100644 0001-journal-letting-interleaved-seqnums-go.patch create mode 100644 0002-journal-remember-last-direction-of-search-and-keep-o.patch diff --git a/0001-journal-letting-interleaved-seqnums-go.patch b/0001-journal-letting-interleaved-seqnums-go.patch new file mode 100644 index 00000000..a3c6054a --- /dev/null +++ b/0001-journal-letting-interleaved-seqnums-go.patch @@ -0,0 +1,74 @@ +From 53113dc8254cae9a27e321e539d2d876677e61b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Jun 2013 22:01:03 -0400 +Subject: [PATCH] journal: letting (interleaved) seqnums go + +In the following scenario: + server creates system.journal + server creates user-1000.journal +both journals share the same seqnum_id. +Then + server writes to user-1000.journal first, + and server writes to system.journal a bit later, +and everything is fine. +The server then terminates (crash, reboot, rsyslog testing, +whatever), and user-1000.journal has entries which end with +a lower seqnum than system.journal. Now + server is restarted + server opens user-1000.journal and writes entries to it... +BAM! duplicate seqnums for the same seqnum_id. + +Now, we usually don't see that happen, because system.journal +is closed last, and opened first. Since usually at least one +message is written during boot and lands in the system.journal, +the seqnum is initialized from it, and is set to a number higher +than than anything found in user journals. Nevertheless, if +system.journal is corrupted and is rotated, it can happen that +an entry is written to the user journal with a seqnum that is +a duplicate with an entry found in the corrupted system.journal~. +When browsing the journal, journalctl can fall into a loop +where it tries to follow the seqnums, and tries to go the +next location by seqnum, and is transported back in time to +to the older duplicate seqnum. There is not way to find +out the maximum seqnum used in a multiple files, without +actually looking at all of them. But we don't want to do +that because it would be slow, and actually it isn't really +possible, because a file might e.g. be temporarily unaccessible. + +Fix the problem by using different seqnum series for user +journals. Using the same seqnum series for rotated journals +is still fine, because we know that nothing will write +to the rotated journal anymore. + +Likely related: +https://bugs.freedesktop.org/show_bug.cgi?id=64566 +https://bugs.freedesktop.org/show_bug.cgi?id=59856 +https://bugs.freedesktop.org/show_bug.cgi?id=64296 +https://bugs.archlinux.org/task/35581 +https://bugzilla.novell.com/show_bug.cgi?id=817778 + +Possibly related: +https://bugs.freedesktop.org/show_bug.cgi?id=64293 + +Conflicts: + src/journal/journald-server.c +--- + src/journal/journald-server.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index cc52b8a..cde63c8 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -280,7 +280,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { + journal_file_close(f); + } + +- r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f); ++ r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f); + free(p); + + if (r < 0) +-- +1.8.2.1 + diff --git a/0002-journal-remember-last-direction-of-search-and-keep-o.patch b/0002-journal-remember-last-direction-of-search-and-keep-o.patch new file mode 100644 index 00000000..b710d55c --- /dev/null +++ b/0002-journal-remember-last-direction-of-search-and-keep-o.patch @@ -0,0 +1,122 @@ +From 87011c25d96e9fbcd8a465ba758fa037c7d08203 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 6 Jun 2013 22:28:05 -0400 +Subject: [PATCH 01/13] journal: remember last direction of search and keep + offset cache + +The fields in JournalFile are moved around to avoid wasting +7 bytes because of alignment. +--- + TODO | 3 --- + src/journal/journal-file.h | 18 +++++++++++------- + src/journal/sd-journal.c | 11 +++++------ + 3 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/TODO b/TODO +index 0dd19a0..1dc585c 100644 +--- a/TODO ++++ b/TODO +@@ -77,9 +77,6 @@ Features: + + * investigate endianess issues of UUID vs. GUID + +-* see if we can fix https://bugs.freedesktop.org/show_bug.cgi?id=63672 +- without dropping the location cache entirely. +- + * dbus: when a unit failed to load (i.e. is in UNIT_ERROR state), we + should be able to safely try another attempt when the bus call LoadUnit() is invoked. + +diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h +index 7b1cd42..5cc2c2d 100644 +--- a/src/journal/journal-file.h ++++ b/src/journal/journal-file.h +@@ -42,10 +42,14 @@ typedef struct JournalMetrics { + uint64_t keep_free; + } JournalMetrics; + ++typedef enum direction { ++ DIRECTION_UP, ++ DIRECTION_DOWN ++} direction_t; ++ + typedef struct JournalFile { + int fd; +- char *path; +- struct stat last_stat; ++ + mode_t mode; + + int flags; +@@ -56,6 +60,11 @@ typedef struct JournalFile { + + bool tail_entry_monotonic_valid; + ++ direction_t last_direction; ++ ++ char *path; ++ struct stat last_stat; ++ + Header *header; + HashItem *data_hash_table; + HashItem *field_hash_table; +@@ -90,11 +99,6 @@ typedef struct JournalFile { + #endif + } JournalFile; + +-typedef enum direction { +- DIRECTION_UP, +- DIRECTION_DOWN +-} direction_t; +- + int journal_file_open( + const char *fname, + int flags, +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 3aa9ed4..4c4cc2d 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -102,7 +102,8 @@ static void init_location(Location *l, LocationType type, JournalFile *f, Object + l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; + } + +-static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) { ++static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, ++ direction_t direction, uint64_t offset) { + assert(j); + assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK); + assert(f); +@@ -110,12 +111,10 @@ static void set_location(sd_journal *j, LocationType type, JournalFile *f, Objec + + init_location(&j->current_location, type, f, o); + +- if (j->current_file) +- j->current_file->current_offset = 0; +- + j->current_file = f; + j->current_field = 0; + ++ f->last_direction = direction; + f->current_offset = offset; + } + +@@ -811,7 +810,7 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc + assert(j); + assert(f); + +- if (f->current_offset > 0) { ++ if (f->last_direction == direction && f->current_offset > 0) { + cp = f->current_offset; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); +@@ -908,7 +907,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { + if (r < 0) + return r; + +- set_location(j, LOCATION_DISCRETE, new_file, o, new_offset); ++ set_location(j, LOCATION_DISCRETE, new_file, o, direction, new_offset); + + return 1; + } +-- +1.8.2.1 + diff --git a/systemd-mini.changes b/systemd-mini.changes index 10a5bdcc..11123c97 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Jun 18 00:33:10 UTC 2013 - crrodriguez@opensuse.org + +- 0001-journal-letting-interleaved-seqnums-go.patch and + 0002-journal-remember-last-direction-of-search-and-keep-o.patch + fix possible infinite loops in the journal code, related to + bnc #817778 + ------------------------------------------------------------------- Sun Jun 16 23:59:28 UTC 2013 - jengelh@inai.de diff --git a/systemd-mini.spec b/systemd-mini.spec index c66934a2..d1e49afe 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -177,6 +177,10 @@ Patch44: 0004-journald-DO-recalculate-the-ACL-mask-but-only-if-it-.patch Patch45: 0006-systemctl-core-allow-nuking-of-symlinks-to-removed-u.patch # PATCH-FIX-UPSTREAM 0008-service-don-t-report-alien-child-as-alive-when-it-s-.patch crrodriguez@opensuse.org do not report alien child as alive when it is dead. Patch46: 0008-service-don-t-report-alien-child-as-alive-when-it-s-.patch +# PATCH-FIX-UPSTREAM 0001-journal-letting-interleaved-seqnums-go.patch crrodriguez@opensuse.org fix journal infinite loops +Patch47: 0001-journal-letting-interleaved-seqnums-go.patch +# PATCH-FIX-UPSTREAM 0002-journal-remember-last-direction-of-search-and-keep-o.patch crrodriguez@opensuse.org fix journal infinite loops +Patch48: 0002-journal-remember-last-direction-of-search-and-keep-o.patch # udev patches # PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch @@ -410,6 +414,8 @@ cp %{SOURCE7} m4/ %patch44 -p1 %patch45 -p1 %patch46 -p1 +%patch47 -p1 +%patch48 -p1 # udev patches %patch1001 -p1 diff --git a/systemd.changes b/systemd.changes index 10a5bdcc..11123c97 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Jun 18 00:33:10 UTC 2013 - crrodriguez@opensuse.org + +- 0001-journal-letting-interleaved-seqnums-go.patch and + 0002-journal-remember-last-direction-of-search-and-keep-o.patch + fix possible infinite loops in the journal code, related to + bnc #817778 + ------------------------------------------------------------------- Sun Jun 16 23:59:28 UTC 2013 - jengelh@inai.de diff --git a/systemd.spec b/systemd.spec index 23e316da..0c475aa2 100644 --- a/systemd.spec +++ b/systemd.spec @@ -172,6 +172,10 @@ Patch44: 0004-journald-DO-recalculate-the-ACL-mask-but-only-if-it-.patch Patch45: 0006-systemctl-core-allow-nuking-of-symlinks-to-removed-u.patch # PATCH-FIX-UPSTREAM 0008-service-don-t-report-alien-child-as-alive-when-it-s-.patch crrodriguez@opensuse.org do not report alien child as alive when it is dead. Patch46: 0008-service-don-t-report-alien-child-as-alive-when-it-s-.patch +# PATCH-FIX-UPSTREAM 0001-journal-letting-interleaved-seqnums-go.patch crrodriguez@opensuse.org fix journal infinite loops +Patch47: 0001-journal-letting-interleaved-seqnums-go.patch +# PATCH-FIX-UPSTREAM 0002-journal-remember-last-direction-of-search-and-keep-o.patch crrodriguez@opensuse.org fix journal infinite loops +Patch48: 0002-journal-remember-last-direction-of-search-and-keep-o.patch # udev patches # PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch @@ -405,6 +409,8 @@ cp %{SOURCE7} m4/ %patch44 -p1 %patch45 -p1 %patch46 -p1 +%patch47 -p1 +%patch48 -p1 # udev patches %patch1001 -p1