Update the logic to force cleanup all edit monitor instances.
Instead of checking the pidfiles, query all the running process with
binary ends with "edit_monitor" and kill all of those processes. This
ensures that if there are any unexpected edit monitor instances running
(e.g. due to b/382135550), the force cleanup can kill those processes as
well.
Bug: 382135550
Test: atest daemon_manager_test
Change-Id: I299f16b7b913e4ee470b5fe9ef0ffdad8d3c0945
diff --git a/tools/edit_monitor/daemon_manager.py b/tools/edit_monitor/daemon_manager.py
index a352e30..36a7593 100644
--- a/tools/edit_monitor/daemon_manager.py
+++ b/tools/edit_monitor/daemon_manager.py
@@ -413,13 +413,19 @@
def _find_all_instances_pids(self) -> list[int]:
pids = []
- for file in os.listdir(self.pid_file_path.parent):
- if file.endswith(".lock"):
- try:
- with open(self.pid_file_path.parent.joinpath(file), "r") as f:
- pids.append(int(f.read().strip()))
- except (FileNotFoundError, IOError, ValueError, TypeError):
- logging.exception("Failed to get pid from file path: %s", file)
+ try:
+ output = subprocess.check_output(
+ ["ps", "-ef", "--no-headers"], text=True)
+ for line in output.splitlines():
+ parts = line.split()
+ process_path = parts[7]
+ if pathlib.Path(process_path).name == 'edit_monitor':
+ pid = int(parts[1])
+ if pid != self.pid: # exclude the current process
+ pids.append(pid)
+ except Exception:
+ logging.exception(
+ "Failed to get pids of existing edit monitors from ps command.")
return pids
diff --git a/tools/edit_monitor/daemon_manager_test.py b/tools/edit_monitor/daemon_manager_test.py
index 350739d..e412ab0 100644
--- a/tools/edit_monitor/daemon_manager_test.py
+++ b/tools/edit_monitor/daemon_manager_test.py
@@ -367,6 +367,26 @@
fake_cclient, edit_event_pb2.EditEvent.FAILED_TO_REBOOT_EDIT_MONITOR
)
+ @mock.patch('subprocess.check_output')
+ def test_cleanup_success(self, mock_check_output):
+ p = self._create_fake_deamon_process()
+ fake_cclient = FakeClearcutClient()
+ mock_check_output.return_value = f'user {p.pid} 1 1 1 1 1 edit_monitor arg'
+
+ dm = daemon_manager.DaemonManager(
+ TEST_BINARY_FILE,
+ daemon_target=long_running_daemon,
+ cclient=fake_cclient,
+ )
+ dm.cleanup()
+
+ self.assertFalse(p.is_alive())
+ self.assertTrue(
+ pathlib.Path(self.working_dir.name)
+ .joinpath(daemon_manager.BLOCK_SIGN_FILE)
+ .exists()
+ )
+
def assert_run_simple_daemon_success(self):
damone_output_file = tempfile.NamedTemporaryFile(
dir=self.working_dir.name, delete=False
diff --git a/tools/edit_monitor/main.py b/tools/edit_monitor/main.py
index 7ca0daa..3c2d183 100644
--- a/tools/edit_monitor/main.py
+++ b/tools/edit_monitor/main.py
@@ -102,12 +102,12 @@
daemon_args=(args.path, args.dry_run),
)
- if args.force_cleanup:
- dm.cleanup()
-
try:
- dm.start()
- dm.monitor_daemon()
+ if args.force_cleanup:
+ dm.cleanup()
+ else:
+ dm.start()
+ dm.monitor_daemon()
except Exception:
logging.exception('Unexpected exception raised when run daemon.')
finally: