summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw2001-07-05 21:56:26 +0000
committerbwarsaw2001-07-05 21:56:26 +0000
commiteb40912beae8b5ca3509d802157b505da025a5c2 (patch)
treeacb091167b55315b960821882d4902574d6206cc
parent3ab72883512e8d360c0ed216797e0763a4c8a8f3 (diff)
downloadmailman-eb40912beae8b5ca3509d802157b505da025a5c2.tar.gz
mailman-eb40912beae8b5ca3509d802157b505da025a5c2.tar.zst
mailman-eb40912beae8b5ca3509d802157b505da025a5c2.zip
intermediate
-rw-r--r--bin/mailmanctl169
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()