Replace screen_it() with run_process() throughout

run_process will use screen if USE_SCREEN=True (the default),
otherwise it will simply start the requested service. Therefore
wherever screen_it used, run_process can be instead.

Where stop_screen was found it has been replaced with stop_process.

A tail_log function has been added which will tail a logfile in a
screen if USE_SCREEN is True.

lib/template has been updated to reflect the use of the new
functions.

When using sg the quoting in run_process gets very complicated.
To get around this run_process and the functions it calls accepts
an optional third argument. If set it is a group to be used with sg.

Change-Id: Ia3843818014f7c6c7526ef3aa9676bbddb8a85ca
diff --git a/lib/ceilometer b/lib/ceilometer
index 340acb9..a71643a 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -224,18 +224,18 @@
 
 # start_ceilometer() - Start running processes, including screen
 function start_ceilometer {
-    screen_it ceilometer-acentral "cd ; ceilometer-agent-central --config-file $CEILOMETER_CONF"
-    screen_it ceilometer-anotification "cd ; ceilometer-agent-notification --config-file $CEILOMETER_CONF"
-    screen_it ceilometer-collector "cd ; ceilometer-collector --config-file $CEILOMETER_CONF"
-    screen_it ceilometer-api "cd ; ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
+    run_process ceilometer-acentral "ceilometer-agent-central --config-file $CEILOMETER_CONF"
+    run_process ceilometer-anotification "ceilometer-agent-notification --config-file $CEILOMETER_CONF"
+    run_process ceilometer-collector "ceilometer-collector --config-file $CEILOMETER_CONF"
+    run_process ceilometer-api "ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
 
     # Start the compute agent last to allow time for the collector to
     # fully wake up and connect to the message bus. See bug #1355809
     if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
-        screen_it ceilometer-acompute "cd ; sg $LIBVIRT_GROUP 'ceilometer-agent-compute --config-file $CEILOMETER_CONF'"
+        run_process ceilometer-acompute "sg $LIBVIRT_GROUP 'ceilometer-agent-compute --config-file $CEILOMETER_CONF'"
     fi
     if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then
-        screen_it ceilometer-acompute "cd ; ceilometer-agent-compute --config-file $CEILOMETER_CONF"
+        run_process ceilometer-acompute "ceilometer-agent-compute --config-file $CEILOMETER_CONF"
     fi
 
     # only die on API if it was actually intended to be turned on
@@ -246,15 +246,15 @@
         fi
     fi
 
-    screen_it ceilometer-alarm-notifier "cd ; ceilometer-alarm-notifier --config-file $CEILOMETER_CONF"
-    screen_it ceilometer-alarm-evaluator "cd ; ceilometer-alarm-evaluator --config-file $CEILOMETER_CONF"
+    run_process ceilometer-alarm-notifier "ceilometer-alarm-notifier --config-file $CEILOMETER_CONF"
+    run_process ceilometer-alarm-evaluator "ceilometer-alarm-evaluator --config-file $CEILOMETER_CONF"
 }
 
 # stop_ceilometer() - Stop running processes
 function stop_ceilometer {
     # Kill the ceilometer screen windows
     for serv in ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-evaluator; do
-        screen_stop $serv
+        stop_process $serv
     done
 }
 
diff --git a/lib/cinder b/lib/cinder
index 0426dbe..6032a9a 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -456,7 +456,7 @@
     # Kill the cinder screen windows
     local serv
     for serv in c-api c-bak c-sch c-vol; do
-        screen_stop $serv
+        stop_process $serv
     done
 
     if is_service_enabled c-vol; then
diff --git a/lib/gantt b/lib/gantt
index 8db2ca1..485613f 100644
--- a/lib/gantt
+++ b/lib/gantt
@@ -77,14 +77,14 @@
 # start_gantt() - Start running processes, including screen
 function start_gantt {
     if is_service_enabled gantt; then
-        screen_it gantt "cd $GANTT_DIR && $GANTT_BIN_DIR/gantt-scheduler --config-file $GANTT_CONF"
+        run_process gantt "$GANTT_BIN_DIR/gantt-scheduler --config-file $GANTT_CONF"
     fi
 }
 
 # stop_gantt() - Stop running processes
 function stop_gantt {
     echo "Stop Gantt"
-    screen_stop gantt
+    stop_process gantt
 }
 
 # Restore xtrace
