[systemd-commits] 5 commits - .gitignore Makefile.am src/bootchart src/bus-proxyd src/core src/dbus1-generator src/journal src/journal-remote src/libsystemd src/login src/network src/resolve src/shared src/test src/timesync src/tty-ask-password-agent src/udev

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Wed Jul 16 16:00:23 PDT 2014


 .gitignore                                          |    1 
 Makefile.am                                         |   21 -
 src/bootchart/bootchart.c                           |   14 
 src/bus-proxyd/bus-policy.c                         |    1 
 src/core/load-dropin.c                              |    5 
 src/core/load-fragment.c                            |    7 
 src/core/main.c                                     |   18 
 src/dbus1-generator/dbus1-generator.c               |   22 -
 src/journal-remote/journal-remote.c                 |   13 
 src/journal-remote/journal-upload.c                 |   13 
 src/journal/coredump.c                              |   14 
 src/journal/journal-verify.c                        |  416 ++++++++++----------
 src/journal/journald-server.c                       |   23 -
 src/libsystemd/sd-rtnl/rtnl-types.c                 |   19 
 src/libsystemd/sd-rtnl/rtnl-types.h                 |   19 
 src/login/logind.c                                  |   23 -
 src/network/networkd-netdev.c                       |   18 
 src/network/networkd-network.c                      |   10 
 src/network/test-network-tables.c                   |   26 +
 src/resolve/resolved-manager.c                      |   14 
 src/shared/conf-parser.c                            |   25 -
 src/shared/conf-parser.h                            |    1 
 src/shared/install.c                                |   11 
 src/shared/install.h                                |    2 
 src/shared/sleep-config.c                           |   16 
 src/shared/test-tables.h                            |    3 
 src/shared/util.c                                   |   11 
 src/shared/util.h                                   |    1 
 src/test/test-tables.c                              |   23 +
 src/timesync/timesyncd.c                            |   25 -
 src/tty-ask-password-agent/tty-ask-password-agent.c |  118 ++---
 src/udev/net/link-config.c                          |   17 
 src/udev/udev-rules.c                               |   18 
 33 files changed, 473 insertions(+), 495 deletions(-)

New commits:
commit 54f3ff079f05fd024ff3686eeea26ab705994494
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Jul 8 09:55:15 2014 -0400

    journal/verify: flush progress bar, print offset in more places
    
    Before, fragments of the progress bar would remain when
    errors or warnings were printed.

diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 5a0751f..333757b 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -34,6 +34,73 @@
 #include "compress.h"
 #include "fsprg.h"
 
+static void draw_progress(uint64_t p, usec_t *last_usec) {
+        unsigned n, i, j, k;
+        usec_t z, x;
+
+        if (!on_tty())
+                return;
+
+        z = now(CLOCK_MONOTONIC);
+        x = *last_usec;
+
+        if (x != 0 && x + 40 * USEC_PER_MSEC > z)
+                return;
+
+        *last_usec = z;
+
+        n = (3 * columns()) / 4;
+        j = (n * (unsigned) p) / 65535ULL;
+        k = n - j;
+
+        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
+
+        for (i = 0; i < j; i++)
+                fputs("\xe2\x96\x88", stdout);
+
+        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+        for (i = 0; i < k; i++)
+                fputs("\xe2\x96\x91", stdout);
+
+        printf(" %3"PRIu64"%%", 100U * p / 65535U);
+
+        fputs("\r\x1B[?25h", stdout);
+        fflush(stdout);
+}
+
+static void flush_progress(void) {
+        unsigned n, i;
+
+        if (!on_tty())
+                return;
+
+        n = (3 * columns()) / 4;
+
+        putchar('\r');
+
+        for (i = 0; i < n + 5; i++)
+                putchar(' ');
+
+        putchar('\r');
+        fflush(stdout);
+}
+
+#define debug(_offset, _fmt, ...) do{                                   \
+                flush_progress();                                       \
+                log_debug(OFSfmt": " _fmt, _offset, ##__VA_ARGS__);     \
+        } while(0)
+
+#define warning(_offset, _fmt, ...) do{                                 \
+                flush_progress();                                       \
+                log_warning(OFSfmt": " _fmt, _offset, ##__VA_ARGS__);   \
+        } while(0)
+
+#define error(_offset, _fmt, ...) do{                                   \
+                flush_progress();                                       \
+                log_error(OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \
+        } while(0)
+
 static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) {
         uint64_t i;
 
@@ -56,18 +123,17 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                 int compression, r;
 
                 if (le64toh(o->data.entry_offset) == 0)
-                        log_warning(OFSfmt": unused data (entry_offset==0)", offset);
+                        warning(offset, "unused data (entry_offset==0)");
 
                 if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) {
-                        log_error(OFSfmt": bad n_entries: %"PRIu64, offset, o->data.n_entries);
+                        error(offset, "bad n_entries: %"PRIu64, o->data.n_entries);
                         return -EBADMSG;
                 }
 
                 if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) {
-                        log_error(OFSfmt": bad object size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(DataObject, payload),
-                                  le64toh(o->object.size));
+                        error(offset, "bad object size (<= %zu): %"PRIu64,
+                              offsetof(DataObject, payload),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
@@ -83,8 +149,8 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                                             le64toh(o->object.size) - offsetof(Object, data.payload),
                                             &b, &alloc, &b_size, 0);
                         if (r < 0) {
-                                log_error(OFSfmt": %s decompression failed: %s", offset,
-                                          object_compressed_to_string(compression), strerror(-r));
+                                error(offset, "%s decompression failed: %s",
+                                      object_compressed_to_string(compression), strerror(-r));
                                 return r;
                         }
 
@@ -93,7 +159,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
 
                 if (h1 != h2) {
-                        log_error(OFSfmt": invalid hash (%08"PRIx64" vs. %08"PRIx64, offset, h1, h2);
+                        error(offset, "invalid hash (%08"PRIx64" vs. %08"PRIx64, h1, h2);
                         return -EBADMSG;
                 }
 
@@ -101,12 +167,11 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                     !VALID64(o->data.next_field_offset) ||
                     !VALID64(o->data.entry_offset) ||
                     !VALID64(o->data.entry_array_offset)) {
-                        log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
-                                  offset,
-                                  o->data.next_hash_offset,
-                                  o->data.next_field_offset,
-                                  o->data.entry_offset,
-                                  o->data.entry_array_offset);
+                        error(offset, "invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
+                              o->data.next_hash_offset,
+                              o->data.next_field_offset,
+                              o->data.entry_offset,
+                              o->data.entry_array_offset);
                         return -EBADMSG;
                 }
 
