journal-upload-journal.c revision b5efdb8af40ea759a1ea584c1bc44ecc81dd00ce
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen This file is part of systemd.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Copyright 2014 Zbigniew Jędrzejewski-Szmek
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is free software; you can redistribute it and/or modify it
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen under the terms of the GNU Lesser General Public License as published by
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen (at your option) any later version.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is distributed in the hope that it will be useful, but
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Lesser General Public License for more details.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen You should have received a copy of the GNU Lesser General Public License
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen * Write up to size bytes to buf. Return negative on error, and number of
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * bytes written otherwise. The last case is a kind of an error too.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic ssize_t write_entry(char *buf, size_t size, Uploader *u) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_cursor(u->journal, &u->current_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get cursor: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_realtime_usec(u->journal, &realtime);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get realtime timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get monotonic timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get monotonic timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to move to next field in entry: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else if (r == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen done = size - pos > u->field_length - u->field_pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *c;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen c = memchr(u->field_data, '=', u->field_length);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!c || c == u->field_data) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for label + '\n' */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for uint64_t */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen le64 = htole64(u->field_length - u->field_pos);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for '\n' */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error_errno(r, "Failed to move to next entry in journal: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else if (r == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("No more entries, waiting for journal.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_info("No more entries, closing journal.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen w = write_entry((char*)buf + filled, size * nmemb - filled, u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error("Buffer space is too small to write entry.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* This means that all available space was used up */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Entry %zu (%s) has been uploaded.",
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int process_journal_input(Uploader *u, int skip) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to skip to next entry: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* have data */
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek return start_upload(u, journal_input_callback, u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error_errno(r, "Failed to process journal: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int dispatch_journal_input(sd_event_source *event,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_warning("dispatch_journal_input called when uploading, ignoring.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Detected journal input, checking for new data.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(fd, "sd_journal_get_fd failed: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_event_add_io(u->events, &u->input_event,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to register input event: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Listening for journal events on fd:%d, timeout %d",
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Not listening for journal events.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to seek to cursor %s: %m",