diff --git a/lib/glance b/lib/glance
index d9c4a20..1ed0d31 100644
--- a/lib/glance
+++ b/lib/glance
@@ -269,8 +269,8 @@
 
 # start_glance() - Start running processes, including screen
 function start_glance {
-    screen_it g-reg "cd $GLANCE_DIR; $GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
-    screen_it g-api "cd $GLANCE_DIR; $GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
+    run_process g-reg "$GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
+    run_process g-api "$GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
     echo "Waiting for g-api ($GLANCE_HOSTPORT) to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$GLANCE_HOSTPORT; do sleep 1; done"; then
         die $LINENO "g-api did not start"
@@ -280,8 +280,8 @@
 # stop_glance() - Stop running processes
 function stop_glance {
     # Kill the Glance screen windows
-    screen_stop g-api
-    screen_stop g-reg
+    stop_process g-api
+    stop_process g-reg
 }
 
 
diff --git a/lib/heat b/lib/heat
index 14094a9..a74d7b5 100644
--- a/lib/heat
+++ b/lib/heat
@@ -189,10 +189,10 @@
 
 # start_heat() - Start running processes, including screen
 function start_heat {
-    screen_it h-eng "cd $HEAT_DIR; bin/heat-engine --config-file=$HEAT_CONF"
-    screen_it h-api "cd $HEAT_DIR; bin/heat-api --config-file=$HEAT_CONF"
-    screen_it h-api-cfn "cd $HEAT_DIR; bin/heat-api-cfn --config-file=$HEAT_CONF"
-    screen_it h-api-cw "cd $HEAT_DIR; bin/heat-api-cloudwatch --config-file=$HEAT_CONF"
+    run_process h-eng "$HEAT_DIR/bin/heat-engine --config-file=$HEAT_CONF"
+    run_process h-api "$HEAT_DIR/bin/heat-api --config-file=$HEAT_CONF"
+    run_process h-api-cfn "$HEAT_DIR/bin/heat-api-cfn --config-file=$HEAT_CONF"
+    run_process h-api-cw "$HEAT_DIR/bin/heat-api-cloudwatch --config-file=$HEAT_CONF"
 }
 
 # stop_heat() - Stop running processes
@@ -200,7 +200,7 @@
     # Kill the screen windows
     local serv
     for serv in h-eng h-api h-api-cfn h-api-cw; do
-        screen_stop $serv
+        stop_process $serv
     done
 }
 
diff --git a/lib/horizon b/lib/horizon
index 614a0c8..a422529 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -152,6 +152,7 @@
 
     # Remove old log files that could mess with how devstack detects whether Horizon
     # has been successfully started (see start_horizon() and functions::screen_it())
+    # and run_process
     sudo rm -f /var/log/$APACHE_NAME/horizon_*
 
 }
@@ -173,7 +174,7 @@
 # start_horizon() - Start running processes, including screen
 function start_horizon {
     restart_apache_server
-    screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
+    tail_log horizon /var/log/$APACHE_NAME/horizon_error.log
 }
 
 # stop_horizon() - Stop running processes (non-screen)
diff --git a/lib/ironic b/lib/ironic
index 2fad0b5..f4de05b 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -381,7 +381,7 @@
 # start_ironic_api() - Used by start_ironic().
 # Starts Ironic API server.
 function start_ironic_api {
-    screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
+    run_process ir-api "$IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
     echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
         die $LINENO "ir-api did not start"
@@ -391,7 +391,7 @@
 # start_ironic_conductor() - Used by start_ironic().
 # Starts Ironic conductor.
 function start_ironic_conductor {
-    screen_it ir-cond "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
+    run_process ir-cond "$IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
     # TODO(romcheg): Find a way to check whether the conductor has started.
 }
 
diff --git a/lib/keystone b/lib/keystone
index da5cf89..66ab3db 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -474,11 +474,11 @@
 
     if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
         restart_apache_server
-        screen_it key "cd $KEYSTONE_DIR && sudo tail -f /var/log/$APACHE_NAME/keystone.log"
-        screen_it key-access "sudo tail -f /var/log/$APACHE_NAME/keystone_access.log"
+        tail_log key /var/log/$APACHE_NAME/keystone.log
+        tail_log key-access /var/log/$APACHE_NAME/keystone_access.log
     else
         # Start Keystone in a screen window
-        screen_it key "cd $KEYSTONE_DIR && $KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF --debug"
+        run_process key "$KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF --debug"
     fi
 
     echo "Waiting for keystone to start..."
@@ -499,7 +499,7 @@
 # stop_keystone() - Stop running processes
 function stop_keystone {
     # Kill the Keystone screen window
-    screen_stop key
+    stop_process key
     # Cleanup the WSGI files and VHOST
     _cleanup_keystone_apache_wsgi
 }
diff --git a/lib/neutron b/lib/neutron
index a00664e..bdd4aee 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -591,7 +591,7 @@
 function start_neutron_service_and_check {
     local cfg_file_options="$(determine_config_files neutron-server)"
     # Start the Neutron service
-    screen_it q-svc "cd $NEUTRON_DIR && python $NEUTRON_BIN_DIR/neutron-server $cfg_file_options"
+    run_process q-svc "python $NEUTRON_BIN_DIR/neutron-server $cfg_file_options"
     echo "Waiting for Neutron to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$Q_HOST:$Q_PORT; do sleep 1; done"; then
         die $LINENO "Neutron did not start"
@@ -601,8 +601,8 @@
 # Start running processes, including screen
 function start_neutron_agents {
     # Start up the neutron agents if enabled
-    screen_it q-agt "cd $NEUTRON_DIR && python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
-    screen_it q-dhcp "cd $NEUTRON_DIR && python $AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE"
+    run_process q-agt "python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
+    run_process q-dhcp "python $AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE"
 
     if is_provider_network; then
         sudo ovs-vsctl add-port $OVS_PHYSICAL_BRIDGE $PUBLIC_INTERFACE
@@ -612,24 +612,24 @@
     fi
 
     if is_service_enabled q-vpn; then
-        screen_it q-vpn "cd $NEUTRON_DIR && $AGENT_VPN_BINARY $(determine_config_files neutron-vpn-agent)"
+        run_process q-vpn "$AGENT_VPN_BINARY $(determine_config_files neutron-vpn-agent)"
     else
-        screen_it q-l3 "cd $NEUTRON_DIR && python $AGENT_L3_BINARY $(determine_config_files neutron-l3-agent)"
+        run_process q-l3 "python $AGENT_L3_BINARY $(determine_config_files neutron-l3-agent)"
     fi
 
-    screen_it q-meta "cd $NEUTRON_DIR && python $AGENT_META_BINARY --config-file $NEUTRON_CONF --config-file=$Q_META_CONF_FILE"
+    run_process q-meta "python $AGENT_META_BINARY --config-file $NEUTRON_CONF --config-file=$Q_META_CONF_FILE"
 
     if [ "$VIRT_DRIVER" = 'xenserver' ]; then
         # For XenServer, start an agent for the domU openvswitch
-        screen_it q-domua "cd $NEUTRON_DIR && python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE.domU"
+        run_process q-domua "python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE.domU"
     fi
 
     if is_service_enabled q-lbaas; then
-        screen_it q-lbaas "cd $NEUTRON_DIR && python $AGENT_LBAAS_BINARY --config-file $NEUTRON_CONF --config-file=$LBAAS_AGENT_CONF_FILENAME"
+        run_process q-lbaas "python $AGENT_LBAAS_BINARY --config-file $NEUTRON_CONF --config-file=$LBAAS_AGENT_CONF_FILENAME"
     fi
 
     if is_service_enabled q-metering; then
-        screen_it q-metering "cd $NEUTRON_DIR && python $AGENT_METERING_BINARY --config-file $NEUTRON_CONF --config-file $METERING_AGENT_CONF_FILENAME"
+        run_process q-metering "python $AGENT_METERING_BINARY --config-file $NEUTRON_CONF --config-file $METERING_AGENT_CONF_FILENAME"
     fi
 }
 
diff --git a/lib/neutron_thirdparty/README.md b/lib/neutron_thirdparty/README.md
index 2460e5c..5655e0b 100644
--- a/lib/neutron_thirdparty/README.md
+++ b/lib/neutron_thirdparty/README.md
@@ -28,12 +28,14 @@
   git clone xxx
 
 * ``start_<third_party>``:
-  start running processes, including screen
+  start running processes, including screen if USE_SCREEN=True
   e.g.
-  screen_it XXXX "cd $XXXXY_DIR && $XXXX_DIR/bin/XXXX-bin"
+  run_process XXXX "$XXXX_DIR/bin/XXXX-bin"
 
 * ``stop_<third_party>``:
   stop running processes (non-screen)
+  e.g.
+  stop_process XXXX
 
 * ``check_<third_party>``:
   verify that the integration between neutron server and third-party components is sane
diff --git a/lib/neutron_thirdparty/ryu b/lib/neutron_thirdparty/ryu
index c737600..233f3aa 100644
--- a/lib/neutron_thirdparty/ryu
+++ b/lib/neutron_thirdparty/ryu
@@ -64,7 +64,7 @@
 }
 
 function start_ryu {
-    screen_it ryu "cd $RYU_DIR && $RYU_DIR/bin/ryu-manager --config-file $RYU_CONF"
+    run_process ryu "$RYU_DIR/bin/ryu-manager --config-file $RYU_CONF"
 }
 
 function stop_ryu {
diff --git a/lib/nova b/lib/nova
index b3a586c..1c1ab8c 100644
--- a/lib/nova
+++ b/lib/nova
@@ -39,6 +39,7 @@
 NOVA_CONF_DIR=/etc/nova
 NOVA_CONF=$NOVA_CONF_DIR/nova.conf
 NOVA_CELLS_CONF=$NOVA_CONF_DIR/nova-cells.conf
+NOVA_FAKE_CONF=$NOVA_CONF_DIR/nova-fake.conf
 NOVA_CELLS_DB=${NOVA_CELLS_DB:-nova_cell}
 
 NOVA_API_PASTE_INI=${NOVA_API_PASTE_INI:-$NOVA_CONF_DIR/api-paste.ini}
@@ -648,7 +649,7 @@
         service_port=$NOVA_SERVICE_PORT_INT
     fi
 
-    screen_it n-api "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-api"
+    run_process n-api "$NOVA_BIN_DIR/nova-api"
     echo "Waiting for nova-api to start..."
     if ! wait_for_service $SERVICE_TIMEOUT http://$SERVICE_HOST:$service_port; then
         die $LINENO "nova-api did not start"
@@ -670,18 +671,24 @@
 
     if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
         # The group **$LIBVIRT_GROUP** is added to the current user in this script.
-        # Use 'sg' to execute nova-compute as a member of the **$LIBVIRT_GROUP** group.
-        screen_it n-cpu "cd $NOVA_DIR && sg $LIBVIRT_GROUP '$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf'"
+        # sg' will be used in run_process to execute nova-compute as a member of the
+        # **$LIBVIRT_GROUP** group.
+        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf" $LIBVIRT_GROUP
     elif [[ "$VIRT_DRIVER" = 'fake' ]]; then
         local i
         for i in `seq 1 $NUMBER_FAKE_NOVA_COMPUTE`; do
-            screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf --config-file <(echo -e '[DEFAULT]\nhost=${HOSTNAME}${i}')"
+            # Avoid process redirection of fake host configurations by
+            # creating or modifying real configurations. Each fake
+            # gets its own configuration and own log file.
+            local fake_conf="${NOVA_FAKE_CONF}-${i}"
+            iniset $fake_conf DEFAULT nhost "${HOSTNAME}${i}"
+            run_process "n-cpu-${i}" "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf --config-file $fake_conf"
         done
     else
         if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
             start_nova_hypervisor
         fi
-        screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf"
+        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf"
     fi
 }
 
@@ -694,25 +701,25 @@
         local compute_cell_conf=$NOVA_CONF
     fi
 
-    # ``screen_it`` checks ``is_service_enabled``, it is not needed here
-    screen_it n-cond "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-conductor --config-file $compute_cell_conf"
-    screen_it n-cell-region "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-cells --config-file $api_cell_conf"
-    screen_it n-cell-child "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-cells --config-file $compute_cell_conf"
+    # ``run_process`` checks ``is_service_enabled``, it is not needed here
+    run_process n-cond "$NOVA_BIN_DIR/nova-conductor --config-file $compute_cell_conf"
+    run_process n-cell-region "$NOVA_BIN_DIR/nova-cells --config-file $api_cell_conf"
+    run_process n-cell-child "$NOVA_BIN_DIR/nova-cells --config-file $compute_cell_conf"
 
-    screen_it n-crt "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-cert --config-file $api_cell_conf"
-    screen_it n-net "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-network --config-file $compute_cell_conf"
-    screen_it n-sch "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-scheduler --config-file $compute_cell_conf"
-    screen_it n-api-meta "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-api-metadata --config-file $compute_cell_conf"
+    run_process n-crt "$NOVA_BIN_DIR/nova-cert --config-file $api_cell_conf"
+    run_process n-net "$NOVA_BIN_DIR/nova-network --config-file $compute_cell_conf"
+    run_process n-sch "$NOVA_BIN_DIR/nova-scheduler --config-file $compute_cell_conf"
+    run_process n-api-meta "$NOVA_BIN_DIR/nova-api-metadata --config-file $compute_cell_conf"
 
-    screen_it n-novnc "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-novncproxy --config-file $api_cell_conf --web $NOVNC_WEB_DIR"
-    screen_it n-xvnc "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-xvpvncproxy --config-file $api_cell_conf"
-    screen_it n-spice "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-spicehtml5proxy --config-file $api_cell_conf --web $SPICE_WEB_DIR"
-    screen_it n-cauth "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-consoleauth --config-file $api_cell_conf"
+    run_process n-novnc "$NOVA_BIN_DIR/nova-novncproxy --config-file $api_cell_conf --web $NOVNC_WEB_DIR"
+    run_process n-xvnc "$NOVA_BIN_DIR/nova-xvpvncproxy --config-file $api_cell_conf"
+    run_process n-spice "$NOVA_BIN_DIR/nova-spicehtml5proxy --config-file $api_cell_conf --web $SPICE_WEB_DIR"
+    run_process n-cauth "$NOVA_BIN_DIR/nova-consoleauth --config-file $api_cell_conf"
 
     # Starting the nova-objectstore only if swift3 service is not enabled.
     # Swift will act as s3 objectstore.
     is_service_enabled swift3 || \
-        screen_it n-obj "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-objectstore --config-file $api_cell_conf"
+        run_process n-obj "$NOVA_BIN_DIR/nova-objectstore --config-file $api_cell_conf"
 }
 
 function start_nova {
@@ -721,7 +728,7 @@
 }
 
 function stop_nova_compute {
-    screen_stop n-cpu
+    stop_process n-cpu
     if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
         stop_nova_hypervisor
     fi
@@ -732,7 +739,7 @@
     # Some services are listed here twice since more than one instance
     # of a service may be running in certain configs.
     for serv in n-api n-crt n-net n-sch n-novnc n-xvnc n-cauth n-spice n-cond n-cell n-cell n-api-meta n-obj; do
-        screen_stop $serv
+        stop_process $serv
     done
 }
 
