Merge pull request #30312 from yuwata/journal-cleanups

journal: several cleanups
This commit is contained in:
Yu Watanabe
2023-12-07 13:23:06 +09:00
committed by GitHub
8 changed files with 109 additions and 100 deletions

View File

@@ -5,13 +5,13 @@
#include "journald-audit.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Server s;
_cleanup_(server_freep) Server *s = NULL;
fuzz_setup_logging();
dummy_server_init(&s, data, size);
process_audit_string(&s, 0, s.buffer, size);
server_done(&s);
assert_se(server_new(&s) >= 0);
dummy_server_init(s, data, size);
process_audit_string(s, 0, s->buffer, size);
return 0;
}

View File

@@ -5,16 +5,16 @@
#include "journald-kmsg.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Server s;
_cleanup_(server_freep) Server *s = NULL;
if (size == 0)
return 0;
fuzz_setup_logging();
dummy_server_init(&s, data, size);
dev_kmsg_record(&s, s.buffer, size);
server_done(&s);
assert_se(server_new(&s) >= 0);
dummy_server_init(s, data, size);
dev_kmsg_record(s, s->buffer, size);
return 0;
}

View File

@@ -10,7 +10,7 @@
#include "tmpfile-util.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Server s;
_cleanup_(server_freep) Server *s = NULL;
_cleanup_close_ int sealed_fd = -EBADF, unsealed_fd = -EBADF;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
char *label = NULL;
@@ -20,7 +20,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
fuzz_setup_logging();
dummy_server_init(&s, NULL, 0);
assert_se(server_new(&s) >= 0);
dummy_server_init(s, NULL, 0);
sealed_fd = memfd_new_and_seal(NULL, data, size);
assert_se(sealed_fd >= 0);
@@ -29,15 +30,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
.uid = geteuid(),
.gid = getegid(),
};
server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len);
server_process_native_file(s, sealed_fd, &ucred, tv, label, label_len);
unsealed_fd = mkostemp_safe(name);
assert_se(unsealed_fd >= 0);
assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len);
server_done(&s);
server_process_native_file(s, unsealed_fd, &ucred, tv, label, label_len);
return 0;
}

View File

@@ -9,12 +9,11 @@
#include "fuzz-journald.h"
#include "journald-stream.h"
static int stream_fds[2] = EBADF_PAIR;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Server s;
_cleanup_close_pair_ int stream_fds[2] = EBADF_PAIR;
_cleanup_(server_freep) Server *s = NULL;
StdoutStream *stream;
int v;
int v, fd0;
if (outside_size_range(size, 1, 65536))
return 0;
@@ -22,15 +21,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
fuzz_setup_logging();
assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0);
dummy_server_init(&s, NULL, 0);
assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0);
assert_se(server_new(&s) >= 0);
dummy_server_init(s, NULL, 0);
assert_se(stdout_stream_install(s, stream_fds[0], &stream) >= 0);
fd0 = TAKE_FD(stream_fds[0]); /* avoid double close */
assert_se(write(stream_fds[1], data, size) == (ssize_t) size);
while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v)
sd_event_run(s.event, UINT64_MAX);
if (s.n_stdout_streams)
while (ioctl(fd0, SIOCINQ, &v) == 0 && v)
sd_event_run(s->event, UINT64_MAX);
if (s->n_stdout_streams > 0)
stdout_stream_destroy(stream);
server_done(&s);
stream_fds[1] = safe_close(stream_fds[1]);
return 0;
}

View File

