]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: introduce JournalStorage and JournalStorageSpace structures
authorFranck Bui <fbui@suse.com>
Tue, 4 Oct 2016 15:13:21 +0000 (17:13 +0200)
committerFranck Bui <fbui@suse.com>
Wed, 19 Oct 2016 07:53:07 +0000 (09:53 +0200)
This structure keeps track of specificities for a given journal type
(persistent or volatile) such as metrics, name, etc...

The cached space values are now moved in this structure so that each
journal has its own set of cached values.

Previously only one set existed and we didn't know if the cached
values were for the runtime journal or the persistent one.

When doing:

   determine_space_for(s, runtime_metrics, ...);
   determine_space_for(s, system_metrics, ...);

the second call returned the cached values for the runtime metrics.

src/journal/journald-gperf.gperf
src/journal/journald-server.c
src/journal/journald-server.h

index 7fecd7a9649c356af4844d4d17fd7b72331bb14c..654fd76a4bfb821a8738a430db7c6c785db2074f 100644 (file)
@@ -23,14 +23,14 @@ Journal.SyncIntervalSec,    config_parse_sec,        0, offsetof(Server, sync_in
 Journal.RateLimitInterval,  config_parse_sec,        0, offsetof(Server, rate_limit_interval)
 Journal.RateLimitIntervalSec,config_parse_sec,       0, offsetof(Server, rate_limit_interval)
 Journal.RateLimitBurst,     config_parse_unsigned,   0, offsetof(Server, rate_limit_burst)
-Journal.SystemMaxUse,       config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_use)
-Journal.SystemMaxFileSize,  config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_size)
-Journal.SystemKeepFree,     config_parse_iec_uint64, 0, offsetof(Server, system_metrics.keep_free)
-Journal.SystemMaxFiles,     config_parse_uint64,     0, offsetof(Server, system_metrics.n_max_files)
-Journal.RuntimeMaxUse,      config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_use)
-Journal.RuntimeMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_size)
-Journal.RuntimeKeepFree,    config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.keep_free)
-Journal.RuntimeMaxFiles,    config_parse_uint64,     0, offsetof(Server, runtime_metrics.n_max_files)
+Journal.SystemMaxUse,       config_parse_iec_uint64, 0, offsetof(Server, system_storage.metrics.max_use)
+Journal.SystemMaxFileSize,  config_parse_iec_uint64, 0, offsetof(Server, system_storage.metrics.max_size)
+Journal.SystemKeepFree,     config_parse_iec_uint64, 0, offsetof(Server, system_storage.metrics.keep_free)
+Journal.SystemMaxFiles,     config_parse_uint64,     0, offsetof(Server, system_storage.metrics.n_max_files)
+Journal.RuntimeMaxUse,      config_parse_iec_uint64, 0, offsetof(Server, runtime_storage.metrics.max_use)
+Journal.RuntimeMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, runtime_storage.metrics.max_size)
+Journal.RuntimeKeepFree,    config_parse_iec_uint64, 0, offsetof(Server, runtime_storage.metrics.keep_free)
+Journal.RuntimeMaxFiles,    config_parse_uint64,     0, offsetof(Server, runtime_storage.metrics.n_max_files)
 Journal.MaxRetentionSec,    config_parse_sec,        0, offsetof(Server, max_retention_usec)
 Journal.MaxFileSec,         config_parse_sec,        0, offsetof(Server, max_file_usec)
 Journal.ForwardToSyslog,    config_parse_bool,       0, offsetof(Server, forward_to_syslog)
index 66392303664759d115891c90a41d6bc260ecaf0a..db228d447ca2127d91d9e82586674a33945955bf 100644 (file)
@@ -90,19 +90,17 @@ static int determine_path_usage(Server *s, const char *path, uint64_t *ret_used,
         _cleanup_closedir_ DIR *d = NULL;
         struct dirent *de;
         struct statvfs ss;
-        const char *p;
 
         assert(ret_used);
         assert(ret_free);
 
-        p = strjoina(path, SERVER_MACHINE_ID(s));
-        d = opendir(p);
+        d = opendir(path);
         if (!d)
                 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
-                                      errno, "Failed to open %s: %m", p);
+                                      errno, "Failed to open %s: %m", path);
 
         if (fstatvfs(dirfd(d), &ss) < 0)
