X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal-remote%2Fjournal-remote.c;h=eb092ce02045439ac267e2227fbfea2dfdd15e76;hb=5e78424f4a27c07be50e246308035c877f204038;hp=ad87783510cff94a02d8f5c42ba5c005322c5c3f;hpb=22259a00fdb54dee818eeb1019421e2c516a330d;p=elogind.git diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index ad8778351..eb092ce02 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -295,6 +295,8 @@ static int dispatch_raw_source_event(sd_event_source *event, int fd, uint32_t revents, void *userdata); +static int dispatch_blocking_source_event(sd_event_source *event, + void *userdata); static int dispatch_raw_connection_event(sd_event_source *event, int fd, uint32_t revents, @@ -309,6 +311,8 @@ static int get_source_for_fd(RemoteServer *s, Writer *writer; int r; + /* This takes ownership of name, but only on success. */ + assert(fd >= 0); assert(source); @@ -358,6 +362,8 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) { RemoteSource *source; int r; + /* This takes ownership of name, even on failure, if own_name is true. */ + assert(s); assert(fd >= 0); assert(name); @@ -372,12 +378,20 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) { if (r < 0) { log_error("Failed to create source for fd:%d (%s): %s", fd, name, strerror(-r)); + free(name); return r; } r = sd_event_add_io(s->events, &source->event, fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI, dispatch_raw_source_event, s); + if (r == -EPERM) { + log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name); + r = sd_event_add_defer(s->events, &source->event, + dispatch_blocking_source_event, source); + if (r == 0) + sd_event_source_set_enabled(source->event, SD_EVENT_ON); + } if (r < 0) { log_error("Failed to register event source for fd:%d: %s", fd, strerror(-r)); @@ -858,8 +872,6 @@ static int remoteserver_init(RemoteServer *s, 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); @@ -1029,6 +1041,13 @@ static int dispatch_raw_source_event(sd_event_source *event, return 1; } +static int dispatch_blocking_source_event(sd_event_source *event, + void *userdata) { + RemoteSource *source = userdata; + + return dispatch_raw_source_event(event, source->fd, EPOLLIN, server); +} + static int accept_connection(const char* type, int fd, SocketAddress *addr, char **hostname) { int fd2, r; @@ -1082,7 +1101,7 @@ static int dispatch_raw_connection_event(sd_event_source *event, uint32_t revents, void *userdata) { RemoteServer *s = userdata; - int fd2, r; + int fd2; SocketAddress addr = { .size = sizeof(union sockaddr_union), .type = SOCK_STREAM, @@ -1093,10 +1112,7 @@ static int dispatch_raw_connection_event(sd_event_source *event, 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); } /**********************************************************************