Ejemplo n.º 1
0
 def run(self):
     num_processes = 0
     num_zombies = 0
     info = ProcessInformation(proc_dir=self._proc_dir)
     for process_info in info.get_all_process_info():
         num_processes += 1
         if process_info["state"] == "Z":
             num_zombies += 1
     if num_zombies:
         if num_zombies == 1:
             msg = "There is 1 zombie process."
         else:
             msg = "There are %d zombie processes." % (num_zombies, )
         self._sysinfo.add_note(msg)
     self._sysinfo.add_header("Processes", str(num_processes))
     return succeed(None)
Ejemplo n.º 2
0
    def test_missing_process_race(self, get_uptime_mock, list_dir_mock,
                                  jiffies_mock):
        """
        We use os.listdir("/proc") to get the list of active processes, if a
        process ends before we attempt to read the process' information, then
        this should not trigger an error.
        """
        class FakeFile(object):
            def __init__(self, response=""):
                self._response = response
                self.closed = False

            def readline(self):
                return self._response

            def __iter__(self):
                if self._response is None:
                    raise IOError("Fake file error")
                else:
                    yield self._response

            def close(self):
                self.closed = True

        list_dir_mock.return_value = ["12345"]
        get_uptime_mock.return_value = 1.0
        fakefile1 = FakeFile("test-binary")
        fakefile2 = FakeFile(None)
        with mock.patch(
                "landscape.lib.process.open",
                mock.mock_open(),
                create=True,
        ) as open_mock:
            # This means "return fakefile1, then fakefile2"
            open_mock.side_effect = [fakefile1, fakefile2]
            process_info = ProcessInformation("/proc")
            processes = list(process_info.get_all_process_info())
            calls = [
                mock.call("/proc/12345/cmdline", "r"),
                mock.call("/proc/12345/status", "r")
            ]
            open_mock.assert_has_calls(calls)
        self.assertEqual(processes, [])
        list_dir_mock.assert_called_with("/proc")
        self.assertTrue(fakefile1.closed)
        self.assertTrue(fakefile2.closed)
Ejemplo n.º 3
0
#!/usr/bin/env python3

from datetime import datetime
from landscape.lib.process import ProcessInformation

info = ProcessInformation()
for process_info in info.get_all_process_info():
    if process_info['state'] == b'Z':
        print(process_info['pid'], process_info['name'],
              datetime.fromtimestamp(process_info['start-time']))
Ejemplo n.º 4
0
class ActiveProcessInfo(DataWatcher):

    message_type = "active-process-info"
    scope = "process"

    def __init__(self,
                 proc_dir="/proc",
                 boot_time=None,
                 jiffies=None,
                 uptime=None,
                 popen=subprocess.Popen):
        super(ActiveProcessInfo, self).__init__()
        self._proc_dir = proc_dir
        self._persist_processes = {}
        self._previous_processes = {}
        self._jiffies_per_sec = jiffies or detect_jiffies()
        self._popen = popen
        self._first_run = True
        self._process_info = ProcessInformation(proc_dir=proc_dir,
                                                jiffies=jiffies,
                                                boot_time=boot_time,
                                                uptime=uptime)

    def register(self, manager):
        super(ActiveProcessInfo, self).register(manager)
        self.call_on_accepted(self.message_type, self.exchange, True)

    def _reset(self):
        """Reset active process data."""
        self._first_run = True
        self._persist_processes = {}
        self._previous_processes = {}

    def get_message(self):
        message = {}
        if self._first_run:
            message["kill-all-processes"] = True
        message.update(self._detect_process_changes())

        if message:
            message["type"] = "active-process-info"
            return message
        return None

    def persist_data(self):
        self._first_run = False
        self._persist_processes = self._previous_processes
        self._previous_processes = {}
        # This forces the registry to write the persistent store to disk
        # This means that the persistent data reflects the state of the
        # messages sent.
        self.registry.flush()

    def _get_processes(self):
        processes = {}
        for process_info in self._process_info.get_all_process_info():
            if process_info["state"] != b"X":
                processes[process_info["pid"]] = process_info
        return processes

    def _detect_process_changes(self):
        changes = {}
        processes = self._get_processes()
        creates, updates, deletes = diff(self._persist_processes, processes)
        if creates:
            changes["add-processes"] = list(itervalues(creates))
        if updates:
            changes["update-processes"] = list(itervalues(updates))
        if deletes:
            changes["kill-processes"] = list(deletes)

        # Update cached values for use on the next run.
        self._previous_processes = processes
        return changes