Browse code

Robustify service shutdown

* Save PID when using screen in screen_it()
* Add screen_stop()
* Call out service stop_*() in unstack.sh functions so screen_stop()
can do its thing

Closes-bug: 1183449
Change-Id: Iac84231cfda960c4197de5b6e8ba6eb19225169a

Dean Troyer authored on 2013/05/23 07:19:06
Showing 10 changed files
... ...
@@ -1132,10 +1132,39 @@ function screen_it {
1132 1132
             sleep 1.5
1133 1133
 
1134 1134
             NL=`echo -ne '\015'`
1135
-            screen -S $SCREEN_NAME -p $1 -X stuff "$2 || echo \"$1 failed to start\" | tee \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
1135
+            # This fun command does the following:
1136
+            # - the passed server command is backgrounded
1137
+            # - the pid of the background process is saved in the usual place
1138
+            # - the server process is brought back to the foreground
1139
+            # - if the server process exits prematurely the fg command errors
1140
+            #   and a message is written to stdout and the service failure file
1141
+            # The pid saved can be used in screen_stop() as a process group
1142
+            # id to kill off all child processes
1143
+            screen -S $SCREEN_NAME -p $1 -X stuff "$2 & echo \$! >$SERVICE_DIR/$SCREEN_NAME/$1.pid; fg || echo \"$1 failed to start\" | tee \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
1136 1144
         else
1137 1145
             # Spawn directly without screen
1138
-            run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$service.pid
1146
+            run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$1.pid
1147
+        fi
1148
+    fi
1149
+}
1150
+
1151
+
1152
+# Stop a service in screen
1153
+# screen_stop service
1154
+function screen_stop() {
1155
+    SCREEN_NAME=${SCREEN_NAME:-stack}
1156
+    SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
1157
+    USE_SCREEN=$(trueorfalse True $USE_SCREEN)
1158
+
1159
+    if is_service_enabled $1; then
1160
+        # Kill via pid if we have one available
1161
+        if [[ -r $SERVICE_DIR/$SCREEN_NAME/$1.pid ]]; then
1162
+            pkill -TERM -P $(cat $SERVICE_DIR/$SCREEN_NAME/$1.pid)
1163
+            rm $SERVICE_DIR/$SCREEN_NAME/$1.pid
1164
+        fi
1165
+        if [[ "$USE_SCREEN" = "True" ]]; then
1166
+            # Clean up the screen window
1167
+            screen -S $SCREEN_NAME -p $1 -X kill
1139 1168
         fi
1140 1169
     fi
1141 1170
 }
