]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vacuum journal remote (#25076)
authorberenddeschouwer <berend.de.schouwer@gmail.com>
Sat, 17 Dec 2022 13:54:16 +0000 (15:54 +0200)
committerGitHub <noreply@github.com>
Sat, 17 Dec 2022 13:54:16 +0000 (13:54 +0000)
* Support vacuuming for journal-remote

Co-authored-by: Berend De Schouwer <berend@deschouwer.co.za>
man/journal-remote.conf.xml
src/journal-remote/journal-remote-main.c
src/journal-remote/journal-remote-write.c
src/journal-remote/journal-remote-write.h
src/journal-remote/journal-remote.conf.in
src/journal-remote/journal-remote.h

index 3f69f30df32f6259a16de6fb249625e7351df697..56992369acd1131082ec95bf1f982c082894eb41 100644 (file)
         <listitem><para>SSL CA certificate.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>MaxUse=</varname></term>
+        <term><varname>KeepFree=</varname></term>
+        <term><varname>MaxFileSize=</varname></term>
+        <term><varname>MaxFiles=</varname></term>
+
+        <listitem><para>These are analogous to <varname>SystemMaxUse=</varname>,
+        <varname>SystemKeepFree=</varname>, <varname>SystemMaxFileSize=</varname>
+        and <varname>SystemMaxFiles=</varname> in
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+        <para><varname>MaxUse=</varname> controls how much disk space
+        the <command>systemd-journal-remote</command> may use up at most.
+        <varname>KeepFree=</varname> controls how much disk
+        space <command>systemd-journal-remote</command> shall leave free for other uses.
+        <command>systemd-journal-remote</command> will respect both limits
+        and use the smaller of the two values.</para>
+
+        <para><varname>MaxFiles=</varname> controls how many
+        individual journal files to keep at most. Note that only
+        archived files are deleted to reduce the number of files until
+        this limit is reached; active files will stay around. This
+        means that, in effect, there might still be more journal files
+        around in total than this limit after a vacuuming operation is
+        complete.</para></listitem>
+      </varlistentry>
+
     </variablelist>
 
   </refsect1>
   <refsect1>
       <title>See Also</title>
       <para>
-        <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       </para>
   </refsect1>
index 440aad1cf7b29ac6ccc85190b40ba713dd3026d1..476c9ad972c627e32fbb421878584abc33b84693 100644 (file)
@@ -53,6 +53,11 @@ static bool arg_trust_all = false;
 static bool arg_trust_all = true;
 #endif
 
+static uint64_t arg_max_use = UINT64_MAX;
+static uint64_t arg_max_size = UINT64_MAX;
+static uint64_t arg_n_max_files = UINT64_MAX;
+static uint64_t arg_keep_free = UINT64_MAX;
+
 STATIC_DESTRUCTOR_REGISTER(arg_gnutls_log, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_key, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_cert, freep);
@@ -759,11 +764,15 @@ static int negative_fd(const char *spec) {
 
 static int parse_config(void) {
         const ConfigTableItem items[] = {
-                { "Remote",  "Seal",                   config_parse_bool,             0, &arg_seal       },
-                { "Remote",  "SplitMode",              config_parse_write_split_mode, 0, &arg_split_mode },
-                { "Remote",  "ServerKeyFile",          config_parse_path,             0, &arg_key        },
-                { "Remote",  "ServerCertificateFile",  config_parse_path,             0, &arg_cert       },
-                { "Remote",  "TrustedCertificateFile", config_parse_path,             0, &arg_trust      },
+                { "Remote",  "Seal",                   config_parse_bool,             0, &arg_seal        },
+                { "Remote",  "SplitMode",              config_parse_write_split_mode, 0, &arg_split_mode  },
+                { "Remote",  "ServerKeyFile",          config_parse_path,             0, &arg_key         },
+                { "Remote",  "ServerCertificateFile",  config_parse_path,             0, &arg_cert        },
+                { "Remote",  "TrustedCertificateFile", config_parse_path,             0, &arg_trust       },
+                { "Remote",  "MaxUse",                 config_parse_iec_uint64,       0, &arg_max_use     },
+                { "Remote",  "MaxFileSize",            config_parse_iec_uint64,       0, &arg_max_size    },
+                { "Remote",  "MaxFiles",               config_parse_uint64,           0, &arg_n_max_files },
+                { "Remote",  "KeepFree",               config_parse_iec_uint64,       0, &arg_keep_free   },
                 {}
         };
 
@@ -1136,6 +1145,12 @@ static int run(int argc, char **argv) {
                 s.check_trust = !arg_trust_all;
         }
 
+        journal_reset_metrics(&s.metrics);
+        s.metrics.max_use = arg_max_use;
+        s.metrics.max_size = arg_max_size;
+        s.metrics.max_size = arg_keep_free;
+        s.metrics.n_max_files = arg_n_max_files;
+
         r = create_remoteserver(&s, key, cert, trust);
         if (r < 0)
                 return r;
index f4f3b64811de549ce96e6c249015c66fcc62d299..2e58c6d91ee95f4fa6446bcfc034d26d170f4f36 100644 (file)
@@ -1,7 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <libgen.h>
+
 #include "alloc-util.h"
 #include "journal-remote.h"
+#include "path-util.h"
+#include "stat-util.h"
 
 static int do_rotate(ManagedJournalFile **f, MMapCache *m, JournalFileFlags file_flags) {
         int r;
@@ -19,12 +23,13 @@ static int do_rotate(ManagedJournalFile **f, MMapCache *m, JournalFileFlags file
 
 Writer* writer_new(RemoteServer *server) {
         Writer *w;
+        int r;
 
         w = new0(Writer, 1);
         if (!w)
                 return NULL;
 
-        memset(&w->metrics, 0xFF, sizeof(w->metrics));
+        w->metrics = server->metrics;
 
         w->mmap = mmap_cache_new();
         if (!w->mmap)
@@ -33,6 +38,18 @@ Writer* writer_new(RemoteServer *server) {
         w->n_ref = 1;
         w->server = server;
 
+        if (is_dir(server->output, /* follow = */ true) > 0) {
+                w->output = strdup(server->output);
+                if (!w->output)
+                        return NULL;
+        } else {
+                r = path_extract_directory(server->output, &w->output);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to find directory of file \"%s\": %m", server->output);
+                        return NULL;
+                }
+        }
+
         return w;
 }
 
@@ -53,6 +70,8 @@ static Writer* writer_free(Writer *w) {
         if (w->mmap)
                 mmap_cache_unref(w->mmap);
 
+        free(w->output);
+
         return mfree(w);
 }
 
@@ -75,6 +94,9 @@ int writer_write(Writer *w,
                 r = do_rotate(&w->journal, w->mmap, file_flags);
                 if (r < 0)
                         return r;
+                r = journal_directory_vacuum(w->output, w->metrics.max_use, w->metrics.n_max_files, 0, NULL, /* verbose = */ true);
+                if (r < 0)
+                        return r;
         }
 
         r = journal_file_append_entry(w->journal->file, ts, boot_id,
@@ -93,6 +115,9 @@ int writer_write(Writer *w,
                 return r;
         else
                 log_debug("%s: Successfully rotated journal", w->journal->file->path);
+        r = journal_directory_vacuum(w->output, w->metrics.max_use, w->metrics.n_max_files, 0, NULL, /* verbose = */ true);
+        if (r < 0)
+                return r;
 
         log_debug("Retrying write.");
         r = journal_file_append_entry(w->journal->file, ts, boot_id,
index 2079214e2349d2f14d7a05b002dc3a6387add9c9..c140f6cba3d4f07bef66be37e35754176d0ba21a 100644 (file)
@@ -9,6 +9,7 @@ typedef struct RemoteServer RemoteServer;
 typedef struct Writer {
         ManagedJournalFile *journal;
         JournalMetrics metrics;
+        char *output;          /* directory where we write, for vacuuming */
 
         MMapCache *mmap;
         RemoteServer *server;
index 648aa1ba11b7bcbec123902a39a8f30386c2addf..afb319102c0473326f803af75cfc301e56978463 100644 (file)
@@ -18,3 +18,7 @@
 # ServerKeyFile={{CERTIFICATE_ROOT}}/private/journal-remote.pem
 # ServerCertificateFile={{CERTIFICATE_ROOT}}/certs/journal-remote.pem
 # TrustedCertificateFile={{CERTIFICATE_ROOT}}/ca/trusted.pem
+# MaxUse=
+# KeepFree=
+# MaxFileSize=
+# MaxFiles=
index facf1516e0563e7b37f750ca9f988d22384a4949..39d044648142616f40afd051089c535f7551d20a 100644 (file)
@@ -6,6 +6,7 @@
 #include "hashmap.h"
 #include "journal-remote-parse.h"
 #include "journal-remote-write.h"
+#include "journal-vacuum.h"
 
 #if HAVE_MICROHTTPD
 #include "microhttpd-util.h"
@@ -40,6 +41,7 @@ struct RemoteServer {
         JournalWriteSplitMode split_mode;
         JournalFileFlags file_flags;
         bool check_trust;
+        JournalMetrics metrics;
 };
 extern RemoteServer *journal_remote_server_global;