summaryrefslogtreecommitdiff
path: root/src/journal/journald-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal/journald-stream.c')
-rw-r--r--src/journal/journald-stream.c67
1 files changed, 45 insertions, 22 deletions
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index 5c15a56bac..e887f01a49 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -22,12 +22,12 @@
#include <fcntl.h>
#include <unistd.h>
#include <stddef.h>
-#include <sys/epoll.h>
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#endif
+#include "sd-event.h"
#include "socket-util.h"
#include "selinux-util.h"
#include "journald-server.h"
@@ -71,6 +71,8 @@ struct StdoutStream {
char buffer[LINE_MAX+1];
size_t length;
+ sd_event_source *event_source;
+
LIST_FIELDS(StdoutStream, stdout_stream);
};
@@ -282,12 +284,18 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
return 0;
}
-int stdout_stream_process(StdoutStream *s) {
+static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
+ StdoutStream *s = userdata;
ssize_t l;
int r;
assert(s);
+ if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
+ log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
+ return -EIO;
+ }
+
l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
if (l < 0) {
@@ -295,13 +303,13 @@ int stdout_stream_process(StdoutStream *s) {
return 0;
log_warning("Failed to read from stream: %m");
- return -errno;
+ goto fail;
}
if (l == 0) {
r = stdout_stream_scan(s, true);
if (r < 0)
- return r;
+ goto fail;
return 0;
}
@@ -309,10 +317,13 @@ int stdout_stream_process(StdoutStream *s) {
s->length += l;
r = stdout_stream_scan(s, false);
if (r < 0)
- return r;
+ goto fail;
return 1;
+fail:
+ stdout_stream_free(s);
+ return 0;
}
void stdout_stream_free(StdoutStream *s) {
@@ -324,12 +335,11 @@ void stdout_stream_free(StdoutStream *s) {
LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
}
- if (s->fd >= 0) {
- if (s->server)
- epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
+ if (s->event_source)
+ s->event_source = sd_event_source_unref(s->event_source);
+ if (s->fd >= 0)
close_nointr_nofail(s->fd);
- }
#ifdef HAVE_SELINUX
if (s->security_context)
@@ -341,14 +351,19 @@ void stdout_stream_free(StdoutStream *s) {
free(s);
}
-int stdout_stream_new(Server *s) {
+static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
+ Server *s = userdata;
StdoutStream *stream;
int fd, r;
socklen_t len;
- struct epoll_event ev;
assert(s);
+ if (revents != EPOLLIN) {
+ log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
+ return -EIO;
+ }
+
fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
if (fd < 0) {
if (errno == EAGAIN)
@@ -392,12 +407,15 @@ int stdout_stream_new(Server *s) {
goto fail;
}
- zero(ev);
- ev.data.ptr = stream;
- ev.events = EPOLLIN;
- if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
- log_error("Failed to add stream to event loop: %m");
- r = -errno;
+ r = sd_event_add_io(s->event, fd, EPOLLIN, stdout_stream_process, stream, &stream->event_source);
+ if (r < 0) {
+ log_error("Failed to add stream to event loop: %s", strerror(-r));
+ goto fail;
+ }
+
+ r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
+ if (r < 0) {
+ log_error("Failed to adjust stdout event source priority: %s", strerror(-r));
goto fail;
}
@@ -414,7 +432,6 @@ fail:
int server_open_stdout_socket(Server *s) {
int r;
- struct epoll_event ev = { .events = EPOLLIN };
assert(s);
@@ -447,10 +464,16 @@ int server_open_stdout_socket(Server *s) {
} else
fd_nonblock(s->stdout_fd, 1);
- ev.data.fd = s->stdout_fd;
- if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) {
- log_error("Failed to add stdout server fd to epoll object: %m");
- return -errno;
+ r = sd_event_add_io(s->event, s->stdout_fd, EPOLLIN, stdout_stream_new, s, &s->stdout_event_source);
+ if (r < 0) {
+ log_error("Failed to add stdout server fd to event source: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+10);
+ if (r < 0) {
+ log_error("Failed to adjust priority of stdout server event source: %s", strerror(-r));
+ return r;
}
return 0;