<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>
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);
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 },
{}
};
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;
/* 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;
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)
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;
}
if (w->mmap)
mmap_cache_unref(w->mmap);
+ free(w->output);
+
return mfree(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,
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,
typedef struct Writer {
ManagedJournalFile *journal;
JournalMetrics metrics;
+ char *output; /* directory where we write, for vacuuming */
MMapCache *mmap;
RemoteServer *server;
# ServerKeyFile={{CERTIFICATE_ROOT}}/private/journal-remote.pem
# ServerCertificateFile={{CERTIFICATE_ROOT}}/certs/journal-remote.pem
# TrustedCertificateFile={{CERTIFICATE_ROOT}}/ca/trusted.pem
+# MaxUse=
+# KeepFree=
+# MaxFileSize=
+# MaxFiles=
#include "hashmap.h"
#include "journal-remote-parse.h"
#include "journal-remote-write.h"
+#include "journal-vacuum.h"
#if HAVE_MICROHTTPD
#include "microhttpd-util.h"
JournalWriteSplitMode split_mode;
JournalFileFlags file_flags;
bool check_trust;
+ JournalMetrics metrics;
};
extern RemoteServer *journal_remote_server_global;