string format. Overrides the default maximum allowed size for a file-descriptor
based input record to be stored in the journal.
+* `$SYSTEMD_JOURNAL_REMOTE_CONFIG_FILE` – path to a configuration file for
+ `systemd-journal-remote`. When set, the specified file is used instead of the
+ default configuration file and drop-in directories. If set to the empty string
+ or `/dev/null`, configuration file parsing is skipped entirely.
+
* `$SYSTEMD_CATALOG` – path to the compiled catalog database file to use for
`journalctl -x`, `journalctl --update-catalog`, `journalctl --list-catalog`
and related calls.
<xi:include href="version-info.xml" xpointer="v239"/></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--max-use=</option></term>
+ <term><option>--keep-free=</option></term>
+ <term><option>--max-file-size=</option></term>
+ <term><option>--max-files=</option></term>
+
+ <listitem><para>These options override the corresponding settings from the configuration file
+ (see <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+ See that page for the descriptions of these options.</para>
+
+ <xi:include href="version-info.xml" xpointer="v261"/></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--forward-journal-max-use=<replaceable>BYTES</replaceable></option></term>
+ <term><option>--forward-journal-keep-free=<replaceable>BYTES</replaceable></option></term>
+ <term><option>--forward-journal-max-file-size=<replaceable>BYTES</replaceable></option></term>
+ <term><option>--forward-journal-max-files=<replaceable>N</replaceable></option></term>
+
+ <listitem><para>These options configure the corresponding settings of
+ <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ when forwarding journal entries from the VM. See
+ <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for the descriptions of these settings.</para>
+
+ <xi:include href="version-info.xml" xpointer="v261"/></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--pass-ssh-key=<replaceable>BOOL</replaceable></option></term>
[BIND]='--bind --bind-ro'
[SSH_KEY]='--ssh-key'
[CONSOLE]='--console'
- [ARG]='--cpus --ram --vsock-cid -M --machine --uuid --private-users --background --set-credential --load-credential'
+ [ARG]='--cpus --ram --vsock-cid -M --machine --uuid --private-users --background --set-credential --load-credential --forward-journal-max-use --forward-journal-keep-free --forward-journal-max-file-size --forward-journal-max-files'
[IMAGE_FORMAT]='--image-format'
[IMAGE_DISK_TYPE]='--image-disk-type'
)
#include "parse-argument.h"
#include "parse-helpers.h"
#include "parse-util.h"
+#include "path-util.h"
#include "pretty-print.h"
#include "process-util.h"
#include "socket-netlink.h"
{}
};
+ const char *config_file = secure_getenv("SYSTEMD_JOURNAL_REMOTE_CONFIG_FILE");
+ if (config_file) {
+ if (isempty(config_file) || path_equal(config_file, "/dev/null"))
+ return 0;
+
+ return config_parse(
+ /* unit= */ NULL,
+ config_file,
+ /* f= */ NULL,
+ "Remote\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ /* userdata= */ NULL,
+ /* ret_stat= */ NULL);
+ }
+
return config_parse_standard_file_with_dropins(
"systemd/journal-remote.conf",
"Remote\0",
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --gnutls-log= is not available.");
#endif
break;
+
+ OPTION_LONG("max-use", "BYTES", "Maximum disk space to use"):
+ r = parse_size(arg, 1024, &arg_max_use);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --max-use= value: %s", arg);
+ break;
+
+ OPTION_LONG("keep-free", "BYTES", "Minimum disk space to keep free"):
+ r = parse_size(arg, 1024, &arg_keep_free);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --keep-free= value: %s", arg);
+ break;
+
+ OPTION_LONG("max-file-size", "BYTES", "Maximum size of individual journal files"):
+ r = parse_size(arg, 1024, &arg_max_size);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --max-file-size= value: %s", arg);
+ break;
+
+ OPTION_LONG("max-files", "N", "Maximum number of journal files to keep"):
+ r = safe_atou64(arg, &arg_n_max_files);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --max-files= value: %s", arg);
+ break;
}
arg_files = strv_copy(option_parser_get_args(&state));
int fork_notify(char * const *argv, PidRef *ret_pidref) {
int r;
- assert(!strv_isempty(argv));
assert(ret_pidref);
if (!is_main_thread())
if (r < 0)
return r;
- if (DEBUG_LOGGING) {
+ if (DEBUG_LOGGING && argv) {
_cleanup_free_ char *l = quote_command_line(argv, SHELL_ESCAPE_EMPTY);
log_debug("Invoking '%s' as child.", strnull(l));
}
_exit(EXIT_MEMORY);
}
+ if (!argv) {
+ *ret_pidref = TAKE_PIDREF(child);
+ return 0; /* Let the caller run custom code in the child */
+ }
+
r = invoke_callout_binary(argv[0], argv);
log_debug_errno(r, "Failed to invoke %s: %m", argv[0]);
_exit(EXIT_EXEC);
*ret_pidref = TAKE_PIDREF(child);
- return 0;
+ return 1; /* In the parent */
}
static void fork_notify_terminate_internal(PidRef *pidref) {
#include "escape.h"
#include "ether-addr-util.h"
#include "event-util.h"
+#include "exit-status.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
static Set *arg_firmware_features_include = NULL;
static Set *arg_firmware_features_exclude = NULL;
static char *arg_forward_journal = NULL;
+static uint64_t arg_forward_journal_max_use = UINT64_MAX;
+static uint64_t arg_forward_journal_keep_free = UINT64_MAX;
+static uint64_t arg_forward_journal_max_file_size = UINT64_MAX;
+static uint64_t arg_forward_journal_max_files = UINT64_MAX;
static int arg_register = -1;
static bool arg_keep_unit = false;
static sd_id128_t arg_uuid = {};
return r;
break;
+ OPTION_LONG("forward-journal-max-use", "BYTES", "Maximum disk space for forwarded journal"):
+ r = parse_size(arg, 1024, &arg_forward_journal_max_use);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --forward-journal-max-use= value: %s", optarg);
+ break;
+
+ OPTION_LONG("forward-journal-keep-free", "BYTES", "Minimum disk space to keep free"):
+ r = parse_size(arg, 1024, &arg_forward_journal_keep_free);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --forward-journal-keep-free= value: %s", optarg);
+ break;
+
+ OPTION_LONG("forward-journal-max-file-size", "BYTES", "Maximum size of individual journal files"):
+ r = parse_size(arg, 1024, &arg_forward_journal_max_file_size);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --forward-journal-max-file-size= value: %s", optarg);
+ break;
+
+ OPTION_LONG("forward-journal-max-files", "N", "Maximum number of journal files to keep"):
+ r = safe_atou64(arg, &arg_forward_journal_max_files);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --forward-journal-max-files= value: %s", optarg);
+ break;
+
OPTION_LONG("pass-ssh-key", "BOOL", "Create an SSH key to access the VM"):
r = parse_boolean_argument("--pass-ssh-key=", arg, &arg_pass_ssh_key);
if (r < 0)
if (arg_ram_slots > 0 && arg_ram_max == 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Memory hotplug slots require a maximum RAM size");
+ if ((arg_forward_journal_max_use != UINT64_MAX ||
+ arg_forward_journal_keep_free != UINT64_MAX ||
+ arg_forward_journal_max_file_size != UINT64_MAX ||
+ arg_forward_journal_max_files != UINT64_MAX) && !arg_forward_journal)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--forward-journal-max-use=/--forward-journal-keep-free=/--forward-journal-max-file-size=/--forward-journal-max-files= require --forward-journal=.");
+
if (arg_ephemeral && arg_extra_drives.n_drives > 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --ephemeral with --extra-drive=");
if (!argv)
return log_oom();
- r = fork_notify(argv, ret_pidref);
+ if (arg_forward_journal_max_use != UINT64_MAX &&
+ strv_extendf(&argv, "--max-use=%" PRIu64, arg_forward_journal_max_use) < 0)
+ return log_oom();
+
+ if (arg_forward_journal_keep_free != UINT64_MAX &&
+ strv_extendf(&argv, "--keep-free=%" PRIu64, arg_forward_journal_keep_free) < 0)
+ return log_oom();
+
+ if (arg_forward_journal_max_file_size != UINT64_MAX &&
+ strv_extendf(&argv, "--max-file-size=%" PRIu64, arg_forward_journal_max_file_size) < 0)
+ return log_oom();
+
+ if (arg_forward_journal_max_files != UINT64_MAX &&
+ strv_extendf(&argv, "--max-files=%" PRIu64, arg_forward_journal_max_files) < 0)
+ return log_oom();
+
+ r = fork_notify(/* argv= */ NULL, ret_pidref);
if (r < 0)
return r;
+ if (r == 0) {
+ /* In the child */
+ if (setenv("SYSTEMD_JOURNAL_REMOTE_CONFIG_FILE",
+ "/dev/null",
+ /* overwrite= */ true) < 0) {
+ log_debug_errno(errno, "Failed to set $SYSTEMD_JOURNAL_REMOTE_CONFIG_FILE: %m");
+ _exit(EXIT_MEMORY);
+ }
+
+ r = invoke_callout_binary(argv[0], argv);
+ log_error_errno(r, "Failed to invoke %s: %m", argv[0]);
+ _exit(EXIT_EXEC);
+ }
if (ret_listen_address)
*ret_listen_address = TAKE_PTR(listen_address);