summaryrefslogtreecommitdiff
path: root/src/journal
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal')
-rw-r--r--src/journal/audit-type.c5
-rw-r--r--src/journal/catalog.h1
-rw-r--r--src/journal/coredump-vacuum.c15
-rw-r--r--src/journal/fsprg.h2
-rw-r--r--src/journal/journal-authenticate.c2
-rw-r--r--src/journal/journal-file.h4
-rw-r--r--src/journal/journal-internal.h2
-rw-r--r--src/journal/journal-qrcode.c7
-rw-r--r--src/journal/journal-verify.c4
-rw-r--r--src/journal/journalctl.c224
-rw-r--r--src/journal/journald-audit.h2
-rw-r--r--src/journal/journald-console.c2
-rw-r--r--src/journal/journald-native.c30
-rw-r--r--src/journal/journald-rate-limit.c6
-rw-r--r--src/journal/journald-server.c67
-rw-r--r--src/journal/journald-server.h1
-rw-r--r--src/journal/journald-wall.c2
-rw-r--r--src/journal/journald.c7
-rw-r--r--src/journal/lookup3.c4
-rw-r--r--src/journal/mmap-cache.c17
-rw-r--r--src/journal/test-catalog.c4
-rw-r--r--src/journal/test-journal-enum.c2
-rw-r--r--src/journal/test-journal-interleaving.c2
-rw-r--r--src/journal/test-journal-verify.c2
-rw-r--r--src/journal/test-journal.c6
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;