... ...
@@ -162,7 +162,7 @@ function start_ceilometer() {
162 162
 function stop_ceilometer() {
163 163
     # Kill the ceilometer screen windows
164 164
     for serv in ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-evaluator; do
165
-        screen -S $SCREEN_NAME -p $serv -X kill
165
+        screen_stop $serv
166 166
     done
167 167
 }
168 168
 
... ...
@@ -556,7 +556,7 @@ function start_cinder() {
556 556
 function stop_cinder() {
557 557
     # Kill the cinder screen windows
558 558
     for serv in c-api c-bak c-sch c-vol; do
559
-        screen -S $SCREEN_NAME -p $serv -X kill
559
+        screen_stop $serv
560 560
     done
561 561
 
562 562
     if is_service_enabled c-vol; then
... ...
@@ -206,8 +206,8 @@ function start_glance() {
206 206
 # stop_glance() - Stop running processes
207 207
 function stop_glance() {
208 208
     # Kill the Glance screen windows
209
-    screen -S $SCREEN_NAME -p g-api -X kill
210
-    screen -S $SCREEN_NAME -p g-reg -X kill
209
+    screen_stop g-api
210
+    screen_stop g-reg
211 211
 }
212 212
 
213 213
 
... ...
@@ -175,7 +175,7 @@ function start_heat() {
175 175
 function stop_heat() {
176 176
     # Kill the screen windows
177 177
     for serv in h-eng h-api h-api-cfn h-api-cw; do
178
-        screen -S $SCREEN_NAME -p $serv -X kill
178
+        screen_stop $serv
179 179
     done
180 180
 }
181 181
 
... ...
@@ -421,7 +421,7 @@ function start_keystone() {
421 421
 # stop_keystone() - Stop running processes
422 422
 function stop_keystone() {
423 423
     # Kill the Keystone screen window
424
-    screen -S $SCREEN_NAME -p key -X kill
424
+    screen_stop key
425 425
 }
426 426
 
427 427
 
... ...
@@ -705,7 +705,7 @@ function stop_nova() {
705 705
     # Some services are listed here twice since more than one instance
706 706
     # of a service may be running in certain configs.
707 707
     for serv in n-api n-cpu n-crt n-net n-sch n-novnc n-xvnc n-cauth n-spice n-cond n-cell n-cell n-api-meta; do
708
-        screen -S $SCREEN_NAME -p $serv -X kill
708
+        screen_stop $serv
709 709
     done
710 710
     if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
711 711
         stop_nova_hypervisor
... ...
@@ -198,7 +198,7 @@ function start_trove() {
198 198
 function stop_trove() {
199 199
     # Kill the trove screen windows
200 200
     for serv in tr-api tr-tmgr tr-cond; do
201
-        screen -S $SCREEN_NAME -p $serv -X kill
201
+        screen_stop $serv
202 202
     done
203 203
 }
204 204
 
... ...
@@ -9,6 +9,9 @@ DEST=/opt/stack
9 9
 # Destination for working data
10 10
 DATA_DIR=${DEST}/data
11 11
 
12
+# Destination for status files
13
+SERVICE_DIR=${DEST}/status
14
+
12 15
 # Determine stack user
13 16
 if [[ $EUID -eq 0 ]]; then
14 17
     STACK_USER=stack
... ...
@@ -36,6 +36,9 @@ source $TOP_DIR/lib/apache
36 36
 # Get project function libraries
37 37
 source $TOP_DIR/lib/baremetal
38 38
 source $TOP_DIR/lib/cinder
39
+source $TOP_DIR/lib/keystone
40
+source $TOP_DIR/lib/glance
41
+source $TOP_DIR/lib/nova
39 42
 source $TOP_DIR/lib/horizon
40 43
 source $TOP_DIR/lib/swift
41 44
 source $TOP_DIR/lib/neutron
... ...
@@ -75,21 +78,29 @@ if [[ "$Q_USE_DEBUG_COMMAND" == "True" ]]; then
75 75
     teardown_neutron_debug
76 76
 fi
77 77
 
78
-# Shut down devstack's screen to get the bulk of OpenStack services in one shot
79
-SCREEN=$(which screen)
80
-if [[ -n "$SCREEN" ]]; then
81
-    SESSION=$(screen -ls | awk '/[0-9].stack/ { print $1 }')
82
-    if [[ -n "$SESSION" ]]; then
83
-        screen -X -S $SESSION quit
84
-    fi
78
+# Call service stop
79
+if is_service_enabled trove; then
80
+    stop_trove
81
+fi
82
+
83
+if is_service_enabled heat; then
84
+    stop_heat
85 85
 fi
86 86
 
87
-# Shut down Nova hypervisor plugins after Nova
88
-NOVA_PLUGINS=$TOP_DIR/lib/nova_plugins
89
-if is_service_enabled nova && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
90
-    # Load plugin
91
-    source $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER
92
-    stop_nova_hypervisor
87
+if is_service_enabled ceilometer; then
88
+    stop_ceilometer
89
+fi
90
+
91
+if is_service_enabled nova; then
92
+    stop_nova
93
+fi
94
+
95
+if is_service_enabled g-api g-reg; then
96
+    stop_glance
97
+fi
98
+
99
+if is_service_enabled key; then
100
+    stop_keystone
93 101
 fi
94 102
 
95 103
 # Swift runs daemons
... ...
@@ -123,6 +134,7 @@ SCSI_PERSIST_DIR=$CINDER_STATE_PATH/volumes/*
123 123
 
124 124
 # Get the iSCSI volumes
125 125
 if is_service_enabled cinder; then
126
+    stop_cinder
126 127
     cleanup_cinder
127 128
 fi
128 129
 
... ...
@@ -152,4 +164,13 @@ if is_service_enabled trove; then
152 152
     cleanup_trove
153 153
 fi
154 154
 
155
+# Clean up the remainder of the screen processes
156
+SCREEN=$(which screen)
157
+if [[ -n "$SCREEN" ]]; then
158
+    SESSION=$(screen -ls | awk '/[0-9].stack/ { print $1 }')
159
+    if [[ -n "$SESSION" ]]; then
160
+        screen -X -S $SESSION quit
161
+    fi
162
+fi
163
+
155 164
 cleanup_tmp