diff options
Diffstat (limited to 'src/journal-remote/journal-remote.c')
-rw-r--r-- | src/journal-remote/journal-remote.c | 183 |
1 files changed, 102 insertions, 81 deletions
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 1baedf6367..d86c3681b1 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -21,31 +19,35 @@ #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/prctl.h> #include <sys/socket.h> #include <unistd.h> -#include <getopt.h> #include "sd-daemon.h" -#include "signal-util.h" + +#include "alloc-util.h" +#include "conf-parser.h" +#include "def.h" +#include "escape.h" +#include "fd-util.h" +#include "fileio.h" #include "journal-file.h" +#include "journal-remote-write.h" +#include "journal-remote.h" #include "journald-native.h" -#include "socket-util.h" -#include "build.h" #include "macro.h" +#include "parse-util.h" +#include "signal-util.h" +#include "socket-util.h" +#include "stat-util.h" +#include "stdio-util.h" +#include "string-table.h" +#include "string-util.h" #include "strv.h" -#include "fileio.h" -#include "conf-parser.h" - -#ifdef HAVE_GNUTLS -#include <gnutls/gnutls.h> -#endif - -#include "journal-remote.h" -#include "journal-remote-write.h" #define REMOTE_JOURNAL_PATH "/var/log/journal/remote" @@ -88,8 +90,7 @@ static int spawn_child(const char* child, char** argv) { child_pid = fork(); if (child_pid < 0) { - r = -errno; - log_error_errno(errno, "Failed to fork: %m"); + r = log_error_errno(errno, "Failed to fork: %m"); safe_close_pair(fd); return r; } @@ -126,6 +127,10 @@ static int spawn_child(const char* child, char** argv) { if (r < 0) log_warning_errno(errno, "Failed to close write end of pipe: %m"); + r = fd_nonblock(fd[0], true); + if (r < 0) + log_warning_errno(errno, "Failed to set child pipe to non-blocking: %m"); + return fd[0]; } @@ -139,26 +144,22 @@ static int spawn_curl(const char* url) { r = spawn_child("curl", argv); if (r < 0) - log_error_errno(errno, "Failed to spawn curl: %m"); + log_error_errno(r, "Failed to spawn curl: %m"); return r; } -static int spawn_getter(const char *getter, const char *url) { +static int spawn_getter(const char *getter) { int r; _cleanup_strv_free_ char **words = NULL; assert(getter); - r = strv_split_quoted(&words, getter, 0); + r = strv_split_extract(&words, getter, WHITESPACE, EXTRACT_QUOTES); if (r < 0) return log_error_errno(r, "Failed to split getter option: %m"); - r = strv_extend(&words, url); - if (r < 0) - return log_error_errno(r, "Failed to create command line: %m"); - r = spawn_child(words[0], words); if (r < 0) - log_error_errno(errno, "Failed to spawn getter %s: %m", getter); + log_error_errno(r, "Failed to spawn getter %s: %m", getter); return r; } @@ -202,7 +203,7 @@ static int open_output(Writer *w, const char* host) { O_RDWR|O_CREAT, 0640, arg_compress, arg_seal, &w->metrics, - w->mmap, + w->mmap, NULL, NULL, &w->journal); if (r < 0) log_error_errno(r, "Failed to open output journal %s: %m", @@ -433,14 +434,14 @@ static int add_raw_socket(RemoteServer *s, int fd) { return r; fd_ = -1; - s->active ++; + s->active++; return 0; } static int setup_raw_socket(RemoteServer *s, const char *address) { int fd; - fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC); + fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM, SOCK_CLOEXEC); if (fd < 0) return fd; @@ -519,7 +520,7 @@ static int process_http_upload( } else finished = true; - while (true) { + for (;;) { r = process_source(source, arg_compress, arg_seal); if (r == -EAGAIN) break; @@ -527,13 +528,12 @@ static int process_http_upload( log_warning("Failed to process data for connection %p", connection); if (r == -E2BIG) return mhd_respondf(connection, - MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, - "Entry is too large, maximum is %u bytes.\n", - DATA_SIZE_MAX); + r, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, + "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes."); else return mhd_respondf(connection, - MHD_HTTP_UNPROCESSABLE_ENTITY, - "Processing failed: %s.", strerror(-r)); + r, MHD_HTTP_UNPROCESSABLE_ENTITY, + "Processing failed: %m."); } } @@ -544,13 +544,14 @@ static int process_http_upload( remaining = source_non_empty(source); if (remaining > 0) { - log_warning("Premature EOFbyte. %zu bytes lost.", remaining); - return mhd_respondf(connection, MHD_HTTP_EXPECTATION_FAILED, + log_warning("Premature EOF byte. %zu bytes lost.", remaining); + return mhd_respondf(connection, + 0, MHD_HTTP_EXPECTATION_FAILED, "Premature EOF. %zu bytes of trailing data not processed.", remaining); } - return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.\n"); + return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK."); }; static int request_handler( @@ -580,19 +581,16 @@ static int request_handler( *connection_cls); if (!streq(method, "POST")) - return mhd_respond(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE, - "Unsupported method.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, "Unsupported method."); if (!streq(url, "/upload")) - return mhd_respond(connection, MHD_HTTP_NOT_FOUND, - "Not found.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found."); header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Type"); if (!header || !streq(header, "application/vnd.fdo.journal")) return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE, - "Content-Type: application/vnd.fdo.journal" - " is required.\n"); + "Content-Type: application/vnd.fdo.journal is required."); { const union MHD_ConnectionInfo *ci; @@ -602,7 +600,7 @@ static int request_handler( if (!ci) { log_error("MHD_get_connection_info failed: cannot get remote fd"); return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - "Cannot check remote address"); + "Cannot check remote address."); } fd = ci->connect_fd; @@ -614,11 +612,10 @@ static int request_handler( if (r < 0) return code; } else { - r = getnameinfo_pretty(fd, &hostname); - if (r < 0) { + r = getpeername_pretty(fd, false, &hostname); + if (r < 0) return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - "Cannot check remote hostname"); - } + "Cannot check remote hostname."); } assert(hostname); @@ -627,8 +624,7 @@ static int request_handler( if (r == -ENOMEM) return respond_oom(connection); else if (r < 0) - return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "%m"); hostname = NULL; return MHD_YES; @@ -643,16 +639,18 @@ static int setup_microhttpd_server(RemoteServer *s, { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free}, { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger}, { MHD_OPTION_LISTEN_SOCKET, fd}, + { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024}, { MHD_OPTION_END}, { MHD_OPTION_END}, { MHD_OPTION_END}, { MHD_OPTION_END}}; - int opts_pos = 3; + int opts_pos = 4; int flags = MHD_USE_DEBUG | - MHD_USE_PEDANTIC_CHECKS | + MHD_USE_DUAL_STACK | MHD_USE_EPOLL_LINUX_ONLY | - MHD_USE_DUAL_STACK; + MHD_USE_PEDANTIC_CHECKS | + MHD_USE_PIPE_FOR_SHUTDOWN; const union MHD_DaemonInfo *info; int r, epoll_fd; @@ -740,7 +738,7 @@ static int setup_microhttpd_server(RemoteServer *s, goto error; } - s->active ++; + s->active++; return 0; error: @@ -757,7 +755,7 @@ static int setup_microhttpd_socket(RemoteServer *s, const char *trust) { int fd; - fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM | SOCK_CLOEXEC); + fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM, SOCK_CLOEXEC); if (fd < 0) return fd; @@ -871,7 +869,7 @@ static int remoteserver_init(RemoteServer *s, } else if (sd_is_socket(fd, AF_UNSPEC, 0, false)) { char *hostname; - r = getnameinfo_pretty(fd, &hostname); + r = getpeername_pretty(fd, false, &hostname); if (r < 0) return log_error_errno(r, "Failed to retrieve remote name: %m"); @@ -889,18 +887,32 @@ static int remoteserver_init(RemoteServer *s, fd); } - if (arg_url) { - const char *url, *hostname; + if (arg_getter) { + log_info("Spawning getter %s...", arg_getter); + fd = spawn_getter(arg_getter); + if (fd < 0) + return fd; + + r = add_source(s, fd, (char*) arg_output, false); + if (r < 0) + return r; + } - url = strjoina(arg_url, "/entries"); + if (arg_url) { + const char *url; + char *hostname, *p; - if (arg_getter) { - log_info("Spawning getter %s...", url); - fd = spawn_getter(arg_getter, url); - } else { - log_info("Spawning curl %s...", url); - fd = spawn_curl(url); + if (!strstr(arg_url, "/entries")) { + if (endswith(arg_url, "/")) + url = strjoina(arg_url, "entries"); + else + url = strjoina(arg_url, "/entries"); } + else + url = strdupa(arg_url); + + log_info("Spawning curl %s...", url); + fd = spawn_curl(url); if (fd < 0) return fd; @@ -909,7 +921,13 @@ static int remoteserver_init(RemoteServer *s, startswith(arg_url, "http://") ?: arg_url; - r = add_source(s, fd, (char*) hostname, false); + hostname = strdupa(hostname); + if ((p = strchr(hostname, '/'))) + *p = '\0'; + if ((p = strchr(hostname, ':'))) + *p = '\0'; + + r = add_source(s, fd, hostname, false); if (r < 0) return r; } @@ -956,7 +974,7 @@ static int remoteserver_init(RemoteServer *s, } if (s->active == 0) { - log_error("Zarro sources specified"); + log_error("Zero sources specified"); return -EINVAL; } @@ -1114,6 +1132,7 @@ static int accept_connection(const char* type, int fd, r = socknameinfo_pretty(&addr->sockaddr, addr->size, &b); if (r < 0) { + log_error_errno(r, "Resolving hostname failed: %m"); close(fd2); return r; } @@ -1172,14 +1191,15 @@ static DEFINE_CONFIG_PARSE_ENUM(config_parse_write_split_mode, static int parse_config(void) { const ConfigTableItem items[] = { + { "Remote", "Seal", config_parse_bool, 0, &arg_seal }, { "Remote", "SplitMode", config_parse_write_split_mode, 0, &arg_split_mode }, { "Remote", "ServerKeyFile", config_parse_path, 0, &arg_key }, { "Remote", "ServerCertificateFile", config_parse_path, 0, &arg_cert }, { "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust }, {}}; - return config_parse_many(PKGSYSCONFDIR "/journal-remote.conf", - CONF_DIRS_NULSTR("systemd/journal-remote.conf"), + return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf", + CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"), "Remote\0", config_item_table_lookup, items, false, NULL); } @@ -1260,9 +1280,7 @@ static int parse_argv(int argc, char *argv[]) { return 0 /* done */; case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0 /* done */; + return version(); case ARG_URL: if (arg_url) { @@ -1410,18 +1428,21 @@ static int parse_argv(int argc, char *argv[]) { case ARG_GNUTLS_LOG: { #ifdef HAVE_GNUTLS - const char *word, *state; - size_t size; + const char* p = optarg; + for (;;) { + _cleanup_free_ char *word = NULL; - FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) { - char *cat; + r = extract_first_word(&p, &word, ",", 0); + if (r < 0) + return log_error_errno(r, "Failed to parse --gnutls-log= argument: %m"); - cat = strndup(word, size); - if (!cat) - return log_oom(); + if (r == 0) + break; - if (strv_consume(&arg_gnutls_log, cat) < 0) + if (strv_push(&arg_gnutls_log, word) < 0) return log_oom(); + + word = NULL; } break; #else @@ -1539,7 +1560,7 @@ int main(int argc, char **argv) { if (r < 0) log_error_errno(r, "Failed to enable watchdog: %m"); else - log_debug("Watchdog is %s.", r > 0 ? "enabled" : "disabled"); + log_debug("Watchdog is %sd.", enable_disable(r > 0)); log_debug("%s running as pid "PID_FMT, program_invocation_short_name, getpid()); |