journal-remote-parse.c revision 92b10cbccdeef3896f45dc340eb7779c78577ede
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync This file is part of systemd.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Copyright 2014 Zbigniew Jędrzejewski-Szmek
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync systemd is free software; you can redistribute it and/or modify it
df03c5ed15c9b5bf6d75fedcdf5057d3ffce8577vboxsync under the terms of the GNU Lesser General Public License as published by
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync the Free Software Foundation; either version 2.1 of the License, or
92a27575521748a392dcd1b996fce55b87411a00vboxsync (at your option) any later version.
92a27575521748a392dcd1b996fce55b87411a00vboxsync systemd is distributed in the hope that it will be useful, but
92a27575521748a392dcd1b996fce55b87411a00vboxsync WITHOUT ANY WARRANTY; without even the implied warranty of
92a27575521748a392dcd1b996fce55b87411a00vboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
92a27575521748a392dcd1b996fce55b87411a00vboxsync Lesser General Public License for more details.
92a27575521748a392dcd1b996fce55b87411a00vboxsync You should have received a copy of the GNU Lesser General Public License
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync along with systemd; If not, see <http://www.gnu.org/licenses/>.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_debug("Closing fd:%d (%s)", source->fd, source->name);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_debug("Writer ref count %u", source->writer->n_ref);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Initialize zero-filled source with given values. On success, takes
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * ownerhship of fd and writer, otherwise does not touch them.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncRemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncstatic char* realloc_buffer(RemoteSource *source, size_t size) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync b = GREEDY_REALLOC(source->buf, source->size, size);
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsyncstatic int get_line(RemoteSource *source, char **line, size_t *size) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync while (true) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync size_t start = MAX(source->scanned, source->offset);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync /* we have to wait for some data to come to us */
360c39d88dfa26b17181b57ebafdb24c2a113c63vboxsync assert(source->size - source->filled >= LINE_CHUNK ||
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync if (n < 0) {
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync } else if (n == 0)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncint push_data(RemoteSource *source, const char *data, size_t size) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync if (!realloc_buffer(source, source->filled + size)) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_error("Failed to store received data of size %zu "
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync "(in addition to existing %zu bytes with %zu filled): %s",
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync size, source->size, source->filled, strerror(ENOMEM));
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncstatic int fill_fixed_size(RemoteSource *source, void **data, size_t size) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* we have to wait for some data to come to us */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync if (!realloc_buffer(source, source->offset + size))
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync if (n < 0) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync } else if (n == 0)
08a80484275b5172ce23729ecccc934c6a92d201vboxsync r = fill_fixed_size(source, &data, sizeof(uint64_t));
08a80484275b5172ce23729ecccc934c6a92d201vboxsync if (r <= 0)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_error("Stream declares field with size %zu > DATA_SIZE_MAX = %u",
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsyncstatic int get_data_data(RemoteSource *source, void **data) {
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync r = fill_fixed_size(source, data, source->data_size);
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync if (r <= 0)
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync if (r <= 0)
59e30364f54880dd846c263711a2506d1182b1b5vboxsyncstatic int process_dunder(RemoteSource *source, char *line, size_t n) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* XXX: is it worth to support timestamps in extended format?
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * We don't produce them, but who knows... */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* ignore __CURSOR */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync timestamp = startswith(line, "__REALTIME_TIMESTAMP=");
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync long long unsigned x;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_warning("Failed to parse __REALTIME_TIMESTAMP: '%s'", timestamp);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync return r < 0 ? r : 1;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync timestamp = startswith(line, "__MONOTONIC_TIMESTAMP=");
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync long long unsigned x;
08a56d5836eceeb24642b61eaa52a4edb0a7b482vboxsync log_warning("Failed to parse __MONOTONIC_TIMESTAMP: '%s'", timestamp);
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync return r < 0 ? r : 1;
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync /* no dunder */
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (r == 0) {
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (n == 1) {
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (r != 0)
24b88f881835a6c392e72177f74f1d5e4544ba1evboxsync return r < 0 ? r : 0;
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync /* MESSAGE=xxx\n
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync LLLLLLLL0011223344...\n
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync /* chomp newline */
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync /* replace \n with = */
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (r < 0) {
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync return 0; /* continue */
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (r == 0) {
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync return 0; /* continue */
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync if (r == 0) {
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync r = iovw_put(&source->iovw, data, source->data_size);
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync if (r < 0) {
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync log_error("failed to put binary buffer in iovect");
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync return 0; /* continue */
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync if (r == 0) {
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync return 0; /* continue */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncint process_source(RemoteSource *source, bool compress, bool seal) {
c3e38cccf650831700227918a021e6c4097ace82vboxsync if (r <= 0)
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync /* We have a full event */
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync log_debug("Received a full event from source@%p fd:%d (%s)",
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync r = writer_write(source->writer, &source->iovw, &source->ts, compress, seal);
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync log_error("Failed to write entry of %zu bytes: %s",
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* possibly reset buffer position */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync source->offset = source->scanned = source->filled = 0;
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync else if (source->offset > source->size - source->filled &&
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync memcpy(source->buf, source->buf + source->offset, remain);
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync while (target > 16 * LINE_CHUNK && remain < target / 2)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_warning("Failed to reallocate buffer to (smaller) size %zu",
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync log_debug("Reallocated buffer from %zu to %zu bytes",