+static int save_attributes(const char *cgroup, pid_t pid, const char *uuid, const char *directory) {
+ char buf[DECIMAL_STR_MAX(pid_t)], path[PATH_MAX];
+ int r = 0, k;
+
+ assert(cgroup);
+ assert(pid >= 0);
+ assert(arg_directory);
+
+#ifdef HAVE_XATTR
+ assert_se(snprintf(buf, sizeof(buf), "%lu", (unsigned long) pid) < (int) sizeof(buf));
+
+ r = snprintf(path, sizeof(path), "/sys/fs/cgroup/systemd/%s", cgroup);
+ if (r >= (int) sizeof(path)) {
+ log_error("cgroup name too long");
+ return -EINVAL;
+ }
+
+ r = setxattr(path, "trusted.init_pid", buf, strlen(buf), XATTR_CREATE);
+ if (r < 0)
+ log_warning("Failed to set %s attribute on %s: %m", "trusted.init_pid", path);
+
+ if (uuid) {
+ k = setxattr(path, "trusted.machine_id", uuid, strlen(uuid), XATTR_CREATE);
+ if (k < 0) {
+ log_warning("Failed to set %s attribute on %s: %m", "trusted.machine_id", path);
+ if (r == 0)
+ r = k;
+ }
+ }
+
+ k = setxattr(path, "trusted.root_directory", directory, strlen(directory), XATTR_CREATE);
+ if (k < 0) {
+ log_warning("Failed to set %s attribute on %s: %m", "trusted.machine_id", path);
+ if (r == 0)
+ r = k;
+ }
+#endif
+ return r;
+}
+
+static int drop_capabilities(void) {
+ return capability_bounding_set_drop(~arg_retain, false);
+}
+
+static int process_pty(int master, pid_t pid, sigset_t *mask) {