chiark / gitweb /
[Patch 3/3] Add cgroups initialization and handling
authorSven Eden <yamakuzure@gmx.net>
Thu, 26 Jan 2017 07:30:04 +0000 (08:30 +0100)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 09:23:04 +0000 (10:23 +0100)
Let elogind setup cgroups support on its manager initialization and
free the cgroups subsystem when the manager is destroyed.

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/def.h
src/login/logind.c
src/login/logind.h

index 08259fc..95f6faf 100644 (file)
@@ -668,8 +668,6 @@ int cg_create(const char *controller, const char *path) {
         return 1;
 }
 
-/// UNNEEDED by elogind
-#if 0
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
         int r, q;
 
@@ -686,7 +684,6 @@ int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
         /* This does not remove the cgroup on failure */
         return r;
 }
-#endif // 0
 
 int cg_attach(const char *controller, const char *path, pid_t pid) {
         _cleanup_free_ char *fs = NULL;
@@ -879,8 +876,6 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         return -ENODATA;
 }
 
-/// UNNEEDED by elogind
-#if 0
 int cg_install_release_agent(const char *controller, const char *agent) {
         _cleanup_free_ char *fs = NULL, *contents = NULL;
         const char *sc;
@@ -965,7 +960,6 @@ int cg_uninstall_release_agent(const char *controller) {
 
         return 0;
 }
-#endif // 0
 
 int cg_is_empty(const char *controller, const char *path) {
         _cleanup_fclose_ FILE *f = NULL;
@@ -1810,6 +1804,7 @@ int cg_slice_to_path(const char *unit, char **ret) {
 
         return 0;
 }
+#endif // 0
 
 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
         _cleanup_free_ char *p = NULL;
@@ -1822,6 +1817,8 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri
         return write_string_file_no_create(p, value);
 }
 
+/// UNNEEDED by elogind
+#if 0
 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
         _cleanup_free_ char *p = NULL;
         int r;
@@ -1832,10 +1829,7 @@ int cg_get_attribute(const char *controller, const char *path, const char *attri
 
         return read_one_line_file(p, ret);
 }
-#endif // 0
 
-/// UNNEEDED by elogind
-#if 0
 int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
         CGroupController c;
         int r, unified;
@@ -1985,6 +1979,7 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
 
         return 0;
 }
+#endif // 0
 
 int cg_mask_supported(CGroupMask *ret) {
         CGroupMask mask = 0;
@@ -2058,6 +2053,8 @@ int cg_mask_supported(CGroupMask *ret) {
         return 0;
 }
 
+/// UNNEEDED by elogind
+#if 0
 int cg_kernel_controllers(Set *controllers) {
         _cleanup_fclose_ FILE *f = NULL;
         char buf[LINE_MAX];
@@ -2131,9 +2128,18 @@ int cg_unified(void) {
         if (statfs("/sys/fs/cgroup/", &fs) < 0)
                 return -errno;
 
+/// elogind can not support the unified hierarchy as a controller,
+/// so always assume a classical hierarchy.
+/// If, ond only *if*, someone really wants to substitute systemd-login
+/// in an environment managed by systemd with elogin, we might have to
+/// add such a support.
+#if 0
         if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
                 unified_cache = true;
         else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
+#else
+        if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
+#endif // elogind
                 unified_cache = false;
         else
                 return -ENOEXEC;
index e1cbd6c..8fa1e9f 100644 (file)
@@ -94,16 +94,16 @@ int cg_rmdir(const char *controller, const char *path);
 int cg_create(const char *controller, const char *path);
 int cg_attach(const char *controller, const char *path, pid_t pid);
 int cg_attach_fallback(const char *controller, const char *path, pid_t pid);
-// UNNEEDED int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
+int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
 
-// UNNEEDED int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
+int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
 // UNNEEDED int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
 
 // UNNEEDED int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
 // UNNEEDED int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
 
-// UNNEEDED int cg_install_release_agent(const char *controller, const char *agent);
-// UNNEEDED int cg_uninstall_release_agent(const char *controller);
+int cg_install_release_agent(const char *controller, const char *agent);
+int cg_uninstall_release_agent(const char *controller);
 
 int cg_is_empty(const char *controller, const char *path);
 int cg_is_empty_recursive(const char *controller, const char *path);
@@ -147,7 +147,7 @@ int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_m
 // UNNEEDED int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root);
 // UNNEEDED int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p);
 
-// UNNEEDED int cg_mask_supported(CGroupMask *ret);
+int cg_mask_supported(CGroupMask *ret);
 
 // UNNEEDED int cg_kernel_controllers(Set *controllers);
 
index a6bd34c..00f9f2f 100644 (file)
@@ -35,7 +35,7 @@
  * the watchdog pings will keep the loop busy. */
 #define DEFAULT_EXIT_USEC (30*USEC_PER_SEC)
 
-#define ELOGIND_CGROUP_CONTROLLER "elogind"
+#define ELOGIND_CGROUP_CONTROLLER "name=elogind"
 
 #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
 #define SIGNALS_IGNORE SIGPIPE
index de6fbfb..586d92f 100644 (file)
@@ -35,6 +35,7 @@
 #include "formats-util.h"
 #include "label.h"
 #include "label.h"
+#include "cgroup.h"
 
 static void manager_free(Manager *m);
 
@@ -46,6 +47,8 @@ static Manager *manager_new(void) {
         if (!m)
                 return NULL;
 
+        m->pin_cgroupfs_fd = -1;
+
         m->console_active_fd = -1;
         m->reserve_vt_fd = -1;
 
@@ -77,6 +80,9 @@ static Manager *manager_new(void) {
         m->user_units = hashmap_new(&string_hash_ops);
         m->session_units = hashmap_new(&string_hash_ops);
 
+        m->running_as = MANAGER_SYSTEM;
+        m->test_run   = false;
+
         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
                 goto fail;
 
@@ -84,6 +90,11 @@ static Manager *manager_new(void) {
         if (!m->kill_exclude_users)
                 goto fail;
 
+        /* Make cgroups */
+        r = manager_setup_cgroup(m);
+        if (r < 0)
+                goto fail;
+
         m->udev = udev_new();
         if (!m->udev)
                 goto fail;
@@ -171,6 +182,8 @@ static void manager_free(Manager *m) {
 
         safe_close(m->reserve_vt_fd);
 
+        manager_shutdown_cgroup(m, true);
+
         strv_free(m->kill_only_users);
         strv_free(m->kill_exclude_users);
 
index 306709e..c0ae523 100644 (file)
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "sd-event.h"
 #include "sd-bus.h"
+#include "cgroup-util.h"
+#include "path-lookup.h"
 #include "list.h"
 #include "hashmap.h"
 #include "set.h"
@@ -62,6 +64,18 @@ struct Manager {
         sd_event_source *udev_vcsa_event_source;
         sd_event_source *udev_button_event_source;
 
+        /* Make sure the user cannot accidentally unmount our cgroup
+         * file system */
+        int pin_cgroupfs_fd;
+
+        /* Flags */
+        ManagerRunningAs running_as;
+        bool test_run:1;
+
+        /* Data specific to the cgroup subsystem */
+        CGroupMask cgroup_supported;
+        char *cgroup_root;
+
         int console_active_fd;
 
         unsigned n_autovts;