Writer *writer;
int r;
+ /* This takes ownership of name, but only on success. */
+
assert(fd >= 0);
assert(source);
RemoteSource *source;
int r;
+ /* This takes ownership of name, even on failure, if own_name is true. */
+
assert(s);
assert(fd >= 0);
assert(name);
if (r < 0) {
log_error("Failed to create source for fd:%d (%s): %s",
fd, name, strerror(-r));
+ free(name);
return r;
}
goto error;
}
+ r = sd_event_source_set_name(source->event, name);
+ if (r < 0) {
+ log_error("Failed to set source name for fd:%d: %s", fd, strerror(-r));
+ goto error;
+ }
+
return 1; /* work to do */
error:
static int add_raw_socket(RemoteServer *s, int fd) {
int r;
+ _cleanup_close_ int fd_ = fd;
+ char name[strlen("raw-socket-") + DECIMAL_STR_MAX(int)];
+
+ assert(fd >= 0);
r = sd_event_add_io(s->events, &s->listen_event,
fd, EPOLLIN,
dispatch_raw_connection_event, s);
- if (r < 0) {
- close(fd);
+ if (r < 0)
return r;
- }
+ snprintf(name, sizeof(name), "raw-socket-%d", fd);
+
+ r = sd_event_source_set_name(s->listen_event, name);
+ if (r < 0)
+ return r;
+
+ fd_ = -1;
s->active ++;
return 0;
}
**********************************************************************
**********************************************************************/
-static RemoteSource *request_meta(void **connection_cls, int fd, char *hostname) {
+static int request_meta(void **connection_cls, int fd, char *hostname) {
RemoteSource *source;
Writer *writer;
int r;
assert(connection_cls);
if (*connection_cls)
- return *connection_cls;
+ return 0;
r = get_writer(server, hostname, &writer);
if (r < 0) {
log_warning("Failed to get writer for source %s: %s",
hostname, strerror(-r));
- return NULL;
+ return r;
}
source = source_new(fd, true, hostname, writer);
if (!source) {
- log_oom();
writer_unref(writer);
- return NULL;
+ return log_oom();
}
log_debug("Added RemoteSource as connection metadata %p", source);
*connection_cls = source;
- return source;
+ return 0;
}
static void request_meta_free(void *cls,
assert(connection_cls);
s = *connection_cls;
- log_debug("Cleaning up connection metadata %p", s);
- source_free(s);
- *connection_cls = NULL;
+ if (s) {
+ log_debug("Cleaning up connection metadata %p", s);
+ source_free(s);
+ *connection_cls = NULL;
+ }
}
static int process_http_upload(
assert(source);
- log_debug("request_handler_upload: connection %p, %zu bytes",
- connection, *upload_data_size);
+ log_trace("%s: connection %p, %zu bytes",
+ __func__, connection, *upload_data_size);
if (*upload_data_size) {
- log_debug("Received %zu bytes", *upload_data_size);
+ log_trace("Received %zu bytes", *upload_data_size);
r = push_data(source, upload_data, *upload_data_size);
if (r < 0)
assert(url);
assert(method);
- log_debug("Handling a connection %s %s %s", method, url, version);
+ log_trace("Handling a connection %s %s %s", method, url, version);
if (*connection_cls)
return process_http_upload(connection,
assert(hostname);
- if (!request_meta(connection_cls, fd, hostname))
+ r = request_meta(connection_cls, fd, hostname);
+ if (r == -ENOMEM)
return respond_oom(connection);
+ else if (r < 0)
+ return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
+ strerror(-r));
+
hostname = NULL;
return MHD_YES;
}
goto error;
}
+ r = sd_event_source_set_name(d->event, "epoll-fd");
+ if (r < 0) {
+ log_error("Failed to set source name: %s", strerror(-r));
+ goto error;
+ }
+
r = hashmap_ensure_allocated(&s->daemons, &uint64_hash_ops);
if (r < 0) {
log_oom();
**********************************************************************
**********************************************************************/
-static int dispatch_sigterm(sd_event_source *event,
- const struct signalfd_siginfo *si,
- void *userdata) {
- RemoteServer *s = userdata;
-
- assert(s);
-
- log_received_signal(LOG_INFO, si);
-
- sd_event_exit(s->events, 0);
- return 0;
-}
-
static int setup_signals(RemoteServer *s) {
sigset_t mask;
int r;
sigset_add_many(&mask, SIGINT, SIGTERM, -1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
- r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, dispatch_sigterm, s);
+ r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, NULL, s);
+ if (r < 0)
+ return r;
+
+ r = sd_event_source_set_name(s->sigterm_event, "sigterm");
if (r < 0)
return r;
- r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, dispatch_sigterm, s);
+ r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, NULL, s);
+ if (r < 0)
+ return r;
+
+ r = sd_event_source_set_name(s->sigint_event, "sigint");
if (r < 0)
return r;
return 0;
}
-static int fd_fd(const char *spec) {
+static int negative_fd(const char *spec) {
+ /* Return a non-positive number as its inverse, -EINVAL otherwise. */
+
int fd, r;
r = safe_atoi(spec, &fd);
if (r < 0)
return r;
- if (fd < 0)
- return -EINVAL;
- return fd;
+ if (fd > 0)
+ return -EINVAL;
+ else
+ return -fd;
}
static int remoteserver_init(RemoteServer *s,
}
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
- if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
+ if (sd_is_socket(fd, AF_UNSPEC, 0, true)) {
log_info("Received a listening socket (fd:%d)", fd);
if (fd == http_socket)
r = setup_microhttpd_server(s, fd, key, cert, trust);
else
r = add_raw_socket(s, fd);
- } else if (sd_is_socket(fd, AF_UNSPEC, 0, true)) {
+ } else if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
char *hostname;
r = getnameinfo_pretty(fd, &hostname);
log_info("Received a connection socket (fd:%d) from %s", fd, hostname);
r = add_source(s, fd, hostname, true);
- if (r < 0)
- free(hostname);
} else {
log_error("Unknown socket passed on fd:%d", fd);
uint32_t revents,
void *userdata) {
RemoteServer *s = userdata;
- int fd2, r;
+ int fd2;
SocketAddress addr = {
.size = sizeof(union sockaddr_union),
.type = SOCK_STREAM,
if (fd2 < 0)
return fd2;
- r = add_source(s, fd2, hostname, true);
- if (r < 0)
- free(hostname);
- return r;
+ return add_source(s, fd2, hostname, true);
}
/**********************************************************************
static void help(void) {
printf("%s [OPTIONS...] {FILE|-}...\n\n"
"Write external journal events to journal file(s).\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --url=URL Read events from systemd-journal-gatewayd at URL\n"
- " --getter=COMMAND Read events from the output of COMMAND\n"
- " --listen-raw=ADDR Listen for connections at ADDR\n"
- " --listen-http=ADDR Listen for HTTP connections at ADDR\n"
- " --listen-https=ADDR Listen for HTTPS connections at ADDR\n"
- " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
- " --compress[=BOOL] Use XZ-compression in the output journal (default: yes)\n"
- " --seal[=BOOL] Use Event sealing in the output journal (default: no)\n"
- " --key=FILENAME Specify key in PEM format (default:\n"
- " \"" PRIV_KEY_FILE "\")\n"
- " --cert=FILENAME Specify certificate in PEM format (default:\n"
- " \"" CERT_FILE "\")\n"
- " --trust=FILENAME|all Specify CA certificate or disable checking (default:\n"
- " \"" TRUST_FILE "\")\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --url=URL Read events from systemd-journal-gatewayd at URL\n"
+ " --getter=COMMAND Read events from the output of COMMAND\n"
+ " --listen-raw=ADDR Listen for connections at ADDR\n"
+ " --listen-http=ADDR Listen for HTTP connections at ADDR\n"
+ " --listen-https=ADDR Listen for HTTPS connections at ADDR\n"
+ " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
+ " --compress[=BOOL] XZ-compress the output journal (default: yes)\n"
+ " --seal[=BOOL] Use event sealing (default: no)\n"
+ " --key=FILENAME SSL key in PEM format (default:\n"
+ " \"" PRIV_KEY_FILE "\")\n"
+ " --cert=FILENAME SSL certificate in PEM format (default:\n"
+ " \"" CERT_FILE "\")\n"
+ " --trust=FILENAME|all SSL CA certificate or disable checking (default:\n"
+ " \"" TRUST_FILE "\")\n"
" --gnutls-log=CATEGORY...\n"
- " Specify a list of gnutls logging categories\n"
+ " Specify a list of gnutls logging categories\n"
+ " --split-mode=none|host How many output files to create\n"
"\n"
"Note: file descriptors from sd_listen_fds() will be consumed, too.\n"
, program_invocation_short_name);
return -EINVAL;
}
- r = fd_fd(optarg);
+ r = negative_fd(optarg);
if (r >= 0)
http_socket = r;
else
return -EINVAL;
}
- r = fd_fd(optarg);
+ r = negative_fd(optarg);
if (r >= 0)
https_socket = r;
else
if (remoteserver_init(&s, key, cert, trust) < 0)
return EXIT_FAILURE;
- sd_event_set_watchdog(s.events, true);
+ r = sd_event_set_watchdog(s.events, true);
+ if (r < 0)
+ log_error("Failed to enable watchdog: %s", strerror(-r));
+ else
+ log_debug("Watchdog is %s.", r > 0 ? "enabled" : "disabled");
log_debug("%s running as pid "PID_FMT,
program_invocation_short_name, getpid());