chiark / gitweb /
journal: fix iteration through journal if one file is corrupt
[elogind.git] / src / journal / sd-journal.c
index 4f3f1b5ff393aede86ecc858503c642c53af545d..75884594a19346819e683748d2fb65e6e6f2288d 100644 (file)
@@ -115,8 +115,17 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
                 return -EINVAL;
         if (!data)
                 return -EINVAL;
-        if (size <= 0)
+        if (size <= 1)
                 return -EINVAL;
+        if (!memchr(data, '=', size))
+                return -EINVAL;
+        if (*(char*) data == '=')
+                return -EINVAL;
+
+        /* FIXME: iterating with multiple matches is currently
+         * broken */
+        if (j->matches)
+                return -ENOTSUP;
 
         le_hash = htole64(hash64(data, size));
 
@@ -661,9 +670,10 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                 bool found;
 
                 r = next_beyond_location(j, f, direction, &o, &p);
-                if (r < 0)
-                        return r;
-                else if (r == 0)
+                if (r < 0) {
+                        log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r));
+                        continue;
+                } else if (r == 0)
                         continue;
 
                 if (!new_current)
@@ -934,7 +944,8 @@ static int add_file(sd_journal *j, const char *prefix, const char *dir, const ch
         assert(filename);
 
         if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) &&
-            !startswith(filename, "system.journal"))
+            !(streq(filename, "system.journal") ||
+             (startswith(filename, "system@") && endswith(filename, ".journal"))))
                 return 0;
 
         if (dir)
@@ -1611,6 +1622,81 @@ _public_ int sd_journal_process(sd_journal *j) {
         }
 }
 
+_public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to) {
+        Iterator i;
+        JournalFile *f;
+        bool first = true;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!from && !to)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                usec_t fr, t;
+
+                r = journal_file_get_cutoff_realtime_usec(f, &fr, &t);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
+
+                if (first) {
+                        if (from)
+                                *from = fr;
+                        if (to)
+                                *to = t;
+                        first = false;
+                } else {
+                        if (from)
+                                *from = MIN(fr, *from);
+                        if (to)
+                                *to = MIN(t, *to);
+                }
+        }
+
+        return first ? 0 : 1;
+}
+
+_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) {
+        Iterator i;
+        JournalFile *f;
+        bool first = true;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!from && !to)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                usec_t fr, t;
+
+                r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
+
+                if (first) {
+                        if (from)
+                                *from = fr;
+                        if (to)
+                                *to = t;
+                        first = false;
+                } else {
+                        if (from)
+                                *from = MIN(fr, *from);
+                        if (to)
+                                *to = MIN(t, *to);
+                }
+        }
+
+        return first ? 0 : 1;
+}
+
+
 /* _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { */
 /*         if (!j) */
 /*                 return -EINVAL; */