serialize: add new helper deserialize_fd()
Currently, when we deserialize an fd we do a lot of manual work. Add a common helper that makes this more robust and uniform. Note that this sometimes changes behaviour slightly, but in ways that shouldn't really matter: if we fail to deserialize an fd correctly we'll unset (i.e. set to -EBADF) the fd in the deserialized data structure. Previously, we'd leave the old value in place. This should not change effective result (as in either case we'll be in a bad state afterwards, just once we mix old/invalidated state with new state, while now we'll reset the state explicitly to invalidated state on failure). In particular as deserialization starts from an empty structure generally, hence the old value should be unset anyway. Another slight change is that if we fail to deserialize some object half way, and we already have taken out one fd from the serialized fdset we'll now just close it instead of returning it to/leaving it in the fdset. Given that such "orphaned" fds are blanket closed after deserialization finishes this also shouldn't change behaviour IRL. Also, the idle_pipe was previously incorrectly serialized: we'd serialize invalidated fds, which would fail, but because parsing errors on this were ignored on the deserializatin noone noticed. This is fixed.
This commit is contained in:
@@ -648,7 +648,8 @@ int dynamic_user_serialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
|
||||
void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds, DynamicUser **ret) {
|
||||
_cleanup_free_ char *name = NULL, *s0 = NULL, *s1 = NULL;
|
||||
int r, fd0, fd1;
|
||||
_cleanup_close_ int fd0 = -EBADF, fd1 = -EBADF;
|
||||
int r;
|
||||
|
||||
assert(value);
|
||||
assert(fds);
|
||||
@@ -661,15 +662,13 @@ void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds, Dyn
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd0 = parse_fd(s0)) < 0 || !fdset_contains(fds, fd0)) {
|
||||
log_debug("Unable to process dynamic user fd specification.");
|
||||
fd0 = deserialize_fd(fds, s0);
|
||||
if (fd0 < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd1 = parse_fd(s1)) < 0 || !fdset_contains(fds, fd1)) {
|
||||
log_debug("Unable to process dynamic user fd specification.");
|
||||
fd1 = deserialize_fd(fds, s1);
|
||||
if (fd1 < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
r = dynamic_user_add(m, name, (int[]) { fd0, fd1 }, ret);
|
||||
if (r < 0) {
|
||||
@@ -677,8 +676,8 @@ void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds, Dyn
|
||||
return;
|
||||
}
|
||||
|
||||
(void) fdset_remove(fds, fd0);
|
||||
(void) fdset_remove(fds, fd1);
|
||||
TAKE_FD(fd0);
|
||||
TAKE_FD(fd1);
|
||||
|
||||
if (ret) /* If the caller uses it directly, increment the refcount */
|
||||
(*ret)->n_ref++;
|
||||
|
||||
Reference in New Issue
Block a user