Folks, I've just released Mailman 2.0.5 which fixes a problem with stale lock files that can occur under certain situations when the user hits the `Stop' button on their browser. These stale lock files can cause mailing lists to be inaccessible for long periods of time (until the stale lock file times out or is manually removed). As usual, I'm releasing this as both a complete tarball and as a patch against Mailman 2.0.4. You /must/ update your source to 2.0.4 before applying the 2.0.5 patch. Since the patch is small, I'm including it in this message. To apply, cd into your 2.0.5 source tree and apply it like so: % patch -p0 < mailman-2.0.4-2.0.5.txt Currently both http://mailman.sourceforge.net and http://www.list.org are updated, and I expect the gnu.org site to be updated soon as well. The release information on SF is at http://sourceforge.net/project/shownotes.php?release_id=31693 See also http://www.gnu.org/software/mailman http://www.list.org http://mailman.sourceforge.net My thanks to those of you who gave the 2.0.5 pre-release a try! Enjoy, -Barry Index: NEWS =================================================================== RCS file: /cvsroot/mailman/mailman/NEWS,v retrieving revision 1.25.2.5 retrieving revision 1.25.2.6 diff -u -r1.25.2.5 -r1.25.2.6 --- NEWS 2001/04/18 10:45:54 1.25.2.5 +++ NEWS 2001/05/03 21:06:56 1.25.2.6 @@ -4,6 +4,13 @@ Here is a history of user visible changes to Mailman. +2.0.5 (04-May-2001) + + Fix a lock stagnation problem that can result when the user hits + the `stop' button on their browser during a write operation that + can take a long time (e.g. hitting the membership management admin + page). + 2.0.4 (18-Apr-2001) Python 2.1 compatibility release. There were a few questionable Index: Mailman/Version.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v retrieving revision 1.20.2.4 retrieving revision 1.20.2.5 diff -u -r1.20.2.4 -r1.20.2.5 --- Mailman/Version.py 2001/04/18 04:43:29 1.20.2.4 +++ Mailman/Version.py 2001/05/03 20:58:19 1.20.2.5 @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Mailman version -VERSION = "2.0.4" +VERSION = "2.0.5" # And as a hex number in the manner of PY_VERSION_HEX ALPHA = 0xa @@ -27,7 +27,7 @@ MAJOR_REV = 2 MINOR_REV = 0 -MICRO_REV = 4 +MICRO_REV = 5 REL_LEVEL = FINAL # at most 15 beta releases! REL_SERIAL = 0 Index: Mailman/Cgi/admin.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admin.py,v retrieving revision 1.82.2.2 retrieving revision 1.82.2.3 diff -u -r1.82.2.2 -r1.82.2.3 --- Mailman/Cgi/admin.py 2001/01/03 16:47:47 1.82.2.2 +++ Mailman/Cgi/admin.py 2001/05/03 21:03:48 1.82.2.3 @@ -18,11 +18,13 @@ """ +import sys import os import cgi import string import types import rfc822 +import signal from Mailman import Utils from Mailman import MailList @@ -63,53 +65,86 @@ # get the list object listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: FormatAdminOverview('No such list <em>%s</em>' % listname) syslog('error', 'Someone tried to access the admin interface for a ' 'non-existent list: %s' % listname) return + + if len(parts) == 1: + category = 'general' + category_suffix = '' + else: + category = parts[1] + category_suffix = category + + # If the user is not authenticated, we're done. + cgidata = cgi.FieldStorage(keep_blank_values=1) try: - if len(parts) == 1: - category = 'general' - category_suffix = '' - else: - category = parts[1] - category_suffix = category - - # If the user is not authenticated, we're done. - cgidata = cgi.FieldStorage(keep_blank_values=1) - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admin', e.message) - return - - # Is this a log-out request? - if category == 'logout': - print mlist.ZapCookie('admin') - Auth.loginpage(mlist, 'admin', frontpage=1) - return - - if category not in map(lambda x: x[0], CATEGORIES): - category = 'general' - - # is the request for variable details? - varhelp = None - if cgidata.has_key('VARHELP'): - varhelp = cgidata['VARHELP'].value - elif cgidata.has_key('request_login') and \ - os.environ.get('QUERY_STRING'): - # POST methods, even if their actions have a query string, don't - # get put into FieldStorage's keys :-( - qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') - if qs and type(qs) == types.ListType: - varhelp = qs[0] - if varhelp: - FormatOptionHelp(doc, varhelp, mlist) - print doc.Format(bgcolor="#ffffff") - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admin', e.message) + return + + # Is this a log-out request? + if category == 'logout': + print mlist.ZapCookie('admin') + Auth.loginpage(mlist, 'admin', frontpage=1) + return + + if category not in map(lambda x: x[0], CATEGORIES): + category = 'general' + # is the request for variable details? + varhelp = None + if cgidata.has_key('VARHELP'): + varhelp = cgidata['VARHELP'].value + elif cgidata.has_key('request_login') and \ + os.environ.get('QUERY_STRING'): + # POST methods, even if their actions have a query string, don't + # get put into FieldStorage's keys :-( + qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') + if qs and type(qs) == types.ListType: + varhelp = qs[0] + if varhelp: + FormatOptionHelp(doc, varhelp, mlist) + print doc.Format(bgcolor="#ffffff") + return + + # From this point on, the MailList object must be locked. However, we + # must release the lock no matter how we exit. try/finally isn't + # enough, because of this scenario: user hits the admin page which may + # take a long time to render; user gets bored and hits the browser's + # STOP button; browser shuts down socket; server tries to write to + # broken socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache + # catches this SIGPIPE (I presume it is buffering output from the cgi + # script), then turns around and SIGTERMs the cgi process. Apache + # waits three seconds and then SIGKILLs the cgi process. We /must/ + # catch the SIGTERM and do the most reasonable thing we can in as + # short a time period as possible. If we get the SIGKILL we're + # screwed (because its uncatchable and we'll have no opportunity to + # clean up after ourselves). + # + # This signal handler catches the SIGTERM and unlocks the list. The + # effect of this is that the changes made to the MailList object will + # be aborted, which seems like the only sensible semantics. + # + # BAW: This may not be portable to other web servers or cgi execution + # models. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + if cgidata.has_key('bounce_matching_headers'): pairs = mlist.parse_matching_header_opt() @@ -135,8 +170,12 @@ FormatConfiguration(doc, mlist, category, category_suffix, cgidata) print doc.Format(bgcolor="#ffffff") - finally: mlist.Save() + finally: + # Now be sure to unlock the list. It's okay if we get a signal here + # because essentially, the signal handler will do the same thing. And + # unlocking is unconditional, so it's not an error if we unlock while + # we're already unlocked. mlist.Unlock() Index: Mailman/Cgi/admindb.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admindb.py,v retrieving revision 1.36.2.1 retrieving revision 1.36.2.4 diff -u -r1.36.2.1 -r1.36.2.4 --- Mailman/Cgi/admindb.py 2001/03/03 06:02:01 1.36.2.1 +++ Mailman/Cgi/admindb.py 2001/05/04 15:54:23 1.36.2.4 @@ -16,10 +16,12 @@ """Produce and process the pending-approval items for a list.""" +import sys import os import string import types import cgi +import signal from errno import ENOENT from Mailman import mm_cfg @@ -62,7 +64,7 @@ return # now that we have the list name, create the list object try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: handle_no_list(doc, 'No such list <em>%s</em><p>' % listname) syslog('error', 'No such list "%s": %s\n' % (listname, e)) @@ -71,14 +73,34 @@ # now we must authorize the user to view this page, and if they are, to # handle both the printing of the current outstanding requests, and the # selected actions + cgidata = cgi.FieldStorage() try: - cgidata = cgi.FieldStorage() - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admindb', e.message) - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admindb', e.message) + return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + # If this is a form submission, then we'll process the requests and # print the results. otherwise (there are no keys in the form), we'll # print out the list of pending requests @@ -91,8 +113,8 @@ PrintRequests(mlist, doc) text = doc.Format(bgcolor="#ffffff") print text - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/handle_opts.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/handle_opts.py,v retrieving revision 1.30 retrieving revision 1.30.2.2 diff -u -r1.30 -r1.30.2.2 --- Mailman/Cgi/handle_opts.py 2000/11/09 16:19:03 1.30 +++ Mailman/Cgi/handle_opts.py 2001/05/03 21:05:06 1.30.2.2 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import mm_cfg from Mailman import Utils @@ -61,7 +62,7 @@ user = parts[1] try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) @@ -69,10 +70,30 @@ syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, user, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/subscribe.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/subscribe.py,v retrieving revision 1.29 retrieving revision 1.29.2.1 diff -u -r1.29 -r1.29.2.1 --- Mailman/Cgi/subscribe.py 2000/09/29 00:05:05 1.29 +++ Mailman/Cgi/subscribe.py 2001/05/03 21:05:43 1.29.2.1 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import Utils from Mailman import MailList @@ -41,18 +42,38 @@ listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) - mlist.IsListInitialized() + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) print doc.Format(bgcolor="#ffffff") syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: admin/www/download.ht =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v retrieving revision 1.5.2.5 retrieving revision 1.5.2.6 diff -u -r1.5.2.5 -r1.5.2.6 --- admin/www/download.ht 2001/04/18 10:44:14 1.5.2.5 +++ admin/www/download.ht 2001/05/03 21:09:36 1.5.2.6 @@ -65,9 +65,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul> Index: admin/www/download.html =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.html,v retrieving revision 1.6.2.7 retrieving revision 1.6.2.8 diff -u -r1.6.2.7 -r1.6.2.8 --- admin/www/download.html 2001/04/18 10:44:14 1.6.2.7 +++ admin/www/download.html 2001/05/03 21:09:36 1.6.2.8 @@ -1,6 +1,6 @@ <HTML> <!-- THIS PAGE IS AUTOMATICALLY GENERATED. DO NOT EDIT. --> -<!-- Wed Apr 18 06:43:32 2001 --> +<!-- Thu May 3 17:09:03 2001 --> <!-- USING HT2HTML 1.1 --> <!-- SEE http://www.wooz.org/barry/software/pyware.html --> <!-- User-specified headers: @@ -237,9 +237,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul>
When you say to CD into our sourcetree, is that the location where I originally compiled mailman or is that where I have the current working copy of the software? Joshua Erdman Ernest & Allen, Inc. CIO/Network Systems Administrator Tel (805) 781-0317 Fax (805) 781-0725 josh@ernestallen.com -----Original Message----- From: mailman-announce-admin@python.org [mailto:mailman-announce-admin@python.org]On Behalf Of Barry A. Warsaw Sent: Monday, May 07, 2001 9:24 AM To: mailman-announce@python.org Cc: mailman-developers@python.org Subject: [Mailman-Announce] ANNOUNCE Mailman 2.0.5 Folks, I've just released Mailman 2.0.5 which fixes a problem with stale lock files that can occur under certain situations when the user hits the `Stop' button on their browser. These stale lock files can cause mailing lists to be inaccessible for long periods of time (until the stale lock file times out or is manually removed). As usual, I'm releasing this as both a complete tarball and as a patch against Mailman 2.0.4. You /must/ update your source to 2.0.4 before applying the 2.0.5 patch. Since the patch is small, I'm including it in this message. To apply, cd into your 2.0.5 source tree and apply it like so: % patch -p0 < mailman-2.0.4-2.0.5.txt Currently both http://mailman.sourceforge.net and http://www.list.org are updated, and I expect the gnu.org site to be updated soon as well. The release information on SF is at http://sourceforge.net/project/shownotes.php?release_id=31693 See also http://www.gnu.org/software/mailman http://www.list.org http://mailman.sourceforge.net My thanks to those of you who gave the 2.0.5 pre-release a try! Enjoy, -Barry Index: NEWS =================================================================== RCS file: /cvsroot/mailman/mailman/NEWS,v retrieving revision 1.25.2.5 retrieving revision 1.25.2.6 diff -u -r1.25.2.5 -r1.25.2.6 --- NEWS 2001/04/18 10:45:54 1.25.2.5 +++ NEWS 2001/05/03 21:06:56 1.25.2.6 @@ -4,6 +4,13 @@ Here is a history of user visible changes to Mailman. +2.0.5 (04-May-2001) + + Fix a lock stagnation problem that can result when the user hits + the `stop' button on their browser during a write operation that + can take a long time (e.g. hitting the membership management admin + page). + 2.0.4 (18-Apr-2001) Python 2.1 compatibility release. There were a few questionable Index: Mailman/Version.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v retrieving revision 1.20.2.4 retrieving revision 1.20.2.5 diff -u -r1.20.2.4 -r1.20.2.5 --- Mailman/Version.py 2001/04/18 04:43:29 1.20.2.4 +++ Mailman/Version.py 2001/05/03 20:58:19 1.20.2.5 @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Mailman version -VERSION = "2.0.4" +VERSION = "2.0.5" # And as a hex number in the manner of PY_VERSION_HEX ALPHA = 0xa @@ -27,7 +27,7 @@ MAJOR_REV = 2 MINOR_REV = 0 -MICRO_REV = 4 +MICRO_REV = 5 REL_LEVEL = FINAL # at most 15 beta releases! REL_SERIAL = 0 Index: Mailman/Cgi/admin.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admin.py,v retrieving revision 1.82.2.2 retrieving revision 1.82.2.3 diff -u -r1.82.2.2 -r1.82.2.3 --- Mailman/Cgi/admin.py 2001/01/03 16:47:47 1.82.2.2 +++ Mailman/Cgi/admin.py 2001/05/03 21:03:48 1.82.2.3 @@ -18,11 +18,13 @@ """ +import sys import os import cgi import string import types import rfc822 +import signal from Mailman import Utils from Mailman import MailList @@ -63,53 +65,86 @@ # get the list object listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: FormatAdminOverview('No such list <em>%s</em>' % listname) syslog('error', 'Someone tried to access the admin interface for a ' 'non-existent list: %s' % listname) return + + if len(parts) == 1: + category = 'general' + category_suffix = '' + else: + category = parts[1] + category_suffix = category + + # If the user is not authenticated, we're done. + cgidata = cgi.FieldStorage(keep_blank_values=1) try: - if len(parts) == 1: - category = 'general' - category_suffix = '' - else: - category = parts[1] - category_suffix = category - - # If the user is not authenticated, we're done. - cgidata = cgi.FieldStorage(keep_blank_values=1) - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admin', e.message) - return - - # Is this a log-out request? - if category == 'logout': - print mlist.ZapCookie('admin') - Auth.loginpage(mlist, 'admin', frontpage=1) - return - - if category not in map(lambda x: x[0], CATEGORIES): - category = 'general' - - # is the request for variable details? - varhelp = None - if cgidata.has_key('VARHELP'): - varhelp = cgidata['VARHELP'].value - elif cgidata.has_key('request_login') and \ - os.environ.get('QUERY_STRING'): - # POST methods, even if their actions have a query string, don't - # get put into FieldStorage's keys :-( - qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') - if qs and type(qs) == types.ListType: - varhelp = qs[0] - if varhelp: - FormatOptionHelp(doc, varhelp, mlist) - print doc.Format(bgcolor="#ffffff") - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admin', e.message) + return + + # Is this a log-out request? + if category == 'logout': + print mlist.ZapCookie('admin') + Auth.loginpage(mlist, 'admin', frontpage=1) + return + + if category not in map(lambda x: x[0], CATEGORIES): + category = 'general' + # is the request for variable details? + varhelp = None + if cgidata.has_key('VARHELP'): + varhelp = cgidata['VARHELP'].value + elif cgidata.has_key('request_login') and \ + os.environ.get('QUERY_STRING'): + # POST methods, even if their actions have a query string, don't + # get put into FieldStorage's keys :-( + qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') + if qs and type(qs) == types.ListType: + varhelp = qs[0] + if varhelp: + FormatOptionHelp(doc, varhelp, mlist) + print doc.Format(bgcolor="#ffffff") + return + + # From this point on, the MailList object must be locked. However, we + # must release the lock no matter how we exit. try/finally isn't + # enough, because of this scenario: user hits the admin page which may + # take a long time to render; user gets bored and hits the browser's + # STOP button; browser shuts down socket; server tries to write to + # broken socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache + # catches this SIGPIPE (I presume it is buffering output from the cgi + # script), then turns around and SIGTERMs the cgi process. Apache + # waits three seconds and then SIGKILLs the cgi process. We /must/ + # catch the SIGTERM and do the most reasonable thing we can in as + # short a time period as possible. If we get the SIGKILL we're + # screwed (because its uncatchable and we'll have no opportunity to + # clean up after ourselves). + # + # This signal handler catches the SIGTERM and unlocks the list. The + # effect of this is that the changes made to the MailList object will + # be aborted, which seems like the only sensible semantics. + # + # BAW: This may not be portable to other web servers or cgi execution + # models. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + if cgidata.has_key('bounce_matching_headers'): pairs = mlist.parse_matching_header_opt() @@ -135,8 +170,12 @@ FormatConfiguration(doc, mlist, category, category_suffix, cgidata) print doc.Format(bgcolor="#ffffff") - finally: mlist.Save() + finally: + # Now be sure to unlock the list. It's okay if we get a signal here + # because essentially, the signal handler will do the same thing. And + # unlocking is unconditional, so it's not an error if we unlock while + # we're already unlocked. mlist.Unlock() Index: Mailman/Cgi/admindb.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admindb.py,v retrieving revision 1.36.2.1 retrieving revision 1.36.2.4 diff -u -r1.36.2.1 -r1.36.2.4 --- Mailman/Cgi/admindb.py 2001/03/03 06:02:01 1.36.2.1 +++ Mailman/Cgi/admindb.py 2001/05/04 15:54:23 1.36.2.4 @@ -16,10 +16,12 @@ """Produce and process the pending-approval items for a list.""" +import sys import os import string import types import cgi +import signal from errno import ENOENT from Mailman import mm_cfg @@ -62,7 +64,7 @@ return # now that we have the list name, create the list object try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: handle_no_list(doc, 'No such list <em>%s</em><p>' % listname) syslog('error', 'No such list "%s": %s\n' % (listname, e)) @@ -71,14 +73,34 @@ # now we must authorize the user to view this page, and if they are, to # handle both the printing of the current outstanding requests, and the # selected actions + cgidata = cgi.FieldStorage() try: - cgidata = cgi.FieldStorage() - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admindb', e.message) - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admindb', e.message) + return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + # If this is a form submission, then we'll process the requests and # print the results. otherwise (there are no keys in the form), we'll # print out the list of pending requests @@ -91,8 +113,8 @@ PrintRequests(mlist, doc) text = doc.Format(bgcolor="#ffffff") print text - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/handle_opts.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/handle_opts.py,v retrieving revision 1.30 retrieving revision 1.30.2.2 diff -u -r1.30 -r1.30.2.2 --- Mailman/Cgi/handle_opts.py 2000/11/09 16:19:03 1.30 +++ Mailman/Cgi/handle_opts.py 2001/05/03 21:05:06 1.30.2.2 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import mm_cfg from Mailman import Utils @@ -61,7 +62,7 @@ user = parts[1] try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) @@ -69,10 +70,30 @@ syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, user, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/subscribe.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/subscribe.py,v retrieving revision 1.29 retrieving revision 1.29.2.1 diff -u -r1.29 -r1.29.2.1 --- Mailman/Cgi/subscribe.py 2000/09/29 00:05:05 1.29 +++ Mailman/Cgi/subscribe.py 2001/05/03 21:05:43 1.29.2.1 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import Utils from Mailman import MailList @@ -41,18 +42,38 @@ listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) - mlist.IsListInitialized() + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) print doc.Format(bgcolor="#ffffff") syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: admin/www/download.ht =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v retrieving revision 1.5.2.5 retrieving revision 1.5.2.6 diff -u -r1.5.2.5 -r1.5.2.6 --- admin/www/download.ht 2001/04/18 10:44:14 1.5.2.5 +++ admin/www/download.ht 2001/05/03 21:09:36 1.5.2.6 @@ -65,9 +65,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul> Index: admin/www/download.html =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.html,v retrieving revision 1.6.2.7 retrieving revision 1.6.2.8 diff -u -r1.6.2.7 -r1.6.2.8 --- admin/www/download.html 2001/04/18 10:44:14 1.6.2.7 +++ admin/www/download.html 2001/05/03 21:09:36 1.6.2.8 @@ -1,6 +1,6 @@ <HTML> <!-- THIS PAGE IS AUTOMATICALLY GENERATED. DO NOT EDIT. --> -<!-- Wed Apr 18 06:43:32 2001 --> +<!-- Thu May 3 17:09:03 2001 --> <!-- USING HT2HTML 1.1 --> <!-- SEE http://www.wooz.org/barry/software/pyware.html --> <!-- User-specified headers: @@ -237,9 +237,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul> _______________________________________________ Mailman-announce mailing list Mailman-announce@python.org http://mail.python.org/mailman/listinfo/mailman-announce
"JE" == Joshua Erdman <josh@ernestallen.com> writes:
JE> When you say to CD into our sourcetree, is that the location
JE> where I originally compiled mailman or is that where I have
JE> the current working copy of the software?
It's the directory where you original did the "configure; make install"
I.e. not /home/mailman.
-Barry
Since installing Mailman I have noticed the size of my backups increasing steadily. I did some investigating and noticed the size of the log file in the mailman/logs directory. By adding a few lines of code to your /etc/logrotate.conf file you can have these log files rotated just like all the log files in /var/logs
Some quick info about the /etc/logrotate.conf file At the top are the global settings with a comment for each one Mine had:
-- Beginning of lines added to logrotate.conf -- # rotate log files weekly weekly
# keep 4 weeks worth of backlogs rotate 4
# e-mail errors to root errors root
# create new (empty) log files after rotating old ones with the same # security settings as the ones already rotated. create
"/home/mailman/logs/post" { }
"/home/mailman/logs/smtp" { compress }
"/home/mailman/logs/smtp-failure" { }
"/home/mailman/logs/subscribe" { }
"/home/mailman/logs/bounce" { }
"/home/mailman/logs/vette" { }
"/home/mailman/logs/qrunner" { }
"/home/mailman/logs/error" { }
"/home/mailman/logs/digest" { }
--End logrotate.conf
If you have any questions about setting up logrotate or extra features, look at your man pages.
Joshua Erdman Ernest & Allen, Inc. CIO/Network Systems Administrator Tel (805) 781-0317 Fax (805) 781-0725 josh@ernestallen.com
On Mon, May 07, 2001 at 12:24:16PM -0400, Barry A. Warsaw wrote:
Folks,
I've just released Mailman 2.0.5 which fixes a problem with stale lock files that can occur under certain situations when the user hits the `Stop' button on their browser. These stale lock files can cause mailing lists to be inaccessible for long periods of time (until the stale lock file times out or is manually removed).
I just noticed this in my locks directory: usw-sf-list1:/var/local/mailman/bin# l ../locks/ total 24 drwxrwsr-x 2 mailman mailman 16384 May 9 10:40 ./ drwxrwsr-x 21 mailman mailman 4096 Apr 10 15:06 ../ -rw-rw-r-- 1 mailman mailman 59 May 7 05:42 jboss-user.lock.usw-sf-list1.26443 usw-sf-list1:/var/local/mailman/bin# (prcoss 26443 doesn't exist obviously)
Note that this is not bad because it doesn't keep the list locked. There is probably a small race in the removal of the temporary lockfile that you link to though.
I'll delete this one and see if others pop up over time.
Marc
Microsoft is to operating systems & security .... .... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | Finger marc_f@merlins.org for PGP key
On Wed, May 09, 2001 at 10:43:04AM -0700, Marc MERLIN wrote:
I just noticed this in my locks directory: usw-sf-list1:/var/local/mailman/bin# l ../locks/ total 24 drwxrwsr-x 2 mailman mailman 16384 May 9 10:40 ./ drwxrwsr-x 21 mailman mailman 4096 Apr 10 15:06 ../ -rw-rw-r-- 1 mailman mailman 59 May 7 05:42 jboss-user.lock.usw-sf-list1.26443 usw-sf-list1:/var/local/mailman/bin# (prcoss 26443 doesn't exist obviously)
Note that this is not bad because it doesn't keep the list locked. There is probably a small race in the removal of the temporary lockfile that you link to though.
I'll delete this one and see if others pop up over time.
Just got another one (so it's apparently not an isolated case) usw-sf-list1:/var/local/mailman/bin# l ../locks/ total 24 drwxrwsr-x 2 mailman mailman 16384 May 10 13:40 ./ drwxrwsr-x 21 mailman mailman 4096 Apr 10 15:06 ../ -rw-rw-r-- 1 mailman mailman 60 May 10 05:29 madchat-spam.lock.usw-sf-list1.8790
Again, it's not fatal since the list doesn't remain in locked state, but something is apparently still slightly off somewhere :-)
Marc
Microsoft is to operating systems & security .... .... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | Finger marc_f@merlins.org for PGP key
"MM" == Marc MERLIN <marc_news@valinux.com> writes:
MM> Just got another one (so it's apparently not an isolated case)
Dang.
MM> usw-sf-list1:/var/local/mailman/bin# l ../locks/ total 24
MM> drwxrwsr-x 2 mailman mailman 16384 May 10 13:40 ./ drwxrwsr-x
MM> 21 mailman mailman 4096 Apr 10 15:06 ../ -rw-rw-r-- 1 mailman
MM> mailman 60 May 10 05:29 madchat-spam.lock.usw-sf-list1.8790
MM> Again, it's not fatal since the list doesn't remain in locked
MM> state, but something is apparently still slightly off
MM> somewhere :-)
Yeah, that's annoying. :) I haven't got any lock turds on python.org, but then again, you probably have slightly higher traffic than we do <wink>.
If I get some time, I'll stare at the LockFile.py code again. Any idea what process 8790 was? I wonder if it's the same code that's not cleaning up after itself.
Hmm, -Barry
On Thu, May 10, 2001 at 05:31:48PM -0400, Barry A. Warsaw wrote:
If I get some time, I'll stare at the LockFile.py code again. Any idea what process 8790 was? I wonder if it's the same code that's not cleaning up after itself.
Sorry for the late answer. I did look in the logfiles, but nothing showed up with pid 8790. Kinda weird...
That said, we just got a list with 10,000+ users (nuked since then, see message sent after this one), and loading the admin page up took a while. My locks directory now has 35 desi-os-maps.lock.usw-sf-list1.pid files.
Then again, it doesn't block the list, so it's not that bad
Marc
Microsoft is to operating systems & security .... .... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | Finger marc_f@merlins.org for PGP key
On 5/14/01 6:05 PM, "Marc MERLIN" <marc_news@valinux.com> wrote:
Sorry for the late answer. I did look in the logfiles, but nothing showed up with pid 8790. Kinda weird...
That said, we just got a list with 10,000+ users (nuked since then, see message sent after this one), and loading the admin page up took a while. My locks directory now has 35 desi-os-maps.lock.usw-sf-list1.pid files.
That implies to me that your process has the list locked, and other people are trying to access it, finding it locked and exiting -- but leaving a lockfile dribble behind.
Barry - I just got lost trying to find the patches. Is there a nice, straight-forward, FTP site I can pull patch 1-5 from? Thanks, Kevin C. -----Original Message----- From: mailman-announce-admin@python.org [mailto:mailman-announce-admin@python.org]On Behalf Of Barry A. Warsaw Sent: Monday, May 07, 2001 11:24 AM To: mailman-announce@python.org Cc: mailman-developers@python.org Subject: [Mailman-Announce] ANNOUNCE Mailman 2.0.5 Folks, I've just released Mailman 2.0.5 which fixes a problem with stale lock files that can occur under certain situations when the user hits the `Stop' button on their browser. These stale lock files can cause mailing lists to be inaccessible for long periods of time (until the stale lock file times out or is manually removed). As usual, I'm releasing this as both a complete tarball and as a patch against Mailman 2.0.4. You /must/ update your source to 2.0.4 before applying the 2.0.5 patch. Since the patch is small, I'm including it in this message. To apply, cd into your 2.0.5 source tree and apply it like so: % patch -p0 < mailman-2.0.4-2.0.5.txt Currently both http://mailman.sourceforge.net and http://www.list.org are updated, and I expect the gnu.org site to be updated soon as well. The release information on SF is at http://sourceforge.net/project/shownotes.php?release_id=31693 See also http://www.gnu.org/software/mailman http://www.list.org http://mailman.sourceforge.net My thanks to those of you who gave the 2.0.5 pre-release a try! Enjoy, -Barry Index: NEWS =================================================================== RCS file: /cvsroot/mailman/mailman/NEWS,v retrieving revision 1.25.2.5 retrieving revision 1.25.2.6 diff -u -r1.25.2.5 -r1.25.2.6 --- NEWS 2001/04/18 10:45:54 1.25.2.5 +++ NEWS 2001/05/03 21:06:56 1.25.2.6 @@ -4,6 +4,13 @@ Here is a history of user visible changes to Mailman. +2.0.5 (04-May-2001) + + Fix a lock stagnation problem that can result when the user hits + the `stop' button on their browser during a write operation that + can take a long time (e.g. hitting the membership management admin + page). + 2.0.4 (18-Apr-2001) Python 2.1 compatibility release. There were a few questionable Index: Mailman/Version.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v retrieving revision 1.20.2.4 retrieving revision 1.20.2.5 diff -u -r1.20.2.4 -r1.20.2.5 --- Mailman/Version.py 2001/04/18 04:43:29 1.20.2.4 +++ Mailman/Version.py 2001/05/03 20:58:19 1.20.2.5 @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Mailman version -VERSION = "2.0.4" +VERSION = "2.0.5" # And as a hex number in the manner of PY_VERSION_HEX ALPHA = 0xa @@ -27,7 +27,7 @@ MAJOR_REV = 2 MINOR_REV = 0 -MICRO_REV = 4 +MICRO_REV = 5 REL_LEVEL = FINAL # at most 15 beta releases! REL_SERIAL = 0 Index: Mailman/Cgi/admin.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admin.py,v retrieving revision 1.82.2.2 retrieving revision 1.82.2.3 diff -u -r1.82.2.2 -r1.82.2.3 --- Mailman/Cgi/admin.py 2001/01/03 16:47:47 1.82.2.2 +++ Mailman/Cgi/admin.py 2001/05/03 21:03:48 1.82.2.3 @@ -18,11 +18,13 @@ """ +import sys import os import cgi import string import types import rfc822 +import signal from Mailman import Utils from Mailman import MailList @@ -63,53 +65,86 @@ # get the list object listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: FormatAdminOverview('No such list <em>%s</em>' % listname) syslog('error', 'Someone tried to access the admin interface for a ' 'non-existent list: %s' % listname) return + + if len(parts) == 1: + category = 'general' + category_suffix = '' + else: + category = parts[1] + category_suffix = category + + # If the user is not authenticated, we're done. + cgidata = cgi.FieldStorage(keep_blank_values=1) try: - if len(parts) == 1: - category = 'general' - category_suffix = '' - else: - category = parts[1] - category_suffix = category - - # If the user is not authenticated, we're done. - cgidata = cgi.FieldStorage(keep_blank_values=1) - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admin', e.message) - return - - # Is this a log-out request? - if category == 'logout': - print mlist.ZapCookie('admin') - Auth.loginpage(mlist, 'admin', frontpage=1) - return - - if category not in map(lambda x: x[0], CATEGORIES): - category = 'general' - - # is the request for variable details? - varhelp = None - if cgidata.has_key('VARHELP'): - varhelp = cgidata['VARHELP'].value - elif cgidata.has_key('request_login') and \ - os.environ.get('QUERY_STRING'): - # POST methods, even if their actions have a query string, don't - # get put into FieldStorage's keys :-( - qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') - if qs and type(qs) == types.ListType: - varhelp = qs[0] - if varhelp: - FormatOptionHelp(doc, varhelp, mlist) - print doc.Format(bgcolor="#ffffff") - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admin', e.message) + return + + # Is this a log-out request? + if category == 'logout': + print mlist.ZapCookie('admin') + Auth.loginpage(mlist, 'admin', frontpage=1) + return + + if category not in map(lambda x: x[0], CATEGORIES): + category = 'general' + # is the request for variable details? + varhelp = None + if cgidata.has_key('VARHELP'): + varhelp = cgidata['VARHELP'].value + elif cgidata.has_key('request_login') and \ + os.environ.get('QUERY_STRING'): + # POST methods, even if their actions have a query string, don't + # get put into FieldStorage's keys :-( + qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP') + if qs and type(qs) == types.ListType: + varhelp = qs[0] + if varhelp: + FormatOptionHelp(doc, varhelp, mlist) + print doc.Format(bgcolor="#ffffff") + return + + # From this point on, the MailList object must be locked. However, we + # must release the lock no matter how we exit. try/finally isn't + # enough, because of this scenario: user hits the admin page which may + # take a long time to render; user gets bored and hits the browser's + # STOP button; browser shuts down socket; server tries to write to + # broken socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache + # catches this SIGPIPE (I presume it is buffering output from the cgi + # script), then turns around and SIGTERMs the cgi process. Apache + # waits three seconds and then SIGKILLs the cgi process. We /must/ + # catch the SIGTERM and do the most reasonable thing we can in as + # short a time period as possible. If we get the SIGKILL we're + # screwed (because its uncatchable and we'll have no opportunity to + # clean up after ourselves). + # + # This signal handler catches the SIGTERM and unlocks the list. The + # effect of this is that the changes made to the MailList object will + # be aborted, which seems like the only sensible semantics. + # + # BAW: This may not be portable to other web servers or cgi execution + # models. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + if cgidata.has_key('bounce_matching_headers'): pairs = mlist.parse_matching_header_opt() @@ -135,8 +170,12 @@ FormatConfiguration(doc, mlist, category, category_suffix, cgidata) print doc.Format(bgcolor="#ffffff") - finally: mlist.Save() + finally: + # Now be sure to unlock the list. It's okay if we get a signal here + # because essentially, the signal handler will do the same thing. And + # unlocking is unconditional, so it's not an error if we unlock while + # we're already unlocked. mlist.Unlock() Index: Mailman/Cgi/admindb.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admindb.py,v retrieving revision 1.36.2.1 retrieving revision 1.36.2.4 diff -u -r1.36.2.1 -r1.36.2.4 --- Mailman/Cgi/admindb.py 2001/03/03 06:02:01 1.36.2.1 +++ Mailman/Cgi/admindb.py 2001/05/04 15:54:23 1.36.2.4 @@ -16,10 +16,12 @@ """Produce and process the pending-approval items for a list.""" +import sys import os import string import types import cgi +import signal from errno import ENOENT from Mailman import mm_cfg @@ -62,7 +64,7 @@ return # now that we have the list name, create the list object try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: handle_no_list(doc, 'No such list <em>%s</em><p>' % listname) syslog('error', 'No such list "%s": %s\n' % (listname, e)) @@ -71,14 +73,34 @@ # now we must authorize the user to view this page, and if they are, to # handle both the printing of the current outstanding requests, and the # selected actions + cgidata = cgi.FieldStorage() try: - cgidata = cgi.FieldStorage() - try: - Auth.authenticate(mlist, cgidata) - except Auth.NotLoggedInError, e: - Auth.loginpage(mlist, 'admindb', e.message) - return + Auth.authenticate(mlist, cgidata) + except Auth.NotLoggedInError, e: + Auth.loginpage(mlist, 'admindb', e.message) + return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + mlist.Lock() + try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + # If this is a form submission, then we'll process the requests and # print the results. otherwise (there are no keys in the form), we'll # print out the list of pending requests @@ -91,8 +113,8 @@ PrintRequests(mlist, doc) text = doc.Format(bgcolor="#ffffff") print text - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/handle_opts.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/handle_opts.py,v retrieving revision 1.30 retrieving revision 1.30.2.2 diff -u -r1.30 -r1.30.2.2 --- Mailman/Cgi/handle_opts.py 2000/11/09 16:19:03 1.30 +++ Mailman/Cgi/handle_opts.py 2001/05/03 21:05:06 1.30.2.2 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import mm_cfg from Mailman import Utils @@ -61,7 +62,7 @@ user = parts[1] try: - mlist = MailList.MailList(listname) + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) @@ -69,10 +70,30 @@ syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, user, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: Mailman/Cgi/subscribe.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/subscribe.py,v retrieving revision 1.29 retrieving revision 1.29.2.1 diff -u -r1.29 -r1.29.2.1 --- Mailman/Cgi/subscribe.py 2000/09/29 00:05:05 1.29 +++ Mailman/Cgi/subscribe.py 2001/05/03 21:05:43 1.29.2.1 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,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 @@ -20,6 +20,7 @@ import os import string import cgi +import signal from Mailman import Utils from Mailman import MailList @@ -41,18 +42,38 @@ listname = string.lower(parts[0]) try: - mlist = MailList.MailList(listname) - mlist.IsListInitialized() + mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: doc.AddItem(Header(2, "Error")) doc.AddItem(Bold('No such list <em>%s</em>' % listname)) print doc.Format(bgcolor="#ffffff") syslog('error', 'No such list "%s": %s\n' % (listname, e)) return + + # We need a signal handler to catch the SIGTERM that can come from Apache + # when the user hits the browser's STOP button. See the comment in + # admin.py for details. + # + # BAW: Strictly speaking, the list should not need to be locked just to + # read the request database. However the request database asserts that + # the list is locked in order to load it and it's not worth complicating + # that logic. + def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) + + mlist.Lock() try: + # Install the emergency shutdown signal handler + signal.signal(signal.SIGTERM, sigterm_handler) + process_form(mlist, doc) - finally: mlist.Save() + finally: mlist.Unlock() Index: admin/www/download.ht =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v retrieving revision 1.5.2.5 retrieving revision 1.5.2.6 diff -u -r1.5.2.5 -r1.5.2.6 --- admin/www/download.ht 2001/04/18 10:44:14 1.5.2.5 +++ admin/www/download.ht 2001/05/03 21:09:36 1.5.2.6 @@ -65,9 +65,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul> Index: admin/www/download.html =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.html,v retrieving revision 1.6.2.7 retrieving revision 1.6.2.8 diff -u -r1.6.2.7 -r1.6.2.8 --- admin/www/download.html 2001/04/18 10:44:14 1.6.2.7 +++ admin/www/download.html 2001/05/03 21:09:36 1.6.2.8 @@ -1,6 +1,6 @@ <HTML> <!-- THIS PAGE IS AUTOMATICALLY GENERATED. DO NOT EDIT. --> -<!-- Wed Apr 18 06:43:32 2001 --> +<!-- Thu May 3 17:09:03 2001 --> <!-- USING HT2HTML 1.1 --> <!-- SEE http://www.wooz.org/barry/software/pyware.html --> <!-- User-specified headers: @@ -237,9 +237,9 @@ <h3>Downloading</h3> <p>Version -(<!-VERSION--->2.0.4<!-VERSION--->, +(<!-VERSION--->2.0.5<!-VERSION--->, released on -<!-DATE--->Apr 18 2001<!-DATE--->) +<!-DATE--->May 4 2001<!-DATE--->) is the current GNU release. It is available from the following mirror sites: <ul> _______________________________________________ Mailman-announce mailing list Mailman-announce@python.org http://mail.python.org/mailman/listinfo/mailman-announce
"KNC" == Kevin N Carpenter <kevinc@seaplace.org> writes:
KNC> I just got lost trying to find the patches. Is there a nice,
KNC> straight-forward, FTP site I can pull patch 1-5 from?
SourceForge should have them, but you can also try ftp.gnu.org, probably in the gnu/mailman subdirectory.
-Barry
participants (5)
-
barry@digicool.com
-
Chuq Von Rospach
-
Joshua Erdman
-
Kevin N. Carpenter
-
Marc MERLIN