Skip to content

Commit 5a762e2

Browse files
committed
refactor(test): spawn uffd handler inside restore_from_snapshot
Drop the requirement of having to call spawn_pf_handler() before the call to microvm.restore_from_snapshot() in integration tests, and instead just have restore_from_snapshot() take the name of the uffd handler as an optional keyword argument, and do the spawning. This removes the weird calling convention of calling restore_from_snapshot() without a snapshot parameter (because it was inferred from uffd). Signed-off-by: Patrick Roy <[email protected]>
1 parent 81f81fc commit 5a762e2

File tree

4 files changed

+24
-43
lines changed

4 files changed

+24
-43
lines changed

tests/framework/microvm.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -975,19 +975,22 @@ def snapshot_full(self, *, mem_path: str = "mem", vmstate_path="vmstate"):
975975

976976
def restore_from_snapshot(
977977
self,
978-
snapshot: Snapshot = None,
978+
snapshot: Snapshot,
979979
resume: bool = False,
980980
rename_interfaces: dict = None,
981+
*,
982+
uffd_handler_name: str = None,
981983
):
982984
"""Restore a snapshot"""
983-
if self.uffd_handler is None:
984-
assert (
985-
snapshot is not None
986-
), "snapshot file must be provided if no uffd handler is attached!"
987985

988-
jailed_snapshot = snapshot.copy_to_chroot(Path(self.chroot()))
989-
else:
990-
jailed_snapshot = self.uffd_handler.snapshot
986+
jailed_snapshot = snapshot.copy_to_chroot(Path(self.chroot()))
987+
988+
if uffd_handler_name:
989+
spawn_pf_handler(
990+
self,
991+
uffd_handler(uffd_handler_name, binary_dir=self.fc_binary_path.parent),
992+
jailed_snapshot,
993+
)
991994

992995
jailed_mem = Path("/") / jailed_snapshot.mem.name
993996
jailed_vmstate = Path("/") / jailed_snapshot.vmstate.name
@@ -1180,14 +1183,9 @@ def build_n_from_snapshot(
11801183
microvm = self.build()
11811184
microvm.spawn()
11821185

1183-
if uffd_handler_name is not None:
1184-
spawn_pf_handler(
1185-
microvm,
1186-
uffd_handler(uffd_handler_name, binary_dir=self.binary_path),
1187-
current_snapshot,
1188-
)
1189-
1190-
snapshot_copy = microvm.restore_from_snapshot(current_snapshot, resume=True)
1186+
snapshot_copy = microvm.restore_from_snapshot(
1187+
current_snapshot, resume=True, uffd_handler_name=uffd_handler_name
1188+
)
11911189

11921190
yield microvm
11931191

tests/framework/utils_uffd.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,9 @@ def __del__(self):
8383
self.proc.kill()
8484

8585

86-
def spawn_pf_handler(vm, handler_path, snapshot):
86+
def spawn_pf_handler(vm, handler_path, jailed_snapshot):
8787
"""Spawn page fault handler process."""
8888
# Copy snapshot memory file into chroot of microVM.
89-
jailed_snapshot = snapshot.copy_to_chroot(Path(vm.chroot()))
9089
# Copy the valid page fault binary into chroot of microVM.
9190
jailed_handler = vm.create_jailed_resource(handler_path)
9291
handler_name = os.path.basename(jailed_handler)

tests/integration_tests/functional/test_uffd.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import requests
1010

1111
from framework.utils import Timeout, check_output
12-
from framework.utils_uffd import spawn_pf_handler, uffd_handler
1312

1413

1514
@pytest.fixture(scope="function", name="snapshot")
@@ -90,11 +89,7 @@ def test_valid_handler(uvm_plain, snapshot):
9089
vm = uvm_plain
9190
vm.memory_monitor = None
9291
vm.spawn()
93-
94-
# Spawn page fault handler process.
95-
spawn_pf_handler(vm, uffd_handler("on_demand"), snapshot)
96-
97-
vm.restore_from_snapshot(resume=True)
92+
vm.restore_from_snapshot(snapshot, resume=True, uffd_handler_name="on_demand")
9893

9994
# Inflate balloon.
10095
vm.api.balloon.patch(amount_mib=200)
@@ -124,14 +119,13 @@ def test_malicious_handler(uvm_plain, snapshot):
124119
vm.memory_monitor = None
125120
vm.spawn()
126121

127-
# Spawn page fault handler process.
128-
spawn_pf_handler(vm, uffd_handler("malicious"), snapshot)
129-
130122
# We expect Firecracker to freeze while resuming from a snapshot
131123
# due to the malicious handler's unavailability.
132124
try:
133125
with Timeout(seconds=30):
134-
vm.restore_from_snapshot(resume=True)
126+
vm.restore_from_snapshot(
127+
snapshot, resume=True, uffd_handler_name="malicious"
128+
)
135129
assert False, "Firecracker should freeze"
136130
except (TimeoutError, requests.exceptions.ReadTimeout):
137131
pass

tests/integration_tests/performance/test_huge_pages.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from framework.microvm import HugePagesConfig
1111
from framework.properties import global_props
1212
from framework.utils_ftrace import ftrace_events
13-
from framework.utils_uffd import spawn_pf_handler, uffd_handler
1413

1514

1615
def check_hugetlbfs_in_use(pid: int, allocation_name: str):
@@ -91,11 +90,7 @@ def test_hugetlbfs_snapshot(microvm_factory, guest_kernel_linux_5_10, rootfs):
9190
### Restore Snapshot ###
9291
vm = microvm_factory.build()
9392
vm.spawn()
94-
95-
# Spawn page fault handler process.
96-
spawn_pf_handler(vm, uffd_handler("on_demand"), snapshot)
97-
98-
vm.restore_from_snapshot(resume=True)
93+
vm.restore_from_snapshot(snapshot, resume=True, uffd_handler_name="on_demand")
9994

10095
check_hugetlbfs_in_use(vm.firecracker_pid, "/anon_hugepage")
10196

@@ -133,11 +128,9 @@ def test_hugetlbfs_diff_snapshot(microvm_factory, uvm_plain):
133128

134129
vm = microvm_factory.build()
135130
vm.spawn()
136-
137-
# Spawn page fault handler process.
138-
spawn_pf_handler(vm, uffd_handler("on_demand"), snapshot_merged)
139-
140-
vm.restore_from_snapshot(resume=True)
131+
vm.restore_from_snapshot(
132+
snapshot_merged, resume=True, uffd_handler_name="on_demand"
133+
)
141134

142135
# Verify if the restored microvm works.
143136

@@ -192,11 +185,8 @@ def test_ept_violation_count(
192185
vm.jailer.extra_args.update({"no-seccomp": None})
193186
vm.spawn()
194187

195-
# Spawn page fault handler process.
196-
spawn_pf_handler(vm, uffd_handler("fault_all"), snapshot)
197-
198188
with ftrace_events("kvm:*"):
199-
vm.restore_from_snapshot(resume=True)
189+
vm.restore_from_snapshot(snapshot, resume=True, uffd_handler_name="fault_all")
200190

201191
# Verify if guest can run commands, and also wake up the fast page fault helper to trigger page faults.
202192
vm.ssh.check_output(f"kill -s {signal.SIGUSR1} {pid}")

0 commit comments

Comments
 (0)