@@ -6,17 +6,9 @@
#include "sd-event.h"
void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
*s = (Server) {
.syslog_fd = -EBADF,
.native_fd = -EBADF,
.stdout_fd = -EBADF,
.dev_kmsg_fd = -EBADF,
.audit_fd = -EBADF,
.hostname_fd = -EBADF,
.notify_fd = -EBADF,
.storage = STORAGE_NONE,
.line_max = 64,
};
assert(s);
s->storage = STORAGE_NONE;
assert_se(sd_event_default(&s->event) >= 0);
if (buffer) {
@@ -30,7 +22,8 @@ void fuzz_journald_processing_function(
size_t size,
void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
) {
Server s;
_cleanup_(server_freep) Server *s = NULL;
char *label = NULL;
size_t label_len = 0;
struct ucred *ucred = NULL;
@@ -39,7 +32,7 @@ void fuzz_journald_processing_function(
if (size == 0)
return;
dummy_server_init(&s, data, size);
(*f)(&s, s.buffer, size, ucred, tv, label, label_len);
server_done(&s);
assert_se(server_new(&s) >= 0);
dummy_server_init(s, data, size);
(*f)(s, s->buffer, size, ucred, tv, label, label_len);
}

View File

@@ -2444,13 +2444,14 @@ static int server_setup_memory_pressure(Server *s) {
return 0;
}
int server_init(Server *s, const char *namespace) {
const char *native_socket, *syslog_socket, *stdout_socket, *varlink_socket, *e;
_cleanup_fdset_free_ FDSet *fds = NULL;
int n, r, fd, varlink_fd = -EBADF;
bool no_sockets;
int server_new(Server **ret) {
_cleanup_(server_freep) Server *s = NULL;
assert(s);
assert(ret);
s = new(Server, 1);
if (!s)
return -ENOMEM;
*s = (Server) {
.syslog_fd = -EBADF,
@@ -2499,6 +2500,18 @@ int server_init(Server *s, const char *namespace) {
.sigrtmin18_info.memory_pressure_userdata = s,
};
*ret = TAKE_PTR(s);
return 0;
}
int server_init(Server *s, const char *namespace) {
const char *native_socket, *syslog_socket, *stdout_socket, *varlink_socket, *e;
_cleanup_fdset_free_ FDSet *fds = NULL;
int n, r, fd, varlink_fd = -EBADF;
bool no_sockets;
assert(s);
r = server_set_namespace(s, namespace);
if (r < 0)
return r;
@@ -2721,6 +2734,7 @@ int server_init(Server *s, const char *namespace) {
return r;
server_start_or_stop_idle_timer(s);
return 0;
}
@@ -2739,8 +2753,9 @@ void server_maybe_append_tags(Server *s) {
#endif
}
void server_done(Server *s) {
assert(s);
Server* server_free(Server *s) {
if (!s)
return NULL;
free(s->namespace);
free(s->namespace_field);
@@ -2799,6 +2814,8 @@ void server_done(Server *s) {
free(s->runtime_directory);
mmap_cache_unref(s->mmap);
return mfree(s);
}
static const char* const storage_table[_STORAGE_MAX] = {

View File

@@ -223,8 +223,10 @@ CONFIG_PARSER_PROTOTYPE(config_parse_split_mode);
const char *split_mode_to_string(SplitMode s) _const_;
SplitMode split_mode_from_string(const char *s) _pure_;
int server_new(Server **ret);
int server_init(Server *s, const char *namespace);
void server_done(Server *s);
Server* server_free(Server *s);
DEFINE_TRIVIAL_CLEANUP_FUNC(Server*, server_free);
void server_sync(Server *s);
void server_vacuum(Server *s, bool verbose);
void server_rotate(Server *s);

View File

@@ -10,19 +10,18 @@
#include "journald-kmsg.h"
#include "journald-server.h"
#include "journald-syslog.h"
#include "main-func.h"
#include "process-util.h"
#include "sigbus.h"
int main(int argc, char *argv[]) {
static int run(int argc, char *argv[]) {
_cleanup_(server_freep) Server *s = NULL;
const char *namespace;
LogTarget log_target;
Server server;
int r;
if (argc > 2) {
log_error("This program takes one or no arguments.");
return EXIT_FAILURE;
}
if (argc > 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes one or no arguments.");
namespace = argc > 1 ? empty_to_null(argv[1]) : NULL;
@@ -48,20 +47,24 @@ int main(int argc, char *argv[]) {
sigbus_install();
r = server_init(&server, namespace);
r = server_new(&s);
if (r < 0)
goto finish;
return log_oom();
server_vacuum(&server, false);
server_flush_to_var(&server, true);
server_flush_dev_kmsg(&server);
r = server_init(s, namespace);
if (r < 0)
return r;
if (server.namespace)
log_debug("systemd-journald running as PID "PID_FMT" for namespace '%s'.", getpid_cached(), server.namespace);
server_vacuum(s, /* verbose = */ false);
server_flush_to_var(s, /* require_flag_file = */ true);
server_flush_dev_kmsg(s);
if (s->namespace)
log_debug("systemd-journald running as PID "PID_FMT" for namespace '%s'.", getpid_cached(), s->namespace);
else
log_debug("systemd-journald running as PID "PID_FMT" for the system.", getpid_cached());
server_driver_message(&server, 0,
server_driver_message(s, 0,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_START_STR,
LOG_MESSAGE("Journal started"),
NULL);
@@ -69,70 +72,63 @@ int main(int argc, char *argv[]) {
/* Make sure to send the usage message *after* flushing the
* journal so entries from the runtime journals are ordered
* before this message. See #4190 for some details. */
server_space_usage_message(&server, NULL);
server_space_usage_message(s, NULL);
for (;;) {
usec_t t = USEC_INFINITY, n;
usec_t t, n;
r = sd_event_get_state(server.event);
if (r < 0) {
log_error_errno(r, "Failed to get event loop state: %m");
goto finish;
}
r = sd_event_get_state(s->event);
if (r < 0)
return log_error_errno(r, "Failed to get event loop state: %m");
if (r == SD_EVENT_FINISHED)
break;
n = now(CLOCK_REALTIME);
r = sd_event_now(s->event, CLOCK_REALTIME, &n);
if (r < 0)
return log_error_errno(r, "Failed to get the current time: %m");
if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) {
if (s->max_retention_usec > 0 && s->oldest_file_usec > 0) {
/* Calculate when to rotate the next time */
t = usec_sub_unsigned(usec_add(s->oldest_file_usec, s->max_retention_usec), n);
/* The retention time is reached, so let's vacuum! */
if (server.oldest_file_usec + server.max_retention_usec < n) {
if (t <= 0) {
log_info("Retention time reached, rotating.");
server_rotate(&server);
server_vacuum(&server, false);
server_rotate(s);
server_vacuum(s, /* verbose = */ false);
continue;
}
/* Calculate when to rotate the next time */
t = server.oldest_file_usec + server.max_retention_usec - n;
}
} else
t = USEC_INFINITY;
#if HAVE_GCRYPT
if (server.system_journal) {
if (s->system_journal) {
usec_t u;
if (journal_file_next_evolve_usec(server.system_journal, &u)) {
if (n >= u)
t = 0;
else
t = MIN(t, u - n);
}
if (journal_file_next_evolve_usec(s->system_journal, &u))
t = MIN(t, usec_sub_unsigned(u, n));
}
#endif
r = sd_event_run(server.event, t);
if (r < 0) {
log_error_errno(r, "Failed to run event loop: %m");
goto finish;
}
r = sd_event_run(s->event, t);
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
server_maybe_append_tags(&server);
server_maybe_warn_forward_syslog_missed(&server);
server_maybe_append_tags(s);
server_maybe_warn_forward_syslog_missed(s);
}
if (server.namespace)
log_debug("systemd-journald stopped as PID "PID_FMT" for namespace '%s'.", getpid_cached(), server.namespace);
if (s->namespace)
log_debug("systemd-journald stopped as PID "PID_FMT" for namespace '%s'.", getpid_cached(), s->namespace);
else
log_debug("systemd-journald stopped as PID "PID_FMT" for the system.", getpid_cached());
server_driver_message(&server, 0,
server_driver_message(s, 0,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_STOP_STR,
LOG_MESSAGE("Journal stopped"),
NULL);
finish:
server_done(&server);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
return 0;
}
DEFINE_MAIN_FUNCTION(run);