Optimize reboots with Android emulator initialization#5280
Optimize reboots with Android emulator initialization#5280jardondiego wants to merge 21 commits into
Conversation
fernandofloresg
left a comment
There was a problem hiding this comment.
lgtm, would be nice to add those docstrings
letitz
left a comment
There was a problem hiding this comment.
I'm a bit confused about the main logic change in initialize_device(), see comment below.
| return | ||
|
|
||
| adb.write_data_to_file(sanitizer_options, sanitizer_options_file_path) | ||
| # Skip reboot as the app will pick up the options file on restart. |
There was a problem hiding this comment.
Just to make sure I understand, this means that the next time the app is started, it will read from the options file?
There was a problem hiding this comment.
Yes. We write the ASan options to the system file. When the target fuzzer application is launched in a new process shortly after this, the new options file are read from disk during its initialization. A full device reboot isn't required for this step, so we can safely skip it to save time. Forcing a ~60s kernel reboot to update a text string that a process is going to read 2 seconds later is redundant.
There was a problem hiding this comment.
I see, thanks. IIUC the logic in write_data_to_file(), that means we'll leave /system in read-write mode. Is that intentional?
There was a problem hiding this comment.
Yes. I don't think it would be a problem for emulated devices since they would be launched and destroyed in every task bit it might be an issue for non-virtual devices since a fuzzing job could break a system file and we would have to address that issue in a physical device, and that could mean having to physically check such device. We could either skip this optimization for virtual devices or manually trigger a read-only re-mounting. What do you suggest?
There was a problem hiding this comment.
I applied Option A for now, but I'm all ears for any suggestions from you. Thanks!
There was a problem hiding this comment.
See other comment, I don't think option A was applied in the end.
In any case, I don't think it's a big deal to lose 1m per fuzzing session - they last 3 hours anyway. I would rather go for option B and avoid the risk of weird issues where /system files get corrupted. I agree with you that for emulated devices that should be safe, but I'm not 100% confident :)
There was a problem hiding this comment.
I think something weird happened in my workspace, I was moving around several branches and got confused. Agreed! I will adjust as suggested!
bff881e to
2888eab
Compare
letitz
left a comment
There was a problem hiding this comment.
One substantive comment around skipping reboots after writing ASan options, otherwise just two small nits.
| return | ||
|
|
||
| adb.write_data_to_file(sanitizer_options, sanitizer_options_file_path) | ||
| # Skip reboot as the app will pick up the options file on restart. |
There was a problem hiding this comment.
I see, thanks. IIUC the logic in write_data_to_file(), that means we'll leave /system in read-write mode. Is that intentional?
This change reduces the number of reboots during Android device setup by: - Adding a wait_for_reboot parameter to adb.write_data_to_file. - Tracking reboot status in initialize_device to skip the final reboot if one already occurred. - Disabling reboots when setting sanitizer options since the app restart is sufficient. These optimizations improve bot startup efficiency and overall fuzzing throughput.
… tracking and short-circuit issues
Adds `-> bool` return type hints and explanatory docstrings to: - `configure_system_build_properties` - `setup_asan_if_needed` These updates clarify that the returned boolean indicates whether a device reboot occurred during the setup step.
- Revert configure_system_build_properties to not return a bool. - Simplify initialize_device to only reboot if ASan setup did not reboot the device. This fixes the bug where it would reboot even if no properties changed. - Refactor device_test.py to use helpers.patch instead of manual mock setups, matching the codebase style.
2888eab to
2c08a43
Compare
This restricts the should_reboot=False optimization to emulators only. Physical devices will always fall back to a hard reboot after modifying a system file to guarantee the /system partition is safely locked back to read-only.
Removed redundant 'helpers' import in AddTestAccountsIfNeededTest.setUp and fixed spacing.
letitz
left a comment
There was a problem hiding this comment.
LGTM % option b and actually fixing the docstring for write_data_to_file().
| return | ||
|
|
||
| adb.write_data_to_file(sanitizer_options, sanitizer_options_file_path) | ||
| # Skip reboot as the app will pick up the options file on restart. |
There was a problem hiding this comment.
See other comment, I don't think option A was applied in the end.
In any case, I don't think it's a big deal to lose 1m per fuzzing session - they last 3 hours anyway. I would rather go for option B and avoid the risk of weird issues where /system files get corrupted. I agree with you that for emulated devices that should be safe, but I'm not 100% confident :)
Previously, the initialization sequence forced physical Android devices to perform a full kernel reboot after modifying the /system partition (e.g., when updating asan.options) to guarantee the partition was safely locked back to read-only. This commit transitions from that conservative approach (Option A) to a shell-based fallback (Option B). Now, when the 'should_reboot=False' optimization is requested, both emulators AND physical devices skip the 60+ second reboot penalty. To maintain security and prevent accidental filesystem corruption from rogue fuzzers, the script explicitly locks the partition back down using the 'mount -o ro,remount /system' shell command.
Goal
Significantly improve the startup efficiency and fuzzing throughput of Android bots by eliminating redundant, time-consuming device reboots during the initialization and sanitizer setup phases.
Background
Historically, Android bots suffered from excessive hard reboots (~60s penalty each) during task execution: