factory_flow: Use SIGINT to terminate servers.

And if a server does not stop in five seconds, send SIGKILL to
kill it.

BUG=chrome-os-partner:26795
TEST=manually on my host

Change-Id: Ib2b650350b508a7da3d537e940b464f8809dbabe
Reviewed-on: https://chromium-review.googlesource.com/199055
Reviewed-by: Ricky Liang <jcliang@chromium.org>
Commit-Queue: Ricky Liang <jcliang@chromium.org>
Tested-by: Ricky Liang <jcliang@chromium.org>
diff --git a/py/factory_flow/start_server.py b/py/factory_flow/start_server.py
index 63c4f66..76e8e64 100644
--- a/py/factory_flow/start_server.py
+++ b/py/factory_flow/start_server.py
@@ -16,6 +16,7 @@
 from cros.factory.factory_flow.common import (
     board_cmd_arg, bundle_dir_cmd_arg, FactoryFlowCommand)
 from cros.factory.hacked_argparse import CmdArg
+from cros.factory.test import utils
 from cros.factory.umpire.common import LoadBundleManifest
 from cros.factory.utils import file_utils
 from cros.factory.utils import process_utils
@@ -210,9 +211,16 @@
         logging.info('PID file of %s found; shut down existing %s (PID=%d)',
                      name, name, pid)
         if process_utils.SpawnOutput(['pgrep', '-F', pid_file]):
-          # Send SIGKILL to the process to stop it.
-          process_utils.Spawn(['kill', '-SIGKILL', '%d' % pid],
+          # Send SIGINT to the process to gracefully stop it.
+          process_utils.Spawn(['kill', '-SIGINT', '%d' % pid],
                               log=True, check_call=True, sudo=True)
+          # Wait at most 5 seconds for process to stop.
+          try:
+            utils.WaitFor(lambda: not utils.is_process_alive(pid), 5)
+          except utils.TimeoutError:
+            # Send SIGKILL to the process to kill it.
+            process_utils.Spawn(['kill', '-SIGKILL', '%d' % pid],
+                                log=True, check_call=True, sudo=True)
         else:
           logging.info(('Process with PID=%d not found; '
                         'assume it is already dead'),