mirror of
https://github.com/systemd/systemd.git
synced 2025-03-21 02:50:18 +03:00
core: properly handle deserialization of unknown unit types (#6476)
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.
This commit is contained in:
parent
01a45898fc
commit
0742986650
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user