Browse Source

Handle SIGTERM to shut down gracefully

Apparently, fuel-agent doesn't handle any signal received except for SIGINT
which is automatically converted by python to KeyboardInterrupt() exception.

fuel-agent is unable to send signal for spawned processes, just because
utils.execute doesn't know PIDs of opened subprocessess. To mitigate that flaw,
fuel-agent will use process group to distribute signals.

Process groups are used to control the distribution of signals.
A signal directed to a process group is delivered individually to all of the
processes that are members of the group.

That allows fuel-agent to send signals to subprocesses without knowing thier
exact PIDs.

Change-Id: Ie59c0425f031fa94e517b79df0a0fc3d0c3e7a07
Related-Bug: #1538645
changes/20/275820/4
Alexander Gordeev 5 years ago
parent
commit
c726948f17
1 changed files with 17 additions and 0 deletions
  1. +17
    -0
      fuel_agent/cmd/agent.py

+ 17
- 0
fuel_agent/cmd/agent.py View File

@ -12,12 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import signal
import sys
from oslo_config import cfg
import six
import yaml
from fuel_agent import errors
from fuel_agent import manager as manager
from fuel_agent.openstack.common import log as logging
from fuel_agent import version
@ -72,6 +75,16 @@ def print_err(line):
sys.stderr.write('\n')
def handle_sigterm(signum, frame):
# NOTE(agordeev): Since group pid of spawned subprocess is unknown,
# fuel-agent needs to ignore SIGTERM sent by itself.
signal.signal(signal.SIGTERM, signal.SIG_IGN)
print_err('SIGTERM RECEIVED. Propagating it to subprocesses')
os.killpg(os.getpid(), signal.SIGTERM)
raise errors.UnexpectedProcessError(
'Application was shut down gracefully')
def handle_exception(exc):
LOG = logging.getLogger(__name__)
LOG.exception(exc)
@ -81,6 +94,10 @@ def handle_exception(exc):
def main(actions=None):
# NOTE(agordeev): get its own process group by calling setpgrp.
# Process group is used to distribute signals to subprocesses.
os.setpgrp()
signal.signal(signal.SIGTERM, handle_sigterm)
CONF(sys.argv[1:], project='fuel-agent',
version=version.version_info.release_string())


Loading…
Cancel
Save