Skip to content

Commit e61302c

Browse files
committed
Got QEMU testing for resume working, took a bunch of changes to test module
changes to test module: - removed "-no-reboot" parameter, needed for full resume test, and added a check for kernel panic messages to stop QEMU from rebooting indefinitely - changed default size of test_rootfs from 16M to 256M to allow 128M of swap for testing (left 128M for disk as it's necessary for certain filesystem, like btrfs which enforces minimum partition size of 40M) - `test_resume` parameter (off by default), enables most of the extra functionality for resume testing - wrote a `resume_tests` function for the `test_image` with script to very hibernate/reboot returns to the same point - rearranged functions in the `test_image` module so that the `test_flag` is printed in the `init_final` stage in the `complete_tests` function, allows tests in `init_main` to be run before passing - changed shebang for `test_image` module to include "-l" to load `/etc/profile` in the test image - added the `swapon` binary to the `test_image`, so the resume swap file can be mounted before hibernation
1 parent f48a95c commit e61302c

File tree

6 files changed

+50
-40
lines changed

6 files changed

+50
-40
lines changed

src/ugrd/base/test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,10 @@ def test_image(self):
163163
if self["test_flag"] in line:
164164
self.logger.info("Test flag found in output: %s", c_(line, "green"))
165165
break
166-
elif line.endswith("exitcode=0x00000000"):
166+
elif (
167+
line.endswith("exitcode=0x00000000")
168+
or "---[ end Kernel panic - not syncing: sysrq triggered crash ]---" in line
169+
):
167170
failed = True
168171
break
169172
elif "press space" in line.lower():

src/ugrd/base/test.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
test_rootfs_name = 'ugrd-test-rootfs'
22
test_rootfs_build_dir = 'initramfs_test_rootfs'
3-
test_image_size = 16
3+
test_image_size = 256
44

55
test_copy_config = ["_mounts", "mounts", "out_dir", "tmpdir", "clean", "test_image_size", "test_no_rootfs", "test_flag", "cryptsetup"]
66
kmod_init = ["ata_piix", "sd_mod"]
77

88
test_memory = '256M'
99
test_cpu = 'host'
1010
test_arch = 'x86_64'
11-
test_timeout = 15
12-
test_cmdline = 'console=ttyS0,115200 panic=1'
13-
#qemu_bool_args = ['nographic', 'no-reboot', 'enable-kvm']
11+
test_timeout = 30
12+
test_cmdline = 'console=ttyS0,115200 panic=0'
1413
qemu_bool_args = ['nographic', 'enable-kvm' ]
1514

1615
[imports.build_pre]

src/ugrd/fs/resume.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def resume(self) -> str:
2727
eerror "Cannot safely resume with mounted block devices:\n$(lsblk -Q MOUNTPOINT -no PATH)"
2828
return 1
2929
fi
30+
3031
[ -b "$1" ] || (ewarn "\'$1\' is not a valid block device!" ; return 1)
3132
einfo "Attempting resume from: $1"
3233
# TODO: This could maybe be printf?
@@ -66,15 +67,18 @@ def handle_late_resume(self) -> None:
6667
self.logger.warning(
6768
"[late_resume] enabled, this can result in data loss if filesystems are modified before resuming. Read the docs for more info."
6869
)
69-
return handle_early_resume(self) # At the moment it's the same code but delayed, will change when more features are added
70+
71+
# At the moment it's the same code but delayed, will change when more features are added
72+
return handle_early_resume(self)
73+
7074

7175
@contains("test_resume")
7276
def test_init_swap_uuid(self):
7377
if "test_cpu" in self:
7478
from uuid import uuid4
7579

76-
self["test_swap_uuid"] = swap_uuid = uuid4()
80+
if not self["test_swap_uuid"]:
81+
self["test_swap_uuid"] = swap_uuid = uuid4()
7782

7883
# append to test kernel cmdline and adjust planned image size to allow enough space
7984
self["test_cmdline"] = f"{self.get('test_cmdline')} resume=UUID={swap_uuid}"
80-
self["test_image_size"] = 256 + self.get("test_image_size")

src/ugrd/fs/resume.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,5 @@ handle_late_resume = ["crypt_init", "init_lvm"]
1919

2020
[custom_parameters]
2121
late_resume = "bool"
22-
test_resume = "bool"
23-
test_swap_uuid = "str"
24-
25-
[import_order.before]
26-
handle_resume = "mount_fstab"
22+
test_resume = "bool" # Test hibernation/resume pathways when test is enabled
23+
test_swap_uuid = "str" # Define the uuid of the swap partition on the test image

src/ugrd/fs/test_image.py

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,43 @@
99

1010
MIN_FS_SIZES = {"btrfs": 110, "f2fs": 50}
1111

12-
@contains("test_flag", "A test flag must be set to create a test image", raise_exception=True)
12+
1313
def init_banner(self):
1414
"""Initialize the test image banner, set a random flag if not set."""
15-
self["banner"] = f"echo {self['test_flag']}"
15+
self["banner"] = "echo ugRD Test Image"
1616

1717

1818
@contains("test_resume")
1919
def resume_tests(self):
20-
return [
21-
'if [ "$(</sys/power/resume)" != "0:0" ] ; then',
22-
' [ -e "/resumed" ] && (rm /resumed ; echo c > /proc/sysrq-trigger)',
23-
# Set correct resume parameters
24-
" echo reboot > /sys/power/disk",
25-
# trigger resume
26-
" echo disk > /sys/power/state",
27-
' [ -e "/resume" ] || echo c > /proc/sysrq-trigger',
28-
# if we reach this point, resume was successful
29-
# reset environment in case resume needs to be rerun
30-
" rm /resumed",
31-
' echo "Resume completed without error.',
32-
"else",
33-
' echo "No resume device found! Resume test not possible!',
34-
"fi",
35-
]
20+
return """
21+
echo "Begin resume testing."
22+
if [ "$(</sys/power/resume)" != "0:0" ] ; then
23+
echo reboot > /sys/power/disk
24+
echo 1 > /sys/power/pm_debug_messages
25+
26+
local SWAPDEV=/dev/$(source "/sys/dev/block/$(</sys/power/resume)/uevent" && echo $DEVNAME)
27+
echo "Activating swap device ${SWAPDEV}..."
28+
swapon ${SWAPDEV}
29+
30+
echo "Triggering test hibernation..."
31+
echo disk > /sys/power/state || (echo "Suspend to disk failed!" ; echo c > /proc/sysrq-trigger)
3632
33+
# Assume at this point system has hibernated then resumed again
34+
echo "Resume test completed without error."
35+
else
36+
echo "No resume device found! Resume test not possible!"
37+
echo c > /proc/sysrq-trigger
38+
fi
39+
"""
3740

41+
42+
@contains("test_flag", "A test flag must be set to create a test image", raise_exception=True)
3843
def complete_tests(self):
39-
return [
40-
"echo s > /proc/sysrq-trigger",
41-
"echo o > /proc/sysrq-trigger",
42-
]
44+
return f"""
45+
echo {self["test_flag"]}
46+
echo s > /proc/sysrq-trigger
47+
echo o > /proc/sysrq-trigger
48+
"""
4349

4450

4551
def _allocate_image(self, image_path, padding=0):
@@ -65,6 +71,7 @@ def _allocate_image(self, image_path, padding=0):
6571
self.logger.debug(f"[{f.name}] Total bytes: { c_(total_size, 'green')}")
6672
f.write(b"\0" * total_size)
6773

74+
6875
def _copy_fs_contents(self, image_path, build_dir):
6976
""" Mount and copy the filesystem contents into the image,
7077
for filesystems which cannot be created directly from a directory"""
@@ -151,9 +158,7 @@ def make_test_image(self):
151158
loopback = None
152159
if self.get("test_resume"):
153160
try:
154-
self._run(["sgdisk", "-og", image_path])
155-
self._run(["sgdisk", "-n", "1:0:+256", image_path])
156-
self._run(["sgdisk", "-n", "2:0", image_path])
161+
self._run(["sgdisk", "-og", "-n", "1:0:+128M", "-n", "2:0:0", image_path])
157162
except RuntimeError as e:
158163
raise RuntimeError("Failed to partition test disk: %s", e)
159164

src/ugrd/fs/test_image.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
modules = [ 'ugrd.base.banner' ] # get_archive_path
22
paths = ['dev', 'sys', 'proc']
3+
binaries = ['swapon']
34

4-
test_image_size = 16
5-
shebang = "#!/bin/sh" # Don't use -l, no profile is generated
5+
test_image_size = 256
6+
shebang = "#!/bin/sh -l"
67
_cryptsetup_root = "root"
78

89

@@ -27,3 +28,4 @@ _cryptsetup_root = "str" # Define the root device for cryptsetup
2728
test_image_size = "int" # Define the size of the test image in MiB
2829
test_flag = "str" # Define the success flag used to determine if the test was successful
2930
test_resume = "bool" # Enable code to test the suspend/resume pathways
31+
test_swap_uuid = "str" # Define the UUID of the swap partition

0 commit comments

Comments
 (0)