Zbigniew Jędrzejewski-Szmek f1004d
From 360af4cf6f18469df97c11af4cd5696e0ca8b3ef Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek f1004d
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek f1004d
Date: Thu, 9 Oct 2014 22:44:29 -0400
Zbigniew Jędrzejewski-Szmek f1004d
Subject: [PATCH] sd-journal: do not reset sd_j_enumerate_unique position on
Zbigniew Jędrzejewski-Szmek f1004d
 error
Zbigniew Jędrzejewski-Szmek f1004d
Zbigniew Jędrzejewski-Szmek f1004d
systemctl would call sd_j_enumerate_unique() interleaved with
Zbigniew Jędrzejewski-Szmek f1004d
sd_j_next(). But the latter can remove a file if it detects an
Zbigniew Jędrzejewski-Szmek f1004d
error in it. In those circumstances sd_j_enumerate_unique would
Zbigniew Jędrzejewski-Szmek f1004d
restart with the first file in hashmap. With many corrupted files
Zbigniew Jędrzejewski-Szmek f1004d
sd_j_enumerate_unique might iterate over the list multiple times.
Zbigniew Jędrzejewski-Szmek f1004d
Zbigniew Jędrzejewski-Szmek f1004d
Avoid this by jumping to the next file in unique list if possible,
Zbigniew Jędrzejewski-Szmek f1004d
or setting a flag that tells sd_j_enumerate_unique that it is done
Zbigniew Jędrzejewski-Szmek f1004d
otherwise.
Zbigniew Jędrzejewski-Szmek f1004d
---
Zbigniew Jędrzejewski-Szmek f1004d
 src/journal/journal-internal.h |  4 ++++
Zbigniew Jędrzejewski-Szmek f1004d
 src/journal/sd-journal.c       | 18 ++++++++++++------
Zbigniew Jędrzejewski-Szmek f1004d
 2 files changed, 16 insertions(+), 6 deletions(-)
Zbigniew Jędrzejewski-Szmek f1004d
Zbigniew Jędrzejewski-Szmek f1004d
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
Zbigniew Jędrzejewski-Szmek f1004d
index 2f1f7fc771..e591fb61f8 100644
Zbigniew Jędrzejewski-Szmek f1004d
--- a/src/journal/journal-internal.h
Zbigniew Jędrzejewski-Szmek f1004d
+++ b/src/journal/journal-internal.h
Zbigniew Jędrzejewski-Szmek f1004d
@@ -124,6 +124,10 @@ struct sd_journal {
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         bool on_network;
Zbigniew Jędrzejewski-Szmek f1004d
         bool no_new_files;
Zbigniew Jędrzejewski-Szmek f1004d
+        bool unique_file_lost; /* File we were iterating over got
Zbigniew Jędrzejewski-Szmek f1004d
+                                  removed, and there were no more
Zbigniew Jędrzejewski-Szmek f1004d
+                                  files, so sd_j_enumerate_unique
Zbigniew Jędrzejewski-Szmek f1004d
+                                  will return a value equal to 0. */
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         size_t data_threshold;
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek f1004d
index 1fc9f01d0a..b72a0867e7 100644
Zbigniew Jędrzejewski-Szmek f1004d
--- a/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek f1004d
+++ b/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek f1004d
@@ -1375,8 +1375,11 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
Zbigniew Jędrzejewski-Szmek f1004d
         }
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         if (j->unique_file == f) {
Zbigniew Jędrzejewski-Szmek f1004d
-                j->unique_file = NULL;
Zbigniew Jędrzejewski-Szmek f1004d
+                /* Jump to the next unique_file or NULL if that one was last */
Zbigniew Jędrzejewski-Szmek f1004d
+                j->unique_file = hashmap_next(j->files, j->unique_file->path);
Zbigniew Jędrzejewski-Szmek f1004d
                 j->unique_offset = 0;
Zbigniew Jędrzejewski-Szmek f1004d
+                if (!j->unique_file)
Zbigniew Jędrzejewski-Szmek f1004d
+                        j->unique_file_lost = true;
Zbigniew Jędrzejewski-Szmek f1004d
         }
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         journal_file_close(f);
Zbigniew Jędrzejewski-Szmek f1004d
@@ -2490,6 +2493,7 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) {
Zbigniew Jędrzejewski-Szmek f1004d
         j->unique_field = f;
Zbigniew Jędrzejewski-Szmek f1004d
         j->unique_file = NULL;
Zbigniew Jędrzejewski-Szmek f1004d
         j->unique_offset = 0;
Zbigniew Jędrzejewski-Szmek f1004d
+        j->unique_file_lost = false;
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         return 0;
Zbigniew Jędrzejewski-Szmek f1004d
 }
Zbigniew Jędrzejewski-Szmek f1004d
@@ -2506,9 +2510,13 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
Zbigniew Jędrzejewski-Szmek f1004d
         k = strlen(j->unique_field);
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         if (!j->unique_file) {
Zbigniew Jędrzejewski-Szmek f1004d
+                if (j->unique_file_lost)
Zbigniew Jędrzejewski-Szmek f1004d
+                        return 0;
Zbigniew Jędrzejewski-Szmek f1004d
+
Zbigniew Jędrzejewski-Szmek f1004d
                 j->unique_file = hashmap_first(j->files);
Zbigniew Jędrzejewski-Szmek f1004d
                 if (!j->unique_file)
Zbigniew Jędrzejewski-Szmek f1004d
                         return 0;
Zbigniew Jędrzejewski-Szmek f1004d
+
Zbigniew Jędrzejewski-Szmek f1004d
                 j->unique_offset = 0;
Zbigniew Jędrzejewski-Szmek f1004d
         }
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
@@ -2538,13 +2546,10 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
                 /* We reached the end of the list? Then start again, with the next file */
Zbigniew Jędrzejewski-Szmek f1004d
                 if (j->unique_offset == 0) {
Zbigniew Jędrzejewski-Szmek f1004d
-                        JournalFile *n;
Zbigniew Jędrzejewski-Szmek f1004d
-
Zbigniew Jędrzejewski-Szmek f1004d
-                        n = hashmap_next(j->files, j->unique_file->path);
Zbigniew Jędrzejewski-Szmek f1004d
-                        if (!n)
Zbigniew Jędrzejewski-Szmek f1004d
+                        j->unique_file = hashmap_next(j->files, j->unique_file->path);
Zbigniew Jędrzejewski-Szmek f1004d
+                        if (!j->unique_file)
Zbigniew Jędrzejewski-Szmek f1004d
                                 return 0;
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
-                        j->unique_file = n;
Zbigniew Jędrzejewski-Szmek f1004d
                         continue;
Zbigniew Jędrzejewski-Szmek f1004d
                 }
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
@@ -2632,6 +2637,7 @@ _public_ void sd_journal_restart_unique(sd_journal *j) {
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
         j->unique_file = NULL;
Zbigniew Jędrzejewski-Szmek f1004d
         j->unique_offset = 0;
Zbigniew Jędrzejewski-Szmek f1004d
+        j->unique_file_lost = false;
Zbigniew Jędrzejewski-Szmek f1004d
 }
Zbigniew Jędrzejewski-Szmek f1004d
 
Zbigniew Jędrzejewski-Szmek f1004d
 _public_ int sd_journal_reliable_fd(sd_journal *j) {