summaryrefslogtreecommitdiff
path: root/src/journal-remote/journal-remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal-remote/journal-remote.c')
-rw-r--r--src/journal-remote/journal-remote.c183
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());