One major step towards total pidfdification of systemd.
(void) serialize_item(f, "result", mount_result_to_string(m->result));
(void) serialize_item(f, "reload-result", mount_result_to_string(m->reload_result));
(void) serialize_item_format(f, "n-retry-umount", "%u", m->n_retry_umount);
-
- if (pidref_is_set(&m->control_pid))
- (void) serialize_item_format(f, "control-pid", PID_FMT, m->control_pid.pid);
+ (void) serialize_pidref(f, fds, "control-pid", &m->control_pid);
if (m->control_command_id >= 0)
(void) serialize_item(f, "control-command", mount_exec_command_to_string(m->control_command_id));
} else if (streq(key, "control-pid")) {
pidref_done(&m->control_pid);
- r = pidref_set_pidstr(&m->control_pid, value);
- if (r < 0)
- log_debug_errno(r, "Failed to set control PID to '%s': %m", value);
+ (void) deserialize_pidref(fds, value, &m->control_pid);
} else if (streq(key, "control-command")) {
MountExecCommand id;
(void) serialize_item(f, "controller", s->controller);
SET_FOREACH(pid, u->pids)
- serialize_item_format(f, "pids", PID_FMT, pid->pid);
+ serialize_pidref(f, fds, "pids", pid);
return 0;
}
return log_oom();
} else if (streq(key, "pids")) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- r = unit_watch_pid_str(u, value, /* exclusive= */ false);
- if (r < 0)
- log_unit_debug(u, "Failed to parse pids value, ignoring: %s", value);
+ if (deserialize_pidref(fds, value, &pidref) >= 0) {
+ r = unit_watch_pidref(u, &pidref, /* exclusive= */ false);
+ if (r < 0)
+ log_unit_debug(u, "Failed to watch PID, ignoring: %s", value);
+ }
} else
log_unit_debug(u, "Unknown serialization key: %s", key);
return 0;
}
-static int service_set_main_pid(Service *s, pid_t pid) {
- _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- int r;
-
- assert(s);
-
- r = pidref_set_pid(&pidref, pid);
- if (r < 0)
- return r;
-
- return service_set_main_pidref(s, &pidref);
-}
-
void service_release_socket_fd(Service *s) {
assert(s);
(void) serialize_item(f, "result", service_result_to_string(s->result));
(void) serialize_item(f, "reload-result", service_result_to_string(s->reload_result));
- if (pidref_is_set(&s->control_pid))
- (void) serialize_item_format(f, "control-pid", PID_FMT, s->control_pid.pid);
-
- if (s->main_pid_known && pidref_is_set(&s->main_pid))
- (void) serialize_item_format(f, "main-pid", PID_FMT, s->main_pid.pid);
+ (void) serialize_pidref(f, fds, "control-pid", &s->control_pid);
+ if (s->main_pid_known)
+ (void) serialize_pidref(f, fds, "main-pid", &s->main_pid);
(void) serialize_bool(f, "main-pid-known", s->main_pid_known);
(void) serialize_bool(f, "bus-name-good", s->bus_name_good);
} else if (streq(key, "control-pid")) {
pidref_done(&s->control_pid);
- r = pidref_set_pidstr(&s->control_pid, value);
- if (r < 0)
- log_unit_debug_errno(u, r, "Failed to initialize control PID '%s' from serialization, ignoring.", value);
+
+ (void) deserialize_pidref(fds, value, &s->control_pid);
+
} else if (streq(key, "main-pid")) {
- pid_t pid;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+
+ if (deserialize_pidref(fds, value, &pidref) >= 0)
+ (void) service_set_main_pidref(s, &pidref);
- if (parse_pid(value, &pid) < 0)
- log_unit_debug(u, "Failed to parse main-pid value: %s", value);
- else
- (void) service_set_main_pid(s, pid);
} else if (streq(key, "main-pid-known")) {
int b;
(void) serialize_item(f, "result", socket_result_to_string(s->result));
(void) serialize_item_format(f, "n-accepted", "%u", s->n_accepted);
(void) serialize_item_format(f, "n-refused", "%u", s->n_refused);
-
- if (pidref_is_set(&s->control_pid))
- (void) serialize_item_format(f, "control-pid", PID_FMT, s->control_pid.pid);
+ (void) serialize_pidref(f, fds, "control-pid", &s->control_pid);
if (s->control_command_id >= 0)
(void) serialize_item(f, "control-command", socket_exec_command_to_string(s->control_command_id));
s->n_refused += k;
} else if (streq(key, "control-pid")) {
pidref_done(&s->control_pid);
- r = pidref_set_pidstr(&s->control_pid, value);
- if (r < 0)
- log_debug_errno(r, "Failed to pin control PID '%s', ignoring: %m", value);
+ (void) deserialize_pidref(fds, value, &s->control_pid);
+
} else if (streq(key, "control-command")) {
SocketExecCommand id;
(void) serialize_item(f, "state", swap_state_to_string(s->state));
(void) serialize_item(f, "result", swap_result_to_string(s->result));
-
- if (pidref_is_set(&s->control_pid))
- (void) serialize_item_format(f, "control-pid", PID_FMT, s->control_pid.pid);
+ (void) serialize_pidref(f, fds, "control-pid", &s->control_pid);
if (s->control_command_id >= 0)
(void) serialize_item(f, "control-command", swap_exec_command_to_string(s->control_command_id));
static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
Swap *s = SWAP(u);
- int r;
assert(s);
assert(fds);
} else if (streq(key, "control-pid")) {
pidref_done(&s->control_pid);
- r = pidref_set_pidstr(&s->control_pid, value);
- if (r < 0)
- log_debug_errno(r, "Failed to pin control PID '%s', ignoring: %m", value);
+ (void) deserialize_pidref(fds, value, &s->control_pid);
} else if (streq(key, "control-command")) {
SwapExecCommand id;
return unit_watch_pidref(u, &pidref, exclusive);
}
-int unit_watch_pid_str(Unit *u, const char *s, bool exclusive) {
- _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- int r;
-
- assert(u);
- assert(s);
-
- r = pidref_set_pidstr(&pidref, s);
- if (r < 0)
- return r;
-
- return unit_watch_pidref(u, &pidref, exclusive);
-}
-
void unit_unwatch_pidref(Unit *u, PidRef *pid) {
assert(u);
assert(pidref_is_set(pid));
int unit_watch_pidref(Unit *u, PidRef *pid, bool exclusive);
int unit_watch_pid(Unit *u, pid_t pid, bool exclusive);
-int unit_watch_pid_str(Unit *u, const char *s, bool exclusive);
void unit_unwatch_pidref(Unit *u, PidRef *pid);
void unit_unwatch_pid(Unit *u, pid_t pid);
void unit_unwatch_all_pids(Unit *u);
#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"
int copy;
assert(f);
+ assert(fds);
assert(key);
if (fd < 0)
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;
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;
#include "fdset.h"
#include "macro.h"
+#include "pidref.h"
#include "string-util.h"
#include "time-util.h"
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);
+int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref);
static inline int serialize_bool(FILE *f, const char *key, bool b) {
return serialize_item(f, key, yes_no(b));
int deserialize_dual_timestamp(const char *value, dual_timestamp *t);
int deserialize_environment(const char *value, char ***environment);
int deserialize_strv(char ***l, const char *value);
+int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret);
int open_serialization_fd(const char *ident);