diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-10-05 12:45:38 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-10-05 12:57:05 +0200 |
commit | 2a7451dc5dba7de5884d39771226e63b1e64159f (patch) | |
tree | bd281ec87c845babf31bb1053f62a356ff79db3a /src/shared/serialize.c | |
parent | repart: Mention that xattrs are not copied when populating XFS with protofile (diff) | |
download | systemd-2a7451dc5dba7de5884d39771226e63b1e64159f.tar.xz systemd-2a7451dc5dba7de5884d39771226e63b1e64159f.zip |
pid1: serialize pidrefs as pidfds if possible
One major step towards total pidfdification of systemd.
Diffstat (limited to 'src/shared/serialize.c')
-rw-r--r-- | src/shared/serialize.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/shared/serialize.c b/src/shared/serialize.c index f9795efe36..2ffc524f15 100644 --- a/src/shared/serialize.c +++ b/src/shared/serialize.c @@ -5,6 +5,7 @@ #include "alloc-util.h" #include "env-util.h" #include "escape.h" +#include "fd-util.h" #include "fileio.h" #include "memfd-util.h" #include "missing_mman.h" @@ -101,6 +102,7 @@ int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd) { int copy; assert(f); + assert(fds); assert(key); if (fd < 0) @@ -149,6 +151,28 @@ int serialize_strv(FILE *f, const char *key, char **l) { return ret; } +int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref) { + int copy; + + assert(f); + assert(fds); + + if (!pidref_is_set(pidref)) + return 0; + + /* If we have a pidfd we serialize the fd and encode the fd number prefixed by "@" in the + * serialization. Otherwise we serialize the numeric PID as it is. */ + + if (pidref->fd < 0) + return serialize_item_format(f, key, PID_FMT, pidref->pid); + + copy = fdset_put_dup(fds, pidref->fd); + if (copy < 0) + return log_error_errno(copy, "Failed to add file descriptor to serialization set: %m"); + + return serialize_item_format(f, key, "@%i", copy); +} + int deserialize_read_line(FILE *f, char **ret) { _cleanup_free_ char *line = NULL; int r; @@ -255,6 +279,42 @@ int deserialize_environment(const char *value, char ***list) { return 0; } +int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret) { + const char *e; + int r; + + assert(value); + assert(ret); + + e = startswith(value, "@"); + if (e) { + _cleanup_close_ int our_fd = -EBADF; + int parsed_fd; + + parsed_fd = parse_fd(e); + if (parsed_fd < 0) + return log_debug_errno(parsed_fd, "Failed to parse file descriptor specification: %s", e); + + 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)); + } else { + pid_t pid; + + r = parse_pid(value, &pid); + if (r < 0) + return log_debug_errno(r, "Failed to parse PID: %s", value); + + r = pidref_set_pid(ret, pid); + } + if (r < 0) + return log_debug_errno(r, "Failed to initialize pidref: %m"); + + return 0; +} + int open_serialization_fd(const char *ident) { int fd; |