File: TEST-19-CGROUP.delegate.sh

package info (click to toggle)
systemd-udeb 259-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 104,120 kB
  • sloc: ansic: 726,480; xml: 121,118; python: 35,852; sh: 33,447; cpp: 946; awk: 102; makefile: 89; lisp: 13; sed: 1
file content (157 lines) | stat: -rwxr-xr-x 6,393 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2235
set -eux
set -o pipefail

# Test cgroup delegation in the unified hierarchy

# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh

if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
    echo "Skipping $0 as we're not running with the unified cgroup hierarchy"
    exit 0
fi

testcase_controllers() {
    systemd-run --wait \
                --unit=test-0.service \
                --property="DynamicUser=1" \
                --property="Delegate=" \
                test -w /sys/fs/cgroup/system.slice/test-0.service/ -a \
                     -w /sys/fs/cgroup/system.slice/test-0.service/cgroup.procs -a \
                     -w /sys/fs/cgroup/system.slice/test-0.service/cgroup.subtree_control

    systemd-run --wait \
                --unit=test-1.service \
                --property="DynamicUser=1" \
                --property="Delegate=memory pids" \
                grep -q memory /sys/fs/cgroup/system.slice/test-1.service/cgroup.controllers

    systemd-run --wait \
                --unit=test-2.service \
                --property="DynamicUser=1" \
                --property="Delegate=memory pids" \
                grep -q pids /sys/fs/cgroup/system.slice/test-2.service/cgroup.controllers

    # "io" is not among the controllers enabled by default for all units, verify that
    grep -qv io /sys/fs/cgroup/system.slice/cgroup.controllers

    # Run a service with "io" enabled, and verify it works
    systemd-run --wait \
                --unit=test-3.service \
                --property="IOAccounting=yes" \
                --property="Slice=system-foo-bar-baz.slice"  \
                grep -q io /sys/fs/cgroup/system.slice/system-foo.slice/system-foo-bar.slice/system-foo-bar-baz.slice/test-3.service/cgroup.controllers

    # We want to check if "io" is removed again from the controllers
    # list. However, PID 1 (rightfully) does this asynchronously. In order
    # to force synchronization on this, let's start a short-lived service
    # which requires PID 1 to refresh the cgroup tree, so that we can
    # verify that this all works.
    systemd-run --wait --unit=test-4.service true

    # And now check again, "io" should have vanished
    grep -qv io /sys/fs/cgroup/system.slice/cgroup.controllers
}

testcase_attributes() {
    # Test if delegation also works for some of the more recent attrs the kernel might or might not support
    for attr in cgroup.threads memory.oom.group memory.reclaim ; do
        if grep -q "$attr" /sys/kernel/cgroup/delegate ; then
            systemd-run --wait \
                        --unit=test-0.service \
                        --property="MemoryAccounting=1" \
                        --property="DynamicUser=1" \
                        --property="Delegate=" \
                        test -w /sys/fs/cgroup/system.slice/test-0.service/ -a \
                        -w /sys/fs/cgroup/system.slice/test-0.service/"$attr"
        fi
    done
}

testcase_scope_unpriv_delegation() {
    # Check that unprivileged delegation works for scopes
    useradd test
    trap "userdel -r test" RETURN
    systemd-run --uid=test \
                --property="User=test" \
                --property="Delegate=yes" \
                --slice workload.slice \
                --unit test-workload0.scope\
                --scope \
                test -w /sys/fs/cgroup/workload.slice/test-workload0.scope -a \
                     -w /sys/fs/cgroup/workload.slice/test-workload0.scope/cgroup.procs -a \
                     -w /sys/fs/cgroup/workload.slice/test-workload0.scope/cgroup.subtree_control
}

testcase_user_unpriv_delegation() {
    # Check that delegation works for unpriv users, and that we can insert a
    # subcgroup owned by a different user (which can happen in case unpriv
    # userns where a UID range was delegated), which is still cleaned up
    # correctly when it goes down.

    run0 -u testuser systemd-run --user \
                --property="Delegate=yes" \
                --unit=test-chown-subcgroup \
                --service-type=exec \
                sleep infinity

    TESTUID=$(id -u testuser)
    CGROUP="/sys/fs/cgroup/user.slice/user-$TESTUID.slice/user@$TESTUID.service/app.slice/test-chown-subcgroup.service"
    test -d "$CGROUP"

    # Create a subcgroup, and make it owned by some unrelated user
    SUBCGROUP="$CGROUP/subcgroup"
    mkdir "$SUBCGROUP"
    chown 1:1 "$SUBCGROUP"

    # Make sure the subcgroup is not empty (empty dirs owned by other users can
    # be removed if one owns the dir they are contained in, after all)
    mkdir "$SUBCGROUP"/filler

    run0 -u testuser systemctl stop --user test-chown-subcgroup.service

    # Verify that the subcgroup got correctly removed
    (! test -e "$CGROUP")

    systemctl stop user@testuser.service
}

testcase_subgroup() {
    # Verify that DelegateSubgroup= affects ownership correctly
    unit="test-subgroup-$RANDOM.service"
    systemd-run --wait \
                --unit="$unit" \
                --property="DynamicUser=1" \
                --property="Delegate=pids" \
                --property="DelegateSubgroup=foo" \
                test -w "/sys/fs/cgroup/system.slice/$unit" -a \
                     -w "/sys/fs/cgroup/system.slice/$unit/foo"

    # Check that for the subgroup also attributes that aren't covered by
    # regular (i.e. main cgroup) delegation ownership rules are delegated properly
    if test -f /sys/fs/cgroup/cgroup.max.depth; then
        unit="test-subgroup-$RANDOM.service"
        systemd-run --wait \
                    --unit="$unit" \
                    --property="DynamicUser=1" \
                    --property="Delegate=pids" \
                    --property="DelegateSubgroup=zzz" \
                    test -w "/sys/fs/cgroup/system.slice/$unit/zzz/cgroup.max.depth"
    fi

    # Check that the invoked process itself is also in the subgroup
    unit="test-subgroup-$RANDOM.service"
    systemd-run --wait \
                --unit="$unit" \
                --property="DynamicUser=1" \
                --property="Delegate=pids" \
                --property="DelegateSubgroup=bar" \
                grep -q -x -F "0::/system.slice/$unit/bar" /proc/self/cgroup
}

run_testcases