X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournald-server.c;h=28ce69dccd6b764e989d3bcf5579b86238e42ab3;hp=654f7ace2177e2f309a4ff92d7cc27ab3e02c223;hb=0a20e3c10761378869af7bbef2733e3ae879d0f1;hpb=fc7b7e2e74ed0c4ce2bda91d693240c9dcd0d526 diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 654f7ace2..28ce69dcc 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,7 @@ #define USER_JOURNALS_MAX 1024 +#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE) #define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC) #define DEFAULT_RATE_LIMIT_BURST 200 @@ -174,7 +176,7 @@ static uint64_t available_space(Server *s) { } static void server_read_file_gid(Server *s) { - const char *adm = "adm"; + const char *g = "systemd-journal"; int r; assert(s); @@ -182,9 +184,9 @@ static void server_read_file_gid(Server *s) { if (s->file_gid_valid) return; - r = get_group_creds(&adm, &s->file_gid); + r = get_group_creds(&g, &s->file_gid); if (r < 0) - log_warning("Failed to resolve 'adm' group: %s", strerror(-r)); + log_warning("Failed to resolve '%s' group: %s", g, strerror(-r)); /* if we couldn't read the gid, then it will be 0, but that's * fine and we shouldn't try to resolve the group again, so @@ -344,6 +346,33 @@ void server_rotate(Server *s) { } } +void server_sync(Server *s) { + JournalFile *f; + void *k; + Iterator i; + int r; + + static const struct itimerspec sync_timer_disable = {}; + + if (s->system_journal) { + r = journal_file_set_offline(s->system_journal); + if (r < 0) + log_error("Failed to sync system journal: %s", strerror(-r)); + } + + HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + r = journal_file_set_offline(f); + if (r < 0) + log_error("Failed to sync user journal: %s", strerror(-r)); + } + + r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_disable, NULL); + if (r < 0) + log_error("Failed to disable max timer: %m"); + + s->sync_scheduled = false; +} + void server_vacuum(Server *s) { char *p; char ids[33]; @@ -475,8 +504,10 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned } r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); - if (r >= 0) + if (r >= 0) { + server_schedule_sync(s); return; + } if (vacuumed || !shall_try_append_again(f, r)) { log_error("Failed to write entry, ignoring: %s", strerror(-r)); @@ -524,8 +555,10 @@ static void dispatch_message_real( assert(n + N_IOVEC_META_FIELDS <= m); if (ucred) { +#ifdef HAVE_AUDIT uint32_t audit; uid_t loginuid; +#endif realuid = ucred->uid; @@ -565,6 +598,7 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], cmdline); } +#ifdef HAVE_AUDIT r = audit_session_from_pid(ucred->pid, &audit); if (r >= 0) if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0) @@ -574,6 +608,7 @@ static void dispatch_message_real( if (r >= 0) if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) IOVEC_SET_STRING(iovec[n++], audit_loginuid); +#endif t = shortened_cgroup_path(ucred->pid); if (t) { @@ -593,7 +628,7 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], session); } - if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) { + if (sd_pid_get_owner_uid(ucred->pid, &owner) >= 0) { owner_valid = true; if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) IOVEC_SET_STRING(iovec[n++], owner_uid); @@ -688,7 +723,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, struct iovec iovec[N_IOVEC_META_FIELDS + 4]; int n = 0; va_list ap; - struct ucred ucred; + struct ucred ucred = {}; assert(s); assert(format); @@ -709,7 +744,6 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, IOVEC_SET_STRING(iovec[n++], mid); } - zero(ucred); ucred.pid = getpid(); ucred.uid = getuid(); ucred.gid = getgid(); @@ -960,8 +994,7 @@ finish: if (r >= 0) rm_rf("/run/log/journal", false, true, false); - if (j) - sd_journal_close(j); + sd_journal_close(j); return r; } @@ -991,11 +1024,10 @@ int process_event(Server *s, struct epoll_event *ev) { return -errno; } - log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo)); - if (sfsi.ssi_signo == SIGUSR1) { touch("/run/systemd/journal/flushed"); server_flush_to_var(s); + server_sync(s); return 1; } @@ -1005,8 +1037,23 @@ int process_event(Server *s, struct epoll_event *ev) { return 1; } + log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo)); + return 0; + } else if (ev->data.fd == s->sync_timer_fd) { + int r; + uint64_t t; + + log_debug("Got sync request from epoll."); + + r = read(ev->data.fd, (void *)&t, sizeof(t)); + if (r < 0) + return 0; + + server_sync(s); + return 1; + } else if (ev->data.fd == s->dev_kmsg_fd) { int r; @@ -1286,16 +1333,67 @@ static int server_parse_config_file(Server *s) { return r; } +static int server_open_sync_timer(Server *s) { + int r; + struct epoll_event ev; + + assert(s); + + s->sync_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + if (s->sync_timer_fd < 0) + return -errno; + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->sync_timer_fd; + + r = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->sync_timer_fd, &ev); + if (r < 0) { + log_error("Failed to add idle timer fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +int server_schedule_sync(Server *s) { + int r; + + assert(s); + + if (s->sync_scheduled) + return 0; + + if (s->sync_interval_usec) { + struct itimerspec sync_timer_enable = { + .it_value.tv_sec = s->sync_interval_usec / USEC_PER_SEC, + .it_value.tv_nsec = s->sync_interval_usec % MSEC_PER_SEC, + }; + + r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL); + if (r < 0) + return -errno; + } + + s->sync_scheduled = true; + + return 0; +} + int server_init(Server *s) { int n, r, fd; assert(s); zero(*s); - s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; + s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd = + s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; s->compress = true; s->seal = true; + s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC; + s->sync_scheduled = false; + s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL; s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST; @@ -1395,6 +1493,10 @@ int server_init(Server *s) { if (r < 0) return r; + r = server_open_sync_timer(s); + if (r < 0) + return r; + r = open_signalfd(s); if (r < 0) return r; @@ -1467,6 +1569,9 @@ void server_done(Server *s) { if (s->dev_kmsg_fd >= 0) close_nointr_nofail(s->dev_kmsg_fd); + if (s->sync_timer_fd >= 0) + close_nointr_nofail(s->sync_timer_fd); + if (s->rate_limit) journal_rate_limit_free(s->rate_limit);