mirror of
https://github.com/systemd/systemd.git
synced 2025-03-10 16:58:28 +03:00
Merge pull request #29583 from poettering/deserialize-fd-many
add serialize_fd_many() + deserialize_fd_many() helpers
This commit is contained in:
commit
668d60627e
@ -99,6 +99,20 @@ void close_many(const int fds[], size_t n_fd) {
|
||||
safe_close(fds[i]);
|
||||
}
|
||||
|
||||
void close_many_unset(int fds[], size_t n_fd) {
|
||||
assert(fds || n_fd <= 0);
|
||||
|
||||
for (size_t i = 0; i < n_fd; i++)
|
||||
fds[i] = safe_close(fds[i]);
|
||||
}
|
||||
|
||||
void close_many_and_free(int *fds, size_t n_fds) {
|
||||
assert(fds || n_fds <= 0);
|
||||
|
||||
close_many(fds, n_fds);
|
||||
free(fds);
|
||||
}
|
||||
|
||||
int fclose_nointr(FILE *f) {
|
||||
assert(f);
|
||||
|
||||
@ -738,8 +752,7 @@ finish:
|
||||
safe_close_above_stdio(original_error_fd);
|
||||
|
||||
/* Close the copies we moved > 2 */
|
||||
for (int i = 0; i < 3; i++)
|
||||
safe_close(copy_fd[i]);
|
||||
close_many(copy_fd, 3);
|
||||
|
||||
/* Close our null fd, if it's > 2 */
|
||||
safe_close_above_stdio(null_fd);
|
||||
|
@ -30,6 +30,8 @@ static inline int safe_close_above_stdio(int fd) {
|
||||
}
|
||||
|
||||
void close_many(const int fds[], size_t n_fd);
|
||||
void close_many_unset(int fds[], size_t n_fd);
|
||||
void close_many_and_free(int *fds, size_t n_fds);
|
||||
|
||||
int fclose_nointr(FILE *f);
|
||||
FILE* safe_fclose(FILE *f);
|
||||
|
@ -925,14 +925,8 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
|
||||
log_unit_error_errno(u, r, "Failed to add expire token to set: %m");
|
||||
}
|
||||
} else if (streq(key, "pipe-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse pipe-fd value: %s", value);
|
||||
else {
|
||||
safe_close(a->pipe_fd);
|
||||
a->pipe_fd = fdset_remove(fds, fd);
|
||||
}
|
||||
safe_close(a->pipe_fd);
|
||||
a->pipe_fd = deserialize_fd(fds, value);
|
||||
} else
|
||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -1008,11 +1008,11 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
return r;
|
||||
c->ip_address_deny_reduced = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
|
||||
r = deserialize_strv(&c->ip_filters_ingress, val);
|
||||
r = deserialize_strv(val, &c->ip_filters_ingress);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
|
||||
r = deserialize_strv(&c->ip_filters_egress, val);
|
||||
r = deserialize_strv(val, &c->ip_filters_egress);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
|
||||
@ -1117,33 +1117,13 @@ static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
|
||||
return r;
|
||||
|
||||
if (rt->shared->netns_storage_socket[0] >= 0 && rt->shared->netns_storage_socket[1] >= 0) {
|
||||
int a, b;
|
||||
|
||||
a = fdset_put_dup(fds, rt->shared->netns_storage_socket[0]);
|
||||
if (a < 0)
|
||||
return a;
|
||||
|
||||
b = fdset_put_dup(fds, rt->shared->netns_storage_socket[1]);
|
||||
if (b < 0)
|
||||
return b;
|
||||
|
||||
r = serialize_item_format(f, "exec-runtime-netns-storage-socket", "%d %d", a, b);
|
||||
r = serialize_fd_many(f, fds, "exec-runtime-netns-storage-socket", rt->shared->netns_storage_socket, 2);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) {
|
||||
int a, b;
|
||||
|
||||
a = fdset_put_dup(fds, rt->shared->ipcns_storage_socket[0]);
|
||||
if (a < 0)
|
||||
return a;
|
||||
|
||||
b = fdset_put_dup(fds, rt->shared->ipcns_storage_socket[1]);
|
||||
if (b < 0)
|
||||
return b;
|
||||
|
||||
r = serialize_item_format(f, "exec-runtime-ipcns-storage-socket", "%d %d", a, b);
|
||||
r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1170,17 +1150,7 @@ static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
|
||||
return r;
|
||||
|
||||
if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
|
||||
int a, b;
|
||||
|
||||
a = fdset_put_dup(fds, rt->ephemeral_storage_socket[0]);
|
||||
if (a < 0)
|
||||
return a;
|
||||
|
||||
b = fdset_put_dup(fds, rt->ephemeral_storage_socket[1]);
|
||||
if (b < 0)
|
||||
return b;
|
||||
|
||||
r = serialize_item_format(f, "exec-runtime-ephemeral-storage-socket", "%d %d", a, b);
|
||||
r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1222,51 +1192,17 @@ static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
|
||||
r = extract_first_word(&val, &w, WHITESPACE, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
if ((fd = parse_fd(w)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, w);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
rt->shared->netns_storage_socket[i] = fd;
|
||||
}
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) {
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
|
||||
r = extract_first_word(&val, &w, WHITESPACE, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
if ((fd = parse_fd(w)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, w);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
rt->shared->ipcns_storage_socket[i] = fd;
|
||||
}
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
|
||||
dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
|
||||
else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
|
||||
@ -1287,28 +1223,10 @@ static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
|
||||
r = extract_first_word(&val, &w, WHITESPACE, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if ((fd = parse_fd(w)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, w);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
rt->ephemeral_storage_socket[i] = fd;
|
||||
}
|
||||
}
|
||||
r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
|
||||
if (r < 0)
|
||||
continue;
|
||||
} else
|
||||
log_warning("Failed to parse serialized line, ignoring: %s", l);
|
||||
}
|
||||
@ -1316,6 +1234,16 @@ static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
|
||||
assert(p);
|
||||
|
||||
return p->idle_pipe &&
|
||||
p->idle_pipe[0] >= 0 &&
|
||||
p->idle_pipe[1] >= 0 &&
|
||||
p->idle_pipe[2] >= 0 &&
|
||||
p->idle_pipe[3] >= 0;
|
||||
}
|
||||
|
||||
static int exec_parameters_serialize(const ExecParameters *p, FILE *f, FDSet *fds) {
|
||||
int r;
|
||||
|
||||
@ -1346,26 +1274,7 @@ static int exec_parameters_serialize(const ExecParameters *p, FILE *f, FDSet *fd
|
||||
}
|
||||
|
||||
if (p->n_socket_fds + p->n_storage_fds > 0) {
|
||||
_cleanup_free_ char *serialized_fds = NULL;
|
||||
|
||||
if (!p->fds)
|
||||
return -EINVAL;
|
||||
|
||||
FOREACH_ARRAY(fd, p->fds, p->n_socket_fds + p->n_storage_fds) {
|
||||
int copy = -EBADF;
|
||||
|
||||
if (*fd >= 0) {
|
||||
copy = fdset_put_dup(fds, *fd);
|
||||
if (copy < 0)
|
||||
return copy;
|
||||
}
|
||||
|
||||
r = strextendf(&serialized_fds, "%d ", copy);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = serialize_item(f, "exec-parameters-fds", serialized_fds);
|
||||
r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_storage_fds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1434,24 +1343,8 @@ static int exec_parameters_serialize(const ExecParameters *p, FILE *f, FDSet *fd
|
||||
return r;
|
||||
}
|
||||
|
||||
if (p->idle_pipe) {
|
||||
_cleanup_free_ char *serialized_fds = NULL;
|
||||
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
int copy = -EBADF;
|
||||
|
||||
if (p->idle_pipe[i] >= 0) {
|
||||
copy = fdset_put_dup(fds, p->idle_pipe[i]);
|
||||
if (copy < 0)
|
||||
return copy;
|
||||
}
|
||||
|
||||
r = strextendf(&serialized_fds, "%d ", copy);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = serialize_item(f, "exec-parameters-idle-pipe", serialized_fds);
|
||||
if (exec_parameters_is_idle_pipe_set(p)) {
|
||||
r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1556,7 +1449,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
|
||||
if (p->runtime_scope < 0)
|
||||
return p->runtime_scope;
|
||||
} else if ((val = startswith(l, "exec-parameters-environment="))) {
|
||||
r = deserialize_strv(&p->environment, val);
|
||||
r = deserialize_strv(val, &p->environment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
|
||||
@ -1599,30 +1492,12 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
|
||||
for (size_t i = 0; i < p->n_socket_fds + p->n_storage_fds; ++i)
|
||||
p->fds[i] = -EBADF;
|
||||
|
||||
for (size_t i = 0; i < p->n_socket_fds + p->n_storage_fds; ++i) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_storage_fds, p->fds);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
r = extract_first_word(&val, &w, WHITESPACE, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if ((fd = parse_fd(w)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, w);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
p->fds[i] = fd;
|
||||
}
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-parameters-fd-names="))) {
|
||||
r = deserialize_strv(&p->fd_names, val);
|
||||
r = deserialize_strv(val, &p->fd_names);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-parameters-flags="))) {
|
||||
@ -1709,104 +1584,58 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
|
||||
|
||||
p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
|
||||
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
r = extract_first_word(&val, &w, WHITESPACE, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if ((fd = parse_fd(w)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, w);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
p->idle_pipe[i] = fd;
|
||||
}
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
p->stdin_fd = fd;
|
||||
|
||||
p->stdin_fd = fd;
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
p->stdout_fd = fd;
|
||||
|
||||
p->stdout_fd = fd;
|
||||
}
|
||||
} else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
p->stderr_fd = fd;
|
||||
}
|
||||
p->stderr_fd = fd;
|
||||
} else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
/* This is special and relies on close-on-exec semantics, make sure it's
|
||||
* there */
|
||||
r = fd_cloexec(fd, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* This is special and relies on close-on-exec semantics, make sure it's
|
||||
* there */
|
||||
r = fd_cloexec(fd, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p->exec_fd = fd;
|
||||
}
|
||||
p->exec_fd = fd;
|
||||
} else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
p->bpf_outer_map_fd = fd;
|
||||
}
|
||||
p->bpf_outer_map_fd = fd;
|
||||
} else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
|
||||
r = free_and_strdup(&p->notify_socket, val);
|
||||
if (r < 0)
|
||||
@ -1826,19 +1655,13 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
|
||||
} else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_debug("Failed to parse %s value: %s, ignoring.", l, val);
|
||||
else {
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to remove %s value=%d from fdset, ignoring: %m", l, fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
p->user_lookup_fd = fd;
|
||||
}
|
||||
p->user_lookup_fd = fd;
|
||||
} else if ((val = startswith(l, "exec-parameters-files-env="))) {
|
||||
r = deserialize_strv(&p->files_env, val);
|
||||
r = deserialize_strv(val, &p->files_env);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-parameters-unit-id="))) {
|
||||
@ -2788,19 +2611,19 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
break;
|
||||
|
||||
if ((val = startswith(l, "exec-context-environment="))) {
|
||||
r = deserialize_strv(&c->environment, val);
|
||||
r = deserialize_strv(val, &c->environment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-environment-files="))) {
|
||||
r = deserialize_strv(&c->environment_files, val);
|
||||
r = deserialize_strv(val, &c->environment_files);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-pass-environment="))) {
|
||||
r = deserialize_strv(&c->pass_environment, val);
|
||||
r = deserialize_strv(val, &c->pass_environment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-unset-environment="))) {
|
||||
r = deserialize_strv(&c->unset_environment, val);
|
||||
r = deserialize_strv(val, &c->unset_environment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-working-directory="))) {
|
||||
@ -3346,7 +3169,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
return r;
|
||||
c->dynamic_user = r;
|
||||
} else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
|
||||
r = deserialize_strv(&c->supplementary_groups, val);
|
||||
r = deserialize_strv(val, &c->supplementary_groups);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-set-login-environment="))) {
|
||||
@ -3358,27 +3181,27 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-read-write-paths="))) {
|
||||
r = deserialize_strv(&c->read_write_paths, val);
|
||||
r = deserialize_strv(val, &c->read_write_paths);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-read-only-paths="))) {
|
||||
r = deserialize_strv(&c->read_only_paths, val);
|
||||
r = deserialize_strv(val, &c->read_only_paths);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
|
||||
r = deserialize_strv(&c->inaccessible_paths, val);
|
||||
r = deserialize_strv(val, &c->inaccessible_paths);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-exec-paths="))) {
|
||||
r = deserialize_strv(&c->exec_paths, val);
|
||||
r = deserialize_strv(val, &c->exec_paths);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
|
||||
r = deserialize_strv(&c->no_exec_paths, val);
|
||||
r = deserialize_strv(val, &c->no_exec_paths);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-exec-search-path="))) {
|
||||
r = deserialize_strv(&c->exec_search_path, val);
|
||||
r = deserialize_strv(val, &c->exec_search_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
|
||||
@ -3852,7 +3675,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
} else if ((val = startswith(l, "exec-context-extension-directories="))) {
|
||||
r = deserialize_strv(&c->extension_directories, val);
|
||||
r = deserialize_strv(val, &c->extension_directories);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-set-credentials="))) {
|
||||
@ -3996,7 +3819,7 @@ static int exec_command_deserialize(ExecCommand *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-command-argv="))) {
|
||||
r = deserialize_strv(&c->argv, val);
|
||||
r = deserialize_strv(val, &c->argv);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-command-flags="))) {
|
||||
|
@ -2002,27 +2002,18 @@ int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char
|
||||
return -ENOMEM;
|
||||
|
||||
} else if (streq(key, "netns-socket-0")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd)) {
|
||||
log_unit_debug(u, "Failed to parse netns socket value: %s", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
safe_close(rt->netns_storage_socket[0]);
|
||||
rt->netns_storage_socket[0] = fdset_remove(fds, fd);
|
||||
rt->netns_storage_socket[0] = deserialize_fd(fds, value);
|
||||
if (rt->netns_storage_socket[0] < 0)
|
||||
return 0;
|
||||
|
||||
} else if (streq(key, "netns-socket-1")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd)) {
|
||||
log_unit_debug(u, "Failed to parse netns socket value: %s", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
safe_close(rt->netns_storage_socket[1]);
|
||||
rt->netns_storage_socket[1] = fdset_remove(fds, fd);
|
||||
|
||||
rt->netns_storage_socket[1] = deserialize_fd(fds, value);
|
||||
if (rt->netns_storage_socket[1] < 0)
|
||||
return 0;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
@ -2088,13 +2079,9 @@ int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fd
|
||||
n = strcspn(v, " ");
|
||||
buf = strndupa_safe(v, n);
|
||||
|
||||
netns_fdpair[0] = parse_fd(buf);
|
||||
netns_fdpair[0] = deserialize_fd(fds, buf);
|
||||
if (netns_fdpair[0] < 0)
|
||||
return log_debug_errno(netns_fdpair[0], "Unable to parse exec-runtime specification netns-socket-0=%s: %m", buf);
|
||||
if (!fdset_contains(fds, netns_fdpair[0]))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
|
||||
"exec-runtime specification netns-socket-0= refers to unknown fd %d: %m", netns_fdpair[0]);
|
||||
netns_fdpair[0] = fdset_remove(fds, netns_fdpair[0]);
|
||||
return netns_fdpair[0];
|
||||
if (v[n] != ' ')
|
||||
goto finalize;
|
||||
p = v + n + 1;
|
||||
@ -2107,13 +2094,9 @@ int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fd
|
||||
n = strcspn(v, " ");
|
||||
buf = strndupa_safe(v, n);
|
||||
|
||||
netns_fdpair[1] = parse_fd(buf);
|
||||
netns_fdpair[1] = deserialize_fd(fds, buf);
|
||||
if (netns_fdpair[1] < 0)
|
||||
return log_debug_errno(netns_fdpair[1], "Unable to parse exec-runtime specification netns-socket-1=%s: %m", buf);
|
||||
if (!fdset_contains(fds, netns_fdpair[1]))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
|
||||
"exec-runtime specification netns-socket-1= refers to unknown fd %d: %m", netns_fdpair[1]);
|
||||
netns_fdpair[1] = fdset_remove(fds, netns_fdpair[1]);
|
||||
return netns_fdpair[1];
|
||||
if (v[n] != ' ')
|
||||
goto finalize;
|
||||
p = v + n + 1;
|
||||
@ -2126,13 +2109,9 @@ int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fd
|
||||
n = strcspn(v, " ");
|
||||
buf = strndupa_safe(v, n);
|
||||
|
||||
ipcns_fdpair[0] = parse_fd(buf);
|
||||
ipcns_fdpair[0] = deserialize_fd(fds, buf);
|
||||
if (ipcns_fdpair[0] < 0)
|
||||
return log_debug_errno(ipcns_fdpair[0], "Unable to parse exec-runtime specification ipcns-socket-0=%s: %m", buf);
|
||||
if (!fdset_contains(fds, ipcns_fdpair[0]))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
|
||||
"exec-runtime specification ipcns-socket-0= refers to unknown fd %d: %m", ipcns_fdpair[0]);
|
||||
ipcns_fdpair[0] = fdset_remove(fds, ipcns_fdpair[0]);
|
||||
return ipcns_fdpair[0];
|
||||
if (v[n] != ' ')
|
||||
goto finalize;
|
||||
p = v + n + 1;
|
||||
@ -2145,13 +2124,9 @@ int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fd
|
||||
n = strcspn(v, " ");
|
||||
buf = strndupa_safe(v, n);
|
||||
|
||||
ipcns_fdpair[1] = parse_fd(buf);
|
||||
ipcns_fdpair[1] = deserialize_fd(fds, buf);
|
||||
if (ipcns_fdpair[1] < 0)
|
||||
return log_debug_errno(ipcns_fdpair[1], "Unable to parse exec-runtime specification ipcns-socket-1=%s: %m", buf);
|
||||
if (!fdset_contains(fds, ipcns_fdpair[1]))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
|
||||
"exec-runtime specification ipcns-socket-1= refers to unknown fd %d: %m", ipcns_fdpair[1]);
|
||||
ipcns_fdpair[1] = fdset_remove(fds, ipcns_fdpair[1]);
|
||||
return ipcns_fdpair[1];
|
||||
}
|
||||
|
||||
finalize:
|
||||
@ -2276,8 +2251,7 @@ void exec_params_serialized_done(ExecParameters *p) {
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; p->fds && i < p->n_socket_fds + p->n_storage_fds; i++)
|
||||
p->fds[i] = safe_close(p->fds[i]);
|
||||
close_many_unset(p->fds, p->n_socket_fds + p->n_storage_fds);
|
||||
|
||||
p->cgroup_path = mfree(p->cgroup_path);
|
||||
|
||||
@ -2285,9 +2259,10 @@ void exec_params_serialized_done(ExecParameters *p) {
|
||||
p->received_credentials_directory = mfree(p->received_credentials_directory);
|
||||
p->received_encrypted_credentials_directory = mfree(p->received_encrypted_credentials_directory);
|
||||
|
||||
for (size_t i = 0; p->idle_pipe && i < 4; i++)
|
||||
p->idle_pipe[i] = safe_close(p->idle_pipe[i]);
|
||||
p->idle_pipe = mfree(p->idle_pipe);
|
||||
if (p->idle_pipe) {
|
||||
close_many_and_free(p->idle_pipe, 4);
|
||||
p->idle_pipe = NULL;
|
||||
}
|
||||
|
||||
p->stdin_fd = safe_close(p->stdin_fd);
|
||||
p->stdout_fd = safe_close(p->stdout_fd);
|
||||
|
@ -456,12 +456,11 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
} else if ((val = startswith(l, "notify-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
|
||||
else {
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd >= 0) {
|
||||
m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
|
||||
safe_close(m->notify_fd);
|
||||
m->notify_fd = fdset_remove(fds, fd);
|
||||
m->notify_fd = fd;
|
||||
}
|
||||
|
||||
} else if ((val = startswith(l, "notify-socket="))) {
|
||||
@ -472,12 +471,11 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
} else if ((val = startswith(l, "cgroups-agent-fd="))) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd))
|
||||
log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
|
||||
else {
|
||||
fd = deserialize_fd(fds, val);
|
||||
if (fd >= 0) {
|
||||
m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
|
||||
safe_close(m->cgroups_agent_fd);
|
||||
m->cgroups_agent_fd = fdset_remove(fds, fd);
|
||||
m->cgroups_agent_fd = fd;
|
||||
}
|
||||
|
||||
} else if ((val = startswith(l, "user-lookup="))) {
|
||||
|
@ -3223,27 +3223,27 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
}
|
||||
|
||||
} else if (streq(key, "socket-fd")) {
|
||||
int fd;
|
||||
asynchronous_close(s->socket_fd);
|
||||
s->socket_fd = deserialize_fd(fds, value);
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse socket-fd value: %s", value);
|
||||
else {
|
||||
asynchronous_close(s->socket_fd);
|
||||
s->socket_fd = fdset_remove(fds, fd);
|
||||
}
|
||||
} else if (streq(key, "fd-store-fd")) {
|
||||
_cleanup_free_ char *fdv = NULL, *fdn = NULL, *fdp = NULL;
|
||||
int fd, do_poll;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int do_poll;
|
||||
|
||||
r = extract_first_word(&value, &fdv, NULL, 0);
|
||||
if (r <= 0 || (fd = parse_fd(fdv)) < 0 || !fdset_contains(fds, fd)) {
|
||||
log_unit_debug(u, "Failed to parse fd-store-fd value: %s", value);
|
||||
if (r <= 0) {
|
||||
log_unit_debug(u, "Failed to parse fd-store-fd value, ignoring: %s", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = deserialize_fd(fds, fdv);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
r = extract_first_word(&value, &fdn, NULL, EXTRACT_CUNESCAPE | EXTRACT_UNQUOTE);
|
||||
if (r <= 0) {
|
||||
log_unit_debug(u, "Failed to parse fd-store-fd value: %s", value);
|
||||
log_unit_debug(u, "Failed to parse fd-store-fd value, ignoring: %s", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3251,23 +3251,18 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
if (r == 0) {
|
||||
/* If the value is not present, we assume the default */
|
||||
do_poll = 1;
|
||||
} else if (r < 0 || safe_atoi(fdp, &do_poll) < 0) {
|
||||
log_unit_debug_errno(u, r, "Failed to parse fd-store-fd value \"%s\": %m", value);
|
||||
} else if (r < 0 || (r = safe_atoi(fdp, &do_poll)) < 0) {
|
||||
log_unit_debug_errno(u, r, "Failed to parse fd-store-fd value \"%s\", ignoring: %m", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = fdset_remove(fds, fd);
|
||||
if (r < 0) {
|
||||
log_unit_error_errno(u, r, "Could not find deserialized fd %i in fdset: %m", fd);
|
||||
return 0;
|
||||
}
|
||||
assert(r == fd);
|
||||
|
||||
r = service_add_fd_store(s, fd, fdn, do_poll);
|
||||
if (r < 0) {
|
||||
log_unit_error_errno(u, r, "Failed to store deserialized fd %i: %m", fd);
|
||||
log_unit_debug_errno(u, r, "Failed to store deserialized fd %i, ignoring: %m", fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_FD(fd);
|
||||
} else if (streq(key, "main-exec-status-pid")) {
|
||||
pid_t pid;
|
||||
|
||||
@ -3312,47 +3307,37 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
else
|
||||
s->forbid_restart = b;
|
||||
} else if (streq(key, "stdin-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse stdin-fd value: %s", value);
|
||||
else {
|
||||
asynchronous_close(s->stdin_fd);
|
||||
s->stdin_fd = fdset_remove(fds, fd);
|
||||
asynchronous_close(s->stdin_fd);
|
||||
s->stdin_fd = deserialize_fd(fds, value);
|
||||
if (s->stdin_fd >= 0)
|
||||
s->exec_context.stdio_as_fds = true;
|
||||
}
|
||||
|
||||
} else if (streq(key, "stdout-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse stdout-fd value: %s", value);
|
||||
else {
|
||||
asynchronous_close(s->stdout_fd);
|
||||
s->stdout_fd = fdset_remove(fds, fd);
|
||||
asynchronous_close(s->stdout_fd);
|
||||
s->stdout_fd = deserialize_fd(fds, value);
|
||||
if (s->stdout_fd >= 0)
|
||||
s->exec_context.stdio_as_fds = true;
|
||||
}
|
||||
|
||||
} else if (streq(key, "stderr-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse stderr-fd value: %s", value);
|
||||
else {
|
||||
asynchronous_close(s->stderr_fd);
|
||||
s->stderr_fd = fdset_remove(fds, fd);
|
||||
asynchronous_close(s->stderr_fd);
|
||||
s->stderr_fd = deserialize_fd(fds, value);
|
||||
if (s->stderr_fd >= 0)
|
||||
s->exec_context.stdio_as_fds = true;
|
||||
}
|
||||
} else if (streq(key, "exec-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse exec-fd value: %s", value);
|
||||
else {
|
||||
} else if (streq(key, "exec-fd")) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
fd = deserialize_fd(fds, value);
|
||||
if (fd >= 0) {
|
||||
s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source);
|
||||
|
||||
fd = fdset_remove(fds, fd);
|
||||
if (service_allocate_exec_fd_event_source(s, fd, &s->exec_fd_event_source) < 0)
|
||||
safe_close(fd);
|
||||
if (service_allocate_exec_fd_event_source(s, fd, &s->exec_fd_event_source) >= 0)
|
||||
TAKE_FD(fd);
|
||||
}
|
||||
|
||||
} else if (streq(key, "watchdog-override-usec")) {
|
||||
if (deserialize_usec(value, &s->watchdog_override_usec) < 0)
|
||||
log_unit_debug(u, "Failed to parse watchdog_override_usec value: %s", value);
|
||||
|
@ -387,16 +387,9 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
|
||||
else if (STR_IN_SET(l, "ipv4-socket-bind-bpf-link-fd", "ipv6-socket-bind-bpf-link-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(v)) < 0 || !fdset_contains(fds, fd))
|
||||
log_unit_debug(u, "Failed to parse %s value: %s, ignoring.", l, v);
|
||||
else {
|
||||
if (fdset_remove(fds, fd) < 0) {
|
||||
log_unit_debug(u, "Failed to remove %s value=%d from fdset", l, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = deserialize_fd(fds, v);
|
||||
if (fd >= 0)
|
||||
(void) bpf_socket_bind_add_initial_link_fd(u, fd);
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "ip-bpf-ingress-installed")) {
|
||||
@ -419,16 +412,10 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
|
||||
} else if (streq(l, "restrict-ifaces-bpf-fd")) {
|
||||
int fd;
|
||||
|
||||
if ((fd = parse_fd(v)) < 0 || !fdset_contains(fds, fd)) {
|
||||
log_unit_debug(u, "Failed to parse restrict-ifaces-bpf-fd value: %s", v);
|
||||
continue;
|
||||
}
|
||||
if (fdset_remove(fds, fd) < 0) {
|
||||
log_unit_debug(u, "Failed to remove restrict-ifaces-bpf-fd %d from fdset", fd);
|
||||
continue;
|
||||
}
|
||||
fd = deserialize_fd(fds, v);
|
||||
if (fd >= 0)
|
||||
(void) restrict_network_interfaces_add_initial_link_fd(u, fd);
|
||||
|
||||
(void) restrict_network_interfaces_add_initial_link_fd(u, fd);
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "ref-uid")) {
|
||||
|
@ -116,6 +116,33 @@ int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd) {
|
||||
return serialize_item_format(f, key, "%i", copy);
|
||||
}
|
||||
|
||||
int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[], size_t n_fd_array) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
assert(f);
|
||||
|
||||
if (n_fd_array == 0)
|
||||
return 0;
|
||||
|
||||
assert(fd_array);
|
||||
|
||||
for (size_t i = 0; i < n_fd_array; i++) {
|
||||
int copy;
|
||||
|
||||
if (fd_array[i] < 0)
|
||||
return -EBADF;
|
||||
|
||||
copy = fdset_put_dup(fds, fd_array[i]);
|
||||
if (copy < 0)
|
||||
return log_error_errno(copy, "Failed to add file descriptor to serialization set: %m");
|
||||
|
||||
if (strextendf_with_separator(&t, " ", "%i", copy) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
return serialize_item(f, key, t);
|
||||
}
|
||||
|
||||
int serialize_usec(FILE *f, const char *key, usec_t usec) {
|
||||
assert(f);
|
||||
assert(key);
|
||||
@ -285,7 +312,66 @@ int deserialize_read_line(FILE *f, char **ret) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int deserialize_strv(char ***l, const char *value) {
|
||||
int deserialize_fd(FDSet *fds, const char *value) {
|
||||
_cleanup_close_ int our_fd = -EBADF;
|
||||
int parsed_fd;
|
||||
|
||||
assert(value);
|
||||
|
||||
parsed_fd = parse_fd(value);
|
||||
if (parsed_fd < 0)
|
||||
return log_debug_errno(parsed_fd, "Failed to parse file descriptor serialization: %s", value);
|
||||
|
||||
our_fd = fdset_remove(fds, parsed_fd); /* Take possession of the fd */
|
||||
if (our_fd < 0)
|
||||
return log_debug_errno(our_fd, "Failed to acquire fd from serialization fds: %m");
|
||||
|
||||
return TAKE_FD(our_fd);
|
||||
}
|
||||
|
||||
int deserialize_fd_many(FDSet *fds, const char *value, size_t n, int *ret) {
|
||||
int r, *fd_array = NULL;
|
||||
size_t m = 0;
|
||||
|
||||
assert(value);
|
||||
|
||||
fd_array = new(int, n);
|
||||
if (!fd_array)
|
||||
return -ENOMEM;
|
||||
|
||||
CLEANUP_ARRAY(fd_array, m, close_many_and_free);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int fd;
|
||||
|
||||
r = extract_first_word(&value, &w, NULL, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
if (m < n) /* Too few */
|
||||
return -EINVAL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (m >= n) /* Too many */
|
||||
return -EINVAL;
|
||||
|
||||
fd = deserialize_fd(fds, w);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
fd_array[m++] = fd;
|
||||
}
|
||||
|
||||
memcpy(ret, fd_array, m * sizeof(int));
|
||||
fd_array = mfree(fd_array);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deserialize_strv(const char *value, char ***l) {
|
||||
ssize_t unescaped_len;
|
||||
char *unescaped;
|
||||
|
||||
@ -303,6 +389,7 @@ int deserialize_usec(const char *value, usec_t *ret) {
|
||||
int r;
|
||||
|
||||
assert(value);
|
||||
assert(ret);
|
||||
|
||||
r = safe_atou64(value, ret);
|
||||
if (r < 0)
|
||||
@ -311,12 +398,12 @@ int deserialize_usec(const char *value, usec_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deserialize_dual_timestamp(const char *value, dual_timestamp *t) {
|
||||
int deserialize_dual_timestamp(const char *value, dual_timestamp *ret) {
|
||||
uint64_t a, b;
|
||||
int r, pos;
|
||||
|
||||
assert(value);
|
||||
assert(t);
|
||||
assert(ret);
|
||||
|
||||
pos = strspn(value, WHITESPACE);
|
||||
if (value[pos] == '-')
|
||||
@ -336,8 +423,10 @@ int deserialize_dual_timestamp(const char *value, dual_timestamp *t) {
|
||||
/* trailing garbage */
|
||||
return -EINVAL;
|
||||
|
||||
t->realtime = a;
|
||||
t->monotonic = b;
|
||||
*ret = (dual_timestamp) {
|
||||
.realtime = a,
|
||||
.monotonic = b,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -372,18 +461,12 @@ int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret) {
|
||||
|
||||
e = startswith(value, "@");
|
||||
if (e) {
|
||||
_cleanup_close_ int our_fd = -EBADF;
|
||||
int parsed_fd;
|
||||
int fd = deserialize_fd(fds, e);
|
||||
|
||||
parsed_fd = parse_fd(e);
|
||||
if (parsed_fd < 0)
|
||||
return log_debug_errno(parsed_fd, "Failed to parse file descriptor specification: %s", e);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
our_fd = fdset_remove(fds, parsed_fd); /* Take possession of the fd */
|
||||
if (our_fd < 0)
|
||||
return log_debug_errno(our_fd, "Failed to acquire pidfd from serialization fds: %m");
|
||||
|
||||
r = pidref_set_pidfd_consume(ret, TAKE_FD(our_fd));
|
||||
r = pidref_set_pidfd_consume(ret, fd);
|
||||
} else {
|
||||
pid_t pid;
|
||||
|
||||
|
@ -17,6 +17,7 @@ int serialize_item_format(FILE *f, const char *key, const char *value, ...) _pri
|
||||
int serialize_item_hexmem(FILE *f, const char *key, const void *p, size_t l);
|
||||
int serialize_item_base64mem(FILE *f, const char *key, const void *p, size_t l);
|
||||
int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd);
|
||||
int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[], size_t n_fd_array);
|
||||
int serialize_usec(FILE *f, const char *key, usec_t usec);
|
||||
int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t);
|
||||
int serialize_strv(FILE *f, const char *key, char **l);
|
||||
@ -37,10 +38,12 @@ static inline int serialize_item_tristate(FILE *f, const char *key, int value) {
|
||||
|
||||
int deserialize_read_line(FILE *f, char **ret);
|
||||
|
||||
int deserialize_usec(const char *value, usec_t *timestamp);
|
||||
int deserialize_dual_timestamp(const char *value, dual_timestamp *t);
|
||||
int deserialize_fd(FDSet *fds, const char *value);
|
||||
int deserialize_fd_many(FDSet *fds, const char *value, size_t n, int *ret);
|
||||
int deserialize_usec(const char *value, usec_t *ret);
|
||||
int deserialize_dual_timestamp(const char *value, dual_timestamp *ret);
|
||||
int deserialize_environment(const char *value, char ***environment);
|
||||
int deserialize_strv(char ***l, const char *value);
|
||||
int deserialize_strv(const char *value, char ***l);
|
||||
int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret);
|
||||
|
||||
int open_serialization_fd(const char *ident);
|
||||
|
@ -128,7 +128,7 @@ TEST(serialize_strv) {
|
||||
|
||||
const char *t = startswith(line, "strv3=");
|
||||
assert_se(t);
|
||||
assert_se(deserialize_strv(&strv2, t) >= 0);
|
||||
assert_se(deserialize_strv(t, &strv2) >= 0);
|
||||
}
|
||||
|
||||
assert_se(strv_equal(strv, strv2));
|
||||
|
Loading…
x
Reference in New Issue
Block a user