|
4 | 4 |
|
5 | 5 | import os
|
6 | 6 | import re
|
| 7 | +import time |
7 | 8 |
|
8 | 9 | import pytest
|
9 | 10 | import requests
|
@@ -142,3 +143,36 @@ def test_malicious_handler(uvm_plain, snapshot):
|
142 | 143 | assert False, "Firecracker should freeze"
|
143 | 144 | except (TimeoutError, requests.exceptions.ReadTimeout):
|
144 | 145 | vm.uffd_handler.mark_killed()
|
| 146 | + |
| 147 | + |
| 148 | +def test_fault_all_handler_exit(uvm_plain, snapshot): |
| 149 | + """ |
| 150 | + Test that the VM is functional if the fault-all handler exits |
| 151 | + after prepopulating the guest memory. |
| 152 | + """ |
| 153 | + vm = uvm_plain |
| 154 | + vm.memory_monitor = None |
| 155 | + vm.spawn() |
| 156 | + vm.restore_from_snapshot(snapshot, resume=True, uffd_handler_name="fault_all") |
| 157 | + |
| 158 | + # Verify if the restored guest works. |
| 159 | + vm.ssh.check_output("true") |
| 160 | + |
| 161 | + # Kill the UFFD handler. |
| 162 | + vm.uffd_handler.kill() |
| 163 | + |
| 164 | + # Give UFFD time to unregister all guest memory. |
| 165 | + time.sleep(1) |
| 166 | + |
| 167 | + # Verify if the restored guest works after the handler exited. |
| 168 | + # |
| 169 | + # It is empirically known that invoking `ps` first time after snapshot restore |
| 170 | + # will likely trigger an access to a guest memory page via userspace mappings |
| 171 | + # either due to an MMIO instruction lookup (x86 only) or due to |
| 172 | + # Firecracker accessing the guest memory. |
| 173 | + # |
| 174 | + # On Secret Free VMs, we do not preinstall userspace mappings when prepopulating |
| 175 | + # guest memory in the fault-all handler. If we fail to unregister all guest memory |
| 176 | + # with UFFD on the handler exit, accessing the userspace mapping will trigger |
| 177 | + # a UFFD notification that will never be handled. |
| 178 | + vm.ssh.check_output("ps") |
0 commit comments