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