@@ -115,67 +180,67 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
 
         case OBJECT_FIELD:
                 if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) {
-                        log_error(OFSfmt": bad field size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(FieldObject, payload),
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "bad field size (<= %zu): %"PRIu64,
+                              offsetof(FieldObject, payload),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID64(o->field.next_hash_offset) ||
                     !VALID64(o->field.head_data_offset)) {
-                        log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt,
-                                  offset,
-                                  o->field.next_hash_offset,
-                                  o->field.head_data_offset);
+                        error(offset,
+                              "invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt,
+                              o->field.next_hash_offset,
+                              o->field.head_data_offset);
                         return -EBADMSG;
                 }
                 break;
 
         case OBJECT_ENTRY:
                 if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) {
-                        log_error(OFSfmt": bad entry size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(EntryObject, items),
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "bad entry size (<= %zu): %"PRIu64,
+                              offsetof(EntryObject, items),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0) {
-                        log_error(OFSfmt": invalid number items in entry: %"PRIu64,
-                                  offset,
-                                  (le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem));
+                        error(offset,
+                              "invalid number items in entry: %"PRIu64,
+                              (le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem));
                         return -EBADMSG;
                 }
 
                 if (le64toh(o->entry.seqnum) <= 0) {
-                        log_error(OFSfmt": invalid entry seqnum: %"PRIx64,
-                                  offset,
-                                  le64toh(o->entry.seqnum));
+                        error(offset,
+                              "invalid entry seqnum: %"PRIx64,
+                              le64toh(o->entry.seqnum));
                         return -EBADMSG;
                 }
 
                 if (!VALID_REALTIME(le64toh(o->entry.realtime))) {
-                        log_error(OFSfmt": invalid entry realtime timestamp: %"PRIu64,
-                                  offset,
-                                  le64toh(o->entry.realtime));
+                        error(offset,
+                              "invalid entry realtime timestamp: %"PRIu64,
+                              le64toh(o->entry.realtime));
                         return -EBADMSG;
                 }
 
                 if (!VALID_MONOTONIC(le64toh(o->entry.monotonic))) {
-                        log_error(OFSfmt": invalid entry monotonic timestamp: %"PRIu64,
-                                  offset,
-                                  le64toh(o->entry.monotonic));
+                        error(offset,
+                              "invalid entry monotonic timestamp: %"PRIu64,
+                              le64toh(o->entry.monotonic));
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_entry_n_items(o); i++) {
                         if (o->entry.items[i].object_offset == 0 ||
                             !VALID64(o->entry.items[i].object_offset)) {
-                                log_error(OFSfmt": invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt,
-                                          offset,
-                                          i, journal_file_entry_n_items(o),
-                                          o->entry.items[i].object_offset);
+                                error(offset,
+                                      "invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt,
+                                      i, journal_file_entry_n_items(o),
+                                      o->entry.items[i].object_offset);
                                 return -EBADMSG;
                         }
                 }
@@ -186,41 +251,41 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         case OBJECT_FIELD_HASH_TABLE:
                 if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0 ||
                     (le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) {
-                        log_error(OFSfmt": invalid %s hash table size: %"PRIu64,
-                                  offset,
-                                  o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid %s hash table size: %"PRIu64,
+                              o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
                         if (o->hash_table.items[i].head_hash_offset != 0 &&
                             !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].head_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].head_hash_offset));
                                 return -EBADMSG;
                         }
                         if (o->hash_table.items[i].tail_hash_offset != 0 &&
                             !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].tail_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].tail_hash_offset));
                                 return -EBADMSG;
                         }
 
                         if ((o->hash_table.items[i].head_hash_offset != 0) !=
                             (o->hash_table.items[i].tail_hash_offset != 0)) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].head_hash_offset),
-                                          le64toh(o->hash_table.items[i].tail_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].head_hash_offset),
+                                      le64toh(o->hash_table.items[i].tail_hash_offset));
                                 return -EBADMSG;
                         }
                 }
