#include "formats-util.h"
#include "terminal-util.h"
-#define RELEASE_USEC (20*USEC_PER_SEC)
+// #define RELEASE_USEC (20*USEC_PER_SEC)
static void session_remove_fifo(Session *s);
return 0;
}
+/// UNNEEDED by elogind
+#if 0
static int session_start_scope(Session *s) {
int r = 0;
if (!scope)
return log_oom();
-/// elogind : Do not try to use dbus to call systemd
-#if 0
r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "logind.service", "systemd-user-sessions.service", &error, &job);
-#endif // 0
if (r < 0) {
log_error("Failed to start session scope %s: %s %s",
scope, bus_error_message(&error, r), error.name);
return r;
} else {
s->scope = scope;
-/// elogind does not support scope jobs
-#if 0
free(s->scope_job);
s->scope_job = job;
-#endif // 0
}
}
return 0;
}
+#endif // 0
+
+static int session_start_cgroup(Session *s) {
+ int r;
+
+ assert(s);
+ assert(s->user);
+ assert(s->leader > 0);
+
+ /* First, create our own group */
+ r = cg_create(ELOGIND_CGROUP_CONTROLLER, s->id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create cgroup %s: %m", s->id);
+
+ r = cg_attach(ELOGIND_CGROUP_CONTROLLER, s->id, s->leader);
+ if (r < 0)
+ log_warning_errno(r, "Failed to attach PID %d to cgroup %s: %m", s->leader, s->id);
+
+ return 0;
+}
+
int session_start(Session *s) {
int r;
return r;
/* Create cgroup */
+/// elogind does its own session management without systemd units,
+/// slices and scopes
+#if 0
r = session_start_scope(s);
+#else
+ r = session_start_cgroup(s);
+#endif // 0
if (r < 0)
return r;
}
#endif // 0
+static int session_stop_cgroup(Session *s, bool force) {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r;
+
+ assert(s);
+
+ if (force || manager_shall_kill(s->manager, s->user->name)) {
+ r = session_kill(s, KILL_ALL, SIGTERM);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
int session_stop(Session *s, bool force) {
- int r = 0;
+ int r;
assert(s);
session_remove_fifo(s);
/* Kill cgroup */
-/// @todo : Currently elogind does not start scopes. It remains to be seen
-/// whether this is really not needed, but then, elogind is not a
-/// systemd cgroups manager.
+/// elogind does not start scopes, but sessions
#if 0
r = session_stop_scope(s, force);
+#else
+ r = session_stop_cgroup(s, force);
#endif // 0
s->stopping = true;
return 0;
}
+/// UNNEEDED by elogind
+#if 0
static int release_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) {
Session *s = userdata;
session_stop(s, false);
return 0;
}
+#endif // 0
int session_release(Session *s) {
assert(s);
if (s->timer_event_source)
return 0;
+ /* In systemd, session release is triggered by user jobs
+ dying. In elogind we don't have that so go ahead and stop
+ now. */
+#if 0
return sd_event_add_time(s->manager->event,
&s->timer_event_source,
CLOCK_MONOTONIC,
now(CLOCK_MONOTONIC) + RELEASE_USEC, 0,
release_timeout_callback, s);
+
+#else
+ return session_stop(s, false);
+#endif // 0
}
bool session_is_active(Session *s) {
if (s->fifo_path) {
unlink(s->fifo_path);
- free(s->fifo_path);
- s->fifo_path = NULL;
+ s->fifo_path = mfree(s->fifo_path);
}
}
return true;
#endif // 0
+ if ( s->user->manager
+ && (cg_is_empty_recursive (ELOGIND_CGROUP_CONTROLLER, s->user->manager->cgroup_root) > 0) )
+ return true;
+
return false;
}
int session_kill(Session *s, KillWho who, int signo) {
assert(s);
-/// FIXME: Without direct cgroup support, elogind can not kill sessions
+/// Without direct cgroup support, elogind can not kill sessions
#if 0
if (!s->scope)
return -ESRCH;
return manager_kill_unit(s->manager, s->scope, who, signo, NULL);
#else
- return -ESRCH;
+ if (who == KILL_LEADER) {
+ if (s->leader <= 0)
+ return -ESRCH;
+
+ /* FIXME: verify that leader is in cgroup? */
+
+ if (kill(s->leader, signo) < 0) {
+ return log_error_errno(errno, "Failed to kill process leader %d for session %s: %m", s->leader, s->id);
+ }
+ return 0;
+ } else {
+ bool sigcont = false;
+ bool ignore_self = true;
+ bool rem = true;
+ return cg_kill_recursive (ELOGIND_CGROUP_CONTROLLER, s->id, signo,
+ sigcont, ignore_self, rem, NULL);
+ }
#endif // 0
}