master
py 171 lines 6.1 KB
Raw
1 #!/usr/bin/env python3
2 #
3 # SPDX-License-Identifier: GPL-2.0-or-later
4
5 from unittest import skip
6 from qemu_test import Asset
7 from qemu_test import wait_for_console_pattern
8 from qemu_test import LinuxKernelTest
9 from qemu_test import exec_command, exec_command_and_wait_for_pattern
10
11 class QEMUFadump(LinuxKernelTest):
12 """
13 Functional test to verify Fadump is working in following scenarios:
14
15 1. test_fadump_pseries: PSeries
16 2. test_fadump_pseries_kvm: PSeries + KVM
17 3. test_fadump_powernv: PowerNV
18 """
19
20 timeout = 90
21 KERNEL_COMMON_COMMAND_LINE = 'console=hvc0 fadump=on '
22 msg_panic = 'Kernel panic - not syncing'
23 msg_not_supported = 'Firmware-Assisted Dump is not supported on this hardware'
24 msg_registered_success = ''
25 msg_registered_failed = ''
26 msg_dump_active = ''
27
28 ASSET_VMLINUZ_KERNEL = Asset(
29 ('https://archives.fedoraproject.org/pub/archive/fedora-secondary/'
30 'releases/39/Everything/ppc64le/os/ppc/ppc64/vmlinuz'),
31 '6d77658130a7de1dd014ae14d7983c27f8ba1a61fa02e8d9064afdb8519e7e96')
32
33 ASSET_FEDORA_INITRD = Asset(
34 ('https://archives.fedoraproject.org/pub/archive/fedora-secondary/'
35 'releases/39/Everything/ppc64le/os/ppc/ppc64/initrd.img'),
36 'e7f24b44cb2aaa67d30e551db6ac8d29cc57c934b158dabca6b7f885f2cfdd9b')
37
38 def do_test_fadump(self, is_kvm=False, is_powernv=False):
39 """
40 Helper Function for Fadump tests below
41
42 It boots the VM with fadump enabled, checks if fadump is correctly
43 registered.
44 Then crashes the system causing a QEMU_SYSTEM_RESET, after which
45 dump should be available in the kernel.
46 Finally it checks the filesize of the exported /proc/vmcore in 2nd
47 kernel to verify it's same as the VM's memory size
48 """
49 if is_kvm:
50 self.require_accelerator("kvm")
51 self.vm.add_args("-accel", "kvm")
52 else:
53 self.require_accelerator("tcg")
54
55 if is_powernv:
56 self.set_machine("powernv")
57 else:
58 # SLOF takes upto >20s in startup time, use VOF
59 self.set_machine("pseries")
60 self.vm.add_args("-machine", "x-vof=on")
61
62 self.vm.add_args("-m", "6G")
63
64 self.vm.set_console()
65
66 kernel_path = None
67
68 kernel_path = self.ASSET_VMLINUZ_KERNEL.fetch()
69
70 initrd_path = self.ASSET_FEDORA_INITRD.fetch()
71
72 self.vm.add_args('-kernel', kernel_path)
73 self.vm.add_args('-initrd', initrd_path)
74 self.vm.add_args('-append', "fadump=on"\
75 " -nodefaults -serial mon:stdio crashkernel=2G"\
76 " rdinit=/bin/sh ")
77
78 self.vm.launch()
79
80 # If kernel detects fadump support, and "fadump=on" is in command
81 # line which we add above, it will print something like:
82 #
83 # fadump: Reserved 1024MB of memory at 0x00000040000000 ...
84 #
85 # Else, if the kernel doesn't detect fadump support, it prints:
86 #
87 # fadump: Firmware-Assisted Dump is not supported on this hardware
88 #
89 # Timeout after 20s if kernel doesn't print any fadump logs, this
90 # can happen due to fadump being disabled in the kernel
91 self.wait_for_regex_console_pattern(
92 success_pattern="fadump: Reserved ",
93 failure_pattern=r"fadump: (Firmware-Assisted Dump is not"\
94 " supported on this hardware|Failed to find memory chunk for"\
95 " reservation!)",
96 timeout=20
97 )
98
99 # Ensure fadump is registered successfully
100 if not is_powernv:
101 self.wait_for_console_pattern(
102 "rtas fadump: Registration is successful!"
103 )
104
105 # Wait for the shell
106 self.wait_for_console_pattern("sh: no job control")
107
108 # Mount /proc since not available in the initrd used
109 exec_command(self, command="mount -t proc proc /proc")
110
111 # Crash the kernel
112 exec_command(self, command="echo c > /proc/sysrq-trigger")
113
114 # Check for the kernel panic message, setting timeout to 20s as it
115 # should occur almost immediately after previous echo c
116 self.wait_for_regex_console_pattern(
117 success_pattern="Kernel panic - not syncing: sysrq" \
118 " triggered crash",
119 timeout=20
120 )
121
122 # Check if fadump is active
123 # If the kernel shows that fadump is active, that implies it's a
124 # crashkernel boot
125 # Else if the kernel shows "fadump: Reserved ..." then it's
126 # treating this as the first kernel boot, this is likely the case
127 # that qemu didn't pass the 'ibm,kernel-dump' device tree node
128 wait_for_console_pattern(
129 test=self,
130 success_message="fadump: Firmware-assisted dump is active",
131 failure_message="fadump: Reserved "
132 )
133
134 # In a successful fadump boot, we get these logs:
135 #
136 # [ 0.000000] fadump: Firmware-assisted dump is active.
137 # [ 0.000000] fadump: Reserving <>MB of memory at <> for preserving crash data
138 #
139 # Check if these logs are present in the fadump boot
140 self.wait_for_console_pattern("preserving crash data")
141
142 # Wait for prompt
143 self.wait_for_console_pattern("Run /bin/sh as init process")
144
145 # Mount /proc since not available in the initrd used
146 exec_command_and_wait_for_pattern(self,
147 command="mount -t proc proc /proc",
148 success_message="#"
149 )
150
151 # Check if vmcore exists
152 exec_command_and_wait_for_pattern(self,
153 command="stat /proc/vmcore",
154 success_message="File: /proc/vmcore",
155 failure_message="No such file or directory"
156 )
157
158 def test_fadump_pseries(self):
159 return self.do_test_fadump(is_kvm=False, is_powernv=False)
160
161 def test_fadump_powernv(self):
162 return self.do_test_fadump(is_kvm=False, is_powernv=True)
163
164 def test_fadump_pseries_kvm(self):
165 """
166 Test Fadump in PSeries with KVM accel
167 """
168 self.do_test_fadump(is_kvm=True, is_powernv=False)
169
170 if __name__ == '__main__':
171 QEMUFadump.main()