diff options
Diffstat (limited to 'src/journal')
-rw-r--r-- | src/journal/audit-type.c | 5 | ||||
-rw-r--r-- | src/journal/catalog.h | 1 | ||||
-rw-r--r-- | src/journal/coredump-vacuum.c | 15 | ||||
-rw-r--r-- | src/journal/fsprg.h | 2 | ||||
-rw-r--r-- | src/journal/journal-authenticate.c | 2 | ||||
-rw-r--r-- | src/journal/journal-file.h | 4 | ||||
-rw-r--r-- | src/journal/journal-internal.h | 2 | ||||
-rw-r--r-- | src/journal/journal-qrcode.c | 7 | ||||
-rw-r--r-- | src/journal/journal-verify.c | 4 | ||||
-rw-r--r-- | src/journal/journalctl.c | 224 | ||||
-rw-r--r-- | src/journal/journald-audit.h | 2 | ||||
-rw-r--r-- | src/journal/journald-console.c | 2 | ||||
-rw-r--r-- | src/journal/journald-native.c | 30 | ||||
-rw-r--r-- | src/journal/journald-rate-limit.c | 6 | ||||
-rw-r--r-- | src/journal/journald-server.c | 67 | ||||
-rw-r--r-- | src/journal/journald-server.h | 1 | ||||
-rw-r--r-- | src/journal/journald-wall.c | 2 | ||||
-rw-r--r-- | src/journal/journald.c | 7 | ||||
-rw-r--r-- | src/journal/lookup3.c | 4 | ||||
-rw-r--r-- | src/journal/mmap-cache.c | 17 | ||||
-rw-r--r-- | src/journal/test-catalog.c | 4 | ||||
-rw-r--r-- | src/journal/test-journal-enum.c | 2 | ||||
-rw-r--r-- | src/journal/test-journal-interleaving.c | 2 | ||||
-rw-r--r-- | src/journal/test-journal-verify.c | 2 | ||||
-rw-r--r-- | src/journal/test-journal.c | 6 |
25 files changed, 296 insertions, 124 deletions
diff --git a/src/journal/audit-type.c b/src/journal/audit-type.c index 4888c7d05d..086bf7e7e3 100644 --- a/src/journal/audit-type.c +++ b/src/journal/audit-type.c @@ -25,8 +25,7 @@ # include <libaudit.h> #endif -#include "audit-type.h" -#include "macro.h" #include "missing.h" - +#include "audit-type.h" #include "audit_type-to-name.h" +#include "macro.h" diff --git a/src/journal/catalog.h b/src/journal/catalog.h index a72ecf6de7..bcc73c2631 100644 --- a/src/journal/catalog.h +++ b/src/journal/catalog.h @@ -24,6 +24,7 @@ #include <stdbool.h> #include "sd-id128.h" + #include "hashmap.h" #include "strbuf.h" diff --git a/src/journal/coredump-vacuum.c b/src/journal/coredump-vacuum.c index 39bc2e4270..09ab60c6c4 100644 --- a/src/journal/coredump-vacuum.c +++ b/src/journal/coredump-vacuum.c @@ -157,8 +157,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { if (errno == ENOENT) return 0; - log_error_errno(errno, "Can't open coredump directory: %m"); - return -errno; + return log_error_errno(errno, "Can't open coredump directory: %m"); } for (;;) { @@ -183,7 +182,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { if (errno == ENOENT) continue; - log_warning("Failed to stat /var/lib/systemd/coredump/%s", de->d_name); + log_warning_errno(errno, "Failed to stat /var/lib/systemd/coredump/%s: %m", de->d_name); continue; } @@ -201,7 +200,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { t = timespec_load(&st.st_mtim); - c = hashmap_get(h, UINT32_TO_PTR(uid)); + c = hashmap_get(h, UID_TO_PTR(uid)); if (c) { if (t < c->oldest_mtime) { @@ -229,7 +228,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { n->oldest_mtime = t; - r = hashmap_put(h, UINT32_TO_PTR(uid), n); + r = hashmap_put(h, UID_TO_PTR(uid), n); if (r < 0) return log_oom(); @@ -259,8 +258,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { if (errno == ENOENT) continue; - log_error_errno(errno, "Failed to remove file %s: %m", worst->oldest_file); - return -errno; + return log_error_errno(errno, "Failed to remove file %s: %m", worst->oldest_file); } else log_info("Removed old coredump %s.", worst->oldest_file); } @@ -268,6 +266,5 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) { return 0; fail: - log_error_errno(errno, "Failed to read directory: %m"); - return -errno; + return log_error_errno(errno, "Failed to read directory: %m"); } diff --git a/src/journal/fsprg.h b/src/journal/fsprg.h index 5959b1fed2..b79221fc2e 100644 --- a/src/journal/fsprg.h +++ b/src/journal/fsprg.h @@ -25,8 +25,8 @@ * */ -#include <sys/types.h> #include <inttypes.h> +#include <sys/types.h> #include "macro.h" #include "util.h" diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c index 0c4ac5cdc3..aeec83da1e 100644 --- a/src/journal/journal-authenticate.c +++ b/src/journal/journal-authenticate.c @@ -24,10 +24,10 @@ #include "fd-util.h" #include "fsprg.h" +#include "hexdecoct.h" #include "journal-authenticate.h" #include "journal-def.h" #include "journal-file.h" -#include "hexdecoct.h" static uint64_t journal_file_tag_seqnum(JournalFile *f) { uint64_t r; diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index 898d12d992..46c1f3278e 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -29,11 +29,11 @@ #include "sd-id128.h" -#include "sparse-endian.h" +#include "hashmap.h" #include "journal-def.h" #include "macro.h" #include "mmap-cache.h" -#include "hashmap.h" +#include "sparse-endian.h" typedef struct JournalMetrics { /* For all these: -1 means "pick automatically", and 0 means "no limit enforced" */ diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index 06847402e0..c3e75ad240 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -21,9 +21,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/types.h> #include <inttypes.h> #include <stdbool.h> +#include <sys/types.h> #include "sd-id128.h" #include "sd-journal.h" diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c index 1db66e89c6..257ddb302b 100644 --- a/src/journal/journal-qrcode.c +++ b/src/journal/journal-qrcode.c @@ -20,12 +20,11 @@ ***/ #include <assert.h> -#include <stdio.h> #include <errno.h> -#include <stdlib.h> -#include <stdbool.h> - #include <qrencode.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> #include "journal-qrcode.h" diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 3676cb8788..715847e018 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -19,10 +19,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <unistd.h> -#include <sys/mman.h> #include <fcntl.h> #include <stddef.h> +#include <sys/mman.h> +#include <unistd.h> #include "alloc-util.h" #include "compress.h" diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 277adba904..d9a8063d31 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -133,6 +133,7 @@ static enum { ACTION_UPDATE_CATALOG, ACTION_LIST_BOOTS, ACTION_FLUSH, + ACTION_SYNC, ACTION_ROTATE, ACTION_VACUUM, } arg_action = ACTION_SHOW; @@ -201,7 +202,7 @@ static void help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" - "Flags:\n" + "Options:\n" " --system Show the system journal\n" " --user Show the user journal for the current user\n" " -M --machine=CONTAINER Operate on local container\n" @@ -234,7 +235,7 @@ static void help(void) { " -m --merge Show entries from all available journals\n" " -D --directory=PATH Show journal files from directory\n" " --file=PATH Show journal file\n" - " --root=ROOT Operate on catalog files underneath the root ROOT\n" + " --root=ROOT Operate on catalog files below a root directory\n" #ifdef HAVE_GCRYPT " --interval=TIME Time interval for changing the FSS sealing key\n" " --verify-key=KEY Specify FSS verification key\n" @@ -244,20 +245,21 @@ static void help(void) { " -h --help Show this help text\n" " --version Show package version\n" " -F --field=FIELD List all values that a specified field takes\n" - " --new-id128 Generate a new 128-bit ID\n" " --disk-usage Show total disk usage of all journal files\n" " --vacuum-size=BYTES Reduce disk usage below specified size\n" " --vacuum-files=INT Leave only the specified number of journal files\n" " --vacuum-time=TIME Remove journal files older than specified time\n" + " --verify Verify journal file consistency\n" + " --sync Synchronize unwritten journal messages to disk\n" " --flush Flush all journal data from /run into /var\n" " --rotate Request immediate rotation of the journal files\n" " --header Show journal header information\n" " --list-catalog Show all message IDs in the catalog\n" " --dump-catalog Show entries in the message catalog\n" " --update-catalog Update the message catalog database\n" + " --new-id128 Generate a new 128-bit ID\n" #ifdef HAVE_GCRYPT " --setup-keys Generate a new FSS key pair\n" - " --verify Verify journal file consistency\n" #endif , program_invocation_short_name); } @@ -289,6 +291,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_UPDATE_CATALOG, ARG_FORCE, ARG_UTC, + ARG_SYNC, ARG_FLUSH, ARG_ROTATE, ARG_VACUUM_SIZE, @@ -345,6 +348,7 @@ static int parse_argv(int argc, char *argv[]) { { "machine", required_argument, NULL, 'M' }, { "utc", no_argument, NULL, ARG_UTC }, { "flush", no_argument, NULL, ARG_FLUSH }, + { "sync", no_argument, NULL, ARG_SYNC }, { "rotate", no_argument, NULL, ARG_ROTATE }, { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE }, { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES }, @@ -729,6 +733,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_ROTATE; break; + case ARG_SYNC: + arg_action = ACTION_SYNC; + break; + case '?': return -EINVAL; @@ -1763,6 +1771,11 @@ static int flush_to_var(void) { _cleanup_close_ int watch_fd = -1; int r; + if (arg_machine) { + log_error("--flush is not supported in conjunction with --machine=."); + return -EOPNOTSUPP; + } + /* Quick exit */ if (access("/run/systemd/journal/flushed", F_OK) >= 0) return 0; @@ -1782,10 +1795,8 @@ static int flush_to_var(void) { &error, NULL, "ssi", "systemd-journald.service", "main", SIGUSR1); - if (r < 0) { - log_error("Failed to kill journal service: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); mkdir_p("/run/systemd/journal", 0755); @@ -1816,30 +1827,97 @@ static int flush_to_var(void) { return 0; } -static int rotate(void) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; +static int send_signal_and_wait(int sig, const char *watch_path) { _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; + _cleanup_close_ int watch_fd = -1; + usec_t start; int r; - r = bus_connect_system_systemd(&bus); - if (r < 0) - return log_error_errno(r, "Failed to get D-Bus connection: %m"); + if (arg_machine) { + log_error("--sync and --rotate are not supported in conjunction with --machine=."); + return -EOPNOTSUPP; + } - r = sd_bus_call_method( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "KillUnit", - &error, - NULL, - "ssi", "systemd-journald.service", "main", SIGUSR2); - if (r < 0) - return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); + start = now(CLOCK_MONOTONIC); + + /* This call sends the specified signal to journald, and waits + * for acknowledgment by watching the mtime of the specified + * flag file. This is used to trigger syncing or rotation and + * then wait for the operation to complete. */ + + for (;;) { + usec_t tstamp; + + /* See if a sync happened by now. */ + r = read_timestamp_file(watch_path, &tstamp); + if (r < 0 && r != -ENOENT) + return log_error_errno(errno, "Failed to read %s: %m", watch_path); + if (r >= 0 && tstamp >= start) + return 0; + + /* Let's ask for a sync, but only once. */ + if (!bus) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + + r = bus_connect_system_systemd(&bus); + if (r < 0) + return log_error_errno(r, "Failed to get D-Bus connection: %m"); + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit", + &error, + NULL, + "ssi", "systemd-journald.service", "main", sig); + if (r < 0) + return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); + + continue; + } + + /* Let's install the inotify watch, if we didn't do that yet. */ + if (watch_fd < 0) { + + mkdir_p("/run/systemd/journal", 0755); + + watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (watch_fd < 0) + return log_error_errno(errno, "Failed to create inotify watch: %m"); + + r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR); + if (r < 0) + return log_error_errno(errno, "Failed to watch journal directory: %m"); + + /* Recheck the flag file immediately, so that we don't miss any event since the last check. */ + continue; + } + + /* OK, all preparatory steps done, let's wait until + * inotify reports an event. */ + + r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY); + if (r < 0) + return log_error_errno(r, "Failed to wait for event: %m"); + + r = flush_fd(watch_fd); + if (r < 0) + return log_error_errno(r, "Failed to flush inotify events: %m"); + } return 0; } +static int rotate(void) { + return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated"); +} + +static int sync_journal(void) { + return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced"); +} + int main(int argc, char *argv[]) { int r; _cleanup_journal_close_ sd_journal *j = NULL; @@ -1865,30 +1943,19 @@ int main(int argc, char *argv[]) { * be split up into many files. */ setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384)); - if (arg_action == ACTION_NEW_ID128) { - r = generate_new_id128(); - goto finish; - } + switch (arg_action) { - if (arg_action == ACTION_FLUSH) { - r = flush_to_var(); - goto finish; - } - - if (arg_action == ACTION_ROTATE) { - r = rotate(); + case ACTION_NEW_ID128: + r = generate_new_id128(); goto finish; - } - if (arg_action == ACTION_SETUP_KEYS) { + case ACTION_SETUP_KEYS: r = setup_keys(); goto finish; - } - - if (arg_action == ACTION_UPDATE_CATALOG || - arg_action == ACTION_LIST_CATALOG || - arg_action == ACTION_DUMP_CATALOG) { + case ACTION_LIST_CATALOG: + case ACTION_DUMP_CATALOG: + case ACTION_UPDATE_CATALOG: { _cleanup_free_ char *database; database = path_join(arg_root, CATALOG_DATABASE, NULL); @@ -1905,9 +1972,9 @@ int main(int argc, char *argv[]) { bool oneline = arg_action == ACTION_LIST_CATALOG; pager_open_if_enabled(); + if (optind < argc) - r = catalog_list_items(stdout, database, - oneline, argv + optind); + r = catalog_list_items(stdout, database, oneline, argv + optind); else r = catalog_list(stdout, database, oneline); if (r < 0) @@ -1917,6 +1984,31 @@ int main(int argc, char *argv[]) { goto finish; } + case ACTION_FLUSH: + r = flush_to_var(); + goto finish; + + case ACTION_SYNC: + r = sync_journal(); + goto finish; + + case ACTION_ROTATE: + r = rotate(); + goto finish; + + case ACTION_SHOW: + case ACTION_PRINT_HEADER: + case ACTION_VERIFY: + case ACTION_DISK_USAGE: + case ACTION_LIST_BOOTS: + case ACTION_VACUUM: + /* These ones require access to the journal files, continue below. */ + break; + + default: + assert_not_reached("Unknown action"); + } + if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); else if (arg_file) @@ -1926,8 +2018,7 @@ int main(int argc, char *argv[]) { else r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { - log_error_errno(r, "Failed to open %s: %m", - arg_directory ? arg_directory : arg_file ? "files" : "journal"); + log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal"); goto finish; } @@ -1935,18 +2026,28 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - if (arg_action == ACTION_VERIFY) { - r = verify(j); - goto finish; - } + switch (arg_action) { + + case ACTION_NEW_ID128: + case ACTION_SETUP_KEYS: + case ACTION_LIST_CATALOG: + case ACTION_DUMP_CATALOG: + case ACTION_UPDATE_CATALOG: + case ACTION_FLUSH: + case ACTION_SYNC: + case ACTION_ROTATE: + assert_not_reached("Unexpected action."); - if (arg_action == ACTION_PRINT_HEADER) { + case ACTION_PRINT_HEADER: journal_print_header(j); r = 0; goto finish; - } - if (arg_action == ACTION_DISK_USAGE) { + case ACTION_VERIFY: + r = verify(j); + goto finish; + + case ACTION_DISK_USAGE: { uint64_t bytes = 0; char sbytes[FORMAT_BYTES_MAX]; @@ -1959,7 +2060,11 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_VACUUM) { + case ACTION_LIST_BOOTS: + r = list_boots(j); + goto finish; + + case ACTION_VACUUM: { Directory *d; Iterator i; @@ -1979,9 +2084,11 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_LIST_BOOTS) { - r = list_boots(j); - goto finish; + case ACTION_SHOW: + break; + + default: + assert_not_reached("Unknown action"); } /* add_boot() must be called first! @@ -2140,7 +2247,8 @@ int main(int argc, char *argv[]) { if (arg_follow) need_seek = true; else { - printf("-- No entries --\n"); + if (!arg_quiet) + printf("-- No entries --\n"); goto finish; } } diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h index 68cdfb3410..5c88bb6383 100644 --- a/src/journal/journald-audit.h +++ b/src/journal/journald-audit.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "socket-util.h" #include "journald-server.h" +#include "socket-util.h" void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const union sockaddr_union *sa, socklen_t salen); diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c index 89f3d4b42f..04487c29b5 100644 --- a/src/journal/journald-console.c +++ b/src/journal/journald-console.c @@ -19,9 +19,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <time.h> #include <fcntl.h> #include <sys/socket.h> +#include <time.h> #include "alloc-util.h" #include "fd-util.h" diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 1e3774dafb..69a685c06f 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -22,6 +22,7 @@ #include <stddef.h> #include <sys/epoll.h> #include <sys/mman.h> +#include <sys/statvfs.h> #include <unistd.h> #include "alloc-util.h" @@ -399,8 +400,37 @@ void server_process_native_file( assert_se(munmap(p, ps) >= 0); } else { _cleanup_free_ void *p = NULL; + struct statvfs vfs; ssize_t n; + if (fstatvfs(fd, &vfs) < 0) { + log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m"); + return; + } + + /* Refuse operating on file systems that have + * mandatory locking enabled, see: + * + * https://github.com/systemd/systemd/issues/1822 + */ + if (vfs.f_flag & ST_MANDLOCK) { + log_error("Received file descriptor from file system with mandatory locking enable, refusing."); + return; + } + + /* Make the fd non-blocking. On regular files this has + * the effect of bypassing mandatory locking. Of + * course, this should normally not be necessary given + * the check above, but let's better be safe than + * sorry, after all NFS is pretty confusing regarding + * file system flags, and we better don't trust it, + * and so is SMB. */ + r = fd_nonblock(fd, true); + if (r < 0) { + log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m"); + return; + } + /* The file is not sealed, we can't map the file here, since * clients might then truncate it and trigger a SIGBUS for * us. So let's stupidly read it */ diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c index 434ddc8ac9..1c406aef8e 100644 --- a/src/journal/journald-rate-limit.c +++ b/src/journal/journald-rate-limit.c @@ -24,11 +24,11 @@ #include "alloc-util.h" #include "hashmap.h" +#include "journald-rate-limit.h" #include "list.h" #include "random-util.h" #include "string-util.h" #include "util.h" -#include "journald-rate-limit.h" #define POOLS_MAX 5 #define BUCKETS_MAX 127 @@ -162,7 +162,7 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, siphash24_init(&state, r->hash_key); string_hash_func(g->id, &state); - siphash24_finalize((uint8_t*)&g->hash, &state); + g->hash = siphash24_finalize(&state); journal_rate_limit_vacuum(r, ts); @@ -230,7 +230,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u siphash24_init(&state, r->hash_key); string_hash_func(id, &state); - siphash24_finalize((uint8_t*)&h, &state); + h = siphash24_finalize(&state); g = r->buckets[h % BUCKETS_MAX]; LIST_FOREACH(bucket, g, g) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 36fe739073..7d11a568aa 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -41,6 +41,7 @@ #include "dirent-util.h" #include "extract-word.h" #include "fd-util.h" +#include "fileio.h" #include "formats-util.h" #include "fs-util.h" #include "hashmap.h" @@ -68,6 +69,7 @@ #include "socket-util.h" #include "string-table.h" #include "string-util.h" +#include "user-util.h" #define USER_JOURNALS_MAX 1024 @@ -280,7 +282,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { if (r < 0) return s->system_journal; - f = ordered_hashmap_get(s->user_journals, UINT32_TO_PTR(uid)); + f = ordered_hashmap_get(s->user_journals, UID_TO_PTR(uid)); if (f) return f; @@ -301,7 +303,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { server_fix_perms(s, f, uid); - r = ordered_hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f); + r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f); if (r < 0) { journal_file_close(f); return s->system_journal; @@ -347,7 +349,7 @@ void server_rotate(Server *s) { (void) do_rotate(s, &s->system_journal, "system", s->seal, 0); ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { - r = do_rotate(s, &f, "user", s->seal, PTR_TO_UINT32(k)); + r = do_rotate(s, &f, "user", s->seal, PTR_TO_UID(k)); if (r >= 0) ordered_hashmap_replace(s->user_journals, k, f); else if (!f) @@ -358,7 +360,6 @@ void server_rotate(Server *s) { void server_sync(Server *s) { JournalFile *f; - void *k; Iterator i; int r; @@ -368,7 +369,7 @@ void server_sync(Server *s) { log_warning_errno(r, "Failed to sync system journal, ignoring: %m"); } - ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) { r = journal_file_set_offline(f); if (r < 0) log_warning_errno(r, "Failed to sync user journal, ignoring: %m"); @@ -1240,29 +1241,38 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { Server *s = userdata; + int r; assert(s); - log_info("Received request to flush runtime journal from PID %"PRIu32, si->ssi_pid); + log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid); server_flush_to_var(s); server_sync(s); server_vacuum(s, false, false); - (void) touch("/run/systemd/journal/flushed"); + r = touch("/run/systemd/journal/flushed"); + if (r < 0) + log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m"); return 0; } static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { Server *s = userdata; + int r; assert(s); - log_info("Received request to rotate journal from PID %"PRIu32, si->ssi_pid); + log_info("Received request to rotate journal from PID " PID_FMT, si->ssi_pid); server_rotate(s); server_vacuum(s, true, true); + /* Let clients know when the most recent rotation happened. */ + r = write_timestamp_file_atomic("/run/systemd/journal/rotated", now(CLOCK_MONOTONIC)); + if (r < 0) + log_warning_errno(r, "Failed to write /run/systemd/journal/rotated, ignoring: %m"); + return 0; } @@ -1277,12 +1287,30 @@ static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo * return 0; } +static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { + Server *s = userdata; + int r; + + assert(s); + + log_debug("Received request to sync from PID " PID_FMT, si->ssi_pid); + + server_sync(s); + + /* Let clients know when the most recent sync happened. */ + r = write_timestamp_file_atomic("/run/systemd/journal/synced", now(CLOCK_MONOTONIC)); + if (r < 0) + log_warning_errno(r, "Failed to write /run/systemd/journal/synced, ignoring: %m"); + + return 0; +} + static int setup_signals(Server *s) { int r; assert(s); - assert(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1) >= 0); + assert(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0); r = sd_event_add_signal(s->event, &s->sigusr1_event_source, SIGUSR1, dispatch_sigusr1, s); if (r < 0) @@ -1312,6 +1340,19 @@ static int setup_signals(Server *s) { if (r < 0) return r; + /* SIGRTMIN+1 causes an immediate sync. We process this very + * late, so that everything else queued at this point is + * really written to disk. Clients can watch + * /run/systemd/journal/synced with inotify until its mtime + * changes to see when a sync happened. */ + r = sd_event_add_signal(s->event, &s->sigrtmin1_event_source, SIGRTMIN+1, dispatch_sigrtmin1, s); + if (r < 0) + return r; + + r = sd_event_source_set_priority(s->sigrtmin1_event_source, SD_EVENT_PRIORITY_NORMAL+15); + if (r < 0) + return r; + return 0; } @@ -1484,11 +1525,6 @@ static int dispatch_notify_event(sd_event_source *es, int fd, uint32_t revents, assert(s->notify_event_source == es); assert(s->notify_fd == fd); - if (revents != EPOLLOUT) { - log_error("Invalid events on notify file descriptor."); - return -EINVAL; - } - /* The $NOTIFY_SOCKET is writable again, now send exactly one * message on it. Either it's the wtachdog event, the initial * READY=1 event or an stdout stream event. If there's nothing @@ -1634,7 +1670,7 @@ static int server_connect_notify(Server *s) { if (sd_watchdog_enabled(false, &s->watchdog_usec) > 0) { s->send_watchdog = true; - r = sd_event_add_time(s->event, &s->watchdog_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->watchdog_usec/2, s->watchdog_usec*3/4, dispatch_watchdog, s); + r = sd_event_add_time(s->event, &s->watchdog_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->watchdog_usec/2, s->watchdog_usec/4, dispatch_watchdog, s); if (r < 0) return log_error_errno(r, "Failed to add watchdog time event: %m"); } @@ -1874,6 +1910,7 @@ void server_done(Server *s) { sd_event_source_unref(s->sigusr2_event_source); sd_event_source_unref(s->sigterm_event_source); sd_event_source_unref(s->sigint_event_source); + sd_event_source_unref(s->sigrtmin1_event_source); sd_event_source_unref(s->hostname_event_source); sd_event_source_unref(s->notify_event_source); sd_event_source_unref(s->watchdog_event_source); diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 03a61bd2ed..dcc21bb7c3 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -72,6 +72,7 @@ struct Server { sd_event_source *sigusr2_event_source; sd_event_source *sigterm_event_source; sd_event_source *sigint_event_source; + sd_event_source *sigrtmin1_event_source; sd_event_source *hostname_event_source; sd_event_source *notify_event_source; sd_event_source *watchdog_event_source; diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c index 69540f1141..88bea3b86e 100644 --- a/src/journal/journald-wall.c +++ b/src/journal/journald-wall.c @@ -22,10 +22,10 @@ #include "alloc-util.h" #include "formats-util.h" #include "journald-server.h" +#include "journald-wall.h" #include "process-util.h" #include "string-util.h" #include "utmp-wtmp.h" -#include "journald-wall.h" void server_forward_wall( Server *s, diff --git a/src/journal/journald.c b/src/journal/journald.c index b137e3c7be..b9f5c099e1 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -21,16 +21,15 @@ #include <unistd.h> -#include "sd-messages.h" #include "sd-daemon.h" +#include "sd-messages.h" +#include "formats-util.h" #include "journal-authenticate.h" -#include "journald-server.h" #include "journald-kmsg.h" +#include "journald-server.h" #include "journald-syslog.h" - #include "sigbus.h" -#include "formats-util.h" int main(int argc, char *argv[]) { Server server; diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c index 52ffdf7b1d..3d791234f4 100644 --- a/src/journal/lookup3.c +++ b/src/journal/lookup3.c @@ -40,10 +40,10 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. */ /* #define SELF_TEST 1 */ -#include <stdio.h> /* defines printf for tests */ -#include <time.h> /* defines time_t for timings in the test */ #include <stdint.h> /* defines uint32_t etc */ +#include <stdio.h> /* defines printf for tests */ #include <sys/param.h> /* attempt to define endianness */ +#include <time.h> /* defines time_t for timings in the test */ #ifdef linux # include <endian.h> /* attempt to define endianness */ #endif diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c index 3cb1dfa986..5a07ddda76 100644 --- a/src/journal/mmap-cache.c +++ b/src/journal/mmap-cache.c @@ -24,13 +24,14 @@ #include <sys/mman.h> #include "alloc-util.h" +#include "fd-util.h" #include "hashmap.h" #include "list.h" #include "log.h" -#include "util.h" #include "macro.h" -#include "sigbus.h" #include "mmap-cache.h" +#include "sigbus.h" +#include "util.h" typedef struct Window Window; typedef struct Context Context; @@ -289,7 +290,7 @@ static void fd_free(FileDescriptor *f) { window_free(f->windows); if (f->cache) - assert_se(hashmap_remove(f->cache->fds, INT_TO_PTR(f->fd + 1))); + assert_se(hashmap_remove(f->cache->fds, FD_TO_PTR(f->fd))); free(f); } @@ -301,7 +302,7 @@ static FileDescriptor* fd_add(MMapCache *m, int fd) { assert(m); assert(fd >= 0); - f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + f = hashmap_get(m->fds, FD_TO_PTR(fd)); if (f) return f; @@ -316,7 +317,7 @@ static FileDescriptor* fd_add(MMapCache *m, int fd) { f->cache = m; f->fd = fd; - r = hashmap_put(m->fds, UINT_TO_PTR(fd + 1), f); + r = hashmap_put(m->fds, FD_TO_PTR(fd), f); if (r < 0) { free(f); return NULL; @@ -429,7 +430,7 @@ static int find_mmap( assert(fd >= 0); assert(size > 0); - f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + f = hashmap_get(m->fds, FD_TO_PTR(fd)); if (!f) return 0; @@ -679,7 +680,7 @@ bool mmap_cache_got_sigbus(MMapCache *m, int fd) { mmap_cache_process_sigbus(m); - f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + f = hashmap_get(m->fds, FD_TO_PTR(fd)); if (!f) return false; @@ -698,7 +699,7 @@ void mmap_cache_close_fd(MMapCache *m, int fd) { mmap_cache_process_sigbus(m); - f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + f = hashmap_get(m->fds, FD_TO_PTR(fd)); if (!f) return; diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index aea8fd15e6..25980b7744 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -20,10 +20,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <locale.h> -#include <unistd.h> #include <errno.h> #include <fcntl.h> +#include <locale.h> +#include <unistd.h> #include "sd-messages.h" diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c index 040c7d58fb..8f56ea1907 100644 --- a/src/journal/test-journal-enum.c +++ b/src/journal/test-journal-enum.c @@ -23,9 +23,9 @@ #include "sd-journal.h" +#include "journal-internal.h" #include "log.h" #include "macro.h" -#include "journal-internal.h" int main(int argc, char *argv[]) { unsigned n = 0; diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c index 4ad89fe4b6..5c055ef748 100644 --- a/src/journal/test-journal-interleaving.c +++ b/src/journal/test-journal-interleaving.c @@ -20,8 +20,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <unistd.h> #include <fcntl.h> +#include <unistd.h> #include "sd-journal.h" diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c index 887a83efe1..a7abb11fba 100644 --- a/src/journal/test-journal-verify.c +++ b/src/journal/test-journal-verify.c @@ -19,9 +19,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <fcntl.h> #include <stdio.h> #include <unistd.h> -#include <fcntl.h> #include "fd-util.h" #include "journal-file.h" diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c index 01d4bc968a..266e0d5473 100644 --- a/src/journal/test-journal.c +++ b/src/journal/test-journal.c @@ -22,11 +22,11 @@ #include <fcntl.h> #include <unistd.h> -#include "log.h" -#include "rm-rf.h" -#include "journal-file.h" #include "journal-authenticate.h" +#include "journal-file.h" #include "journal-vacuum.h" +#include "log.h" +#include "rm-rf.h" static bool arg_keep = false; |