From 43a0450d87b33acf0f99b409a3a292c4866cbb41 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 10 Mar 2023 20:42:53 -0600 Subject: [PATCH] Update: Add example contrroller script for running under systemd using cgroups. 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). --- .../example/cgroup_example/entries/chromium.entry | 7 ++ .../example/cgroup_example/entries/eclipse.entry | 7 ++ .../example/cgroup_example/entries/firefox.entry | 7 ++ .../cgroup_example/entries/setup_cgroups.entry | 7 ++ .../cgroup_example/rules/program/chromium.rule | 8 ++ .../cgroup_example/rules/program/eclipse.rule | 8 ++ .../cgroup_example/rules/program/firefox.rule | 8 ++ .../cgroup_example/rules/setup/cgroups.rule | 122 +++++++++++++++++++++ 8 files changed, 174 insertions(+) create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/entries/chromium.entry create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/entries/eclipse.entry create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/entries/firefox.entry create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/rules/program/chromium.rule create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/rules/program/firefox.rule create mode 100644 level_3/controller/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule 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 index 0000000..8e41837 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/entries/chromium.entry @@ -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 index 0000000..7a3aedb --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/entries/eclipse.entry @@ -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 index 0000000..5d5ff15 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/entries/firefox.entry @@ -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 index 0000000..7a59836 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry @@ -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 index 0000000..75d10f0 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/chromium.rule @@ -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 index 0000000..8b1020a --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule @@ -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 index 0000000..79b19f9 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/rules/program/firefox.rule @@ -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 index 0000000..87de765 --- /dev/null +++ b/level_3/controller/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule @@ -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 + } -- 1.8.3.1