summaryrefslogtreecommitdiffstats
path: root/src/shared/serialize.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-10-05 12:45:38 +0200
committerLennart Poettering <lennart@poettering.net>2023-10-05 12:57:05 +0200
commit2a7451dc5dba7de5884d39771226e63b1e64159f (patch)
treebd281ec87c845babf31bb1053f62a356ff79db3a /src/shared/serialize.c
parentrepart: Mention that xattrs are not copied when populating XFS with protofile (diff)
downloadsystemd-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.c60
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;