diff --git a/lib/opendaylight b/lib/opendaylight
index 33b3f0a..1541ac1 100644
--- a/lib/opendaylight
+++ b/lib/opendaylight
@@ -139,6 +139,8 @@
     # The flags to ODL have the following meaning:
     #   -of13: runs ODL using OpenFlow 1.3 protocol support.
     #   -virt ovsdb: Runs ODL in "virtualization" mode with OVSDB support
+    # NOTE(chdent): Leaving this as screen_it instead of run_process until
+    # the right thing for this service is determined.
     screen_it odl-server "cd $ODL_DIR/opendaylight && JAVA_HOME=$JHOME ./run.sh $ODL_ARGS -of13 -virt ovsdb"
 
     # Sleep a bit to let OpenDaylight finish starting up
@@ -147,7 +149,7 @@
 
 # stop_opendaylight() - Stop running processes (non-screen)
 function stop_opendaylight {
-    screen_stop odl-server
+    stop_process odl-server
 }
 
 # stop_opendaylight-compute() - Remove OVS bridges
diff --git a/lib/sahara b/lib/sahara
index 70319d9..b50ccde 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -168,7 +168,7 @@
 
 # start_sahara() - Start running processes, including screen
 function start_sahara {
-    screen_it sahara "cd $SAHARA_DIR && $SAHARA_BIN_DIR/sahara-all --config-file $SAHARA_CONF_FILE"
+    run_process sahara "$SAHARA_BIN_DIR/sahara-all --config-file $SAHARA_CONF_FILE"
 }
 
 # stop_sahara() - Stop running processes
