1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "journal-remote.h"
5
do_rotate(ManagedJournalFile ** f,MMapCache * m,JournalFileFlags file_flags)6 static int do_rotate(ManagedJournalFile **f, MMapCache *m, JournalFileFlags file_flags) {
7 int r;
8
9 r = managed_journal_file_rotate(f, m, file_flags, UINT64_MAX, NULL);
10 if (r < 0) {
11 if (*f)
12 log_error_errno(r, "Failed to rotate %s: %m", (*f)->file->path);
13 else
14 log_error_errno(r, "Failed to create rotated journal: %m");
15 }
16
17 return r;
18 }
19
writer_new(RemoteServer * server)20 Writer* writer_new(RemoteServer *server) {
21 Writer *w;
22
23 w = new0(Writer, 1);
24 if (!w)
25 return NULL;
26
27 memset(&w->metrics, 0xFF, sizeof(w->metrics));
28
29 w->mmap = mmap_cache_new();
30 if (!w->mmap)
31 return mfree(w);
32
33 w->n_ref = 1;
34 w->server = server;
35
36 return w;
37 }
38
writer_free(Writer * w)39 static Writer* writer_free(Writer *w) {
40 if (!w)
41 return NULL;
42
43 if (w->journal) {
44 log_debug("Closing journal file %s.", w->journal->file->path);
45 managed_journal_file_close(w->journal);
46 }
47
48 if (w->server && w->hashmap_key)
49 hashmap_remove(w->server->writers, w->hashmap_key);
50
51 free(w->hashmap_key);
52
53 if (w->mmap)
54 mmap_cache_unref(w->mmap);
55
56 return mfree(w);
57 }
58
59 DEFINE_TRIVIAL_REF_UNREF_FUNC(Writer, writer, writer_free);
60
writer_write(Writer * w,const struct iovec_wrapper * iovw,const dual_timestamp * ts,const sd_id128_t * boot_id,JournalFileFlags file_flags)61 int writer_write(Writer *w,
62 const struct iovec_wrapper *iovw,
63 const dual_timestamp *ts,
64 const sd_id128_t *boot_id,
65 JournalFileFlags file_flags) {
66 int r;
67
68 assert(w);
69 assert(iovw);
70 assert(iovw->count > 0);
71
72 if (journal_file_rotate_suggested(w->journal->file, 0, LOG_DEBUG)) {
73 log_info("%s: Journal header limits reached or header out-of-date, rotating",
74 w->journal->file->path);
75 r = do_rotate(&w->journal, w->mmap, file_flags);
76 if (r < 0)
77 return r;
78 }
79
80 r = journal_file_append_entry(w->journal->file, ts, boot_id,
81 iovw->iovec, iovw->count,
82 &w->seqnum, NULL, NULL);
83 if (r >= 0) {
84 if (w->server)
85 w->server->event_count += 1;
86 return 0;
87 } else if (r == -EBADMSG)
88 return r;
89
90 log_debug_errno(r, "%s: Write failed, rotating: %m", w->journal->file->path);
91 r = do_rotate(&w->journal, w->mmap, file_flags);
92 if (r < 0)
93 return r;
94 else
95 log_debug("%s: Successfully rotated journal", w->journal->file->path);
96
97 log_debug("Retrying write.");
98 r = journal_file_append_entry(w->journal->file, ts, boot_id,
99 iovw->iovec, iovw->count,
100 &w->seqnum, NULL, NULL);
101 if (r < 0)
102 return r;
103
104 if (w->server)
105 w->server->event_count += 1;
106 return 0;
107 }
108