chiark / gitweb /
log: introduce a macro to format message id
[elogind.git] / src / journal / journald.c
index 5d0d2033f2c3425d3ba80d9d1c2cf668c32fc575..4dcf7d32c2327f5810ee0b8af266f7f70c8e5f4a 100644 (file)
@@ -87,6 +87,15 @@ static const char* const storage_table[] = {
 DEFINE_STRING_TABLE_LOOKUP(storage, Storage);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
 
+static const char* const split_mode_table[] = {
+        [SPLIT_NONE] = "none",
+        [SPLIT_UID] = "uid",
+        [SPLIT_LOGIN] = "login"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
+
 static uint64_t available_space(Server *s) {
         char ids[33], *p;
         const char *f;
@@ -132,9 +141,10 @@ static uint64_t available_space(Server *s) {
 
         for (;;) {
                 struct stat st;
-                struct dirent buf, *de;
+                struct dirent *de;
+                union dirent_storage buf;
 
-                r = readdir_r(d, &buf, &de);
+                r = readdir_r(d, &buf.de, &de);
                 if (r != 0)
                         break;
 
@@ -338,7 +348,7 @@ static void server_rotate(Server *s) {
                                 log_error("Failed to create user journal: %s", strerror(-r));
                 else {
                         hashmap_replace(s->user_journals, k, f);
-                        server_fix_perms(s, s->system_journal, PTR_TO_UINT32(k));
+                        server_fix_perms(s, f, PTR_TO_UINT32(k));
                 }
         }
 }
@@ -430,6 +440,35 @@ static char *shortened_cgroup_path(pid_t pid) {
         return path;
 }
 
+static bool shall_try_append_again(JournalFile *f, int r) {
+
+        /* -E2BIG            Hit configured limit
+           -EFBIG            Hit fs limit
+           -EDQUOT           Quota limit hit
+           -ENOSPC           Disk full
+           -EHOSTDOWN        Other machine
+           -EBUSY            Unclean shutdown
+           -EPROTONOSUPPORT  Unsupported feature
+           -EBADMSG          Corrupted
+           -ENODATA          Truncated
+           -ESHUTDOWN        Already archived */
+
+        if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
+                log_debug("%s: Allocation limit reached, rotating.", f->path);
+        else if (r == -EHOSTDOWN)
+                log_info("%s: Journal file from other machine, rotating.", f->path);
+        else if (r == -EBUSY)
+                log_info("%s: Unclean shutdown, rotating.", f->path);
+        else if (r == -EPROTONOSUPPORT)
+                log_info("%s: Unsupported feature, rotating.", f->path);
+        else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
+                log_warning("%s: Journal file corrupted, rotating.", f->path);
+        else
+                return false;
+
+        return true;
+}
+
 static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
         JournalFile *f;
         bool vacuumed = false;
@@ -444,7 +483,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
                 return;
 
         if (journal_file_rotate_suggested(f)) {
-                log_debug("Journal header limits reached or header out-of-date, rotating.");
+                log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
                 server_rotate(s);
                 server_vacuum(s);
                 vacuumed = true;
@@ -454,45 +493,26 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
                         return;
         }
 
-        for (;;) {
-                r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
-                if (r >= 0)
-                        return;
-
-                if (vacuumed ||
-                    (r != -E2BIG && /* hit limit */
-                     r != -EFBIG && /* hit fs limit */
-                     r != -EDQUOT && /* quota hit */
-                     r != -ENOSPC && /* disk full */
-                     r != -EBADMSG && /* corrupted */
-                     r != -ENODATA && /* truncated */
-                     r != -EHOSTDOWN && /* other machine */
-                     r != -EPROTONOSUPPORT && /* unsupported feature */
-                     r != -EBUSY && /* unclean shutdown */
-                     r != -ESHUTDOWN /* already archived */)) {
-                        log_error("Failed to write entry, ignoring: %s", strerror(-r));
-                        return;
-                }
+        r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
+        if (r >= 0)
+                return;
 
-                if (r == -E2BIG || r == -EFBIG || r == EDQUOT || r == ENOSPC)
-                        log_debug("Allocation limit reached, rotating.");
-                else if (r == -EHOSTDOWN)
-                        log_info("Journal file from other machine, rotating.");
-                else if (r == -EBUSY)
-                        log_info("Unclean shutdown, rotating.");
-                else
-                        log_warning("Journal file corrupted, rotating.");
+        if (vacuumed || !shall_try_append_again(f, r)) {
+                log_error("Failed to write entry, ignoring: %s", strerror(-r));
+                return;
+        }
 
-                server_rotate(s);
-                server_vacuum(s);
-                vacuumed = true;
+        server_rotate(s);
+        server_vacuum(s);
 
-                f = find_journal(s, uid);
-                if (!f)
-                        return;
+        f = find_journal(s, uid);
+        if (!f)
+                return;
 
-                log_debug("Retrying write.");
-        }
+        log_debug("Retrying write.");
+        r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
+        if (r < 0)
+                log_error("Failed to write entry, ignoring: %s", strerror(-r));
 }
 
 static void dispatch_message_real(
@@ -659,7 +679,10 @@ static void dispatch_message_real(
 
         assert(n <= m);
 
-        write_to_journal(s, realuid == 0 ? 0 : loginuid, iovec, n);
+        write_to_journal(s,
+                         s->split_mode == SPLIT_NONE ? 0 :
+                         (s->split_mode == SPLIT_UID ? realuid :
+                          (realuid == 0 ? 0 : loginuid)), iovec, n);
 
         free(pid);
         free(uid);
@@ -701,9 +724,11 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
         char_array_0(buffer);
         IOVEC_SET_STRING(iovec[n++], buffer);
 
-        snprintf(mid, sizeof(mid), "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(message_id));
-        char_array_0(mid);
-        IOVEC_SET_STRING(iovec[n++], mid);
+        if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
+                snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
+                char_array_0(mid);
+                IOVEC_SET_STRING(iovec[n++], mid);
+        }
 
         zero(ucred);
         ucred.pid = getpid();
@@ -814,9 +839,14 @@ static int system_journal_open(Server *s) {
                 r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
                 free(fn);
 
-                if (r >= 0)
+                if (r >= 0) {
+                        char fb[FORMAT_BYTES_MAX];
+
                         server_fix_perms(s, s->system_journal, 0);
-                else if (r < 0) {
+                        server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.",
+                                              format_bytes(fb, sizeof(fb), s->system_metrics.max_use));
+
+                } else if (r < 0) {
 
                         if (r != -ENOENT && r != -EROFS)
                                 log_warning("Failed to open system journal: %s", strerror(-r));
@@ -863,18 +893,22 @@ static int system_journal_open(Server *s) {
                         }
                 }
 
-                if (s->runtime_journal)
+                if (s->runtime_journal) {
+                        char fb[FORMAT_BYTES_MAX];
+
                         server_fix_perms(s, s->runtime_journal, 0);
+                        server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.",
+                                              format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use));
+                }
         }
 
         return r;
 }
 
 static int server_flush_to_var(Server *s) {
-        Object *o = NULL;
         int r;
         sd_id128_t machine;
-        sd_journal *j;
+        sd_journal *j = NULL;
 
         assert(s);
 
@@ -905,6 +939,7 @@ static int server_flush_to_var(Server *s) {
         }
 
         SD_JOURNAL_FOREACH(j) {
+                Object *o = NULL;
                 JournalFile *f;
 
                 f = j->current_file;
@@ -917,16 +952,19 @@ static int server_flush_to_var(Server *s) {
                 }
 
                 r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
-                if (r == -E2BIG) {
-                        log_debug("Allocation limit reached.");
-
-                        journal_file_post_change(s->system_journal);
-                        server_rotate(s);
-                        server_vacuum(s);
+                if (r >= 0)
+                        continue;
 
-                        r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
+                if (!shall_try_append_again(s->system_journal, r)) {
+                        log_error("Can't write entry: %s", strerror(-r));
+                        goto finish;
                 }
 
+                server_rotate(s);
+                server_vacuum(s);
+
+                log_debug("Retrying write.");
+                r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
                 if (r < 0) {
                         log_error("Can't write entry: %s", strerror(-r));
                         goto finish;
@@ -942,6 +980,9 @@ finish:
         if (r >= 0)
                 rm_rf("/run/log/journal", false, true, false);
 
+        if (j)
+                sd_journal_close(j);
+
         return r;
 }
 
@@ -1480,7 +1521,6 @@ int main(int argc, char *argv[]) {
 
         log_set_target(LOG_TARGET_SAFE);
         log_set_facility(LOG_SYSLOG);
-        log_set_max_level(LOG_DEBUG);
         log_parse_environment();
         log_open();
 
@@ -1542,6 +1582,7 @@ int main(int argc, char *argv[]) {
                 }
 
                 server_maybe_append_tags(&server);
+                server_maybe_warn_forward_syslog_missed(&server);
         }
 
         log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());