int server_open_native_socket(Server *s) { static const union sockaddr_union sa = { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/socket", }; int r; assert(s); if (s->native_fd < 0) { s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (s->native_fd < 0) return log_error_errno(errno, "socket() failed: %m"); (void) sockaddr_un_unlink(&sa.un); r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path); (void) chmod(sa.un.sun_path, 0666); } else (void) fd_nonblock(s->native_fd, true); r = setsockopt_int(s->native_fd, SOL_SOCKET, SO_PASSCRED, true); if (r < 0) return log_error_errno(r, "SO_PASSCRED failed: %m"); #if HAVE_SELINUX if (mac_selinux_use()) { r = setsockopt_int(s->native_fd, SOL_SOCKET, SO_PASSSEC, true); if (r < 0) log_warning_errno(r, "SO_PASSSEC failed: %m"); } #endif r = setsockopt_int(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, true); if (r < 0) return log_error_errno(r, "SO_TIMESTAMP failed: %m"); r = sd_event_add_io(s->event, &s->native_event_source, s->native_fd, EPOLLIN, server_process_datagram, s); if (r < 0) return log_error_errno(r, "Failed to add native server fd to event loop: %m"); r = sd_event_source_set_priority(s->native_event_source, SD_EVENT_PRIORITY_NORMAL+5); if (r < 0) return log_error_errno(r, "Failed to adjust native event source priority: %m"); return 0; }
int server_open_stdout_socket(Server *s) { static const union sockaddr_union sa = { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/stdout", }; int r; assert(s); if (s->stdout_fd < 0) { s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (s->stdout_fd < 0) return log_error_errno(errno, "socket() failed: %m"); (void) sockaddr_un_unlink(&sa.un); r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path); (void) chmod(sa.un.sun_path, 0666); if (listen(s->stdout_fd, SOMAXCONN) < 0) return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path); } else (void) fd_nonblock(s->stdout_fd, true); r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s); if (r < 0) return log_error_errno(r, "Failed to add stdout server fd to event source: %m"); r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5); if (r < 0) return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m"); return 0; } void stdout_stream_send_notify(StdoutStream *s) { struct iovec iovec = { .iov_base = (char*) "FDSTORE=1", .iov_len = STRLEN("FDSTORE=1"), }; struct msghdr msghdr = { .msg_iov = &iovec, .msg_iovlen = 1, }; struct cmsghdr *cmsg; ssize_t l; assert(s); assert(!s->fdstore); assert(s->in_notify_queue); assert(s->server); assert(s->server->notify_fd >= 0); /* Store the connection fd in PID 1, so that we get it passed * in again on next start */ msghdr.msg_controllen = CMSG_SPACE(sizeof(int)); msghdr.msg_control = alloca0(msghdr.msg_controllen); cmsg = CMSG_FIRSTHDR(&msghdr); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int)); memcpy(CMSG_DATA(cmsg), &s->fd, sizeof(int)); l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAIT|MSG_NOSIGNAL); if (l < 0) { if (errno == EAGAIN) return; log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m"); } else { log_debug("Successfully sent stream file descriptor to service manager."); s->fdstore = 1; } LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s); s->in_notify_queue = false; }