Commit b42ea9ed authored by Iustin Pop's avatar Iustin Pop
Browse files

Change utils.GenericMain protocol



Currently, GenericMain does a two-staged workflow:

- Check, before forking
- then Exec, after forking

This means we don't have any possibility to treat preparation work
(before the daemon is ready for work) different from the actual work.

The patch adds another PreExec function that is run just before Exec,
and which should ensure that the daemon is ready for serving client
before it returns. Its result is then sent as the third argument to
Exec.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 5c4d37f9
......@@ -258,7 +258,7 @@ def CheckConfd(_, args):
# conflict with that. If so, we might warn or EXIT_FAILURE.
def ExecConfd(options, _):
def ExecConfd(options, _dummy1, _dummy2):
"""Main confd function, executed with PID file held
"""
......@@ -293,7 +293,7 @@ def main():
version="%%prog (ganeti) %s" %
constants.RELEASE_VERSION)
daemon.GenericMain(constants.CONFD, parser, CheckConfd, ExecConfd)
daemon.GenericMain(constants.CONFD, parser, CheckConfd, None, ExecConfd)
if __name__ == "__main__":
......
......@@ -530,7 +530,7 @@ def CheckMasterd(options, args):
utils.RunInSeparateProcess(ActivateMasterIP)
def ExecMasterd(options, args): # pylint: disable-msg=W0613
def ExecMasterd(options, args, _): # pylint: disable-msg=W0613
"""Main master daemon function, executed with the PID file held.
"""
......@@ -568,8 +568,8 @@ def main():
parser.add_option("--yes-do-it", dest="yes_do_it",
help="Override interactive check for --no-voting",
default=False, action="store_true")
daemon.GenericMain(constants.MASTERD, parser, CheckMasterd, ExecMasterd,
multithreaded=True)
daemon.GenericMain(constants.MASTERD, parser, CheckMasterd, None,
ExecMasterd, multithreaded=True)
if __name__ == "__main__":
......
......@@ -914,7 +914,7 @@ def CheckNoded(_, args):
sys.exit(constants.EXIT_FAILURE)
def ExecNoded(options, _):
def ExecNoded(options, _dummy1, _dummy2):
"""Main node daemon function, executed with the PID file held.
"""
......@@ -965,7 +965,7 @@ def main():
help="Do not mlock the node memory in ram",
default=True, action="store_false")
daemon.GenericMain(constants.NODED, parser, CheckNoded, ExecNoded,
daemon.GenericMain(constants.NODED, parser, CheckNoded, None, ExecNoded,
default_ssl_cert=constants.NODED_CERT_FILE,
default_ssl_key=constants.NODED_CERT_FILE,
console_logging=True)
......
#!/usr/bin/python
#
# Copyright (C) 2006, 2007 Google Inc.
# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -280,7 +280,7 @@ def CheckRapi(options, args):
options.ssl_params = None
def ExecRapi(options, _):
def ExecRapi(options, _dummy1, _dummy2):
"""Main remote API function, executed with the PID file held.
"""
......@@ -315,7 +315,7 @@ def main():
usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
version="%%prog (ganeti) %s" % constants.RELEASE_VERSION)
daemon.GenericMain(constants.RAPI, parser, CheckRapi, ExecRapi,
daemon.GenericMain(constants.RAPI, parser, CheckRapi, None, ExecRapi,
default_ssl_cert=constants.RAPI_CERT_FILE,
default_ssl_key=constants.RAPI_CERT_FILE)
......
......@@ -512,7 +512,8 @@ def _VerifyDaemonUser(daemon_name):
daemon_uids[daemon_name])
def GenericMain(daemon_name, optionparser, check_fn, exec_fn,
def GenericMain(daemon_name, optionparser,
check_fn, prepare_fn, exec_fn,
multithreaded=False, console_logging=False,
default_ssl_cert=None, default_ssl_key=None):
"""Shared main function for daemons.
......@@ -525,7 +526,11 @@ def GenericMain(daemon_name, optionparser, check_fn, exec_fn,
@type check_fn: function which accepts (options, args)
@param check_fn: function that checks start conditions and exits if they're
not met
@type exec_fn: function which accepts (options, args)
@type prepare_fn: function which accepts (options, args)
@param prepare_fn: function that is run before forking, or None;
it's result will be passed as the third parameter to exec_fn, or
if None was passed in, we will just pass None to exec_fn
@type exec_fn: function which accepts (options, args, prepare_results)
@param exec_fn: function that's executed with the daemon's pid file held, and
runs the daemon itself.
@type multithreaded: bool
......@@ -631,6 +636,11 @@ def GenericMain(daemon_name, optionparser, check_fn, exec_fn,
syslog=options.syslog,
console_logging=console_logging)
logging.info("%s daemon startup", daemon_name)
exec_fn(options, args)
if callable(prepare_fn):
prep_results = prepare_fn(options, args)
else:
prep_results = None
exec_fn(options, args, prep_results)
finally:
utils.RemovePidFile(daemon_name)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment