From 02f9e8bbdddd69603cbb0afc93279c4151afd5f5 Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Sun, 10 Sep 2017 02:51:10 +0200 Subject: [PATCH] Replace pmap shellout with pure python implementation Without this patch, the pmap -XX call fails on openSUSE Leap distributions as those have a fairly ancient procps version that does not support the -XX parameter. A pure python implementation is more portable, faster and even shorter than the subprocess call. Closes-Bug: #1716066 Change-Id: I2fdb457e65359a1c9d40452c922cfdca0e6e74dc --- tools/mlock_report.py | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/tools/mlock_report.py b/tools/mlock_report.py index 2169cc2dce..07716b04d6 100755 --- a/tools/mlock_report.py +++ b/tools/mlock_report.py @@ -3,12 +3,12 @@ # This tool lists processes that lock memory pages from swapping to disk. import re -import subprocess import psutil -SUMMARY_REGEX = re.compile(b".*\s+(?P[\d]+)\s+KB") +LCK_SUMMARY_REGEX = re.compile( + "^VmLck:\s+(?P[\d]+)\s+kB", re.MULTILINE) def main(): @@ -22,28 +22,21 @@ def main(): def _get_report(): mlock_users = [] for proc in psutil.process_iter(): - pid = proc.pid # sadly psutil does not expose locked pages info, that's why we - # call to pmap and parse the output here + # iterate over the /proc/%pid/status files manually try: - out = subprocess.check_output(['pmap', '-XX', str(pid)]) - except subprocess.CalledProcessError as e: - # 42 means process just vanished, which is ok - if e.returncode == 42: - continue - raise - last_line = out.splitlines()[-1] - - # some processes don't provide a memory map, for example those - # running as kernel services, so we need to skip those that don't - # match - result = SUMMARY_REGEX.match(last_line) - if result: - locked = int(result.group('locked')) - if locked: - mlock_users.append({'name': proc.name(), - 'pid': pid, - 'locked': locked}) + s = open("%s/%d/status" % (psutil.PROCFS_PATH, proc.pid), 'r') + except EnvironmentError: + continue + with s: + for line in s: + result = LCK_SUMMARY_REGEX.search(line) + if result: + locked = int(result.group('locked')) + if locked: + mlock_users.append({'name': proc.name(), + 'pid': proc.pid, + 'locked': locked}) # produce a single line log message with per process mlock stats if mlock_users: