journal-remote-write.c revision eacbb4d33e2bb5c54311544851140efe3dd0f774
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2012 Zbigniew Jędrzejewski-Szmek
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "journal-remote-write.h"
int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
return log_oom();
iovw->iovec[iovw->count++] = (struct iovec) {data, len};
return 0;
}
void iovw_free_contents(struct iovec_wrapper *iovw) {
for (size_t j = 0; j < iovw->count; j++)
free(iovw->iovec[j].iov_base);
free(iovw->iovec);
iovw->iovec = NULL;
iovw->size_bytes = iovw->count = 0;
}
size_t iovw_size(struct iovec_wrapper *iovw) {
size_t n = 0, i;
for(i = 0; i < iovw->count; i++)
n += iovw->iovec[i].iov_len;
return n;
}
/**********************************************************************
**********************************************************************
**********************************************************************/
static int do_rotate(JournalFile **f, bool compress, bool seal) {
int r = journal_file_rotate(f, compress, seal);
if (r < 0) {
if (*f)
log_error("Failed to rotate %s: %s", (*f)->path,
strerror(-r));
else
log_error("Failed to create rotated journal: %s",
strerror(-r));
}
return r;
}
int writer_init(Writer *s) {
assert(s);
s->journal = NULL;
memset(&s->metrics, 0xFF, sizeof(s->metrics));
s->mmap = mmap_cache_new();
if (!s->mmap)
return log_oom();
s->seqnum = 0;
return 0;
}
int writer_close(Writer *s) {
if (s->journal) {
journal_file_close(s->journal);
log_debug("Journal has been closed.");
}
if (s->mmap)
mmap_cache_unref(s->mmap);
return 0;
}
int writer_write(Writer *s,
struct iovec_wrapper *iovw,
dual_timestamp *ts,
bool compress,
bool seal) {
int r;
assert(s);
assert(iovw);
assert(iovw->count > 0);
if (journal_file_rotate_suggested(s->journal, 0)) {
log_info("%s: Journal header limits reached or header out-of-date, rotating",
s->journal->path);
r = do_rotate(&s->journal, compress, seal);
if (r < 0)
return r;
}
r = journal_file_append_entry(s->journal, ts, iovw->iovec, iovw->count,
&s->seqnum, NULL, NULL);
if (r >= 0)
return 1;
log_info("%s: Write failed, rotating", s->journal->path);
r = do_rotate(&s->journal, compress, seal);
if (r < 0)
return r;
log_debug("Retrying write.");
r = journal_file_append_entry(s->journal, ts, iovw->iovec, iovw->count,
&s->seqnum, NULL, NULL);
return r < 0 ? r : 1;
}