Skip to content

Commit a97b025

Browse files
committed
qemu: Add some callbacks
1 parent 4d57e9f commit a97b025

2 files changed

Lines changed: 128 additions & 0 deletions

File tree

lib/qemu.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import logging
77
from utils import *
88
from pexpect_utils import PexpectHelper, standard_boot, ping_test, wget_test
9+
import qemu_callbacks
910

1011

1112
class QemuConfig:

lib/qemu_callbacks.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import logging
2+
from utils import setup_timeout
3+
4+
########################################
5+
# Callbacks that can run once the VM has booted
6+
#
7+
# Use with the --callback argument. More than one can be specified.
8+
########################################
9+
10+
# Run a shell command
11+
# eg. --callback "sh(ls /dev)"
12+
def sh(qconf, p, arg):
13+
p.send(f'{arg}')
14+
p.expect(p.prompt, timeout=None)
15+
return True
16+
17+
# Set the script timeout, in seconds, 0 for no timeout.
18+
def set_timeout(qconf, p, arg):
19+
setup_timeout(int(arg))
20+
return True
21+
22+
# Mount debugfs and cat a file under it
23+
# eg. --callback "cat_debugfs(powerpc/security_features)"
24+
# eg. --callback "cat_debugfs(kernel_page_tables)"
25+
def cat_debugfs(qconf, p, arg):
26+
p.cmd('mount -t debugfs none /sys/kernel/debug')
27+
# Clear timeout, we don't know how long it will take
28+
setup_timeout(0)
29+
p.send(f'cat /sys/kernel/debug/{arg}')
30+
p.expect_prompt(timeout=None)
31+
return True
32+
33+
# Check /proc/config.gz for a symbol
34+
# eg. --callback "check_config(PREEMPT)"
35+
def check_config(qconf, p, arg):
36+
p.cmd(f'zcat /proc/config.gz | grep {arg}')
37+
return True
38+
39+
# Run one or more selftest collections
40+
# eg. --callback "run_selftest_collections(rlimits size)"
41+
def run_selftest_collections(qconf, p, arg, check=True):
42+
collections = []
43+
for name in arg.split(' '):
44+
collections.append(name)
45+
46+
return __run_selftests(qconf, p, collections=collections, check=check)
47+
48+
def run_selftest_collections_nocheck(qconf, p, arg):
49+
return run_selftest_collections(qconf, p, arg, check=False)
50+
51+
# Run all powerpc selftests
52+
# eg. --callback run_ppctests
53+
def run_ppctests(qconf, p):
54+
return __run_selftests(qconf, p, collections=['powerpc.*'])
55+
56+
57+
# Run one or more individual selftests
58+
# eg. --callback "run_selftests(powerpc/math:fpu_syscall core:close_range_test)"
59+
def run_selftests(qconf, p, arg=None, check=True):
60+
if arg:
61+
tests = []
62+
for name in arg.split(' '):
63+
tests.append(name)
64+
65+
return __run_selftests(qconf, p, tests=tests, check=check)
66+
67+
return __run_selftests(qconf, p, check=check)
68+
69+
70+
def run_selftests_nocheck(qconf, p, arg=None):
71+
return run_selftests(qconf, p, arg, check=False)
72+
73+
74+
# Invoke lkdtm via sysfs
75+
# eg. --callback "lkdtm(BUG WARNING)"
76+
def lkdtm(qconf, p, arg):
77+
p.cmd('modprobe lkdtm')
78+
p.cmd('mount -t debugfs none /sys/kernel/debug')
79+
for word in arg.split():
80+
p.send(f'sh -c "echo {word} > /sys/kernel/debug/provoke-crash/DIRECT"')
81+
p.expect(p.prompt, bug_patterns=[])
82+
return True
83+
84+
85+
# Run some or all lkdtm selftests
86+
# eg. --callback "lkdtm_selftests()"
87+
# eg. --callback "lkdtm_selftests(BUG WARNING)"
88+
def lkdtm_selftests(qconf, p, arg=None):
89+
if arg:
90+
tests = [f'lkdtm:{t}.sh' for t in arg.split(' ')]
91+
return __run_selftests(qconf, p, tests=tests)
92+
93+
return __run_selftests(qconf, p, collections=['lkdtm'])
94+
95+
########################################
96+
# Helper functions
97+
########################################
98+
99+
# Not a callback
100+
def __run_selftests(qconf, p, tests=None, collections=None, check=True):
101+
# Clear timeout, we don't know how long it will take
102+
setup_timeout(0)
103+
104+
# Lots of selftests need debugfs, make sure its mounted
105+
p.cmd('mount -t debugfs none /sys/kernel/debug')
106+
107+
if tests:
108+
logging.info(f'Running individual selftests {", ".join(tests)}')
109+
arg = f'-t {" -t ".join(tests)}'
110+
elif collections:
111+
formatted = ', '.join(collections)
112+
logging.info(f'Running selftest collections {formatted}')
113+
arg = f'-c {" -c ".join(collections)}'
114+
else:
115+
logging.info('Running selftests')
116+
arg = ''
117+
118+
p.send(f'/var/tmp/selftests/run_kselftest.sh {arg} | tee test.log')
119+
p.expect(p.prompt, timeout=None, bug_patterns=[])
120+
121+
if check:
122+
p.send('grep "^[n]ot ok" test.log')
123+
idx = p.expect(['not ok', p.prompt])
124+
if idx == 0:
125+
return False
126+
127+
return True

0 commit comments

Comments
 (0)