journald-server.c revision db91ea32aa223d1b087d99811226a9c59a1bb281
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering This file is part of systemd.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Copyright 2011 Lennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is free software; you can redistribute it and/or modify it
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering under the terms of the GNU Lesser General Public License as published by
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering (at your option) any later version.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is distributed in the hope that it will be useful, but
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Lesser General Public License for more details.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering You should have received a copy of the GNU Lesser General Public License
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic const char* const storage_table[] = {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic const char* const split_mode_table[] = {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic uint64_t available_space(Server *s) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering const char *f;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering uint64_t sum = 0, avail = 0, ss_avail = 0;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering p = strappend(f, sd_id128_to_string(machine, ids));
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering avail = sum >= m->max_use ? 0 : m->max_use - sum;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
return avail;
assert(s);
if (s->file_gid_valid)
s->file_gid_valid = true;
#ifdef HAVE_ACL
assert(f);
#ifdef HAVE_ACL
if (uid <= 0)
if (!acl) {
goto finish;
goto finish;
JournalFile *f;
assert(s);
if (s->runtime_journal)
return s->runtime_journal;
if (uid <= 0)
return s->system_journal;
return s->system_journal;
return s->system_journal;
assert(f);
r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
free(p);
return s->system_journal;
return s->system_journal;
JournalFile *f;
Iterator i;
if (s->runtime_journal) {
if (s->runtime_journal)
if (s->system_journal) {
if (s->system_journal)
s->oldest_file_usec = 0;
if (s->system_journal) {
log_oom();
r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
free(p);
if (s->runtime_journal) {
log_oom();
r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
free(p);
s->cached_available_space_timestamp = 0;
char *path;
return NULL;
return NULL;
init_path[0] = 0;
return path;
else if (r == -EHOSTDOWN)
else if (r == -EBUSY)
else if (r == -EPROTONOSUPPORT)
JournalFile *f;
bool vacuumed = false;
assert(s);
assert(n > 0);
server_rotate(s);
server_vacuum(s);
vacuumed = true;
server_rotate(s);
server_vacuum(s);
static void dispatch_message_real(
Server *s,
const char *unit_id) {
assert(s);
assert(n > 0);
if (ucred) {
#ifdef HAVE_LOGIND
free(t);
if (comm)
free(t);
if (exe)
free(t);
if (cmdline)
free(t);
if (cgroup)
#ifdef HAVE_LOGIND
free(t);
if (session)
free(t);
} else if (unit_id)
if (unit)
#ifdef HAVE_SELINUX
if (label) {
if (selinux_context) {
if (selinux_context)
if (tv) {
t = gethostname_malloc();
free(t);
if (hostname)
assert(n <= m);
assert(s);
void server_dispatch_message(
Server *s,
const char *unit_id,
int priority) {
int rl;
assert(s);
if (!ucred)
goto finish;
if (!path)
goto finish;
if (rl == 0)
char *fn;
if (!s->system_journal &&
if (!fn)
return -ENOMEM;
if (!fn)
return -ENOMEM;
r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
if (!s->runtime_journal &&
if (!fn)
return -ENOMEM;
if (s->system_journal) {
r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
if (r != -ENOENT)
r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
if (s->runtime_journal) {
assert(s);
if (!s->runtime_journal)
if (!s->system_journal)
SD_JOURNAL_FOREACH(j) {
JournalFile *f;
f = j->current_file;
goto finish;
goto finish;
server_rotate(s);
server_vacuum(s);
goto finish;
sd_journal_close(j);
assert(s);
ssize_t n;
return -EIO;
if (n != sizeof(sfsi)) {
return -EIO;
return -errno;
server_rotate(s);
server_vacuum(s);
return -EIO;
r = server_read_dev_kmsg(s);
return -EIO;
} control;
ssize_t n;
unsigned n_fds = 0;
return -errno;
size_t l;
return -ENOMEM;
s->buffer_size = l;
s->buffer = b;
return -errno;
if (n > 0 && n_fds == 0) {
s->buffer[n] = 0;
} else if (n_fds > 0)
if (n > 0 && n_fds == 0)
else if (n_fds > 0)
return -EIO;
return -EIO;
assert(s);
if (s->signal_fd < 0) {
return -errno;
return -errno;
char *w, *state;
size_t l;
if (!word)
return -ENOMEM;
s->forward_to_syslog = r;
s->forward_to_kmsg = r;
s->forward_to_console = r;
assert(s);
return -errno;
(void*) journald_gperf_lookup, false, s);
int n, r, fd;
assert(s);
zero(*s);
s->compress = true;
s->seal = true;
s->forward_to_syslog = true;
if (!s->user_journals)
return log_oom();
if (!s->mmap)
return log_oom();
if (s->epoll_fd < 0) {
return -errno;
n = sd_listen_fds(true);
if (s->native_fd >= 0) {
return -EINVAL;
if (s->stdout_fd >= 0) {
return -EINVAL;
if (s->syslog_fd >= 0) {
return -EINVAL;
return -EINVAL;
r = server_open_syslog_socket(s);
r = server_open_native_socket(s);
r = server_open_stdout_socket(s);
r = server_open_dev_kmsg(s);
r = server_open_kernel_seqnum(s);
r = open_signalfd(s);
if (!s->udev)
return -ENOMEM;
if (!s->rate_limit)
return -ENOMEM;
r = system_journal_open(s);
#ifdef HAVE_GCRYPT
JournalFile *f;
Iterator i;
usec_t n;
if (s->system_journal)
JournalFile *f;
assert(s);
while (s->stdout_streams)
if (s->system_journal)
if (s->runtime_journal)
if (s->epoll_fd >= 0)
if (s->signal_fd >= 0)
if (s->syslog_fd >= 0)
if (s->native_fd >= 0)
if (s->stdout_fd >= 0)
if (s->dev_kmsg_fd >= 0)
if (s->rate_limit)
if (s->kernel_seqnum)
if (s->mmap)
if (s->udev)