- if (link(f, t) < 0) {
- if (errno == EEXIST) {
- unlink(t);
-
- if (link(f, t) >= 0)
- goto done;
- }
-
- if (symlink(f, t) < 0) {
-
- if (errno == EEXIST) {
- unlink(t);
-
- if (symlink(f, t) >= 0)
- goto done;
- }
-
- log_error("Failed to link %s to %s: %m", f, t);
- free(f);
- free(t);
- return -errno;
- }
- }
-
-done:
- log_info("Linked %s to %s.", f, t);
- free(f);
- free(t);
-
- s->user->display = s;
-
- return 0;
-}
-
-static int session_create_one_group(Session *s, const char *controller, const char *path) {
- int r;
-
- assert(s);
- assert(s->user);
- assert(path);
-
- if (s->leader > 0)
- r = cg_create_and_attach(controller, path, s->leader);
- else
- r = -EINVAL;
-
- if (r < 0) {
- r = cg_create(controller, path);
- if (r < 0)
- return r;
- }
-
- r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid);
- if (r >= 0)
- r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid);
-
- return r;
-}
-
-static int session_create_cgroup(Session *s) {
- char **k;
- int r;
-
- assert(s);
- assert(s->user);
- assert(s->user->cgroup_path);
-
- if (!s->cgroup_path) {
- _cleanup_free_ char *name = NULL, *escaped = NULL;
-
- name = strappend(s->id, ".session");
- if (!name)
- return log_oom();
-
- escaped = cg_escape(name);
- if (!escaped)
- return log_oom();
-
- if (s->slice) {
- _cleanup_free_ char *slice = NULL;
-
- r = cg_slice_to_path(s->slice, &slice);
- if (r < 0)
- return r;
-
- s->cgroup_path = strjoin(s->manager->cgroup_root, "/", slice, "/", escaped, NULL);
- } else
- s->cgroup_path = strjoin(s->user->cgroup_path, "/", escaped, NULL);
-
- if (!s->cgroup_path)
- return log_oom();
- }
-
- if (!s->slice) {
- s->slice = strdup(s->user->slice);
- if (!s->slice)
- return log_oom();
- }
-
- r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path);
- if (r < 0) {
- log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", s->cgroup_path, strerror(-r));
- return r;
- }
-
- STRV_FOREACH(k, s->controllers) {
-
- if (strv_contains(s->reset_controllers, *k))
- continue;
-
- r = session_create_one_group(s, *k, s->cgroup_path);
- if (r < 0)
- log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r));
- }
-
- STRV_FOREACH(k, s->manager->controllers) {
-
- if (strv_contains(s->reset_controllers, *k) ||
- strv_contains(s->manager->reset_controllers, *k) ||
- strv_contains(s->controllers, *k))
- continue;
-
- r = session_create_one_group(s, *k, s->cgroup_path);
- if (r < 0)
- log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r));
- }
-
- if (s->leader > 0) {
-
- STRV_FOREACH(k, s->reset_controllers) {
- r = cg_attach(*k, "/", s->leader);
- if (r < 0)
- log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
-
- }
-
- STRV_FOREACH(k, s->manager->reset_controllers) {
-
- if (strv_contains(s->reset_controllers, *k) ||
- strv_contains(s->controllers, *k))
- continue;
-
- r = cg_attach(*k, "/", s->leader);
- if (r < 0)
- log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
- }
- }
-
- r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
- if (r < 0)
- log_warning("Failed to create mapping between cgroup and session");