From e156d769c3ee756cdb20f8522ace9ea459a82655 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 1 Jul 2012 20:17:48 +0200 Subject: [PATCH] journald: add Storage= setting to control where the journal is stored --- TODO | 16 ++++++++----- man/journald.conf.xml | 40 ++++++++++++++++++++++++++++++++ src/journal/journald-gperf.gperf | 1 + src/journal/journald.c | 37 +++++++++++++++++++++++------ src/journal/journald.h | 16 +++++++++++++ src/login/logind.conf | 1 + 6 files changed, 98 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 37c048c32..679008848 100644 --- a/TODO +++ b/TODO @@ -22,6 +22,14 @@ Bugfixes: Features: +* reexec journald across initrd transition + +* nspawn: bind mount /var/log/journal from the host + +* The current Storage=auto logic is borked, since people cannot mount + /var/log/journal via NFS since the mount point has to exist and we + already take that as signal to store our stuff there. + * rename systemd-udev.service to systemd-udevd.service * document that journal data is primarily ASCII, UTF-8 where necessary and binary only where nothing else makes sense. @@ -110,8 +118,6 @@ Features: * don't delete /tmp/systemd-namespace-* before a process is gone down -* don't delete /run/users/lennart if lennart is still logged in even if aging is used - * vconsole: implement setterm -store -foreground xxx --background zzz * ExecOnFailure=/usr/bin/foo @@ -170,8 +176,6 @@ Features: * journal: store euid in journal if it differs from uid -* support chrony in addition to ntpd in timedated - * There's currently no way to cancel fsck (used to be possible via C-c or c on the console) * journal: sanely deal with entries which are larger than the individual file size, but where the componets would fit @@ -236,8 +240,6 @@ Features: * when an instanced service exits, remove its parent cgroup too if possible. -* automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service@serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary. - * if we can not get user quota for tmpfs, mount a separate tmpfs instance for every user in /run/user/$USER with a configured maximum size @@ -417,3 +419,5 @@ Regularly: Scheduled for removal (or fixing): * xxxOverridable dependencies + +* journald.conf: ImportKernel= diff --git a/man/journald.conf.xml b/man/journald.conf.xml index deb2344fc..72d81fbdf 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -286,6 +286,46 @@ traditional syslog service. + + + Storage= + + Controls where to + store journal data. One of + volatile, + permanent, + auto and + none. If + volatile journal + log data will be stored only in + memory, i.e. below the + /run/log/journal + hierarchy (which is created if + needed). If + permanent data will + be stored preferably on disk, + i.e. below the + /var/log/journal + hierarchy (which is created if + needed), with a fallback to + /run/log/journal + (which is created if needed), during + early boot and if the disk is not + writable. auto is + similar to + permanent but the + directory + /var/log/journal + is not created if needed, so that its + existance controls where log data + goes. none turns + off all storage, all log data received + will be dropped. Forwarding to other + targets, such as the console, the + kernel log buffer or a syslog daemon + will still work however. Defaults to + auto. + diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf index c9b0fbb0e..4fe2ea0ec 100644 --- a/src/journal/journald-gperf.gperf +++ b/src/journal/journald-gperf.gperf @@ -34,3 +34,4 @@ Journal.MaxLevelStore, config_parse_level, 0, offsetof(Server, max_leve Journal.MaxLevelSyslog, config_parse_level, 0, offsetof(Server, max_level_syslog) Journal.MaxLevelKMsg, config_parse_level, 0, offsetof(Server, max_level_kmsg) Journal.MaxLevelConsole, config_parse_level, 0, offsetof(Server, max_level_console) +Journal.Storage, config_parse_storage, 0, offsetof(Server, storage) diff --git a/src/journal/journald.c b/src/journal/journald.c index 7ea68aab3..08597ae3e 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -111,6 +111,16 @@ struct StdoutStream { LIST_FIELDS(StdoutStream, stdout_stream); }; +static const char* const storage_table[] = { + [STORAGE_AUTO] = "auto", + [STORAGE_VOLATILE] = "volatile", + [STORAGE_PERMANENT] = "permanent", + [STORAGE_NONE] = "none" +}; + +DEFINE_STRING_TABLE_LOOKUP(storage, Storage); +DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting"); + static int server_flush_to_var(Server *s); static uint64_t available_space(Server *s) { @@ -397,7 +407,6 @@ static void server_vacuum(Server *s) { free(p); } - if (s->runtime_journal) { if (asprintf(&p, "/run/log/journal/%s", ids) < 0) { log_error("Out of memory."); @@ -625,9 +634,7 @@ static void dispatch_message_real( retry: f = find_journal(s, realuid == 0 ? 0 : loginuid); - if (!f) - log_warning("Dropping message, as we can't find a place to store the data."); - else { + if (f) { r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); if ((r == -E2BIG || /* hit limit */ @@ -1955,12 +1962,23 @@ static int system_journal_open(Server *s) { sd_id128_to_string(machine, ids); - if (!s->system_journal) { + if (!s->system_journal && + (s->storage == STORAGE_PERMANENT || + s->storage == STORAGE_AUTO)) { + + /* If in auto mode: first try to create the machine + * path, but not the prefix. + * + * If in permanent mode: create /var/log/journal and + * the machine path */ + + if (s->storage & STORAGE_PERMANENT) + (void) mkdir("/var/log/journal/", 0755); - /* First try to create the machine path, but not the prefix */ fn = strappend("/var/log/journal/", ids); if (!fn) return -ENOMEM; + (void) mkdir(fn, 0755); free(fn); @@ -1988,7 +2006,8 @@ static int system_journal_open(Server *s) { } } - if (!s->runtime_journal) { + if (!s->runtime_journal && + (s->storage != STORAGE_NONE)) { fn = join("/run/log/journal/", ids, "/system.journal", NULL); if (!fn) @@ -2048,6 +2067,10 @@ static int server_flush_to_var(Server *s) { assert(s); + if (s->storage != STORAGE_AUTO && + s->storage != STORAGE_PERMANENT) + return 0; + if (!s->runtime_journal) return 0; diff --git a/src/journal/journald.h b/src/journal/journald.h index 159364d93..34deb8561 100644 --- a/src/journal/journald.h +++ b/src/journal/journald.h @@ -33,6 +33,15 @@ #include "journal-rate-limit.h" #include "list.h" +typedef enum Storage { + STORAGE_AUTO, + STORAGE_VOLATILE, + STORAGE_PERMANENT, + STORAGE_NONE, + _STORAGE_MAX, + _STORAGE_INVALID = -1 +} Storage; + typedef struct StdoutStream StdoutStream; typedef struct Server { @@ -86,9 +95,16 @@ typedef struct Server { int max_level_syslog; int max_level_kmsg; int max_level_console; + + Storage storage; } Server; /* gperf lookup function */ const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length); +int config_parse_storage(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +const char *storage_to_string(Storage s); +Storage storage_from_string(const char *s); + #endif diff --git a/src/login/logind.conf b/src/login/logind.conf index 78496a0ef..c3798f7c7 100644 --- a/src/login/logind.conf +++ b/src/login/logind.conf @@ -18,3 +18,4 @@ #HandlePowerKey=no-session #HandleSleepKey=tty-session #HandleLidSwitch=off +#Storage=auto -- 2.30.2