7 # We're exiting with a non-zero EC, let's dump test artifacts
9 [ -f "$straceLog" ] && cat "$straceLog"
10 [ -f "$journalLog" ] && cat "$journalLog"
16 systemd-analyze log-level debug
17 systemd-analyze log-target journal
20 straceLog
='strace.log'
21 journalLog
='journal.log'
23 # Systemd config files
24 testUnit
='numa-test.service'
25 testUnitFile
="/etc/systemd/system/$testUnit"
26 testUnitNUMAConf
="$testUnitFile.d/numa.conf"
28 # Sleep constants (we should probably figure out something better but nothing comes to mind)
32 # Journal cursor for easier navigation
33 journalCursorFile
="jounalCursorFile"
36 coproc strace
-qq -p 1 -o $straceLog -e set_mempolicy
-s 1024 $1
37 # Wait for strace to properly "initialize"
38 sleep $sleepAfterStart
42 kill -s TERM
$COPROC_PID
43 # Make sure the strace process is indeed dead
44 while kill -0 $COPROC_PID 2>/dev
/null
; do sleep 0.1; done
48 # Save journal's cursor for later navigation
49 journalctl
--no-pager --cursor-file="$journalCursorFile" -n0 -ocat
53 local unit
="${1:-init.scope}"
54 # Using journalctl --sync should be better than using SIGRTMIN+1, as
55 # the --sync wait until the synchronization is complete
56 echo "Force journald to write all queued messages"
58 journalctl
-u $unit --cursor-file="$journalCursorFile" > "$journalLog"
62 # NUMA enabled system should have at least NUMA node0
63 test -e /sys
/devices
/system
/node
/node0
66 writePID1NUMAPolicy
() {
67 echo [Manager
] > $confDir/numa.conf
68 echo NUMAPolicy
=$1 >> $confDir/numa.conf
69 echo NUMAMask
=$2>> $confDir/numa.conf
73 echo [Service
] > $testUnitFile
74 echo ExecStart
=/bin
/sleep 3600 >> $testUnitFile
75 mkdir
-p $testUnitFile.d
/
78 writeTestUnitNUMAPolicy
() {
79 echo [Service
] > $testUnitNUMAConf
80 echo NUMAPolicy
=$1 >> $testUnitNUMAConf
81 echo NUMAMask
=$2>> $testUnitNUMAConf
82 systemctl daemon-reload
85 pid1ReloadWithStrace
() {
87 systemctl daemon-reload
88 sleep $sleepAfterStart
92 pid1ReloadWithJournal
() {
94 systemctl daemon-reload
98 pid1StartUnitWithStrace
() {
101 sleep $sleepAfterStart
105 pid1StartUnitWithJournal
() {
108 sleep $sleepAfterStart
116 systemctlCheckNUMAProperties
() {
117 local LOGFILE
="$(mktemp)"
118 systemctl show
-p NUMAPolicy
$1 > "$LOGFILE"
119 grep "NUMAPolicy=$2" "$LOGFILE"
124 systemctl show
-p NUMAMask
$1 > "$LOGFILE"
125 grep "NUMAMask=$3" "$LOGFILE"
131 # Create systemd config drop-in directory
132 confDir
="/etc/systemd/system.conf.d/"
136 echo >&2 "NUMA is not supported on this machine, switching to a simple sanity check"
138 echo "PID1 NUMAPolicy=default && NUMAMask=0 check without NUMA support"
139 writePID1NUMAPolicy
"default" "0"
141 systemctl daemon-reload
143 grep "NUMA support not available, ignoring" "$journalLog"
145 echo "systemd-run NUMAPolicy=default && NUMAMask=0 check without NUMA support"
146 runUnit
='numa-systemd-run-test.service'
148 systemd-run
-p NUMAPolicy
=default
-p NUMAMask
=0 --unit $runUnit sleep 1000
149 sleep $sleepAfterStart
150 pid1StopUnit
$runUnit
151 stopJournalctl
$runUnit
152 grep "NUMA support not available, ignoring" "$journalLog"
155 echo "PID1 NUMAPolicy support - Default policy w/o mask"
156 writePID1NUMAPolicy
"default"
158 # Kernel requires that nodemask argument is set to NULL when setting default policy
159 grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
161 echo "PID1 NUMAPolicy support - Default policy w/ mask"
162 writePID1NUMAPolicy
"default" "0"
164 grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
166 echo "PID1 NUMAPolicy support - Bind policy w/o mask"
167 writePID1NUMAPolicy
"bind"
168 pid1ReloadWithJournal
169 grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
171 echo "PID1 NUMAPolicy support - Bind policy w/ mask"
172 writePID1NUMAPolicy
"bind" "0"
174 grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
176 echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
177 writePID1NUMAPolicy
"interleave"
178 pid1ReloadWithJournal
179 grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
181 echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
182 writePID1NUMAPolicy
"interleave" "0"
184 grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
186 echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
187 writePID1NUMAPolicy
"preferred"
188 pid1ReloadWithJournal
189 # Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
190 ! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
192 echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
193 writePID1NUMAPolicy
"preferred" "0"
195 grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
197 echo "PID1 NUMAPolicy support - Local policy w/o mask"
198 writePID1NUMAPolicy
"local"
200 # Kernel requires that nodemask argument is set to NULL when setting default policy
201 # The unpatched versions of strace don't recognize the MPOL_LOCAL constant and
202 # return a numerical constant instead (with a comment):
203 # set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
204 # Let's cover this scenario as well
205 grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
207 echo "PID1 NUMAPolicy support - Local policy w/ mask"
208 writePID1NUMAPolicy
"local" "0"
210 grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
212 echo "Unit file NUMAPolicy support - Default policy w/o mask"
213 writeTestUnitNUMAPolicy
"default"
214 pid1StartUnitWithStrace
$testUnit
215 systemctlCheckNUMAProperties
$testUnit "default"
216 pid1StopUnit
$testUnit
217 grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
219 echo "Unit file NUMAPolicy support - Default policy w/ mask"
220 writeTestUnitNUMAPolicy
"default" "0"
221 pid1StartUnitWithStrace
$testUnit
222 systemctlCheckNUMAProperties
$testUnit "default" "0"
223 pid1StopUnit
$testUnit
224 # Maks must be ignored
225 grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
227 echo "Unit file NUMAPolicy support - Bind policy w/o mask"
228 writeTestUnitNUMAPolicy
"bind"
229 pid1StartUnitWithJournal
$testUnit
230 pid1StopUnit
$testUnit
231 grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
233 echo "Unit file NUMAPolicy support - Bind policy w/ mask"
234 writeTestUnitNUMAPolicy
"bind" "0"
235 pid1StartUnitWithStrace
$testUnit
236 systemctlCheckNUMAProperties
$testUnit "bind" "0"
237 pid1StopUnit
$testUnit
238 grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
240 echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
241 writeTestUnitNUMAPolicy
"interleave"
242 pid1StartUnitWithStrace
$testUnit
243 pid1StopUnit
$testUnit
244 grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
246 echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
247 writeTestUnitNUMAPolicy
"interleave" "0"
248 pid1StartUnitWithStrace
$testUnit
249 systemctlCheckNUMAProperties
$testUnit "interleave" "0"
250 pid1StopUnit
$testUnit
251 grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
253 echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
254 writeTestUnitNUMAPolicy
"preferred"
255 pid1StartUnitWithJournal
$testUnit
256 systemctlCheckNUMAProperties
$testUnit "preferred"
257 pid1StopUnit
$testUnit
258 ! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
260 echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
261 writeTestUnitNUMAPolicy
"preferred" "0"
262 pid1StartUnitWithStrace
$testUnit
263 systemctlCheckNUMAProperties
$testUnit "preferred" "0"
264 pid1StopUnit
$testUnit
265 grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
267 echo "Unit file NUMAPolicy support - Local policy w/o mask"
268 writeTestUnitNUMAPolicy
"local"
269 pid1StartUnitWithStrace
$testUnit
270 systemctlCheckNUMAProperties
$testUnit "local"
271 pid1StopUnit
$testUnit
272 grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
274 echo "Unit file NUMAPolicy support - Local policy w/ mask"
275 writeTestUnitNUMAPolicy
"local" "0"
276 pid1StartUnitWithStrace
$testUnit
277 systemctlCheckNUMAProperties
$testUnit "local" "0"
278 pid1StopUnit
$testUnit
279 # Maks must be ignored
280 grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
282 echo "Unit file CPUAffinity=NUMA support"
283 writeTestUnitNUMAPolicy
"bind" "0"
284 echo "CPUAffinity=numa" >> $testUnitNUMAConf
285 systemctl daemon-reload
286 systemctl start
$testUnit
287 systemctlCheckNUMAProperties
$testUnit "bind" "0"
288 pid
=$
(systemctl show
--value -p MainPID
$testUnit)
289 cpulist
=$
(cat /sys
/devices
/system
/node
/node
0/cpulist
)
290 affinity_systemd
=$
(systemctl show
--value -p CPUAffinity
$testUnit)
291 [ $cpulist = $affinity_systemd ]
292 pid1StopUnit
$testUnit
294 echo "systemd-run NUMAPolicy support"
295 runUnit
='numa-systemd-run-test.service'
297 systemd-run
-p NUMAPolicy
=default
--unit $runUnit sleep 1000
298 systemctlCheckNUMAProperties
$runUnit "default"
299 pid1StopUnit
$runUnit
301 systemd-run
-p NUMAPolicy
=default
-p NUMAMask
=0 --unit $runUnit sleep 1000
302 systemctlCheckNUMAProperties
$runUnit "default" ""
303 pid1StopUnit
$runUnit
305 systemd-run
-p NUMAPolicy
=bind -p NUMAMask
=0 --unit $runUnit sleep 1000
306 systemctlCheckNUMAProperties
$runUnit "bind" "0"
307 pid1StopUnit
$runUnit
309 systemd-run
-p NUMAPolicy
=interleave
-p NUMAMask
=0 --unit $runUnit sleep 1000
310 systemctlCheckNUMAProperties
$runUnit "interleave" "0"
311 pid1StopUnit
$runUnit
313 systemd-run
-p NUMAPolicy
=preferred
-p NUMAMask
=0 --unit $runUnit sleep 1000
314 systemctlCheckNUMAProperties
$runUnit "preferred" "0"
315 pid1StopUnit
$runUnit
317 systemd-run
-p NUMAPolicy
=local --unit $runUnit sleep 1000
318 systemctlCheckNUMAProperties
$runUnit "local"
319 pid1StopUnit
$runUnit
321 systemd-run
-p NUMAPolicy
=local -p NUMAMask
=0 --unit $runUnit sleep 1000
322 systemctlCheckNUMAProperties
$runUnit "local" ""
323 pid1StopUnit
$runUnit
325 systemd-run
-p NUMAPolicy
=local -p NUMAMask
=0 -p CPUAffinity
=numa
--unit $runUnit sleep 1000
326 systemctlCheckNUMAProperties
$runUnit "local" ""
327 systemctl
cat $runUnit |
grep -q 'CPUAffinity=numa'
328 pid1StopUnit
$runUnit
335 systemctl daemon-reload
337 systemd-analyze log-level info