]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: properly handle deserialization of unknown unit types (#6476)
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 31 Jul 2017 06:05:35 +0000 (02:05 -0400)
committerMartin Pitt <martinpitt@users.noreply.github.com>
Mon, 31 Jul 2017 06:05:35 +0000 (08:05 +0200)
We just abort startup, without printing any error. Make sure we always
print something, and when we cannot deserialize some unit, just ignore it and
continue.

Fixup for 4bc5d27b942afa83cc3d95debd2ad48d42ac07a8. Without this, we would hang
in daemon-reexec after upgrade.

src/core/manager.c
src/core/unit.c
src/core/unit.h

index d29acf500fd741b7e0c626e216bd2a9c18c8c758..1aadb7076ef59cca9eb8ab204c5975372ddd5da1 100644 (file)
@@ -1343,8 +1343,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         dual_timestamp_get(&m->units_load_finish_timestamp);
 
         /* Second, deserialize if there is something to deserialize */
-        if (serialization)
+        if (serialization) {
                 r = manager_deserialize(m, serialization, fds);
+                if (r < 0)
+                        log_error_errno(r, "Deserialization failed: %m");
+        }
 
         /* Any fds left? Find some unit which wants them. This is
          * useful to allow container managers to pass some file
@@ -2779,6 +2782,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
         for (;;) {
                 Unit *u;
                 char name[UNIT_NAME_MAX+2];
+                const char* unit_name;
 
                 /* Start marker */
                 if (!fgets(name, sizeof(name), f)) {
@@ -2791,14 +2795,23 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                 }
 
                 char_array_0(name);
+                unit_name = strstrip(name);
 
-                r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
-                if (r < 0)
-                        goto finish;
+                r = manager_load_unit(m, unit_name, NULL, NULL, &u);
+                if (r < 0) {
+                        log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name);
+                        if (r == -ENOMEM)
+                                goto finish;
+                        unit_deserialize_skip(f);
+                        continue;
+                }
 
                 r = unit_deserialize(u, f, fds);
-                if (r < 0)
-                        goto finish;
+                if (r < 0) {
+                        log_notice_errno(r, "Failed to deserialize unit \"%s\": %m", unit_name);
+                        if (r == -ENOMEM)
+                                goto finish;
+                }
         }
 
 finish:
@@ -2871,8 +2884,12 @@ int manager_reload(Manager *m) {
 
         /* Second, deserialize our stored data */
         q = manager_deserialize(m, f, fds);
-        if (q < 0 && r >= 0)
-                r = q;
+        if (q < 0) {
+                log_error_errno(q, "Deserialization failed: %m");
+
+                if (r >= 0)
+                        r = q;
+        }
 
         fclose(f);
         f = NULL;
index 394832e8ba5b1806af809ac03f720341d14672f3..a42c667754af86da9514213c22040596b6721bce 100644 (file)
@@ -3111,6 +3111,27 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
         return 0;
 }
 
+void unit_deserialize_skip(FILE *f) {
+        assert(f);
+
+        /* Skip serialized data for this unit. We don't know what it is. */
+
+        for (;;) {
+                char line[LINE_MAX], *l;
+
+                if (!fgets(line, sizeof line, f))
+                        return;
+
+                char_array_0(line);
+                l = strstrip(line);
+
+                /* End marker */
+                if (isempty(l))
+                        return;
+        }
+}
+
+
 int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep) {
         Unit *device;
         _cleanup_free_ char *e = NULL;
index 5ecaba11e90fb544c5e9d8928fe6625200cda4ee..a384f264ee412b87972ab09b5e6452adc24307d5 100644 (file)
@@ -563,6 +563,7 @@ bool unit_can_serialize(Unit *u) _pure_;
 
 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs);
 int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
+void unit_deserialize_skip(FILE *f);
 
 int unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
 int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *value);