-                return log_error_errno(errno, "Failed to fstatvfs(%s): %m", p);
+                return log_error_errno(errno, "Failed to fstatvfs(%s): %m", path);
 
         *ret_free = ss.f_bsize * ss.f_bavail;
         *ret_used = 0;
@@ -114,7 +112,7 @@ static int determine_path_usage(Server *s, const char *path, uint64_t *ret_used,
                         continue;
 
                 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
-                        log_debug_errno(errno, "Failed to stat %s/%s, ignoring: %m", p, de->d_name);
+                        log_debug_errno(errno, "Failed to stat %s/%s, ignoring: %m", path, de->d_name);
                         continue;
                 }
 
@@ -129,9 +127,7 @@ static int determine_path_usage(Server *s, const char *path, uint64_t *ret_used,
 
 static int determine_space_for(
                 Server *s,
-                JournalMetrics *metrics,
-                const char *path,
-                const char *name,
+                JournalStorage *storage,
                 bool verbose,
                 bool patch_min_use,
                 uint64_t *available,
@@ -139,22 +135,25 @@ static int determine_space_for(
 
         uint64_t sum, avail, ss_avail;
         _cleanup_closedir_ DIR *d = NULL;
+        JournalMetrics *metrics;
+        const char *path, *name;
         usec_t ts;
         int r;
 
         assert(s);
-        assert(metrics);
-        assert(path);
-        assert(name);
+
+        name = storage->name;
+        path = storage->path;
+        metrics = &storage->metrics;
 
         ts = now(CLOCK_MONOTONIC);
 
-        if (!verbose && s->cached_space_timestamp + RECHECK_SPACE_USEC > ts) {
+        if (!verbose && storage->space.timestamp + RECHECK_SPACE_USEC > ts) {
 
                 if (available)
-                        *available = s->cached_space_available;
+                        *available = storage->space.available;
                 if (limit)
-                        *limit = s->cached_space_limit;
+                        *limit = storage->space.limit;
 
                 return 0;
         }
@@ -175,9 +174,9 @@ static int determine_space_for(
 
         avail = LESS_BY(ss_avail, metrics->keep_free);
 
-        s->cached_space_limit = MIN(MAX(sum + avail, metrics->min_use), metrics->max_use);
-        s->cached_space_available = LESS_BY(s->cached_space_limit, sum);
-        s->cached_space_timestamp = ts;
+        storage->space.limit = MIN(MAX(sum + avail, metrics->min_use), metrics->max_use);
+        storage->space.available = LESS_BY(storage->space.limit, sum);
+        storage->space.timestamp = ts;
 
         if (verbose) {
                 char    fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
@@ -186,8 +185,8 @@ static int determine_space_for(
                 format_bytes(fb2, sizeof(fb2), metrics->max_use);
                 format_bytes(fb3, sizeof(fb3), metrics->keep_free);
                 format_bytes(fb4, sizeof(fb4), ss_avail);
-                format_bytes(fb5, sizeof(fb5), s->cached_space_limit);
-                format_bytes(fb6, sizeof(fb6), s->cached_space_available);
+                format_bytes(fb5, sizeof(fb5), storage->space.limit);
+                format_bytes(fb6, sizeof(fb6), storage->space.available);
 
                 server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
                                       LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
@@ -202,38 +201,28 @@ static int determine_space_for(
                                       "DISK_KEEP_FREE_PRETTY=%s", fb3,
                                       "DISK_AVAILABLE=%"PRIu64, ss_avail,
                                       "DISK_AVAILABLE_PRETTY=%s", fb4,
-                                      "LIMIT=%"PRIu64, s->cached_space_limit,
+                                      "LIMIT=%"PRIu64, storage->space.limit,
                                       "LIMIT_PRETTY=%s", fb5,
-                                      "AVAILABLE=%"PRIu64, s->cached_space_available,
+                                      "AVAILABLE=%"PRIu64, storage->space.available,
                                       "AVAILABLE_PRETTY=%s", fb6,
                                       NULL);
         }
 
         if (available)
-                *available = s->cached_space_available;
+                *available = storage->space.available;
         if (limit)
-                *limit = s->cached_space_limit;
+                *limit = storage->space.limit;
 
         return 1;
 }
 
 static int determine_space(Server *s, bool verbose, bool patch_min_use, uint64_t *available, uint64_t *limit) {
-        JournalMetrics *metrics;
-        const char *path, *name;
+        JournalStorage *js;
 
         assert(s);
 
-        if (s->system_journal) {
-                path = "/var/log/journal/";
-                metrics = &s->system_metrics;
-                name = "System journal";
-        } else {
-                path = "/run/log/journal/";
-                metrics = &s->runtime_metrics;
-                name = "Runtime journal";
-        }
-
-        return determine_space_for(s, metrics, path, name, verbose, patch_min_use, available, limit);
+        js = s->system_journal ? &s->system_storage : &s->runtime_storage;
+        return determine_space_for(s, js, verbose, patch_min_use, available, limit);
 }
 
 static void server_add_acls(JournalFile *f, uid_t uid) {
@@ -306,14 +295,13 @@ static int system_journal_open(Server *s, bool flush_requested) {
                 if (s->storage == STORAGE_PERSISTENT)
                         (void) mkdir_p("/var/log/journal/", 0755);
 
-                fn = strjoina("/var/log/journal/", SERVER_MACHINE_ID(s));
-                (void) mkdir(fn, 0755);
+                (void) mkdir(s->system_storage.path, 0755);
 
-                fn = strjoina(fn, "/system.journal");
-                r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &s->system_journal);
+                fn = strjoina(s->system_storage.path, "/system.journal");
+                r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_storage.metrics, &s->system_journal);
                 if (r >= 0) {
                         server_add_acls(s->system_journal, 0);
-                        (void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
+                        (void) determine_space_for(s, &s->system_storage, true, true, NULL, NULL);
                 } else if (r < 0) {
                         if (r != -ENOENT && r != -EROFS)
                                 log_warning_errno(r, "Failed to open system journal: %m");
@@ -335,7 +323,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
         if (!s->runtime_journal &&
             (s->storage != STORAGE_NONE)) {
 
-                fn = strjoina("/run/log/journal/", SERVER_MACHINE_ID(s), "/system.journal");
+                fn = strjoina(s->runtime_storage.path, "/system.journal");
 
                 if (s->system_journal) {
 
@@ -343,7 +331,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
                          * if it already exists, so that we can flush
                          * it into the system journal */
 
-                        r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, &s->runtime_journal);
+                        r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_storage.metrics, &s->runtime_journal);
                         if (r < 0) {
                                 if (r != -ENOENT)
                                         log_warning_errno(r, "Failed to open runtime journal: %m");
@@ -360,14 +348,14 @@ static int system_journal_open(Server *s, bool flush_requested) {
                         (void) mkdir("/run/log/journal", 0755);
                         (void) mkdir_parents(fn, 0750);
 
-                        r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, &s->runtime_journal);
+                        r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_storage.metrics, &s->runtime_journal);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to open runtime journal: %m");
                 }
 
                 if (s->runtime_journal) {
                         server_add_acls(s->runtime_journal, 0);
-                        (void) determine_space_for(s, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", true, true, NULL, NULL);
+                        (void) determine_space_for(s, &s->runtime_storage, true, true, NULL, NULL);
                 }
         }
 
@@ -423,7 +411,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
                 (void) journal_file_close(f);
         }
 
-        r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
+        r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_storage.metrics, &f);
         if (r < 0)
                 return s->system_journal;
 
@@ -519,33 +507,28 @@ void server_sync(Server *s) {
 
 static void do_vacuum(
                 Server *s,
-                JournalFile *f,
-                JournalMetrics *metrics,
-                const char *path,
-                const char *name,
+                JournalStorage *storage,
                 bool verbose,
                 bool patch_min_use) {
 
-        const char *p;
+        JournalMetrics *metrics;
         uint64_t limit;
         int r;
 
         assert(s);
-        assert(metrics);
-        assert(path);
-        assert(name);
-
-        if (!f)
-                return;
-
-        p = strjoina(path, SERVER_MACHINE_ID(s));
+        assert(storage);
 
+        metrics = &storage->metrics;
         limit = metrics->max_use;
-        (void) determine_space_for(s, metrics, path, name, verbose, patch_min_use, NULL, &limit);
+        (void) determine_space_for(s, storage, verbose, patch_min_use, NULL, &limit);
 
-        r = journal_directory_vacuum(p, limit, metrics->n_max_files, s->max_retention_usec, &s->oldest_file_usec,  verbose);
+        r = journal_directory_vacuum(storage->path, limit, metrics->n_max_files, s->max_retention_usec, &s->oldest_file_usec,  verbose);
         if (r < 0 && r != -ENOENT)
-                log_warning_errno(r, "Failed to vacuum %s, ignoring: %m", p);
+                log_warning_errno(r, "Failed to vacuum %s, ignoring: %m", storage->path);
+
+        storage->space.limit = 0;
+        storage->space.available = 0;
+        storage->space.timestamp = 0;
 }
 
 int server_vacuum(Server *s, bool verbose, bool patch_min_use) {
@@ -555,12 +538,10 @@ int server_vacuum(Server *s, bool verbose, bool patch_min_use) {
 
         s->oldest_file_usec = 0;
 
-        do_vacuum(s, s->system_journal, &s->system_metrics, "/var/log/journal/", "System journal", verbose, patch_min_use);
-        do_vacuum(s, s->runtime_journal, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", verbose, patch_min_use);
-
-        s->cached_space_limit = 0;
-        s->cached_space_available = 0;
-        s->cached_space_timestamp = 0;
+        if (s->system_journal)
+                do_vacuum(s, &s->system_storage, verbose, patch_min_use);
+        if (s->runtime_journal)
+                do_vacuum(s, &s->runtime_storage, verbose, patch_min_use);
 
         return 0;
 }
@@ -1888,8 +1869,8 @@ int server_init(Server *s) {
         s->max_level_console = LOG_INFO;
         s->max_level_wall = LOG_EMERG;
 
-        journal_reset_metrics(&s->system_metrics);
-        journal_reset_metrics(&s->runtime_metrics);
+        journal_reset_metrics(&s->system_storage.metrics);
+        journal_reset_metrics(&s->runtime_storage.metrics);
 
         server_parse_config_file(s);
         server_parse_proc_cmdline(s);
@@ -2042,6 +2023,14 @@ int server_init(Server *s) {
         server_cache_boot_id(s);
         server_cache_machine_id(s);
 
+        s->runtime_storage.name = "Runtime journal";
+        s->system_storage.name = "System journal";
+
+        s->runtime_storage.path = strjoin("/run/log/journal/", SERVER_MACHINE_ID(s), NULL);
+        s->system_storage.path  = strjoin("/var/log/journal/", SERVER_MACHINE_ID(s), NULL);
+        if (!s->runtime_storage.path || !s->system_storage.path)
+                return -ENOMEM;
+
         (void) server_connect_notify(s);
 
         return system_journal_open(s, false);
index cc68a0a690fb8de7e77a6653af7a79b4f008996a..9cf4fad722a8cbcc0ade16d8b46a91745181097e 100644 (file)
@@ -49,6 +49,20 @@ typedef enum SplitMode {
         _SPLIT_INVALID = -1
 } SplitMode;
 
+typedef struct JournalStorageSpace {
+        uint64_t available;
+        uint64_t limit;
+        usec_t   timestamp;
+} JournalStorageSpace;
+
+typedef struct JournalStorage {
+        const char *name;
+        const char *path;
+
+        JournalMetrics metrics;
+        JournalStorageSpace space;
+} JournalStorage;
+
 struct Server {
         int syslog_fd;
         int native_fd;
@@ -89,8 +103,8 @@ struct Server {
         usec_t rate_limit_interval;
         unsigned rate_limit_burst;
 
-        JournalMetrics runtime_metrics;
-        JournalMetrics system_metrics;
+        JournalStorage runtime_storage;
+        JournalStorage system_storage;
 
         bool compress;
         bool seal;
@@ -103,10 +117,6 @@ struct Server {
         unsigned n_forward_syslog_missed;
         usec_t last_warn_forward_syslog_missed;
 
-        uint64_t cached_space_available;
-        uint64_t cached_space_limit;
-        usec_t cached_space_timestamp;
-
         uint64_t var_available_timestamp;
 
         usec_t max_retention_usec;