]> Kevux Git Server - fll/commitdiff
Update: Add example contrroller script for running under systemd using cgroups.
authorKevin Day <kevin@kevux.org>
Sat, 11 Mar 2023 02:42:49 +0000 (20:42 -0600)
committerKevin Day <kevin@kevux.org>
Sat, 11 Mar 2023 02:42:49 +0000 (20:42 -0600)
This provides an example cgroups setup.
I found that on systems with cgroups2, this is harder to figure out.
This turned out to be because of the existing setup used by many systemd systems.

This provides an example that I managed to get to work under some systems in some circumstances.
The biggest problems is that the subtree needs to be passed along and that tends to not be done by default.
The current user, if not root, usually lacks the privileges to do so.

The best case would be to use the cgroups generation when running as root to setup the appropriate user.
Then, use the program startup examples as the normal user.
This should show the cgroup situation.

I would not be surprised if the cgroup setup scripts has to be altered (not just the user and group name).

level_3/controller/data/settings/controller/example/cgroup_example/entries/chromium.entry [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/entries/eclipse.entry [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/entries/firefox.entry [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/rules/program/chromium.rule [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/rules/program/firefox.rule [new file with mode: 0644]
level_3/controller/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule [new file with mode: 0644]

diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/entries/chromium.entry b/level_3/controller/data/settings/controller/example/cgroup_example/entries/chromium.entry
new file mode 100644 (file)
index 0000000..8e41837
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-0005
+
+settings:
+  mode helper
+
+main:
+  start program chromium asynchronous
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/entries/eclipse.entry b/level_3/controller/data/settings/controller/example/cgroup_example/entries/eclipse.entry
new file mode 100644 (file)
index 0000000..7a3aedb
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-0005
+
+settings:
+  mode helper
+
+main:
+  start program eclipse asynchronous
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/entries/firefox.entry b/level_3/controller/data/settings/controller/example/cgroup_example/entries/firefox.entry
new file mode 100644 (file)
index 0000000..5d5ff15
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-0005
+
+settings:
+  mode helper
+
+main:
+  start program firefox asynchronous
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry b/level_3/controller/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry
new file mode 100644 (file)
index 0000000..7a59836
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-0005
+
+settings:
+  mode program
+
+main:
+  start setup cgroups
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/chromium.rule b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/chromium.rule
new file mode 100644 (file)
index 0000000..75d10f0
--- /dev/null
@@ -0,0 +1,8 @@
+# fss-000d
+
+settings:
+  name "Run Chromium"
+  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser
+
+command:
+  start chromium --disable-features=UserAgentClientHint
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule
new file mode 100644 (file)
index 0000000..8b1020a
--- /dev/null
@@ -0,0 +1,8 @@
+# fss-000d
+
+settings:
+  name "Run Eclipse"
+  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/eclipse
+
+command:
+  start eclipse
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/firefox.rule b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/firefox.rule
new file mode 100644 (file)
index 0000000..79b19f9
--- /dev/null
@@ -0,0 +1,8 @@
+# fss-000d
+
+settings:
+  name "Run Firefox (ESR)"
+  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser
+
+command:
+  start firefox-esr
diff --git a/level_3/controller/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule b/level_3/controller/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule
new file mode 100644 (file)
index 0000000..87de765
--- /dev/null
@@ -0,0 +1,122 @@
+# fss-000d
+#
+# A cgroups2 example for systemd-based system using example user with example subdirectories and example programs.
+#
+# This uses a 12-core system as an example.
+#
+# This is intended to be run as the user rather than as root.
+#
+# Example sizes:
+#  For 2GB: 2 * 1024 * 1024 * 1024.
+#
+
+settings:
+  name "Setup Cgroups for User 1000, named "you""
+
+script:
+
+  start {
+    main() {
+      local user="you"
+      local group="you"
+      local path_cgroup="/sys/fs/cgroup/"
+      local path_slice_1="${path_cgroup}user.slice/"
+      local path_slice_2="${path_slice_1}user-1000.slice/"
+      #local path_slice_3="${path_slice_2}" # Some systemd's might work without the service directory.
+      local path_slice_3="${path_slice_2}user@1000.service/" # Some systemd's only give access to this service directory (the '@' is a problem and requires quoting).
+      local path_user="${path_slice_3}user_${user}/"
+      local path_group="${path_user}group/"
+      local path_top_subtree="${path_cgroup}cgroup.subtree_control" # Modifying this likely requires root privileges.
+      local directories="browser eclipse untrusted"
+      local d=
+      local i=
+      local subtree="+cpu +cpuset +memory +pids"
+
+      # The user path is for restricting the user and should not grant permissions to user other than read and execute directory.
+      if [[ ! -d "${path_user}" ]] ; then
+        mkdir -p "${path_user}"
+
+        if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_user}." ; return 1 ; fi
+      fi
+
+      chmod -R u+rwX,g+rX-w,o-rwx "${path_user}" &&
+      chgrp -R ${group} "${path_user}"
+
+      if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi
+
+      # The group path is for the user to restrict processes they run and must have ownership with write access.
+      if [[ ! -d "${path_group}" ]] ; then
+        mkdir -p "${path_group}"
+
+        if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi
+      fi
+
+      # Must have common ancestor with write acces, so fix setup from systemd to work with this one.
+      chmod -R u+rw+X,g+rX-w,o-rwx "${path_group}" &&
+      chown -R ${user}:${group} "${path_group}"
+
+      if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${path_group}." ; return 1 ; fi
+
+      # Make sure the user can manipulate subtrees (May fail if any path outside of ${path_slice_1} lacks things wanted by ${subtree}).
+      echo ${subtree} >> "${path_slice_1}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_1}cgroup.subtree_control." ; return 1 ; fi
+
+      echo ${subtree} >> "${path_slice_2}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_2}cgroup.subtree_control." ; return 1 ; fi
+
+      echo ${subtree} >> "${path_slice_3}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_3}cgroup.subtree_control." ; return 1 ; fi
+
+      echo ${subtree} >> "${path_slice_4}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_4}cgroup.subtree_control." ; return 1 ; fi
+
+      echo ${subtree} >> "${path_user}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_user}cgroup.subtree_control." ; return 1 ; fi
+
+      echo ${subtree} >> "${path_group}cgroup.subtree_control"
+      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_group}cgroup.subtree_control." ; return 1 ; fi
+
+      for d in ${directories} ; do
+        i="${path_group}${d}/"
+
+        if [[ ! -d ${i} ]] ; then
+          echo "Creating cgroup directory '${i}'."
+
+          mkdir -p "${i}" &&
+          chown -R ${user}:${group} "${i}" &&
+          chmod -R u+rw+X,g+rX-w,o-rwx "${i}" &&
+          chmod g+s "${i}"
+
+          if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${i}." ; return 1 ; fi
+        fi
+
+        if [[ ${d} == "browser" ]] ; then
+          put_into "7516192768" "${i}memory.high" &&
+          put_into "8589934592" "${i}memory.max" &&
+          put_into "3-6" "${i}cpuset.cpus"
+        elif [[ ${d} == "eclipse" ]] ; then
+          put_into "3758096384" "${i}memory.high" &&
+          put_into "4294967296" "${i}memory.max" &&
+          put_into "5-8" "${i}cpuset.cpus"
+        else
+          put_into "858993459" "${i}memory.high" &&
+          put_into "1073741824" "${i}memory.max" &&
+          put_into "9-11" "${i}cpuset.cpus"
+        fi
+
+        if [[ $? -ne 0 ]] ; then echo "Failed to restrictions for ${d} at ${i}." ; return 1 ; fi
+      done
+
+      return 0
+    \}
+
+     put_into() {
+       if [[ -e ${2} ]] ; then
+         echo ${1} > ${2} || return 1
+       fi
+
+       return 0
+     \}
+
+     main
+  }