diff --git a/lib/swift b/lib/swift
index b050b57..13f4307 100644
--- a/lib/swift
+++ b/lib/swift
@@ -659,10 +659,10 @@
     if [ "$SWIFT_USE_MOD_WSGI" == "True" ]; then
         restart_apache_server
         swift-init --run-dir=${SWIFT_DATA_DIR}/run rest start
-        screen_it s-proxy "cd $SWIFT_DIR && sudo tail -f /var/log/$APACHE_NAME/proxy-server"
+        tail_log s-proxy /var/log/$APACHE_NAME/proxy-server
         if [[ ${SWIFT_REPLICAS} == 1 ]]; then
             for type in object container account; do
-                screen_it s-${type} "cd $SWIFT_DIR && sudo tail -f /var/log/$APACHE_NAME/${type}-server-1"
+                tail_log s-${type} /var/log/$APACHE_NAME/${type}-server-1
             done
         fi
         return 0
@@ -683,10 +683,10 @@
     for type in proxy ${todo}; do
         swift-init --run-dir=${SWIFT_DATA_DIR}/run ${type} stop || true
     done
-    screen_it s-proxy "cd $SWIFT_DIR && $SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
+    run_process s-proxy "$SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
     if [[ ${SWIFT_REPLICAS} == 1 ]]; then
         for type in object container account; do
