summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eden <yamakuzure@gmx.net>2017-02-10 14:09:39 +0100
committerSven Eden <yamakuzure@gmx.net>2017-03-14 10:23:13 +0100
commit9eb822a5a6b67eb82909f0d68213afbfcee6e93e (patch)
tree2a1ef0029f5d480065b62a3e72309b553b327d8a
parent2055a4de39bdf062645a7a58b50aae029df80857 (diff)
Classify processes from sessions into cgroups
Create a private cgroup tree associated with no controllers, and use it to map PIDs to sessions. Since we use our own path structure, remove internal cgroup-related helpers that interpret the cgroup path structure to pull out users, slices, and scopes.
-rw-r--r--README27
-rw-r--r--src/basic/cgroup-util.c39
-rw-r--r--src/basic/cgroup-util.h28
-rw-r--r--src/cgroups-agent/cgroups-agent.c19
-rw-r--r--src/libelogind/sd-bus/bus-creds.c9
-rw-r--r--src/libelogind/sd-bus/bus-internal.h2
-rw-r--r--src/libelogind/sd-bus/sd-bus.c26
-rw-r--r--src/libelogind/sd-login/sd-login.c65
-rw-r--r--src/login/logind-core.c29
-rw-r--r--src/login/logind-session.c82
-rw-r--r--src/login/logind-user.c17
-rw-r--r--src/login/logind.c40
-rw-r--r--src/shared/bus-util.c6
-rw-r--r--src/shared/bus-util.h2
-rw-r--r--src/systemd/sd-bus.h2
15 files changed, 339 insertions, 54 deletions
diff --git a/README b/README
index 06f1fc80c..3d323cfb6 100644
--- a/README
+++ b/README
@@ -29,7 +29,7 @@ provide a subset of the interfaces of systemd 219.
To contribute to elogind, fork the current source code from github:
- https://github.com/andywingo/elogind
+ https://github.com/elogind/elogind
Send a pull request for the changes you like.
@@ -39,7 +39,7 @@ To chat about elogind:
Finally, bug reports:
- https://github.com/andywingo/elogind/issues
+ https://github.com/elogind/elogind/issues
Why bother?
-----------
@@ -77,21 +77,26 @@ of <systemd/sd-login.h>.
Libelogind just implements login-related functionality. It also
provides the sd-bus API.
-Unlike systemd, whose logind arranges to run user sessions in cgroups
-via RPC calls to systemd, in elogind there is no systemd so there are
-no cgroups. This has a few implications:
+Unlike systemd, whose logind arranges to manage resources for user
+sessions via RPC calls to systemd, in elogind there is no systemd so
+there is no global cgroup-based resource management. This has a few
+implications:
* Elogind does not create "slices" for users. Elogind will not
record that users are associated with slices.
- * Systemd's logind waits for all user jobs to stop before recording
- that a user's session has gone away. Since we have no cgroups,
- elogind just removes the session directly when pam_elogind.so
- indicates the user has logged out.
-
* The /run/systemd/slices directory will always be empty.
- * Support for lingering is not so great.
+ * Elogind does not have the concept of a "scope", internally, as
+ it's the same as a session. Any API that refers to scopes will
+ always return an error code.
+
+On the other hand, elogind does use a similar strategy to systemd in
+that it places processes in a private cgroup for organizational
+purposes, without installing any controllers (see
+http://0pointer.de/blog/projects/cgroups-vs-cgroups.html). This
+allows elogind to map arbitrary processes to sessions, even if the
+process does the usual double-fork to be reparented to PID 1.
Elogind does not manage virtual terminals.
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index f8386f01c..cd5db6f69 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -35,7 +35,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "path-util.h"
-#include "unit-name.h"
+// #include "unit-name.h"
#include "fileio.h"
// #include "special.h"
#include "mkdir.h"
@@ -1155,7 +1155,9 @@ int cg_mangle_path(const char *path, char **result) {
}
int cg_get_root_path(char **path) {
- char *p; //, *e;
+/// elogind does not support systemd scopes and slices
+#if 0
+ char *p, *e;
int r;
assert(path);
@@ -1164,8 +1166,6 @@ int cg_get_root_path(char **path) {
if (r < 0)
return r;
-/// elogind does not support systemd scopes and slices
-#if 0
e = endswith(p, "/" SPECIAL_INIT_SCOPE);
if (!e)
e = endswith(p, "/" SPECIAL_SYSTEM_SLICE); /* legacy */
@@ -1173,10 +1173,13 @@ int cg_get_root_path(char **path) {
e = endswith(p, "/system"); /* even more legacy */
if (e)
*e = 0;
-#endif // 0
*path = p;
return 0;
+#else
+ assert(path);
+ return cg_pid_get_path(ELOGIND_CGROUP_CONTROLLER, 1, path);
+#endif // 0
}
int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
@@ -1239,6 +1242,8 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
return 0;
}
+/// UNNEEDED by elogind
+#if 0
int cg_path_decode_unit(const char *cgroup, char **unit){
char *c, *s;
size_t n;
@@ -1487,8 +1492,12 @@ int cg_pid_get_machine_name(pid_t pid, char **machine) {
return cg_path_get_machine_name(cgroup, machine);
}
+#endif // 0
int cg_path_get_session(const char *path, char **session) {
+ /* Elogind uses a flat hierarchy, just "/SESSION". The only
+ wrinkle is that SESSION might be escaped. */
+#if 0
_cleanup_free_ char *unit = NULL;
char *start, *end;
int r;
@@ -1509,6 +1518,23 @@ int cg_path_get_session(const char *path, char **session) {
*end = 0;
if (!session_id_valid(start))
return -ENXIO;
+#else
+ const char *e, *n, *start;
+
+ assert(path);
+ assert(path[0] == '/');
+
+ e = path + 1;
+ n = strchrnul(e, '/');
+ if (e == n)
+ return -ENOENT;
+
+ start = strndupa(e, n - e);
+ start = cg_unescape(start);
+
+ if (!start[0])
+ return -ENOENT;
+#endif // 0
if (session) {
char *rr;
@@ -1534,6 +1560,8 @@ int cg_pid_get_session(pid_t pid, char **session) {
return cg_path_get_session(cgroup, session);
}
+/// UNNEEDED by elogind
+#if 0
int cg_path_get_owner_uid(const char *path, uid_t *uid) {
_cleanup_free_ char *slice = NULL;
char *start, *end;
@@ -1645,6 +1673,7 @@ int cg_pid_get_user_slice(pid_t pid, char **slice) {
return cg_path_get_user_slice(cgroup, slice);
}
+#endif // 0
char *cg_escape(const char *p) {
bool need_prefix = false;
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 8fa1e9f82..90a68be34 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -111,25 +111,25 @@ int cg_is_empty_recursive(const char *controller, const char *path);
int cg_get_root_path(char **path);
int cg_path_get_session(const char *path, char **session);
-int cg_path_get_owner_uid(const char *path, uid_t *uid);
-int cg_path_get_unit(const char *path, char **unit);
-int cg_path_get_user_unit(const char *path, char **unit);
-int cg_path_get_machine_name(const char *path, char **machine);
-int cg_path_get_slice(const char *path, char **slice);
-int cg_path_get_user_slice(const char *path, char **slice);
+// UNNEEDED int cg_path_get_owner_uid(const char *path, uid_t *uid);
+// UNNEEDED int cg_path_get_unit(const char *path, char **unit);
+// UNNEEDED int cg_path_get_user_unit(const char *path, char **unit);
+// UNNEEDED int cg_path_get_machine_name(const char *path, char **machine);
+// UNNEEDED int cg_path_get_slice(const char *path, char **slice);
+// UNNEEDED int cg_path_get_user_slice(const char *path, char **slice);
int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted);
int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup);
int cg_pid_get_session(pid_t pid, char **session);
-int cg_pid_get_owner_uid(pid_t pid, uid_t *uid);
-int cg_pid_get_unit(pid_t pid, char **unit);
-int cg_pid_get_user_unit(pid_t pid, char **unit);
-int cg_pid_get_machine_name(pid_t pid, char **machine);
-int cg_pid_get_slice(pid_t pid, char **slice);
-int cg_pid_get_user_slice(pid_t pid, char **slice);
-
-int cg_path_decode_unit(const char *cgroup, char **unit);
+// UNNEEDED int cg_pid_get_owner_uid(pid_t pid, uid_t *uid);
+// UNNEEDED int cg_pid_get_unit(pid_t pid, char **unit);
+// UNNEEDED int cg_pid_get_user_unit(pid_t pid, char **unit);
+// UNNEEDED int cg_pid_get_machine_name(pid_t pid, char **machine);
+// UNNEEDED int cg_pid_get_slice(pid_t pid, char **slice);
+// UNNEEDED int cg_pid_get_user_slice(pid_t pid, char **slice);
+
+// UNNEEDED int cg_path_decode_unit(const char *cgroup, char **unit);
char *cg_escape(const char *p);
char *cg_unescape(const char *p) _pure_;
diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c
index 612bc8fde..47a526b87 100644
--- a/src/cgroups-agent/cgroups-agent.c
+++ b/src/cgroups-agent/cgroups-agent.c
@@ -38,17 +38,32 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
+#if 0
/* We send this event to the private D-Bus socket and then the
* system instance will forward this to the system bus. We do
* this to avoid an activation loop when we start dbus when we
* are called when the dbus service is shut down. */
r = bus_open_system_systemd(&bus);
+#else
+ /* Unlike in systemd where this has to use a private socket,
+ since elogind doesn't associate control groups with services
+ and doesn't manage the dbus service, we can just use the
+ system bus. */
+ r = sd_bus_open_system(&bus);
+#endif // 0
+
if (r < 0) {
+#if 0
/* If we couldn't connect we assume this was triggered
* while systemd got restarted/transitioned from
* initrd to the system, so let's ignore this */
log_debug_errno(r, "Failed to get D-Bus connection: %m");
+#else
+ /* If dbus isn't running or responding, there is nothing
+ * we can do about it. */
+ log_debug_errno(r, "Failed to open system bus: %m");
+#endif
return EXIT_FAILURE;
}
@@ -58,7 +73,11 @@ int main(int argc, char *argv[]) {
"Released",
"s", argv[1]);
if (r < 0) {
+#if 0
log_debug_errno(r, "Failed to send signal message on private connection: %m");
+#else
+ log_debug_errno(r, "Failed to send signal message: %m");
+#endif
return EXIT_FAILURE;
}
diff --git a/src/libelogind/sd-bus/bus-creds.c b/src/libelogind/sd-bus/bus-creds.c
index cca0855be..58436d630 100644
--- a/src/libelogind/sd-bus/bus-creds.c
+++ b/src/libelogind/sd-bus/bus-creds.c
@@ -555,7 +555,13 @@ _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
if (r < 0)
return r;
+/// elogind does not support systemd slices
+#if 0
return cg_path_get_owner_uid(shifted, uid);
+#else
+ *uid = c->uid;
+ return 0;
+#endif // 0
}
_public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
@@ -577,8 +583,6 @@ _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
return 0;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
assert_return(c, -EINVAL);
assert_return(sessionid, -EINVAL);
@@ -592,7 +596,6 @@ _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessio
*sessionid = c->audit_session_id;
return 0;
}
-#endif // 0
_public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
assert_return(c, -EINVAL);
diff --git a/src/libelogind/sd-bus/bus-internal.h b/src/libelogind/sd-bus/bus-internal.h
index efee735b9..e0d7c9ee7 100644
--- a/src/libelogind/sd-bus/bus-internal.h
+++ b/src/libelogind/sd-bus/bus-internal.h
@@ -384,7 +384,7 @@ char *bus_address_escape(const char *v);
_cleanup_bus_unref_ _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)
int bus_set_address_system(sd_bus *bus);
-int bus_set_address_user(sd_bus *bus);
+// UNNEEDED int bus_set_address_user(sd_bus *bus);
int bus_set_address_system_remote(sd_bus *b, const char *host);
int bus_set_address_system_machine(sd_bus *b, const char *machine);
diff --git a/src/libelogind/sd-bus/sd-bus.c b/src/libelogind/sd-bus/sd-bus.c
index fc4f8f3f2..2ccfacbdf 100644
--- a/src/libelogind/sd-bus/sd-bus.c
+++ b/src/libelogind/sd-bus/sd-bus.c
@@ -1162,15 +1162,21 @@ _public_ int sd_bus_open(sd_bus **ret) {
if (e) {
if (streq(e, "system"))
return sd_bus_open_system(ret);
+/// elogind does not support systemd units
+#if 0
else if (STR_IN_SET(e, "session", "user"))
return sd_bus_open_user(ret);
+#endif // 0
}
e = secure_getenv("DBUS_STARTER_ADDRESS");
if (!e) {
+/// elogind does not support systemd units
+#if 0
if (cg_pid_get_owner_uid(0, NULL) >= 0)
return sd_bus_open_user(ret);
else
+#endif // 0
return sd_bus_open_system(ret);
}
@@ -1248,6 +1254,8 @@ fail:
return r;
}
+/// elogind can not open/use a user bus
+#if 0
int bus_set_address_user(sd_bus *b) {
const char *e;
uid_t uid;
@@ -1280,8 +1288,11 @@ int bus_set_address_user(sd_bus *b) {
return 0;
}
+#endif // 0
_public_ int sd_bus_open_user(sd_bus **ret) {
+/// elogind does not support user buses
+#if 0
sd_bus *b;
int r;
@@ -1312,6 +1323,9 @@ _public_ int sd_bus_open_user(sd_bus **ret) {
fail:
bus_free(b);
return r;
+#else
+ return sd_bus_open_system(ret);
+#endif // 0
}
int bus_set_address_system_remote(sd_bus *b, const char *host) {
@@ -3382,9 +3396,14 @@ _public_ int sd_bus_default_system(sd_bus **ret) {
}
_public_ int sd_bus_default_user(sd_bus **ret) {
+/// elogind does not support user buses
+#if 0
static thread_local sd_bus *default_user_bus = NULL;
return bus_default(sd_bus_open_user, &default_user_bus, ret);
+#else
+ return sd_bus_default_system(ret);
+#endif // 0
}
_public_ int sd_bus_default(sd_bus **ret) {
@@ -3401,8 +3420,11 @@ _public_ int sd_bus_default(sd_bus **ret) {
if (e) {
if (streq(e, "system"))
return sd_bus_default_system(ret);
+/// elogind does not support systemd units
+#if 0
else if (STR_IN_SET(e, "user", "session"))
return sd_bus_default_user(ret);
+#endif // 0
}
/* No type is specified, so we have not other option than to
@@ -3417,10 +3439,12 @@ _public_ int sd_bus_default(sd_bus **ret) {
/* Finally, if nothing is set use the cached connection for
* the right scope */
-
+/// elogind does not support systemd units
+#if 0
if (cg_pid_get_owner_uid(0, NULL) >= 0)
return sd_bus_default_user(ret);
else
+#endif // 0
return sd_bus_default_system(ret);
}
diff --git a/src/libelogind/sd-login/sd-login.c b/src/libelogind/sd-login/sd-login.c
index f4dd7feec..4f625ea33 100644
--- a/src/libelogind/sd-login/sd-login.c
+++ b/src/libelogind/sd-login/sd-login.c
@@ -58,7 +58,12 @@ _public_ int sd_pid_get_unit(pid_t pid, char **unit) {
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_unit(pid, unit);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
@@ -66,7 +71,12 @@ _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_user_unit(pid, unit);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
@@ -74,7 +84,12 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
assert_return(pid >= 0, -EINVAL);
assert_return(name, -EINVAL);
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_machine_name(pid, name);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_slice(pid_t pid, char **slice) {
@@ -82,7 +97,12 @@ _public_ int sd_pid_get_slice(pid_t pid, char **slice) {
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
+/// elogind does not support systemd slices
+#if 0
return cg_pid_get_slice(pid, slice);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_user_slice(pid_t pid, char **slice) {
@@ -90,7 +110,12 @@ _public_ int sd_pid_get_user_slice(pid_t pid, char **slice) {
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
+/// elogind does not support systemd slices
+#if 0
return cg_pid_get_user_slice(pid, slice);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
@@ -98,7 +123,12 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
assert_return(pid >= 0, -EINVAL);
assert_return(uid, -EINVAL);
+/// elogind does not support systemd slices
+#if 0
return cg_pid_get_owner_uid(pid, uid);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
@@ -138,7 +168,12 @@ _public_ int sd_peer_get_session(int fd, char **session) {
if (r < 0)
return r;
+/// elogind does not support systemd scopes
+#if 0
return cg_pid_get_session(ucred.pid, session);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
@@ -152,7 +187,12 @@ _public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
if (r < 0)
return r;
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_owner_uid(ucred.pid, uid);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_unit(int fd, char **unit) {
@@ -166,7 +206,12 @@ _public_ int sd_peer_get_unit(int fd, char **unit) {
if (r < 0)
return r;
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_unit(ucred.pid, unit);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_user_unit(int fd, char **unit) {
@@ -180,7 +225,12 @@ _public_ int sd_peer_get_user_unit(int fd, char **unit) {
if (r < 0)
return r;
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_user_unit(ucred.pid, unit);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_machine_name(int fd, char **machine) {
@@ -194,7 +244,12 @@ _public_ int sd_peer_get_machine_name(int fd, char **machine) {
if (r < 0)
return r;
+/// elogind does not support systemd units
+#if 0
return cg_pid_get_machine_name(ucred.pid, machine);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_slice(int fd, char **slice) {
@@ -208,7 +263,12 @@ _public_ int sd_peer_get_slice(int fd, char **slice) {
if (r < 0)
return r;
+/// elogind does not support systemd slices
+#if 0
return cg_pid_get_slice(ucred.pid, slice);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_user_slice(int fd, char **slice) {
@@ -222,7 +282,12 @@ _public_ int sd_peer_get_user_slice(int fd, char **slice) {
if (r < 0)
return r;
+/// elogind does not support systemd slices
+#if 0
return cg_pid_get_user_slice(ucred.pid, slice);
+#else
+ return -ESRCH;
+#endif // 0
}
_public_ int sd_peer_get_cgroup(int fd, char **cgroup) {
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index dd681401a..277e26255 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -274,7 +274,12 @@ int manager_process_button_device(Manager *m, struct udev_device *d) {
}
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
+/// elogind does not support systemd units, but its own session system
+#if 0
_cleanup_free_ char *unit = NULL;
+#else
+ _cleanup_free_ char *session_name = NULL;
+#endif
Session *s;
int r;
@@ -284,11 +289,20 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
if (pid < 1)
return -EINVAL;
+/// elogind does not support systemd units, but its own session system
+#if 0
r = cg_pid_get_unit(pid, &unit);
if (r < 0)
return 0;
s = hashmap_get(m->session_units, unit);
+#else
+ r = cg_pid_get_session(pid, &session_name);
+ if (r < 0)
+ return 0;
+
+ s = hashmap_get(m->sessions, session_name);
+#endif
if (!s)
return 0;
@@ -297,8 +311,13 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
}
int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
+/// elogind does not support systemd units, but its own session system
+#if 0
_cleanup_free_ char *unit = NULL;
User *u;
+#else
+ Session *s;
+#endif
int r;
assert(m);
@@ -307,6 +326,8 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
if (pid < 1)
return -EINVAL;
+/// elogind does not support systemd units, but its own session system
+#if 0
r = cg_pid_get_slice(pid, &unit);
if (r < 0)
return 0;
@@ -316,6 +337,14 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
return 0;
*user = u;
+#else
+ r = manager_get_session_by_pid (m, pid, &s);
+ if (r <= 0)
+ return r;
+
+ *user = s->user;
+#endif // 0
+
return 1;
}
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index b5e4bee9e..c7033bd18 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -508,6 +508,8 @@ int session_activate(Session *s) {
return 0;
}
+/// UNNEEDED by elogind
+#if 0
static int session_start_scope(Session *s) {
int r = 0;
@@ -528,10 +530,7 @@ static int session_start_scope(Session *s) {
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);
@@ -539,11 +538,8 @@ static int session_start_scope(Session *s) {
return r;
} else {
s->scope = scope;
-/// elogind does not support scope jobs
-#if 0
free(s->scope_job);
s->scope_job = job;
-#endif // 0
}
}
@@ -552,6 +548,27 @@ static int session_start_scope(Session *s) {
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;
@@ -569,7 +586,13 @@ int session_start(Session *s) {
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;
@@ -643,8 +666,23 @@ static int session_stop_scope(Session *s, bool force) {
}
#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);
@@ -660,11 +698,11 @@ int session_stop(Session *s, bool force) {
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;
@@ -974,6 +1012,10 @@ bool session_check_gc(Session *s, bool drop_not_started) {
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;
}
@@ -1011,14 +1053,30 @@ SessionState session_get_state(Session *s) {
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
}
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 54c210835..ccabe3d47 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -793,16 +793,27 @@ UserState user_get_state(User *u) {
}
int user_kill(User *u, int signo) {
+/// Without systemd unit support, elogind has to rely on its session system
+#if 0
assert(u);
-/// FIXME: Without direct cgroup support, elogind can not kill users
-#if 0
if (!u->slice)
return -ESRCH;
return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL);
#else
- return -ESRCH;
+ Session *s;
+ int res = 0;
+
+ assert(u);
+
+ LIST_FOREACH(sessions_by_user, s, u->sessions) {
+ int r = session_kill(s, KILL_ALL, signo);
+ if (res == 0 && r < 0)
+ res = r;
+ }
+
+ return res;
#endif // 0
}
diff --git a/src/login/logind.c b/src/login/logind.c
index 5da76a767..86208c7d4 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -635,6 +635,34 @@ static int manager_reserve_vt(Manager *m) {
}
#endif // 0
+static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ Session *s;
+ const char *cgroup;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &cgroup);
+ if (r < 0) {
+ bus_log_parse_error(r);
+ return 0;
+ }
+
+ s = hashmap_get(m->sessions, cgroup);
+
+ if (!s) {
+ log_warning("Session not found: %s", cgroup);
+ return 0;
+ }
+
+ session_finalize(s);
+ session_free(s);
+
+ return 0;
+}
+
static int manager_connect_bus(Manager *m) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@@ -650,6 +678,14 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to add manager object vtable: %m");
+ /* elogind relies on signals from its release agent */
+ r = sd_bus_add_match(m->bus, NULL,
+ "type='signal',"
+ "interface='org.freedesktop.systemd1.Agent',"
+ "member='Released',"
+ "path='/org/freedesktop/systemd1/agent'",
+ signal_agent_released, m);
+
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add seat object vtable: %m");
@@ -674,7 +710,7 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to add user enumerator: %m");
-/// elogind does not support systemd action jobs
+/// elogind does not support systemd as PID 1
#if 0
r = sd_bus_add_match(m->bus,
NULL,
@@ -686,7 +722,6 @@ static int manager_connect_bus(Manager *m) {
match_job_removed, m);
if (r < 0)
log_warning_errno(r, "Failed to add match for JobRemoved: %m");
-#endif // 0
r = sd_bus_add_match(m->bus,
NULL,
@@ -730,6 +765,7 @@ static int manager_connect_bus(Manager *m) {
NULL, NULL);
if (r < 0)
log_notice("Failed to enable subscription: %s", bus_error_message(&error, r));
+#endif // 0
r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
if (r < 0)
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 64c389b35..0eb7034c9 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -629,6 +629,8 @@ int bus_open_system_systemd(sd_bus **_bus) {
return 0;
}
+/// UNNEEDED by elogind
+#if 0
int bus_open_user_systemd(sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
_cleanup_free_ char *ee = NULL;
@@ -686,6 +688,7 @@ int bus_open_user_systemd(sd_bus **_bus) {
return 0;
}
+#endif // 0
int bus_print_property(const char *name, sd_bus_message *property, bool all) {
char type;
@@ -1226,9 +1229,12 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b
switch (transport) {
case BUS_TRANSPORT_LOCAL:
+/// elogind does not support a user bus
+#if 0
if (user)
r = sd_bus_default_user(bus);
else
+#endif // 0
r = sd_bus_default_system(bus);
break;
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index e442ccb76..a310087d8 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -66,7 +66,7 @@ int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *ac
void bus_verify_polkit_async_registry_free(Hashmap *registry);
int bus_open_system_systemd(sd_bus **_bus);
-int bus_open_user_systemd(sd_bus **_bus);
+// UNNEEDED int bus_open_user_systemd(sd_bus **_bus);
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
// UNNEEDED int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 4ed197e59..fcb518317 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -363,7 +363,7 @@ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability);
// UNNEEDED int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability);
// UNNEEDED int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability);
int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **context);
-// UNNEEDED int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid);
+int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid);
int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *loginuid);
int sd_bus_creds_get_tty(sd_bus_creds *c, const char **tty);
// UNNEEDED int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **name);