Add utility that gets the full command line of a process
authorHrvoje Ribicic <riba@google.com>
Sun, 7 Jun 2015 21:12:22 +0000 (23:12 +0200)
committerHrvoje Ribicic <riba@google.com>
Thu, 11 Jun 2015 14:23:15 +0000 (16:23 +0200)
This patch provides a simple function which fetches the command line of
a process given its PID, and some tests for it. It was introduced for
safety reasons in introducing socat-based migration to our Xen-handling
code.

Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Klaus Aehlig <aehlig@google.com>

lib/utils/process.py
test/py/ganeti.utils.process_unittest.py

index f2c29bb..268ff54 100644 (file)
@@ -760,6 +760,24 @@ def _GetProcStatusPath(pid):
   return "/proc/%d/status" % pid
 
 
+def GetProcCmdline(pid):
+  """Returns the command line of a pid as a list of arguments.
+
+  @type pid: int
+  @param pid: Process ID
+  @rtype: list of string
+
+  @raise EnvironmentError: If the process does not exist
+
+  """
+  proc_path = "/proc/%d/cmdline" % pid
+  with open(proc_path, 'r') as f:
+    nulled_cmdline = f.read()
+  # Individual arguments are separated by nul chars in the contents of the proc
+  # file
+  return nulled_cmdline.split('\x00')
+
+
 def IsProcessAlive(pid):
   """Check if a given pid exists on the system.
 
index 2cfb841..5b2107f 100755 (executable)
 
 """Script for testing ganeti.utils.process"""
 
-import unittest
-import tempfile
-import shutil
 import os
-import stat
-import time
 import select
+import shutil
 import signal
+import stat
+import subprocess
+import tempfile
+import time
+import unittest
 
 from ganeti import constants
 from ganeti import utils
@@ -742,5 +743,15 @@ class RunInSeparateProcess(unittest.TestCase):
                       utils.RunInSeparateProcess, _exc)
 
 
+class GetCmdline(unittest.TestCase):
+  def test(self):
+    sample_cmd = "sleep 2; true"
+    pid = subprocess.Popen(sample_cmd, shell=True).pid
+    cmdline = utils.GetProcCmdline(pid)
+    # As the popen will quote and pass on the sample_cmd, it should be returned
+    # by the function as an element in the list of arguments
+    self.assertTrue(sample_cmd in cmdline)
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()