-            screen_it s-${type} "cd $SWIFT_DIR && $SWIFT_DIR/bin/swift-${type}-server ${SWIFT_CONF_DIR}/${type}-server/1.conf -v"
+            run_process s-${type} "$SWIFT_DIR/bin/swift-${type}-server ${SWIFT_CONF_DIR}/${type}-server/1.conf -v"
         done
     fi
 
@@ -708,9 +708,9 @@
         swift-init --run-dir=${SWIFT_DATA_DIR}/run all stop || true
     fi
     # Dump all of the servers
-    # Maintain the iteration as screen_stop() has some desirable side-effects
+    # Maintain the iteration as stop_process() has some desirable side-effects
     for type in proxy object container account; do
-        screen_stop s-${type}
+        stop_process s-${type}
     done
     # Blast out any stragglers
     pkill -f swift-
diff --git a/lib/template b/lib/template
index efe5826..f77409b 100644
--- a/lib/template
+++ b/lib/template
@@ -75,13 +75,17 @@
 
 # start_XXXX() - Start running processes, including screen
 function start_XXXX {
-    # screen_it XXXX "cd $XXXX_DIR && $XXXX_DIR/bin/XXXX-bin"
+    # The quoted command must be a single command and not include an
+    # shell metacharacters, redirections or shell builtins.
+    # run_process XXXX "$XXXX_DIR/bin/XXXX-bin"
     :
 }
 
 # stop_XXXX() - Stop running processes (non-screen)
 function stop_XXXX {
-    # FIXME(dtroyer): stop only our screen screen window?
+    # for serv in serv-a serv-b; do
+    #     stop_process $serv
+    # done
     :
 }
 
diff --git a/lib/trove b/lib/trove
index aa9442b..8628e35 100644
--- a/lib/trove
+++ b/lib/trove
@@ -228,9 +228,9 @@
 
 # start_trove() - Start running processes, including screen
 function start_trove {
-    screen_it tr-api "cd $TROVE_DIR; $TROVE_BIN_DIR/trove-api --config-file=$TROVE_CONF_DIR/trove.conf --debug 2>&1"
-    screen_it tr-tmgr "cd $TROVE_DIR; $TROVE_BIN_DIR/trove-taskmanager --config-file=$TROVE_CONF_DIR/trove-taskmanager.conf --debug 2>&1"
-    screen_it tr-cond "cd $TROVE_DIR; $TROVE_BIN_DIR/trove-conductor --config-file=$TROVE_CONF_DIR/trove-conductor.conf --debug 2>&1"
+    run_process tr-api "$TROVE_BIN_DIR/trove-api --config-file=$TROVE_CONF_DIR/trove.conf --debug"
+    run_process tr-tmgr "$TROVE_BIN_DIR/trove-taskmanager --config-file=$TROVE_CONF_DIR/trove-taskmanager.conf --debug"
+    run_process tr-cond "$TROVE_BIN_DIR/trove-conductor --config-file=$TROVE_CONF_DIR/trove-conductor.conf --debug"
 }
 
 # stop_trove() - Stop running processes
@@ -238,7 +238,7 @@
     # Kill the trove screen windows
     local serv
     for serv in tr-api tr-tmgr tr-cond; do
-        screen_stop $serv
+        stop_process $serv
     done
 }
 
diff --git a/lib/zaqar b/lib/zaqar
index 0d33df2..33f1092 100644
--- a/lib/zaqar
+++ b/lib/zaqar
@@ -162,9 +162,9 @@
 # start_zaqar() - Start running processes, including screen
 function start_zaqar {
     if [[ "$USE_SCREEN" = "False" ]]; then
-        screen_it zaqar-server "zaqar-server --config-file $ZAQAR_CONF --daemon"
+        run_process zaqar-server "zaqar-server --config-file $ZAQAR_CONF --daemon"
     else
-        screen_it zaqar-server "zaqar-server --config-file $ZAQAR_CONF"
+        run_process zaqar-server "zaqar-server --config-file $ZAQAR_CONF"
     fi
 
     echo "Waiting for Zaqar to start..."