chiark / gitweb /
journal: expose and make use of cutoff times of journal
[elogind.git] / src / journal / journal-file.c
index 8f301b87f9c62d1ddd4c8e676bf07d3429db8e44..73420d9c1b17530cd7aecb07d04702026d3addb7 100644 (file)
@@ -183,6 +183,7 @@ static int journal_file_verify_header(JournalFile *f) {
 
                 if (state == STATE_ONLINE)
                         log_debug("Journal file %s is already online. Assuming unclean closing. Ignoring.", f->path);
+                        /* FIXME: immediately rotate */
                 else if (state == STATE_ARCHIVED)
                         return -ESHUTDOWN;
                 else if (state != STATE_OFFLINE)
@@ -596,7 +597,7 @@ static int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, ui
         o->data.n_entries = 0;
 
         h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem));
-        p = le64toh(f->data_hash_table[h].head_hash_offset);
+        p = le64toh(f->data_hash_table[h].tail_hash_offset);
         if (p == 0) {
                 /* Only entry in the hash table is easy */
                 f->data_hash_table[h].head_hash_offset = htole64(offset);
@@ -2284,3 +2285,74 @@ void journal_default_metrics(JournalMetrics *m, int fd) {
                  format_bytes(c, sizeof(c), m->min_size),
                  format_bytes(d, sizeof(d), m->keep_free));
 }
+
+int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(from || to);
+
+        if (from) {
+                r = journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, NULL);
+                if (r <= 0)
+                        return r;
+
+                *from = le64toh(o->entry.realtime);
+        }
+
+        if (to) {
+                r = journal_file_next_entry(f, NULL, 0, DIRECTION_UP, &o, NULL);
+                if (r <= 0)
+                        return r;
+
+                *to = le64toh(o->entry.realtime);
+        }
+
+        return 1;
+}
+
+int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) {
+        char t[9+32+1] = "_BOOT_ID=";
+        Object *o;
+        uint64_t p;
+        int r;
+
+        assert(f);
+        assert(from || to);
+
+        sd_id128_to_string(boot_id, t + 9);
+
+        r = journal_file_find_data_object(f, t, strlen(t), &o, &p);
+        if (r <= 0)
+                return r;
+
+        if (le64toh(o->data.n_entries) <= 0)
+                return 0;
+
+        if (from) {
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, le64toh(o->data.entry_offset), &o);
+                if (r < 0)
+                        return r;
+
+                *from = le64toh(o->entry.monotonic);
+        }
+
+        if (to) {
+                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (r < 0)
+                        return r;
+
+                r = generic_array_get_plus_one(f,
+                                               le64toh(o->data.entry_offset),
+                                               le64toh(o->data.entry_array_offset),
+                                               le64toh(o->data.n_entries)-1,
+                                               &o, NULL);
+                if (r <= 0)
+                        return r;
+
+                *to = le64toh(o->entry.monotonic);
+        }
+
+        return 1;
+}