Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 130da8ed authored by Zhuoyao Zhang's avatar Zhuoyao Zhang
Browse files

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
parent afdc92c6
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -413,13 +413,19 @@ class DaemonManager:
  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)
      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

+20 −0
Original line number Diff line number Diff line
@@ -367,6 +367,26 @@ class DaemonManagerTest(unittest.TestCase):
        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
+5 −5
Original line number Diff line number Diff line
@@ -102,10 +102,10 @@ def main(argv: list[str]):
      daemon_args=(args.path, args.dry_run),
  )

  try:
    if args.force_cleanup:
      dm.cleanup()

  try:
    else:
      dm.start()
      dm.monitor_daemon()
  except Exception: