parallel_emerge: set process title to something useful

We can easily spawn dozens of processes which makes `ps` output really
hard to track.  Set the title of each process to something useful so we
can distinguish between them.

BUG=chromium:366480
TEST=ran build_packages and looked at `ps` output
TEST=`cbuildbot chromiumos-sdk`

Change-Id: I24b53d8cc99fa58cfe83a50f4c36cd484017ee98
Reviewed-on: https://chromium-review.googlesource.com/196850
Tested-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: David James <davidjames@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/parallel_emerge.py b/scripts/parallel_emerge.py
index 94b9881..31b902e 100644
--- a/scripts/parallel_emerge.py
+++ b/scripts/parallel_emerge.py
@@ -37,6 +37,7 @@
 
 from chromite.lib import cros_build_lib
 from chromite.lib import osutils
+from chromite.lib import proctitle
 
 # If PORTAGE_USERNAME isn't specified, scrape it from the $HOME variable. On
 # Chromium OS, the default "portage" user doesn't have the necessary
@@ -881,11 +882,13 @@
   signal.signal(signal.SIGINT, ExitHandler)
   signal.signal(signal.SIGTERM, ExitHandler)
 
-def EmergeProcess(output, *args, **kwargs):
+
+def EmergeProcess(output, target, *args, **kwargs):
   """Merge a package in a subprocess.
 
   Args:
     output: Temporary file to write output.
+    target: The package we'll be processing (for display purposes).
     *args: Arguments to pass to Scheduler constructor.
     **kwargs: Keyword arguments to pass to Scheduler constructor.
 
@@ -895,6 +898,8 @@
   pid = os.fork()
   if pid == 0:
     try:
+      proctitle.settitle('EmergeProcess', target)
+
       # Sanity checks.
       if sys.stdout.fileno() != 1:
         raise Exception("sys.stdout.fileno() != 1")
@@ -999,6 +1004,13 @@
   The output is stored in filename. When a merge starts or finishes, we push
   EmergeJobState objects to the job_queue.
   """
+  if fetch_only:
+    mode = 'fetch'
+  elif unpack_only:
+    mode = 'unpack'
+  else:
+    mode = 'emerge'
+  proctitle.settitle('EmergeWorker', mode, '[idle]')
 
   SetupWorkerSignals()
   settings, trees, mtimedb = emerge.settings, emerge.trees, emerge.mtimedb
@@ -1032,6 +1044,7 @@
       return
 
     target = pkg_state.target
+    proctitle.settitle('EmergeWorker', mode, target)
 
     db_pkg = package_db[target]
 
@@ -1061,8 +1074,8 @@
         if unpack_only:
           retcode = UnpackPackage(pkg_state)
         else:
-          retcode = EmergeProcess(output, settings, trees, mtimedb, opts,
-                                  spinner, favorites=emerge.favorites,
+          retcode = EmergeProcess(output, target, settings, trees, mtimedb,
+                                  opts, spinner, favorites=emerge.favorites,
                                   graph_config=emerge.scheduler_graph)
       except Exception:
         traceback.print_exc(file=output)
@@ -1077,6 +1090,10 @@
                          unpack_only=unpack_only)
     job_queue.put(job)
 
+    # Set the title back to idle as the multiprocess pool won't destroy us;
+    # when another job comes up, it'll re-use this process.
+    proctitle.settitle('EmergeWorker', mode, '[idle]')
+
 
 class LinePrinter(object):
   """Helper object to print a single line."""
@@ -1149,6 +1166,7 @@
 
 def PrintWorker(queue):
   """A worker that prints stuff to the screen as requested."""
+  proctitle.settitle('PrintWorker')
 
   def ExitHandler(_signum, _frame):
     # Set KILLED flag.
@@ -1344,6 +1362,8 @@
     if pid == 0:
       os.setsid()
     else:
+      proctitle.settitle('SessionManager')
+
       def PropagateToChildren(signum, _frame):
         # Just propagate the signals down to the child. We'll exit when the
         # child does.