--- /dev/null
+# 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
+ }