diff --git a/src/core/manager.c b/src/core/manager.c index d29acf500fd..1aadb7076ef 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -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; diff --git a/src/core/unit.c b/src/core/unit.c index 394832e8ba5..a42c667754a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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; diff --git a/src/core/unit.h b/src/core/unit.h index 5ecaba11e90..a384f264ee4 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -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);