]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-journal: re-read object on next try
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 Oct 2022 07:08:57 +0000 (16:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 Oct 2022 10:32:59 +0000 (19:32 +0900)
Otherwise, the object may be already altered by another cached entry.

src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/sd-journal.c

index ca5f5c9fccf144601bead3406402b9735f86f2c7..54bad925b2af28091c7b448c3d5e716e51b06450 100644 (file)
@@ -4000,7 +4000,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
                 r = journal_file_data_payload(from, NULL, q, NULL, 0, 0, &data, &l);
                 if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                         log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
-                        continue;
+                        goto next;
                 }
                 if (r < 0)
                         return r;
@@ -4023,6 +4023,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
                         .hash = le64toh(u->data.hash),
                 };
 
+        next:
                 /* The above journal_file_data_payload() may clear or overwrite cached object. Hence, we need
                  * to re-read the object from the cache. */
                 r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o);
index 5a75994d1594d016e8dcae097cda819b906f5495..53c0b2a01e93f6b2baf86afca650f6c4d6825f0e 100644 (file)
@@ -2264,8 +2264,8 @@ static bool field_is_valid(const char *field) {
 _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
         JournalFile *f;
         size_t field_length;
-        int r;
         Object *o;
+        int r;
 
         assert_return(j, -EINVAL);
         assert_return(!journal_pid_changed(j), -ECHILD);
@@ -2296,10 +2296,10 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
                 p = journal_file_entry_item_object_offset(f, o, i);
                 r = journal_file_data_payload(f, NULL, p, field, field_length, j->data_threshold, &d, &l);
                 if (r == 0)
-                        continue;
+                        goto next;
                 if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                         log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
-                        continue;
+                        goto next;
                 }
                 if (r < 0)
                         return r;
@@ -2308,6 +2308,12 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
                 *size = l;
 
                 return 0;
+
+        next:
+                /* journal_file_data_payload() may clear or overwrite cached object. */
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+                if (r < 0)
+                        return r;
         }
 
         return -ENOENT;
@@ -2343,7 +2349,7 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
                 r = journal_file_data_payload(f, NULL, p, NULL, 0, j->data_threshold, &d, &l);
                 if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                         log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", j->current_field);
-                        continue;
+                        goto next;
                 }
                 if (r < 0)
                         return r;
@@ -2355,6 +2361,12 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
                 j->current_field++;
 
                 return 1;
+
+        next:
+                /* journal_file_data_payload() may clear or overwrite cached object. */
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+                if (r < 0)
+                        return r;
         }
 
         return 0;