diff options
| author | bwarsaw | 2001-07-05 21:56:26 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-07-05 21:56:26 +0000 |
| commit | eb40912beae8b5ca3509d802157b505da025a5c2 (patch) | |
| tree | acb091167b55315b960821882d4902574d6206cc | |
| parent | 3ab72883512e8d360c0ed216797e0763a4c8a8f3 (diff) | |
| download | mailman-eb40912beae8b5ca3509d802157b505da025a5c2.tar.gz mailman-eb40912beae8b5ca3509d802157b505da025a5c2.tar.zst mailman-eb40912beae8b5ca3509d802157b505da025a5c2.zip | |
intermediate
| -rw-r--r-- | bin/mailmanctl | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/bin/mailmanctl b/bin/mailmanctl new file mode 100644 index 000000000..73312415e --- /dev/null +++ b/bin/mailmanctl @@ -0,0 +1,169 @@ +#! /usr/bin/env python + +# Copyright (C) 2001 by the Free Software Foundation, 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 the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +"""Primary start-up and shutdown script for Mailman's qrunner daemon. + +This script is intended to be run as an init script. It simply makes sure +that the various long-running qrunners are still alive and kicking. It does +this by forking the individual qrunners and waiting on their pids. When it +detects a subprocess has exited, it will restart it (unless the -n option is +given). + +The master qrunner will leave its process id in the file data/qrunner.pid +which can be used to shutdown or HUP the qrunner daemon. Sending a SIGINT to +the master qrunner causes it and all sub-qrunners to exit. This is equivalent +to the `stop' command. Sending a SIGHUP causes the master to re-open all of +its log files, and to SIGINT kill and restart all sub-qrunners processes. +This is equivalent to the `restart' command. + +Usage: %(PROGRAM)s [options] [ start | stop | restart ] + +Options: + + -n/--no-restart + Don't restart queue runners when they exit because of an error. Use + this only for debugging. Only useful if the `start' command is given. + + -h/--help + Print this message and exit. + +Commands: + + start - Start the master qrunner daemon. Prints a message and returns + if the master qrunner daemon is already running. + + stop - Stops the master qrunner daemon and all worker qrunners. After + stopping, no more messages will be processed. + + restart - Restarts the master qrunner daemon by sending it a SIGHUP. This + will cause all worker qrunners to be stopped and restarted, and + will cause any log files open by the master qrunner to be + re-opened. +""" + +import sys +import os +import getopt +import signal +import errno + +import paths +from Mailman import mm_cfg +from Mailman import LockFile +from Mailman.Queue import Control +from Mailman.i18n import _ + +PROGRAM = sys.argv[0] +COMMASPACE = ', ' + + + +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) + if msg: + print >> sys.stderr, msg + sys.exit(code) + + + +def kill_subrunners(sig): + try: + fp = open(mm_cfg.PIDFILE) + pidstr = fp.read() + fp.close() + pid = int(pidstr.strip()) + except (IOError, ValueError), e: + # For i18n convenience + pidfile = mm_cfg.PIDFILE + print >> sys.stderr, _('PID unreadable in: %(pidfile)s') + print >> sys.stderr, e + print >> sys.stderr, 'Is qrunner even running?' + return + try: + os.kill(pid, sig) + except OSError, e: + if e.errno <> errno.ESRCH: raise + print >> sys.stderr, _('No child with pid: %(pid)s') + print >> sys.stderr, e + print >> sys.stderr, 'Stale pid file removed.' + os.unlink(mm_cfg.PIDFILE) + + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], 'hn', + ['help', 'no-start']) + except getopt.error, msg: + usage(1, msg) + + restart = 1 + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-n', '--no-restart'): + restart = 0 + + if len(args) < 1: + usage(1, _('No command given.')) + elif len(args) > 1: + command = COMMASPACE.join(args) + usage(1, _('Bad command: %(command)s')) + + command = args[0].lower() + if command not in ('start', 'stop', 'restart'): + usage(1, _('Bad command: %(command)s')) + + # Handle the commands + if command == 'stop': + # Sent the master qrunner process a SIGINT, which is equivalent to + # giving cron/qrunner a ctrl-c or KeyboardInterrupt. This will + # effectively shut everything down. + kill_subrunners(signal.SIGINT) + elif command == 'restart': + # Sent the master qrunner process a SIGHUP. This will cause the + # master qrunner to kill and restart all the worker qrunners, and to + # close and re-open its log files. + kill_subrunners(signal.SIGHUP) + else: + # Must be `start' + # + # Daemon process startup according to Stevens, Advanced Programming in + # the UNIX Environment, Chapter 13. + if os.fork(): + # parent + sys.exit(0) + # child + # + # Create a new session and become the session leader, but since we + # won't be opening any terminal devices, don't do the ultra-paranoid + # suggestion of doing a second fork after the setsid() call. + os.setsid() + # Instead of cd'ing to root, cd to the Mailman installation home + os.chdir(mm_cfg.PREFIX) + # Clear our file mode creation umask + os.umask(0) + # I don't think we have any unneeded file descriptors. + try: + Control.start(restart) + except LockFile.TimeOutError: + print >> sys.stderr, 'Another qrunner is already running, exiting.' + + + +if __name__ == '__main__': + main() |
