mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:56:38 +00:00
Merge tag 'pull-request-2026-07-07' of https://gitlab.com/huth/qemu into staging
* Add test for hotplugging a virtio-scsi disk * Improve boot completion detection in aspeed tests * Use QMP to query available machines in functional tests # -----BEGIN PGP SIGNATURE----- # # iQJGBAABCAAwFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmpMl5oSHHRoLmh1dGhA # cG9zdGVvLmV1AAoJEC7Z13T+cC21pmAQAJa2bVXA7cvKz0w7p7R0AAGrYfetiqbR # f/HLuO17OE6Df2quoIpcYzAOjyLwFFBjb4RyPVMdcuKWPWcFnCA9i5ft30TLK84I # 3SIx6M7N9OZnAlxPOGsVy8eyoIny8bQOm1/RsGP+SDkNpfQSPcQzp6IAVazEFcM/ # g6sOPuHp2SOUe+as1+ZTqGDTS5O9VTna/WLGV/Hka1+KCtAwAYws9SWnczHdFvMd # rvTJOSKVe2gfs0vLdTIOx44Bj8xhty402+jQqvL8Rwm5wjXRECEQQe7g+qPXINot # pnR2LCe952KHhkSoL+70N4SZTimX+UMt0qACr03isqSpVJDcYDD9T/rY5RL9PYPE # TdVZM66ZfxmQGSfqNI0GI0vrEXr7zilOjowq/F8BBgT1RG8EzMM23WykPQtwqXuu # vsVuu1IV99vbSH76EJEsMra5JuQrAnTNAkXLBtI9BQvlrP/553dl/2DQd7GUb8we # B+bFtIk9QXkmkBGOGWOtOfkazPir5GKyy6zLFomZt1SBsbKyL8ZdHvV/XHeChSqO # boMFfO67WnoqZeVhc53U3Hm8poo8sIw5UIRU/HAc3thE+esDXnYALEDwwcy8fdnE # 2FB0PVzqVOuLXe0rNGsPFP/h+Fd30YFsTGQxxvS65ADAGkP5bztuZqejR2tVgeOU # iHgw5kauDJ31 # =RNE6 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 07 Jul 2026 08:07:22 CEST # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "th.huth@posteo.eu" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # gpg: issuer "th.huth@posteo.eu" does not match any User ID # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2026-07-07' of https://gitlab.com/huth/qemu: tests/functional: use QMP to query available machines tests/functional/aspeed: unify boot completion detection on 'login:' prompt tests/functional: Add hotplug_scsi test to hotplug virtio-scsi disk Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -2338,6 +2338,7 @@ F: tests/qtest/virtio-scsi-test.c
|
||||
F: tests/qtest/fuzz-virtio-scsi-test.c
|
||||
F: tests/qtest/am53c974-test.c
|
||||
F: tests/qtest/fuzz-lsi53c895a-test.c
|
||||
F: tests/functional/x86_64/test_hotplug_scsi.py
|
||||
T: git https://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
SSI
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from qemu_test import Asset
|
||||
from aspeed import FacebookAspeedTest
|
||||
from aspeed import AspeedTest
|
||||
|
||||
|
||||
class AnacapaMachine(FacebookAspeedTest):
|
||||
class AnacapaMachine(AspeedTest):
|
||||
|
||||
ASSET_ANACAPA_FLASH = Asset(
|
||||
'https://github.com/legoater/qemu-aspeed-boot/raw/refs/heads/master/images/anacapa-bmc/openbmc-20260616025349/obmc-phosphor-image-anacapa-20260616025349.static.mtd.xz',
|
||||
@@ -22,4 +22,4 @@ class AnacapaMachine(FacebookAspeedTest):
|
||||
soc='AST2600 rev A3')
|
||||
|
||||
if __name__ == '__main__':
|
||||
FacebookAspeedTest.main()
|
||||
AspeedTest.main()
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from qemu_test import Asset
|
||||
from aspeed import FacebookAspeedTest
|
||||
from aspeed import AspeedTest
|
||||
|
||||
|
||||
class BletchleyMachine(FacebookAspeedTest):
|
||||
class BletchleyMachine(AspeedTest):
|
||||
|
||||
ASSET_BLETCHLEY_FLASH = Asset(
|
||||
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/bletchley-bmc/openbmc-20250128071329/obmc-phosphor-image-bletchley-20250128071329.static.mtd.xz',
|
||||
@@ -22,4 +22,4 @@ class BletchleyMachine(FacebookAspeedTest):
|
||||
soc='AST2600 rev A3')
|
||||
|
||||
if __name__ == '__main__':
|
||||
FacebookAspeedTest.main()
|
||||
AspeedTest.main()
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from qemu_test import Asset
|
||||
from aspeed import FacebookAspeedTest
|
||||
from aspeed import AspeedTest
|
||||
|
||||
|
||||
class CatalinaMachine(FacebookAspeedTest):
|
||||
class CatalinaMachine(AspeedTest):
|
||||
|
||||
ASSET_CATALINA_FLASH = Asset(
|
||||
'https://github.com/legoater/qemu-aspeed-boot/raw/a866feb5ef81245b4827a214584bf6bcc72939f6/images/catalina-bmc/obmc-phosphor-image-catalina-20250619123021.static.mtd.xz',
|
||||
@@ -22,4 +22,4 @@ class CatalinaMachine(FacebookAspeedTest):
|
||||
soc='AST2600 rev A3')
|
||||
|
||||
if __name__ == '__main__':
|
||||
FacebookAspeedTest.main()
|
||||
AspeedTest.main()
|
||||
|
||||
@@ -19,8 +19,7 @@ class GB200Machine(AspeedTest):
|
||||
|
||||
self.do_test_arm_aspeed_openbmc('gb200nvl-bmc', image=image_path,
|
||||
uboot='2019.04', cpu_id='0xf00',
|
||||
soc='AST2600 rev A3',
|
||||
image_hostname='gb200nvl-obmc')
|
||||
soc='AST2600 rev A3')
|
||||
|
||||
if __name__ == '__main__':
|
||||
AspeedTest.main()
|
||||
|
||||
@@ -8,14 +8,7 @@ from qemu_test import LinuxKernelTest
|
||||
class AspeedTest(LinuxKernelTest):
|
||||
|
||||
def do_test_arm_aspeed_openbmc(self, machine, image, uboot='2019.04',
|
||||
cpu_id='0x0', soc='AST2500 rev A1',
|
||||
image_hostname=None):
|
||||
# Allow for the image hostname to not end in "-bmc"
|
||||
if image_hostname is not None:
|
||||
hostname = image_hostname
|
||||
else:
|
||||
hostname = machine.removesuffix('-bmc')
|
||||
|
||||
cpu_id='0x0', soc='AST2500 rev A1'):
|
||||
self.set_machine(machine)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-drive', f'file={image},if=mtd,format=raw',
|
||||
@@ -28,10 +21,10 @@ class AspeedTest(LinuxKernelTest):
|
||||
self.wait_for_console_pattern(f'Booting Linux on physical CPU {cpu_id}')
|
||||
self.wait_for_console_pattern(f'ASPEED {soc}')
|
||||
self.wait_for_console_pattern('/init as init process')
|
||||
self.wait_for_boot_complete(hostname)
|
||||
self.wait_for_boot_complete()
|
||||
|
||||
def wait_for_boot_complete(self, hostname):
|
||||
self.wait_for_console_pattern(f'systemd[1]: Hostname set to <{hostname}>.')
|
||||
def wait_for_boot_complete(self):
|
||||
self.wait_for_console_pattern('login:')
|
||||
|
||||
def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'):
|
||||
self.require_netdev('user')
|
||||
@@ -71,9 +64,3 @@ class AspeedTest(LinuxKernelTest):
|
||||
with open(path, "wb") as f:
|
||||
f.write(pattern)
|
||||
return path
|
||||
|
||||
|
||||
class FacebookAspeedTest(AspeedTest):
|
||||
|
||||
def wait_for_boot_complete(self, hostname):
|
||||
self.wait_for_console_pattern(f'{hostname} login:')
|
||||
|
||||
@@ -314,13 +314,32 @@ class QemuSystemTest(QemuBaseTest):
|
||||
console_log.addHandler(self._console_log_fh)
|
||||
|
||||
def set_machine(self, machinename):
|
||||
# TODO: We should use QMP to get the list of available machines
|
||||
if not self._machinehelp:
|
||||
self._machinehelp = run(
|
||||
[self.qemu_bin, '-M', 'help'],
|
||||
capture_output=True, check=True, encoding='utf8').stdout
|
||||
if self._machinehelp.find(machinename) < 0:
|
||||
cls = type(self)
|
||||
|
||||
if not hasattr(cls, "_machines"):
|
||||
tmp_vm = QEMUMachine(self.qemu_bin)
|
||||
tmp_vm.set_machine('none')
|
||||
|
||||
try:
|
||||
tmp_vm.launch()
|
||||
resp = tmp_vm.qmp('query-machines')
|
||||
|
||||
machines = resp.get('return', [])
|
||||
cls._machines = [
|
||||
m.get('name') for m in machines if 'name' in m
|
||||
]
|
||||
|
||||
finally:
|
||||
try:
|
||||
tmp_vm.shutdown()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self._machines = cls._machines
|
||||
|
||||
if machinename not in self._machines:
|
||||
self.skipTest('no support for machine ' + machinename)
|
||||
|
||||
self.machine = machinename
|
||||
|
||||
def require_accelerator(self, accelerator):
|
||||
|
||||
@@ -31,6 +31,7 @@ endif
|
||||
tests_x86_64_system_thorough = [
|
||||
'acpi_bits',
|
||||
'hotplug_blk',
|
||||
'hotplug_scsi',
|
||||
'hotplug_cpu',
|
||||
'intel_iommu',
|
||||
'kvm_xen',
|
||||
|
||||
86
tests/functional/x86_64/test_hotplug_scsi.py
Executable file
86
tests/functional/x86_64/test_hotplug_scsi.py
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that hotplugs a virtio scsi disk and checks it on a Linux
|
||||
# guest
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
|
||||
|
||||
class HotPlugScsi(LinuxKernelTest):
|
||||
ASSET_KERNEL = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
|
||||
'/31/Server/x86_64/os/images/pxeboot/vmlinuz'),
|
||||
'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
|
||||
|
||||
ASSET_INITRD = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
|
||||
'/31/Server/x86_64/os/images/pxeboot/initrd.img'),
|
||||
'277cd6c7adf77c7e63d73bbb2cded8ef9e2d3a2f100000e92ff1f8396513cd8b')
|
||||
|
||||
def blockdev_add(self) -> None:
|
||||
self.vm.cmd('blockdev-add', **{
|
||||
'driver': 'null-co',
|
||||
'size': 1073741824,
|
||||
'node-name': 'disk0'
|
||||
})
|
||||
|
||||
def add_scsi_controller(self) -> None:
|
||||
self.vm.cmd('device_add', {
|
||||
'driver': 'virtio-scsi-pci',
|
||||
'id': 'scsi0',
|
||||
'bus': 'pci.1',
|
||||
'addr': '1',
|
||||
})
|
||||
|
||||
def assert_sda(self) -> None:
|
||||
exec_command_and_wait_for_pattern(self, 'while ! test -e /sys/block/sda ;'
|
||||
' do sleep 0.2 ; done', '# ')
|
||||
|
||||
def assert_no_sda(self) -> None:
|
||||
exec_command_and_wait_for_pattern(self, 'while test -e /sys/block/sda ;'
|
||||
' do sleep 0.2 ; done', '# ')
|
||||
|
||||
def plug(self) -> None:
|
||||
args = {
|
||||
'driver':'scsi-hd',
|
||||
'drive':'disk0',
|
||||
'bus':'scsi0.0',
|
||||
'id':'scsi-disk0',
|
||||
}
|
||||
|
||||
self.assert_no_sda()
|
||||
self.vm.cmd('device_add', args)
|
||||
self.wait_for_console_pattern('[sda] Attached SCSI disk')
|
||||
self.assert_sda()
|
||||
|
||||
def unplug(self) -> None:
|
||||
self.vm.cmd('device_del', id='scsi-disk0')
|
||||
|
||||
self.vm.event_wait('DEVICE_DELETED', 1.0,
|
||||
match={'data': {'device': 'scsi-disk0'}})
|
||||
|
||||
self.assert_no_sda()
|
||||
|
||||
def test(self) -> None:
|
||||
self.require_accelerator('kvm')
|
||||
self.set_machine('q35')
|
||||
self.vm.add_args('-accel', 'kvm')
|
||||
self.vm.add_args('-device', 'pcie-pci-bridge,id=pci.1,bus=pcie.0')
|
||||
self.vm.add_args('-m', '1G')
|
||||
self.vm.add_args('-append', 'console=ttyS0 rd.rescue')
|
||||
|
||||
self.launch_kernel(self.ASSET_KERNEL.fetch(),
|
||||
self.ASSET_INITRD.fetch(),
|
||||
wait_for='Entering emergency mode.')
|
||||
self.wait_for_console_pattern('# ')
|
||||
|
||||
self.blockdev_add()
|
||||
self.add_scsi_controller()
|
||||
self.plug()
|
||||
self.unplug()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LinuxKernelTest.main()
|
||||
|
||||
Reference in New Issue
Block a user