@@ -230,26 +295,26 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         case OBJECT_ENTRY_ARRAY:
                 if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0 ||
                     (le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) {
-                        log_error(OFSfmt": invalid object entry array size: %"PRIu64,
-                                  offset,
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid object entry array size: %"PRIu64,
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID64(o->entry_array.next_entry_array_offset)) {
-                        log_error(OFSfmt": invalid object entry array next_entry_array_offset: "OFSfmt,
-                                  offset,
-                                  o->entry_array.next_entry_array_offset);
+                        error(offset,
+                              "invalid object entry array next_entry_array_offset: "OFSfmt,
+                              o->entry_array.next_entry_array_offset);
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_entry_array_n_items(o); i++)
                         if (le64toh(o->entry_array.items[i]) != 0 &&
                             !VALID64(le64toh(o->entry_array.items[i]))) {
-                                log_error(OFSfmt": invalid object entry array item (%"PRIu64"/%"PRIu64"): "OFSfmt,
-                                          offset,
-                                          i, journal_file_entry_array_n_items(o),
-                                          le64toh(o->entry_array.items[i]));
+                                error(offset,
+                                      "invalid object entry array item (%"PRIu64"/%"PRIu64"): "OFSfmt,
+                                      i, journal_file_entry_array_n_items(o),
+                                      le64toh(o->entry_array.items[i]));
                                 return -EBADMSG;
                         }
 
@@ -257,16 +322,16 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
 
         case OBJECT_TAG:
                 if (le64toh(o->object.size) != sizeof(TagObject)) {
-                        log_error(OFSfmt": invalid object tag size: %"PRIu64,
-                                  offset,
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid object tag size: %"PRIu64,
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID_EPOCH(o->tag.epoch)) {
-                        log_error(OFSfmt": invalid object tag epoch: %"PRIu64,
-                                  offset,
-                                  o->tag.epoch);
+                        error(offset,
+                              "invalid object tag epoch: %"PRIu64,
+                              o->tag.epoch);
                         return -EBADMSG;
                 }
 
@@ -276,58 +341,6 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         return 0;
 }
 
-static void draw_progress(uint64_t p, usec_t *last_usec) {
-        unsigned n, i, j, k;
-        usec_t z, x;
-
-        if (!on_tty())
-                return;
-
-        z = now(CLOCK_MONOTONIC);
-        x = *last_usec;
-
-        if (x != 0 && x + 40 * USEC_PER_MSEC > z)
-                return;
-
-        *last_usec = z;
-
-        n = (3 * columns()) / 4;
-        j = (n * (unsigned) p) / 65535ULL;
-        k = n - j;
-
-        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
-
-        for (i = 0; i < j; i++)
-                fputs("\xe2\x96\x88", stdout);
-
-        fputs(ANSI_HIGHLIGHT_OFF, stdout);
-
-        for (i = 0; i < k; i++)
-                fputs("\xe2\x96\x91", stdout);
-
-        printf(" %3"PRIu64"%%", 100U * p / 65535U);
-
-        fputs("\r\x1B[?25h", stdout);
-        fflush(stdout);
-}
-
-static void flush_progress(void) {
-        unsigned n, i;
-
-        if (!on_tty())
-                return;
-
-        n = (3 * columns()) / 4;
-
-        putchar('\r');
-
-        for (i = 0; i < n + 5; i++)
-                putchar(' ');
-
-        putchar('\r');
-        fflush(stdout);
-}
-
 static int write_uint64(int fd, uint64_t p) {
         ssize_t k;
 
@@ -390,7 +403,8 @@ static int entry_points_to_data(
         assert(entry_fd >= 0);
 
         if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
-                log_error("Data object references invalid entry at %"PRIu64, data_p);
+                error(data_p,
+                      "data object references invalid entry at "OFSfmt, entry_p);
                 return -EBADMSG;
         }
 
@@ -406,7 +420,8 @@ static int entry_points_to_data(
                 }
 
         if (!found) {
-                log_error("Data object not referenced by linked entry at %"PRIu64, data_p);
+                error(entry_p,
+                      "data object at "OFSfmt" not referenced by linked entry", data_p);
                 return -EBADMSG;
         }
 
@@ -449,7 +464,7 @@ static int entry_points_to_data(
                                         x = z;
                         }
 
-                        log_error("Entry object doesn't exist in main entry array at %"PRIu64, entry_p);
+                        error(entry_p, "entry object doesn't exist in main entry array");
                         return -EBADMSG;
                 }
 
@@ -479,8 +494,9 @@ static int verify_data(
 
         /* Entry array means at least two objects */
         if (a && n < 2) {
-                log_error("Entry array present (entry_array_offset=%"PRIu64", but n_entries=%"PRIu64,
-                          a, n);
+                error(p,
+                      "entry array present (entry_array_offset="OFSfmt", but n_entries=%"PRIu64")",
+                      a, n);
                 return -EBADMSG;
         }
 
@@ -500,12 +516,12 @@ static int verify_data(
                 uint64_t next, m, j;
 
                 if (a == 0) {
-                        log_error("Array chain too short at %"PRIu64, p);
+                        error(p, "array chain too short");
                         return -EBADMSG;
                 }
 
                 if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
-                        log_error("Invalid array at %"PRIu64, p);
+                        error(p, "invalid array offset "OFSfmt, a);
                         return -EBADMSG;
                 }
 
@@ -515,7 +531,8 @@ static int verify_data(
 
                 next = le64toh(o->entry_array.next_entry_array_offset);
                 if (next != 0 && next <= a) {
-                        log_error("Array chain has cycle at %"PRIu64, p);
+                        error(p, "array chain has cycle (jumps back from "OFSfmt" to "OFSfmt")",
+                              a, next);
                         return -EBADMSG;
                 }
 
@@ -524,7 +541,7 @@ static int verify_data(
 
                         q = le64toh(o->entry_array.items[j]);
                         if (q <= last) {
-                                log_error("Data object's entry array not sorted at %"PRIu64, p);
+                                error(p, "data object's entry array not sorted");
                                 return -EBADMSG;
                         }
                         last = q;
@@ -575,8 +592,8 @@ static int verify_hash_table(
                         uint64_t next;
 
                         if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
-                                log_error("Invalid data object at hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "invalid data object at hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -586,14 +603,14 @@ static int verify_hash_table(
 
                         next = le64toh(o->data.next_hash_offset);
                         if (next != 0 && next <= p) {
-                                log_error("Hash chain has a cycle in hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "hash chain has a cycle in hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
                         if (le64toh(o->data.hash) % n != i) {
-                                log_error("Hash value mismatch in hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "hash value mismatch in hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -606,7 +623,7 @@ static int verify_hash_table(
                 }
 
                 if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
-                        log_error("Tail hash pointer mismatch in hash table");
+                        error(p, "tail hash pointer mismatch in hash table");
                         return -EBADMSG;
                 }
         }
@@ -660,7 +677,7 @@ static int verify_entry(
                 h = le64toh(o->entry.items[i].hash);
 
                 if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
-                        log_error("Invalid data object at entry %"PRIu64, p);
+                        error(p, "invalid data object of entry");
                                 return -EBADMSG;
                         }
 
@@ -669,7 +686,7 @@ static int verify_entry(
                         return r;
 
                 if (le64toh(u->data.hash) != h) {
-                        log_error("Hash mismatch for data object at entry %"PRIu64, p);
+                        error(p, "hash mismatch for data object of entry");
                         return -EBADMSG;
                 }
 
@@ -677,7 +694,7 @@ static int verify_entry(
                 if (r < 0)
                         return r;
                 if (r == 0) {
-                        log_error("Data object missing from hash at entry %"PRIu64, p);
+                        error(p, "data object missing from hash table");
                         return -EBADMSG;
                 }
         }
@@ -712,12 +729,12 @@ static int verify_entry_array(
                         draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
 
                 if (a == 0) {
-                        log_error("Array chain too short at %"PRIu64" of %"PRIu64, i, n);
+                        error(a, "array chain too short at %"PRIu64" of %"PRIu64, i, n);
                         return -EBADMSG;
                 }
 
                 if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
-                        log_error("Invalid array at %"PRIu64" of %"PRIu64, i, n);
+                        error(a, "invalid array %"PRIu64" of %"PRIu64, i, n);
                         return -EBADMSG;
                 }
 
@@ -727,7 +744,9 @@ static int verify_entry_array(
 
                 next = le64toh(o->entry_array.next_entry_array_offset);
                 if (next != 0 && next <= a) {
-                        log_error("Array chain has cycle at %"PRIu64" of %"PRIu64, i, n);
+                        error(a,
+                              "array chain has cycle at %"PRIu64" of %"PRIu64" (jumps back from to "OFSfmt")",
+                              i, n, next);
                         return -EBADMSG;
                 }
 
@@ -737,15 +756,15 @@ static int verify_entry_array(
 
                         p = le64toh(o->entry_array.items[j]);
                         if (p <= last) {
-                                log_error("Entry array not sorted at %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(a, "entry array not sorted at %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
                         last = p;
 
                         if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
-                                log_error("Invalid array entry at %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(a, "invalid array entry at %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -825,12 +844,7 @@ int journal_file_verify(
                 goto fail;
         }
 
-#ifdef HAVE_GCRYPT
-        if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
-#else
-        if (f->header->compatible_flags != 0)
-#endif
-        {
+        if (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SUPPORTED) {
                 log_error("Cannot verify file with unknown extensions.");
                 r = -ENOTSUP;
                 goto fail;
@@ -838,7 +852,7 @@ int journal_file_verify(
 
         for (i = 0; i < sizeof(f->header->reserved); i++)
                 if (f->header->reserved[i] != 0) {
-                        log_error("Reserved field in non-zero.");
+                        error(offsetof(Header, reserved[i]), "reserved field is non-zero");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -853,12 +867,12 @@ int journal_file_verify(
 
                 r = journal_file_move_to_object(f, -1, p, &o);
                 if (r < 0) {
-                        log_error("Invalid object at "OFSfmt, p);
+                        error(p, "invalid object");
                         goto fail;
                 }
 
                 if (p > le64toh(f->header->tail_object_offset)) {
-                        log_error("Invalid tail object pointer");
+                        error(offsetof(Header, tail_object_offset), "invalid tail object pointer");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -870,25 +884,25 @@ int journal_file_verify(
 
                 r = journal_file_object_verify(f, p, o);
                 if (r < 0) {
-                        log_error("Invalid object contents at "OFSfmt": %s", p, strerror(-r));
+                        error(p, "invalid object contents: %s", strerror(-r));
                         goto fail;
                 }
 
                 if ((o->object.flags & OBJECT_COMPRESSED_XZ) &&
                     (o->object.flags & OBJECT_COMPRESSED_LZ4)) {
-                        log_error("Objected with double compression at "OFSfmt, p);
-                        r = -EBADMSG;
+                        error(p, "objected with double compression");
+                        r = -EINVAL;
                         goto fail;
                 }
 
                 if ((o->object.flags & OBJECT_COMPRESSED_XZ) && !JOURNAL_HEADER_COMPRESSED_XZ(f->header)) {
-                        log_error("XZ compressed object in file without XZ compression at "OFSfmt, p);
+                        error(p, "XZ compressed object in file without XZ compression");
                         r = -EBADMSG;
                         goto fail;
                 }
 
                 if ((o->object.flags & OBJECT_COMPRESSED_LZ4) && !JOURNAL_HEADER_COMPRESSED_LZ4(f->header)) {
-                        log_error("LZ4 compressed object in file without LZ4 compression at "OFSfmt, p);
+                        error(p, "LZ4 compressed object in file without LZ4 compression");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -909,7 +923,7 @@ int journal_file_verify(
 
                 case OBJECT_ENTRY:
                         if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) {
-                                log_error("First entry before first tag at "OFSfmt, p);
+                                error(p, "first entry before first tag");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -919,21 +933,21 @@ int journal_file_verify(
                                 goto fail;
 
                         if (le64toh(o->entry.realtime) < last_tag_realtime) {
-                                log_error("Older entry after newer tag at "OFSfmt, p);
+                                error(p, "older entry after newer tag");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (!entry_seqnum_set &&
                             le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
-                                log_error("Head entry sequence number incorrect at "OFSfmt, p);
+                                error(p, "head entry sequence number incorrect");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (entry_seqnum_set &&
                             entry_seqnum >= le64toh(o->entry.seqnum)) {
-                                log_error("Entry sequence number out of synchronization at "OFSfmt, p);
+                                error(p, "entry sequence number out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -944,7 +958,7 @@ int journal_file_verify(
                         if (entry_monotonic_set &&
                             sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
                             entry_monotonic > le64toh(o->entry.monotonic)) {
-                                log_error("Entry timestamp out of synchronization at "OFSfmt, p);
+                                error(p, "entry timestamp out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -955,7 +969,7 @@ int journal_file_verify(
 
                         if (!entry_realtime_set &&
                             le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
-                                log_error("Head entry realtime timestamp incorrect");
+                                error(p, "head entry realtime timestamp incorrect");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -968,14 +982,14 @@ int journal_file_verify(
 
                 case OBJECT_DATA_HASH_TABLE:
                         if (n_data_hash_tables > 1) {
-                                log_error("More than one data hash table at "OFSfmt, p);
+                                error(p, "more than one data hash table");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) ||
                             le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
-                                log_error("Header fields for data hash table invalid");
+                                error(p, "header fields for data hash table invalid");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -985,14 +999,14 @@ int journal_file_verify(
 
                 case OBJECT_FIELD_HASH_TABLE:
                         if (n_field_hash_tables > 1) {
-                                log_error("More than one field hash table at "OFSfmt, p);
+                                error(p, "more than one field hash table");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) ||
                             le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
-                                log_error("Header fields for field hash table invalid");
+                                error(p, "header fields for field hash table invalid");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -1007,7 +1021,7 @@ int journal_file_verify(
 
                         if (p == le64toh(f->header->entry_array_offset)) {
                                 if (found_main_entry_array) {
-                                        log_error("More than one main entry array at "OFSfmt, p);
+                                        error(p, "more than one main entry array");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1020,19 +1034,19 @@ int journal_file_verify(
 
                 case OBJECT_TAG:
                         if (!JOURNAL_HEADER_SEALED(f->header)) {
-                                log_error("Tag object in file without sealing at "OFSfmt, p);
+                                error(p, "tag object in file without sealing");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(o->tag.seqnum) != n_tags + 1) {
-                                log_error("Tag sequence number out of synchronization at "OFSfmt, p);
+                                error(p, "tag sequence number out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(o->tag.epoch) < last_epoch) {
-                                log_error("Epoch sequence out of synchronization at "OFSfmt, p);
+                                error(p, "epoch sequence out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -1041,11 +1055,11 @@ int journal_file_verify(
                         if (f->seal) {
                                 uint64_t q, rt;
 
-                                log_debug("Checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
+                                debug(p, "checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
 
                                 rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
                                 if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
-                                        log_error("Tag/entry realtime timestamp out of synchronization at "OFSfmt, p);
+                                        error(p, "tag/entry realtime timestamp out of synchronization");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1088,7 +1102,7 @@ int journal_file_verify(
                                         goto fail;
 
                                 if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
-                                        log_error("Tag failed verification at "OFSfmt, p);
+                                        error(p, "tag failed verification");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1117,72 +1131,72 @@ int journal_file_verify(
         }
 
         if (!found_last) {
-                log_error("Tail object pointer dead");
+                error(le64toh(f->header->tail_object_offset), "tail object pointer dead");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_objects != le64toh(f->header->n_objects)) {
-                log_error("Object number mismatch");
+                error(offsetof(Header, n_objects), "object number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_entries != le64toh(f->header->n_entries)) {
-                log_error("Entry number mismatch");
+                error(offsetof(Header, n_entries), "entry number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
             n_data != le64toh(f->header->n_data)) {
-                log_error("Data number mismatch");
+                error(offsetof(Header, n_data), "data number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
             n_fields != le64toh(f->header->n_fields)) {
-                log_error("Field number mismatch");
+                error(offsetof(Header, n_fields), "field number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
             n_tags != le64toh(f->header->n_tags)) {
-                log_error("Tag number mismatch");
+                error(offsetof(Header, n_tags), "tag number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) &&
             n_entry_arrays != le64toh(f->header->n_entry_arrays)) {
-                log_error("Entry array number mismatch");
+                error(offsetof(Header, n_entry_arrays), "entry array number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_data_hash_tables != 1) {
-                log_error("Missing data hash table");
+                error(0, "missing data hash table");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_field_hash_tables != 1) {
-                log_error("Missing field hash table");
+                error(0, "missing field hash table");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (!found_main_entry_array) {
-                log_error("Missing entry array");
+                error(0, "missing entry array");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (entry_seqnum_set &&
             entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
-                log_error("Invalid tail seqnum");
+                error(offsetof(Header, tail_entry_seqnum), "invalid tail seqnum");
                 r = -EBADMSG;
                 goto fail;
         }
@@ -1190,13 +1204,13 @@ int journal_file_verify(
         if (entry_monotonic_set &&
             (!sd_id128_equal(entry_boot_id, f->header->boot_id) ||
              entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
-                log_error("Invalid tail monotonic timestamp");
+                error(0, "invalid tail monotonic timestamp");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
-                log_error("Invalid tail realtime timestamp");
+                error(0, "invalid tail realtime timestamp");
                 r = -EBADMSG;
                 goto fail;
         }

commit 86bbe5bfbc0bf213e9d3fafbe6c64d59b9fc90ea
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Jul 9 22:29:24 2014 -0400

    test-tables: add new entries
    
    One missing string found.
    
    A few things had to be moved around to make it possible to test them.

diff --git a/.gitignore b/.gitignore
index eab1f4c..bf53064 100644
--- a/.gitignore
+++ b/.gitignore
@@ -198,6 +198,7 @@
 /test-mmap-cache
 /test-namespace
 /test-network
+/test-network-tables
 /test-ns
 /test-path-util
 /test-prioq
diff --git a/Makefile.am b/Makefile.am
index 94cd402..7025137 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1453,16 +1453,22 @@ test_list_LDADD = \
 
 test_tables_SOURCES = \
 	src/test/test-tables.c \
-	src/shared/test-tables.h
+	src/shared/test-tables.h \
+	src/bus-proxyd/bus-policy.c \
+	src/bus-proxyd/bus-policy.h \
+	src/journal/journald-server.c \
+	src/journal/journald-server.h
 
 test_tables_CFLAGS = \
 	$(AM_CFLAGS) \
-	$(SECCOMP_CFLAGS)
+	$(SECCOMP_CFLAGS) \
+	-I$(srcdir)/src/bus-proxyd
 
 test_tables_LDADD = \
 	libsystemd-logs.la \
 	libsystemd-journal-internal.la \
 	libsystemd-core.la \
+	libudev-core.la \
 	$(RT_LIBS)
 
 test_prioq_SOURCES = \
@@ -4784,8 +4790,17 @@ test_network_CFLAGS = \
 test_network_LDADD = \
 	libsystemd-networkd-core.la
 
+test_network_tables_SOURCES = \
+	src/network/test-network-tables.c \
+	src/shared/test-tables.h
+
+test_network_tables_LDADD = \
+	libsystemd-networkd-core.la \
+	libudev-core.la
+
 tests += \
-	test-network
+	test-network \
+	test-network-tables
 
 nodist_systemunit_DATA += \
 	units/systemd-networkd.service \
diff --git a/src/bus-proxyd/bus-policy.c b/src/bus-proxyd/bus-policy.c
index 3f1d755..06c16a7 100644
--- a/src/bus-proxyd/bus-policy.c
+++ b/src/bus-proxyd/bus-policy.c
@@ -724,5 +724,6 @@ static const char* const policy_item_class_table[_POLICY_ITEM_CLASS_MAX] = {
         [POLICY_ITEM_OWN_PREFIX] = "own-prefix",
         [POLICY_ITEM_USER] = "user",
         [POLICY_ITEM_GROUP] = "group",
+        [POLICY_ITEM_IGNORE] = "ignore",
 };
 DEFINE_STRING_TABLE_LOOKUP(policy_item_class, PolicyItemClass);
diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c
index 9c3430d..ff90895 100644
--- a/src/libsystemd/sd-rtnl/rtnl-types.c
+++ b/src/libsystemd/sd-rtnl/rtnl-types.c
@@ -155,25 +155,6 @@ static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
         [IFLA_VTI_REMOTE]       = { .type = NLA_IN_ADDR  },
 };
 
-typedef enum NLUnionLinkInfoData {
-        NL_UNION_LINK_INFO_DATA_BOND,
-        NL_UNION_LINK_INFO_DATA_BRIDGE,
-        NL_UNION_LINK_INFO_DATA_VLAN,
-        NL_UNION_LINK_INFO_DATA_VETH,
-        NL_UNION_LINK_INFO_DATA_DUMMY,
-        NL_UNION_LINK_INFO_DATA_MACVLAN,
-        NL_UNION_LINK_INFO_DATA_VXLAN,
-        NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL,
-        NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL,
-        NL_UNION_LINK_INFO_DATA_SIT_TUNNEL,
-        NL_UNION_LINK_INFO_DATA_VTI_TUNNEL,
-        _NL_UNION_LINK_INFO_DATA_MAX,
-        _NL_UNION_LINK_INFO_DATA_INVALID = -1
-} NLUnionLinkInfoData;
-
-const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_;
-NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
-
 /* these strings must match the .kind entries in the kernel */
 static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
         [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
diff --git a/src/libsystemd/sd-rtnl/rtnl-types.h b/src/libsystemd/sd-rtnl/rtnl-types.h
index 7ce9597..8621746 100644
--- a/src/libsystemd/sd-rtnl/rtnl-types.h
+++ b/src/libsystemd/sd-rtnl/rtnl-types.h
@@ -63,3 +63,22 @@ int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, ui
 int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type);
 int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type);
 int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key);
+
+typedef enum NLUnionLinkInfoData {
+        NL_UNION_LINK_INFO_DATA_BOND,
+        NL_UNION_LINK_INFO_DATA_BRIDGE,
+        NL_UNION_LINK_INFO_DATA_VLAN,
+        NL_UNION_LINK_INFO_DATA_VETH,
+        NL_UNION_LINK_INFO_DATA_DUMMY,
+        NL_UNION_LINK_INFO_DATA_MACVLAN,
+        NL_UNION_LINK_INFO_DATA_VXLAN,
+        NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_SIT_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_VTI_TUNNEL,
+        _NL_UNION_LINK_INFO_DATA_MAX,
+        _NL_UNION_LINK_INFO_DATA_INVALID = -1
+} NLUnionLinkInfoData;
+
+const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_;
+NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c
new file mode 100644
index 0000000..6f6bb37
--- /dev/null
+++ b/src/network/test-network-tables.c
@@ -0,0 +1,26 @@
+#include "networkd.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-macvlan.h"
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+#include "rtnl-internal.h"
+#include "ethtool-util.h"
+
+#include "test-tables.h"
+
+int main(int argc, char **argv) {
+        test_table(bond_mode, NETDEV_BOND_MODE);
+        /* test_table(link_state, LINK_STATE);  -- not a reversible mapping */
+        test_table(link_operstate, LINK_OPERSTATE);
+        test_table(dhcp_support, DHCP_SUPPORT);
+        test_table(netdev_kind, NETDEV_KIND);
+        test_table(dhcp6_message_status, DHCP6_STATUS);
+        test_table(duplex, DUP);
+        test_table(wol, WOL);
+        test_table(nl_union_link_info_data, NL_UNION_LINK_INFO_DATA);
+
+        test_table_sparse(macvlan_mode, NETDEV_MACVLAN_MODE);
+        test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE);
+
+        return EXIT_SUCCESS;
+}
diff --git a/src/shared/install.c b/src/shared/install.c
index bc2a377..a2f84f8 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1877,7 +1877,7 @@ int unit_file_preset(
 
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
-        assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
+        assert(mode < _UNIT_FILE_PRESET_MAX);
 
         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
@@ -1945,7 +1945,7 @@ int unit_file_preset_all(
 
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
-        assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
+        assert(mode < _UNIT_FILE_PRESET_MAX);
 
         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
@@ -2182,7 +2182,7 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
 
 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
 
-static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MODE_MAX] = {
+static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
         [UNIT_FILE_PRESET_FULL] = "full",
         [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
         [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
diff --git a/src/shared/install.h b/src/shared/install.h
index 91ce192..ff16d9f 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -49,7 +49,7 @@ typedef enum UnitFilePresetMode {
         UNIT_FILE_PRESET_FULL,
         UNIT_FILE_PRESET_ENABLE_ONLY,
         UNIT_FILE_PRESET_DISABLE_ONLY,
-        _UNIT_FILE_PRESET_MODE_MAX,
+        _UNIT_FILE_PRESET_MAX,
         _UNIT_FILE_PRESET_INVALID = -1
 } UnitFilePresetMode;
 
diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h
index 3261302..3ac8729 100644
--- a/src/shared/test-tables.h
+++ b/src/shared/test-tables.h
@@ -49,3 +49,6 @@ static inline void _test_table(const char *name,
 
 #define test_table(lower, upper) \
         _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, false)
+
+#define test_table_sparse(lower, upper) \
+        _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, true)
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index fb751d1..9fc4d93 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -19,6 +19,7 @@
 
 #include "automount.h"
 #include "cgroup.h"
+#include "compress.h"
 #include "condition.h"
 #include "device.h"
 #include "execute.h"
@@ -43,17 +44,26 @@
 #include "unit-name.h"
 #include "unit.h"
 #include "util.h"
+#include "architecture.h"
+#include "link-config.h"
+#include "bus-policy.h"
+#include "journald-server.h"
 
 #include "test-tables.h"
 
 int main(int argc, char **argv) {
+        test_table(architecture, ARCHITECTURE);
         test_table(automount_result, AUTOMOUNT_RESULT);
         test_table(automount_state, AUTOMOUNT_STATE);
+        test_table(busname_policy_access, BUSNAME_POLICY_ACCESS);
+        test_table(busname_result, BUSNAME_RESULT);
+        test_table(busname_state, BUSNAME_STATE);
         test_table(cgroup_device_policy, CGROUP_DEVICE_POLICY);
         test_table(condition_type, CONDITION_TYPE);
         test_table(device_state, DEVICE_STATE);
         test_table(exec_input, EXEC_INPUT);
         test_table(exec_output, EXEC_OUTPUT);
+        test_table(failure_action, SERVICE_FAILURE_ACTION);
         test_table(job_mode, JOB_MODE);
         test_table(job_result, JOB_RESULT);
         test_table(job_state, JOB_STATE);
@@ -61,14 +71,21 @@ int main(int argc, char **argv) {
         test_table(kill_mode, KILL_MODE);
         test_table(kill_who, KILL_WHO);
         test_table(log_target, LOG_TARGET);
+        test_table(mac_policy, MACPOLICY);
+        test_table(manager_state, MANAGER_STATE);
         test_table(mount_exec_command, MOUNT_EXEC_COMMAND);
         test_table(mount_result, MOUNT_RESULT);
         test_table(mount_state, MOUNT_STATE);
+        test_table(name_policy, NAMEPOLICY);
         test_table(notify_access, NOTIFY_ACCESS);
         test_table(output_mode, OUTPUT_MODE);
         test_table(path_result, PATH_RESULT);
         test_table(path_state, PATH_STATE);
         test_table(path_type, PATH_TYPE);
+        test_table(policy_item_class, POLICY_ITEM_CLASS);
+        test_table(policy_item_type, POLICY_ITEM_TYPE);
+        test_table(protect_home, PROTECT_HOME);
+        test_table(protect_system, PROTECT_SYSTEM);
         test_table(scope_result, SCOPE_RESULT);
         test_table(scope_state, SCOPE_STATE);
         test_table(service_exec_command, SERVICE_EXEC_COMMAND);
@@ -82,7 +99,8 @@ int main(int argc, char **argv) {
         test_table(socket_exec_command, SOCKET_EXEC_COMMAND);
         test_table(socket_result, SOCKET_RESULT);
         test_table(socket_state, SOCKET_STATE);
-        test_table(failure_action, SERVICE_FAILURE_ACTION);
+        test_table(split_mode, SPLIT);
+        test_table(storage, STORAGE);
         test_table(swap_exec_command, SWAP_EXEC_COMMAND);
         test_table(swap_result, SWAP_RESULT);
         test_table(swap_state, SWAP_STATE);
@@ -94,9 +112,12 @@ int main(int argc, char **argv) {
         test_table(unit_active_state, UNIT_ACTIVE_STATE);
         test_table(unit_dependency, UNIT_DEPENDENCY);
         test_table(unit_file_change_type, UNIT_FILE_CHANGE_TYPE);
+        test_table(unit_file_preset_mode, UNIT_FILE_PRESET);
         test_table(unit_file_state, UNIT_FILE_STATE);
         test_table(unit_load_state, UNIT_LOAD_STATE);
         test_table(unit_type, UNIT_TYPE);
 
+        test_table_sparse(object_compressed, OBJECT_COMPRESSED);
+
         return EXIT_SUCCESS;
 }

commit e46eab86cd119b04ac14f5a2b404a614ae350016
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Jul 16 18:37:52 2014 -0400

    tty-ask-password-agent: modernization

diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 8b96d60..8e53439 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -538,7 +538,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
                 return 0;
 
         if (!NETDEV_VTABLE(netdev)) {
-                log_warning("NetDev with invalid Kind configured in %s. Igonring", filename);
+                log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
                 return 0;
         }
 
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 5852f71..a7fce51 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -243,10 +243,9 @@ finish:
 }
 
 static int parse_password(const char *filename, char **wall) {
-        char *socket_name = NULL, *message = NULL, *packet = NULL;
+        _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
         uint64_t not_after = 0;
         unsigned pid = 0;
-        int socket_fd = -1;
         bool accept_cached = false;
 
         const ConfigTableItem items[] = {
@@ -271,24 +270,18 @@ static int parse_password(const char *filename, char **wall) {
 
         if (!socket_name) {
                 log_error("Invalid password file %s", filename);
-                r = -EBADMSG;
-                goto finish;
+                return -EBADMSG;
         }
 
-        if (not_after > 0) {
-                if (now(CLOCK_MONOTONIC) > not_after) {
-                        r = 0;
-                        goto finish;
-                }
-        }
+        if (not_after > 0 && now(CLOCK_MONOTONIC) > not_after)
+                return 0;
 
-        if (pid > 0 && !pid_is_alive(pid)) {
-                r = 0;
-                goto finish;
-        }
+        if (pid > 0 && !pid_is_alive(pid))
+                return 0;
 
         if (arg_action == ACTION_LIST)
                 printf("'%s' (PID %u)\n", message, pid);
+
         else if (arg_action == ACTION_WALL) {
                 char *_wall;
 
@@ -298,43 +291,40 @@ static int parse_password(const char *filename, char **wall) {
                              *wall ? *wall : "",
                              *wall ? "\r\n\r\n" : "",
                              message,
-                             pid) < 0) {
-                        r = log_oom();
-                        goto finish;
-                }
+                             pid) < 0)
+                        return log_oom();
 
                 free(*wall);
                 *wall = _wall;
+
         } else {
-                union {
-                        struct sockaddr sa;
-                        struct sockaddr_un un;
-                } sa = {};
+                union sockaddr_union sa = {};
                 size_t packet_length = 0;
+                _cleanup_close_ int socket_fd = -1;
 
                 assert(arg_action == ACTION_QUERY ||
                        arg_action == ACTION_WATCH);
 
                 if (access(socket_name, W_OK) < 0) {
-
                         if (arg_action == ACTION_QUERY)
                                 log_info("Not querying '%s' (PID %u), lacking privileges.", message, pid);
 
-                        r = 0;
-                        goto finish;
+                        return 0;
                 }
 
                 if (arg_plymouth) {
                         _cleanup_strv_free_ char **passwords = NULL;
 
-                        if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) {
+                        r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords);
+                        if (r >= 0) {
                                 char **p;
 
                                 packet_length = 1;
                                 STRV_FOREACH(p, passwords)
                                         packet_length += strlen(*p) + 1;
 
-                                if (!(packet = new(char, packet_length)))
+                                packet = new(char, packet_length);
+                                if (!packet)
                                         r = -ENOMEM;
                                 else {
                                         char *d;
@@ -349,13 +339,13 @@ static int parse_password(const char *filename, char **wall) {
 
                 } else {
                         int tty_fd = -1;
-                        char *password = NULL;
+                        _cleanup_free_ char *password = NULL;
 
-                        if (arg_console)
-                                if ((tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1)) < 0) {
-                                        r = tty_fd;
-                                        goto finish;
-                                }
+                        if (arg_console) {
+                                tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1);
+                                if (tty_fd < 0)
+                                        return tty_fd;
+                        }
 
                         r = ask_password_tty(message, not_after, filename, &password);
 
@@ -365,53 +355,44 @@ static int parse_password(const char *filename, char **wall) {
                         }
 
                         if (r >= 0) {
-                                packet_length = 1+strlen(password)+1;
-                                if (!(packet = new(char, packet_length)))
+                                packet_length = 1 + strlen(password) + 1;
+                                packet = new(char, packet_length);
+                                if (!packet)
                                         r = -ENOMEM;
                                 else {
                                         packet[0] = '+';
-                                        strcpy(packet+1, password);
+                                        strcpy(packet + 1, password);
                                 }
-
-                                free(password);
                         }
                 }
 
-                if (r == -ETIME || r == -ENOENT) {
+                if (r == -ETIME || r == -ENOENT)
                         /* If the query went away, that's OK */
-                        r = 0;
-                        goto finish;
-                }
+                        return 0;
 
                 if (r < 0) {
                         log_error("Failed to query password: %s", strerror(-r));
-                        goto finish;
+                        return r;
                 }
 
-                if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+                socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+                if (socket_fd < 0) {
                         log_error("socket(): %m");
-                        r = -errno;
-                        goto finish;
+                        return -errno;
                 }
 
                 sa.un.sun_family = AF_UNIX;
                 strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
 
-                if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
+                r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa,
+                           offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
+                if (r < 0) {
                         log_error("Failed to send: %m");
-                        r = -errno;
-                        goto finish;
+                        return r;
                 }
         }
 
-finish:
-        safe_close(socket_fd);
-
-        free(packet);
-        free(socket_name);
-        free(message);
-
-        return r;
+        return 0;
 }
 
 static int wall_tty_block(void) {

commit ed88bcfb7c15029f9fc95ee2380759a9eb782d46
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Jul 16 18:59:49 2014 -0400

    Be more careful when checking for empty files
    
    If we want to avoid reading a totally empty file, it seems better
    to check after we have opened the file, not before.

diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 9974913..8b96d60 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -495,11 +495,6 @@ static int netdev_load_one(Manager *manager, const char *filename) {
         assert(manager);
         assert(filename);
 
-        if (null_or_empty_path(filename)) {
-                log_debug("skipping empty file: %s", filename);
-                return 0;
-        }
-
         file = fopen(filename, "re");
         if (!file) {
                 if (errno == ENOENT)
@@ -508,6 +503,11 @@ static int netdev_load_one(Manager *manager, const char *filename) {
                         return -errno;
         }
 
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
+        }
+
         netdev = new0(NetDev, 1);
         if (!netdev)
                 return log_oom();
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 700577f..3e46a1a 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -48,8 +48,8 @@ static int network_load_one(Manager *manager, const char *filename) {
                         return -errno;
         }
 
-        if (null_or_empty_path(filename)) {
-                log_debug("skipping empty file: %s", filename);
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
                 return 0;
         }
 
diff --git a/src/shared/util.c b/src/shared/util.c
index 75dc58b..4fda31c 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3604,6 +3604,17 @@ int null_or_empty_path(const char *fn) {
         return null_or_empty(&st);
 }
 
+int null_or_empty_fd(int fd) {
+        struct stat st;
+
+        assert(fd >= 0);
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        return null_or_empty(&st);
+}
+
 DIR *xopendirat(int fd, const char *name, int flags) {
         int nfd;
         DIR *d;
diff --git a/src/shared/util.h b/src/shared/util.h
index b3187a9..d9d525e 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -499,6 +499,7 @@ noreturn void freeze(void);
 
 bool null_or_empty(struct stat *st) _pure_;
 int null_or_empty_path(const char *fn);
+int null_or_empty_fd(int fd);
 
 DIR *xopendirat(int dirfd, const char *name, int flags);
 
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 73243fa..512885f 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -153,11 +153,6 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
         assert(ctx);
         assert(filename);
 
-        if (null_or_empty_path(filename)) {
-                log_debug("skipping empty file: %s", filename);
-                return 0;
-        }
-
         file = fopen(filename, "re");
         if (!file) {
                 if (errno == ENOENT)
@@ -166,6 +161,11 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
                         return -errno;
         }
 
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
+        }
+
         link = new0(link_config, 1);
         if (!link)
                 return log_oom();
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 85f78bc..9864016 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1533,15 +1533,19 @@ static int parse_file(struct udev_rules *rules, const char *filename)
         int line_nr = 0;
         unsigned int i;
 
-        if (null_or_empty_path(filename)) {
-                log_debug("skip empty file: %s", filename);
-                return 0;
+        f = fopen(filename, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+                else
+                        return -errno;
         }
-        log_debug("read rules file: %s", filename);
 
-        f = fopen(filename, "re");
-        if (f == NULL)
-                return -1;
+        if (null_or_empty_fd(fileno(f))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
+        } else
+                log_debug("Reading rules file: %s", filename);
 
         first_token = rules->token_cur;
         filename_off = rules_add_string(rules, filename);

commit 36f822c4bd077f9121757e24b6516e5c7ada63b5
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Jul 16 18:27:12 2014 -0400

    Let config_parse open file where applicable
    
    Special care is needed so that we get an error message if the
    file failed to parse, but not when it is missing. To avoid duplicating
    the same error check in every caller, add an additional 'warn' boolean
    to tell config_parse whether a message should be issued.
    This makes things both shorter and more robust wrt. to error reporting.

diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c
index 8e849da..cbfc28d 100644
--- a/src/bootchart/bootchart.c
+++ b/src/bootchart/bootchart.c
@@ -124,17 +124,11 @@ static void parse_conf(void) {
                 { "Bootchart", "ControlGroup",     config_parse_bool,   0, &arg_show_cgroup },
                 { NULL, NULL, NULL, 0, NULL }
         };
-        _cleanup_fclose_ FILE *f;
-        int r;
-
-        f = fopen(BOOTCHART_CONF, "re");
-        if (!f)
-                return;
 
-        r = config_parse(NULL, BOOTCHART_CONF, f,
-                         NULL, config_item_table_lookup, items, true, false, NULL);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
+        config_parse(NULL, BOOTCHART_CONF, NULL,
+                     NULL,
+                     config_item_table_lookup, items,
+                     true, false, true, NULL);
 
         if (init != NULL)
                 strscpy(arg_init_path, sizeof(arg_init_path), init);
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 66547cf..21c9915 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -186,8 +186,9 @@ int unit_load_dropin(Unit *u) {
 
         STRV_FOREACH(f, u->dropin_paths) {
                 config_parse(u->id, *f, NULL,
-                             UNIT_VTABLE(u)->sections, config_item_perf_lookup,
-                             load_fragment_gperf_lookup, false, false, u);
+                             UNIT_VTABLE(u)->sections,
+                             config_item_perf_lookup, load_fragment_gperf_lookup,
+                             false, false, false, u);
         }
 
         u->dropin_mtime = now(CLOCK_REALTIME);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 54010b8..81f1379 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -3368,9 +3368,10 @@ static int load_from_path(Unit *u, const char *path) {
                 u->load_state = UNIT_LOADED;
 
                 /* Now, parse the file contents */
-                r = config_parse(u->id, filename, f, UNIT_VTABLE(u)->sections,
-                                 config_item_perf_lookup,
-                                 load_fragment_gperf_lookup, false, true, u);
+                r = config_parse(u->id, filename, f,
+                                 UNIT_VTABLE(u)->sections,
+                                 config_item_perf_lookup, load_fragment_gperf_lookup,
+                                 false, true, false, u);
                 if (r < 0)
                         return r;
         }
diff --git a/src/core/main.c b/src/core/main.c
index d1fb265..f9ee297 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -682,23 +682,13 @@ static int parse_config_file(void) {
                 {}
         };
 
-        _cleanup_fclose_ FILE *f;
         const char *fn;
-        int r;
 
         fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file '%s': %m", fn);
-                return 0;
-        }
-
-        r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, items, false, false, NULL);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
+        config_parse(NULL, fn, NULL,
+                     "Manager\0",
+                     config_item_table_lookup, items,
+                     false, false, true, NULL);
 
         return 0;
 }
diff --git a/src/dbus1-generator/dbus1-generator.c b/src/dbus1-generator/dbus1-generator.c
index ba29530..dcfceec 100644
--- a/src/dbus1-generator/dbus1-generator.c
+++ b/src/dbus1-generator/dbus1-generator.c
@@ -163,27 +163,17 @@ static int add_dbus(const char *path, const char *fname, const char *type) {
                 { "D-BUS Service", "SystemdService", config_parse_string, 0, &service },
         };
 
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
+        char *p;
         int r;
 
         assert(path);
         assert(fname);
 
-        p = strjoin(path, "/", fname, NULL);
-        if (!p)
-                return log_oom();
-
-        f = fopen(p, "re");
-        if (!f) {
-                if (errno == -ENOENT)
-                        return 0;
-
-                log_error("Failed to read %s: %m", p);
-                return -errno;
-        }
-
-        r = config_parse(NULL, p, f, "D-BUS Service\0", config_item_table_lookup, table, true, false, NULL);
+        p = strappenda3(path, "/", fname);
+        r = config_parse(NULL, p, NULL,
+                         "D-BUS Service\0",
+                         config_item_table_lookup, table,
+                         true, false, true, NULL);
         if (r < 0)
                 return r;
 
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index 08de9d0..37ad902 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -1122,16 +1122,11 @@ static int parse_config(void) {
                 { "Remote",  "ServerCertificateFile",  config_parse_path,             0, &arg_cert       },
                 { "Remote",  "TrustedCertificateFile", config_parse_path,             0, &arg_trust      },
                 {}};
-        int r;
-
-        r = config_parse(NULL, PKGSYSCONFDIR "/journal-remote.conf", NULL,
-                         "Remote\0",
-                         config_item_table_lookup, items,
-                         false, false, NULL);
-        if (r < 0)
-                log_error("Failed to parse configuration file: %s", strerror(-r));
 
-        return r;
+        return config_parse(NULL, PKGSYSCONFDIR "/journal-remote.conf", NULL,
+                            "Remote\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
 }
 
 static void help(void) {
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index a381ec5..72396bf 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -495,16 +495,11 @@ static int parse_config(void) {
                 { "Upload",  "ServerCertificateFile",  config_parse_path,   0, &arg_cert   },
                 { "Upload",  "TrustedCertificateFile", config_parse_path,   0, &arg_trust  },
                 {}};
-        int r;
-
-        r = config_parse(NULL, PKGSYSCONFDIR "/journal-upload.conf", NULL,
-                         "Upload\0",
-                         config_item_table_lookup, items,
-                         false, false, NULL);
-        if (r < 0)
-                log_error("Failed to parse configuration file: %s", strerror(-r));
 
-        return r;
+        return config_parse(NULL, PKGSYSCONFDIR "/journal-upload.conf", NULL,
+                            "Upload\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
 }
 
 static void help(void) {
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 4ac1a41..182c2b1 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -114,16 +114,10 @@ static int parse_config(void) {
                 {}
         };
 
-        return config_parse(
-                        NULL,
-                        "/etc/systemd/coredump.conf",
-                        NULL,
-                        "Coredump\0",
-                        config_item_table_lookup,
-                        items,
-                        false,
-                        false,
-                        NULL);
+        return config_parse(NULL, "/etc/systemd/coredump.conf", NULL,
+                            "Coredump\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
 }
 
 static int fix_acl(int fd, uid_t uid) {
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 097af24..4ea9d43 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1331,27 +1331,12 @@ static int server_parse_proc_cmdline(Server *s) {
 }
 
 static int server_parse_config_file(Server *s) {
-        static const char fn[] = "/etc/systemd/journald.conf";
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
         assert(s);
 
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file %s: %m", fn);
-                return -errno;
-        }
-
-        r = config_parse(NULL, fn, f, "Journal\0", config_item_perf_lookup,
-                         journald_gperf_lookup, false, false, s);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return r;
+        return config_parse(NULL, "/etc/systemd/journald.conf", NULL,
+                            "Journal\0",
+                            config_item_perf_lookup, journald_gperf_lookup,
+                            false, false, true, s);
 }
 
 static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
diff --git a/src/login/logind.c b/src/login/logind.c
index a188184..ec5529d 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1097,27 +1097,12 @@ int manager_run(Manager *m) {
 }
 
 static int manager_parse_config_file(Manager *m) {
-        static const char fn[] = "/etc/systemd/logind.conf";
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
         assert(m);
 
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file %s: %m", fn);
-                return -errno;
-        }
-
-        r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
-                         logind_gperf_lookup, false, false, m);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return r;
+        return config_parse(NULL, "/etc/systemd/logind.conf", NULL,
+                            "Login\0",
+                            config_item_perf_lookup, logind_gperf_lookup,
+                            false, false, true, m);
 }
 
 int main(int argc, char *argv[]) {
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 7d12af3..9974913 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -526,11 +526,9 @@ static int netdev_load_one(Manager *manager, const char *filename) {
         r = config_parse(NULL, filename, file,
                          "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0Bond\0",
                          config_item_perf_lookup, network_netdev_gperf_lookup,
-                         false, false, netdev);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
+                         false, false, true, netdev);
+        if (r < 0)
                 return r;
-        }
 
         /* skip out early if configuration does not match the environment */
         if (net_match_config(NULL, NULL, NULL, NULL, NULL,
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 252c9a0..700577f 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -96,11 +96,9 @@ static int network_load_one(Manager *manager, const char *filename) {
         r = config_parse(NULL, filename, file,
                          "Match\0Network\0Address\0Route\0DHCP\0DHCPv4\0",
                          config_item_perf_lookup, network_network_gperf_lookup,
-                         false, false, network);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
+                         false, false, true, network);
+        if (r < 0)
                 return r;
-        }
 
         LIST_PREPEND(networks, manager->networks, network);
 
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 3d2979d..ab504d0 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -373,18 +373,12 @@ int config_parse_dnsv(
 }
 
 int manager_parse_config_file(Manager *m) {
-        int r;
-
         assert(m);
 
-        r = config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
-                         "Resolve\0",
-                         config_item_perf_lookup, resolved_gperf_lookup,
-                         false, false, m);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return 0;
+        return config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
+                            "Resolve\0",
+                            config_item_perf_lookup, resolved_gperf_lookup,
+                            false, false, true, m);
 }
 
 int manager_new(Manager **ret) {
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 1f40986..0be7226 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -245,7 +245,7 @@ static int parse_line(const char* unit,
                 if (!fn)
                         return -ENOMEM;
 
-                return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, userdata);
+                return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, false, userdata);
         }
 
         if (*l == '[') {
@@ -326,6 +326,7 @@ int config_parse(const char *unit,
                  const void *table,
                  bool relaxed,
                  bool allow_include,
+                 bool warn,
                  void *userdata) {
 
         _cleanup_free_ char *section = NULL, *continuation = NULL;
@@ -340,7 +341,11 @@ int config_parse(const char *unit,
         if (!f) {
                 f = ours = fopen(filename, "re");
                 if (!f) {
-                        log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR, "Failed to open configuration file '%s': %m", filename);
+                        /* Only log on request, except for ENOENT,
+                         * since we return 0 to the caller. */
+                        if (warn || errno == ENOENT)
+                                log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
+                                         "Failed to open configuration file '%s': %m", filename);
                         return errno == ENOENT ? 0 : -errno;
                 }
         }
@@ -363,8 +368,11 @@ int config_parse(const char *unit,
 
                 if (continuation) {
                         c = strappend(continuation, l);
-                        if (!c)
+                        if (!c) {
+                                if (warn)
+                                        log_oom();
                                 return -ENOMEM;
+                        }
 
                         free(continuation);
                         continuation = NULL;
@@ -386,8 +394,11 @@ int config_parse(const char *unit,
                                 continuation = c;
                         else {
                                 continuation = strdup(l);
-                                if (!continuation)
+                                if (!continuation) {
+                                        if (warn)
+                                                log_oom();
                                         return -ENOMEM;
+                                }
                         }
 
                         continue;
@@ -408,8 +419,12 @@ int config_parse(const char *unit,
                                userdata);
                 free(c);
 
-                if (r < 0)
+                if (r < 0) {
+                        if (warn)
+                                log_warning("Failed to parse file '%s': %s",
+                                            filename, strerror(-r));
                         return r;
+                }
         }
 
         return 0;
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 3e2c784..ea7b710 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -89,6 +89,7 @@ int config_parse(const char *unit,
                  const void *table,
                  bool relaxed,
                  bool allow_include,
+                 bool warn,
                  void *userdata);
 
 /* Generic parsers */
diff --git a/src/shared/install.c b/src/shared/install.c
index a080d8f..bc2a377 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1076,7 +1076,10 @@ static int unit_file_load(
                 return -ENOMEM;
         }
 
-        r = config_parse(NULL, path, f, NULL, config_item_table_lookup, items, true, true, info);
+        r = config_parse(NULL, path, f,
+                         NULL,
+                         config_item_table_lookup, items,
+                         true, true, false, info);
         if (r < 0)
                 return r;
 
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index 4b2b0fe..16a488d 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -48,19 +48,9 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
                 {}
         };
 
-        int r;
-        _cleanup_fclose_ FILE *f;
-
-        f = fopen(PKGSYSCONFDIR "/sleep.conf", "re");
-        if (!f)
-                log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING,
-                         "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m");
-        else {
-                r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0",
-                                 config_item_table_lookup, items, false, false, NULL);
-                if (r < 0)
-                        log_warning("Failed to parse configuration file: %s", strerror(-r));
-        }
+        config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", NULL,
+                     "Sleep\0",
+                     config_item_table_lookup, items, false, false, true, NULL);
 
         if (streq(verb, "suspend")) {
                 /* empty by default */
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 67a434a..e4e3aae 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -1095,27 +1095,10 @@ int config_parse_servers(
 }
 
 static int manager_parse_config_file(Manager *m) {
-        static const char fn[] = "/etc/systemd/timesyncd.conf";
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
-        assert(m);
-
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file %s: %m", fn);
-                return -errno;
-        }
-
-        r = config_parse(NULL, fn, f, "Time\0", config_item_perf_lookup,
-                         timesyncd_gperf_lookup, false, false, m);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return r;
+        return config_parse(NULL, "/etc/systemd/timesyncd.conf", NULL,
+                            "Time\0",
+                            config_item_perf_lookup, timesyncd_gperf_lookup,
+                            false, false, true, m);
 }
 
 static bool network_is_online(void) {
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 0398a9d..5852f71 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -258,25 +258,16 @@ static int parse_password(const char *filename, char **wall) {
                 { NULL, NULL, NULL, 0, NULL }
         };
 
-        FILE *f;
         int r;
 
         assert(filename);
 
-        f = fopen(filename, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_error("open(%s): %m", filename);
-                return -errno;
-        }
-
-        r = config_parse(NULL, filename, f, NULL, config_item_table_lookup, items, true, false, NULL);
-        if (r < 0) {
-                log_error("Failed to parse password file %s: %s", filename, strerror(-r));
-                goto finish;
-        }
+        r = config_parse(NULL, filename, NULL,
+                         NULL,
+                         config_item_table_lookup, items,
+                         true, false, true, NULL);
+        if (r < 0)
+                return r;
 
         if (!socket_name) {
                 log_error("Invalid password file %s", filename);
@@ -414,8 +405,6 @@ static int parse_password(const char *filename, char **wall) {
         }
 
 finish:
-        fclose(f);
-
         safe_close(socket_fd);
 
         free(packet);
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index fe916a4..73243fa 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -177,11 +177,10 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
         r = config_parse(NULL, filename, file,
                          "Match\0Link\0Ethernet\0",
                          config_item_perf_lookup, link_config_gperf_lookup,
-                         false, false, link);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
+                         false, false, true, link);
+        if (r < 0)
                 return r;
-        } else
+        else
                 log_debug("Parsed configuration file %s", filename);
 
         link->filename = strdup(filename);



More information about the systemd-commits mailing list