chiark / gitweb /
journal: disable default debug logging
[elogind.git] / src / journal / journald.c
index 1efe0420dbdb869b35a12841c3f6d95023c333a2..a25f81ef666d942a17a2d1df30887db2f381da9b 100644 (file)
 
 #define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
 
+#define RECHECK_VAR_AVAILABLE_USEC (30*USEC_PER_SEC)
+
+#define SYSLOG_TIMEOUT_USEC (5*USEC_PER_SEC)
+
 typedef struct StdoutStream StdoutStream;
 
 typedef struct Server {
@@ -78,6 +82,8 @@ typedef struct Server {
         uint64_t cached_available_space;
         usec_t cached_available_space_timestamp;
 
+        uint64_t var_available_timestamp;
+
         LIST_HEAD(StdoutStream, stdout_streams);
         unsigned n_stdout_streams;
 } Server;
@@ -372,11 +378,22 @@ static char *shortened_cgroup_path(pid_t pid) {
         if (streq(init_path, "/"))
                 init_path[0] = 0;
 
-        if (startswith(process_path, init_path))
-                path = process_path + strlen(init_path);
-        else
+        if (startswith(process_path, init_path)) {
+                char *p;
+
+                p = strdup(process_path + strlen(init_path));
+                if (!p) {
+                        free(process_path);
+                        free(init_path);
+                        return NULL;
+                }
+                path = p;
+        } else {
                 path = process_path;
+                process_path = NULL;
+        }
 
+        free(process_path);
         free(init_path);
 
         return path;
@@ -538,7 +555,7 @@ static void dispatch_message(Server *s,
                              struct timeval *tv,
                              int priority) {
         int rl;
-        char *path, *c;
+        char *path = NULL, *c;
 
         assert(s);
         assert(iovec || n == 0);
@@ -1200,12 +1217,22 @@ static int server_flush_to_var(Server *s) {
         int r;
         sd_id128_t machine;
         sd_journal *j;
+        usec_t ts;
 
         assert(s);
 
+        if (!s->runtime_journal)
+                return 0;
+
+        ts = now(CLOCK_MONOTONIC);
+        if (s->var_available_timestamp + RECHECK_VAR_AVAILABLE_USEC > ts)
+                return 0;
+
+        s->var_available_timestamp = ts;
+
         system_journal_open(s);
 
-        if (!s->system_journal || !s->runtime_journal)
+        if (!s->system_journal)
                 return 0;
 
         r = sd_id128_get_machine(&machine);
@@ -1262,6 +1289,69 @@ finish:
         return r;
 }
 
+static void forward_syslog(Server *s, const void *buffer, size_t length, struct ucred *ucred, struct timeval *tv) {
+        struct msghdr msghdr;
+        struct iovec iovec;
+        struct cmsghdr *cmsg;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
+                            CMSG_SPACE(sizeof(struct timeval))];
+        } control;
+        union sockaddr_union sa;
+
+        assert(s);
+
+        zero(msghdr);
+
+        zero(iovec);
+        iovec.iov_base = (void*) buffer;
+        iovec.iov_len = length;
+        msghdr.msg_iov = &iovec;
+        msghdr.msg_iovlen = 1;
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/systemd/syslog", sizeof(sa.un.sun_path));
+        msghdr.msg_name = &sa;
+        msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
+
+        zero(control);
+        msghdr.msg_control = &control;
+        msghdr.msg_controllen = sizeof(control);
+
+        cmsg = CMSG_FIRSTHDR(&msghdr);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_CREDENTIALS;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+        memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred));
+        msghdr.msg_controllen = cmsg->cmsg_len;
+
+        /* Forward the syslog message we received via /dev/log to
+         * /run/systemd/syslog. Unfortunately we currently can't set
+         * the SO_TIMESTAMP auxiliary data, and hence we don't. */
+
+        if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
+                return;
+
+        if (errno == ESRCH) {
+                struct ucred u;
+
+                /* Hmm, presumably the sender process vanished
+                 * by now, so let's fix it as good as we
+                 * can, and retry */
+
+                u = *ucred;
+                u.pid = getpid();
+                memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
+
+                if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
+                        return;
+        }
+
+        log_debug("Failed to forward syslog message: %m");
+}
+
 static int process_event(Server *s, struct epoll_event *ev) {
         assert(s);
 
@@ -1382,6 +1472,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
                                 else
                                         s->buffer[n] = 0;
 
+                                forward_syslog(s, s->buffer, n, ucred, tv);
                                 process_syslog_message(s, strstrip(s->buffer), ucred, tv);
                         } else
                                 process_native_message(s, s->buffer, n, ucred, tv);
@@ -1430,6 +1521,7 @@ static int open_syslog_socket(Server *s) {
         union sockaddr_union sa;
         int one, r;
         struct epoll_event ev;
+        struct timeval tv;
 
         assert(s);
 
@@ -1443,7 +1535,7 @@ static int open_syslog_socket(Server *s) {
 
                 zero(sa);
                 sa.un.sun_family = AF_UNIX;
-                strncpy(sa.un.sun_path, "/run/systemd/syslog", sizeof(sa.un.sun_path));
+                strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
 
                 unlink(sa.un.sun_path);
 
@@ -1470,6 +1562,15 @@ static int open_syslog_socket(Server *s) {
                 return -errno;
         }
 
+        /* Since we use the same socket for forwarding this to some
+         * other syslog implementation, make sure we don't hang
+         * forever */
+        timeval_store(&tv, SYSLOG_TIMEOUT_USEC);
+        if (setsockopt(s->syslog_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
+                log_error("SO_SNDTIMEO failed: %m");
+                return -errno;
+        }
+
         zero(ev);
         ev.events = EPOLLIN;
         ev.data.fd = s->syslog_fd;
@@ -1738,6 +1839,8 @@ static void server_done(Server *s) {
 
         if (s->rate_limit)
                 journal_rate_limit_free(s->rate_limit);
+
+        free(s->buffer);
 }
 
 int main(int argc, char *argv[]) {
@@ -1755,7 +1858,6 @@ int main(int argc, char *argv[]) {
         }
 
         log_set_target(LOG_TARGET_CONSOLE);
-        log_set_max_level(LOG_DEBUG);
         log_parse_environment();
         log_open();