-
Notifications
You must be signed in to change notification settings - Fork 43
Description
Runner.umount() intends to execute cleanup callbacks stored in self.umount_hook (e.g., deinit_mem_disk()), but under Python 3 the hooks are never invoked because the code uses map(...) without consuming the iterator.
Affected code
In Runner.umount():
(umount_hook, self.umount_hook) = (self.umount_hook, [])
# In Python 3, map() returns an iterator and does nothing until iterated.
map(lambda hook: hook(), umount_hook)Expected behavior
All functions appended to self.umount_hook should be executed when Runner.umount() is called (after unmount attempts), and then the hook list should be cleared.
Actual behavior
Hooks are not executed on Python 3, since map() is lazy and the returned iterator is not consumed anywhere.
Why it matters
For the mem media path, init_mem_disk() appends deinit_mem_disk() into self.umount_hook after a successful losetup. Because these hooks never run, loop devices and temporary mounts leak across runs (e.g., /dev/loopX remains attached and the backing file stays mounted), which can lead to setup failures in subsequent runs or resource exhaustion.
Steps to reproduce (minimal)
- Run a configuration that triggers
init_mem_disk()(e.g.,media=memwithext4or other block-based filesystems). - Observe that cleanup actions expected in
deinit_mem_disk()are not performed after the run (the loop device is not detached).
Proposed fix
Replace the lazy map() call with an explicit loop:
for hook in umount_hook:
hook()Side Note: The usage of
if p.returncode is not 0:in the same function is also incorrect for checking values and triggers aSyntaxWarningin Python 3.8+. It should be updated toif p.returncode != 0:.
I'm happy to submit a pull request with this fix if you'd like.