[mod_python] stumped by inputfilter infinite repeat

Ken Manheimer ken.manheimer at gmail.com
Mon Aug 20 20:19:21 EDT 2007


On 8/20/07, Graham Dumpleton <graham.dumpleton at gmail.com> wrote:
> On 21/08/07, Ken Manheimer <ken.manheimer at gmail.com> wrote:
> > On 8/18/07, Graham Dumpleton <graham.dumpleton at gmail.com> wrote:
> > > Which version of mod_python and Apache are you using?
> > >
> > > The Tramline author suspected there existed a problem in mod_python
> > > and/or Apache that caused some issues. They suggest in their
> > > documentation a change that should be made to mod_python, although it
> > > hasn't been done in official releases as it wouldn't seem to be the
> > > correct thing to do. One issue was fixed in filter code in mod_python
> > > in recent versions which may have caused issues, but not the same
> > > change they suggested. They also felt that certain older versions of
> > > Apache may have had some problem.
> > >
> > > For some more details see:
> > >
> > >   https://issues.apache.org/jira/browse/MODPYTHON-76
> >
> > thanks much, graham, for your reply.  i did know about the need to
> > inihbit filter.flush() - it's described in the tramline install
> > instructions.  i also factored tramline completely out of the picture,
> > reproducing the behavior using instead some trivial artifical
> > inputfilter and outputfilter functions:
> >
> >   def inputfilter(filter):
> >       "stub input filter"
> >       filter.req.log_error("klm input filter")
> >
> >   def outputfilter(filter):
> >       "stub output filter"
> >       filter.req.log_error("klm output filter")
> >
> > running without pdb enabled but through the rewrite rule i mentioned
> > earlier, to Zope, yields an infinite stream of the "klm input filter"
> > messages, and no "klm output filter" ones.  (the problem does *not*
> > happen when the Zope backend is not running.)
>
> As I would expect, as the input filter is neither consuming the data
> or passing it on. Try something like:
>
> from mod_python import apache
>
> def inputfilter(filter):
>
>     s = filter.read()
>     while s:
>         filter.write(s)
>         s = filter.read()
>
>     if s is None:
>         filter.close()
>
> Similar for output filter.

hmm!

the lack of any input handling in my routine was really dumb.  but in
any case, this may point to something that gets tramline working.

the tramline input filter is intended to only intervene for main POST
requests that consist of multipart/form-data.  for other requests it
would do a filter.pass_on() and return:

    def inputfilter(filter):
        # we're done if we're in a subrequest
        if filter.req.main is not None:
            filter.pass_on()
            return

        # we only handle POST requests
        if filter.req.method != 'POST':
            filter.pass_on()
            return

        # we only handle multipart/form-data
        enctype = filter.req.headers_in.get('Content-Type')
        if enctype[:19] != 'multipart/form-data':
            filter.pass_on()
            return

        [do some real stuff, otherwise]

i the assume that the filter.pass_on() was supposed to do the right
thing, but i tried that in my stub filters (after confirming that your
filter.read()/filter.write() handling did in fact work, graham), and
it didn't.  so i replaced the above with:

    def inputfilter(filter):

        enctype = filter.req.headers_in.get('Content-Type')
        if ((filter.req.main is not None)   # we are in a subrequest
            or (filter.req.method != 'POST')# this is not a POST
request
            or (enctype[:19] != 'multipart/form-data')): # not
multipart/form-data:
            s = filter.read()
            while s:
                filter.write(s)
                s = filter.read()
            if s is None:
                filter.close()
            return

        [do some real stuff, otherwise]

and i don't get the hang.  i have to test the intended tramline
operation, and don't understand enough yet about it or mod_python
filters to be confident that i have something right, but at least i
have something to work with now!

can you say why the filter.pass_on() is not sufficient, by the way?
even with and added filter.flush() the infinite repeat still happens.

> > i did reread the bug report, and it occurred to me to try the current
> > apache svn version, as the bug report mentions - an off chance,
> > though, since the features of the svn version around the time of the
> > bug report should have seen released by now.  unfortunately, that
> > works worse.  i'm getting a fatal error trying to run the latest svn
> > version with mod_python installed:
> >
> > httpd: Syntax error on line 116 of /usr/local/apache2/conf/httpd.conf:
> > Cannot load /usr/local/apache2/modules/mod_python.so into server:
> > /usr/local/apache2/modules/mod_python.so: undefined symbol:
> > ap_requires
> > err 1:  2811  /usr/local/apache2/bin/apachectl configtest
>
> Do you have multiple versions of Apache on your system? This error
> suggest the mod_python source code has been compiled against a
> different version of Apache than you are trying to use it with.

now that i have something to work with using the current apache
version (which i put back in place from a tarball i created before
trying the install of the svn version), i don't need to resolve the
svn version problems.  still, here are the details:

i do have an older installation, but i'm not running it, and i build
(configure) mod_python with the apxs of the new version.  checked that
a bunch of times, and examined config.status, besides.

  ./configure --with-apxs=/usr/local/apache2/bin/apxs
--with-python=/usr/local/bin/python2.4 --with-max-locks=32

i've been running a version of apache2 out of /usr/local/apache2 for a
few months, though with very light use.  i actually deleted the older
apache2 installation before installing the svn checkout one, to avoid
cross-version contamination.

> > this obstacle on obstacle is discouraging.  a google search reveals no
> > other reports of this particular error, and i have no reason to be
> > confident that getting it working would actually improve the original
> > inputfilter problem.  i plan to inquire on the tramline and plone
> > lists for alternatives.  i am interested to hear insights on this, but
> > think i'm better off pursuing other avenues (there's some alpha plone
> > accommodations for blobs in the zodb), and if that works, giving up on
> > mod_python.
> >
> > i did solve one interesting incidental problem along the way, that
> > might be of value to someone else.  when the interminable inputfilter
> > invocation is happening i have to kill apache with a KILL signal (9).
> > doing that lead to mutex leaks, soon leading to apache start failures,
> > with an error_log complaint like this:
> >
> > [Fri Aug 17 12:00:00 2007] [error] (28)No space left on device:
> > mod_python: Failed to create global mutex 0 of 32 (/tmp/mpmtx125450).
>
> You need to make sure you kill off the zombie Apache parent processes
> as well if any exist. It will only be when they have gone that the
> mutexes will be released.

i am usually running apache in non-daemon mode, in order to interact
with the pdb session, when this happens:

  /usr/local/apache2/bin/httpd -k start -X -DONE_PROCESS

^C or default kill signal doesn't kill it.  no other httpd processes
exist.  i don't think the problem is due to running in the foreground,
however - i think the server is blocking on some kind of IO.  it
happens whether or not PythonDebugPdb is set, but it doesn't happen
when i do a regular apachectl start - then killing the lead httpd
processes results in an eventual KILL signal from some supervisor.
the mutex leaks don't happen then.

> > investigating, i learned about ipcs to report semaphores and ipcrm to
> > remove them, and created a little script that did the job for me:
> >
> > ipcs -s | while read key id garbage; do
> >   case "$id" in
> >     [0-9]* ) echo -n "$id "
> >              ipcrm -s $id;;
> >     * ) : ;;
> >   esac
> > done
> >
> > handy.
>
> Hmmm, wont this be dangerous if something is using them. Things other
> than Apache use these things.

whoops again.  i have an exclusive-use machine, for now, and was
taking that overmuch for granted.

this should be a better focused approach, though still requires
caution, since it will screw over a properly running apache.  (it
removes the mutexes owned by the apache user, which is the one i'm
using.)

trash_mutexes () {
  ipcs -s | while read key id owner garbage; do
    case "$owner" in
      apache ) echo -n "$id "
               ipcrm -s $id;;
      * ) : ;;
    esac
  done
}

the important thing is that i have something to go on with tramline,
even if it's not quite right, yet.  thanks much!

ken

> > also, in case anyone still thinks attention to mod_python and tramline
> > is worthwhile, here are my web server details, from mod_python's
> > mpinfo:
> >
> >   Apache/2.2.4 (Unix) mod_ssl/2.2.4  OpenSSL/0.9.7a  DAV/2  mod_python/3.3.1
> >   Python/2.4.3
> >
> > and host server os and hardware: linux kernel 2.6.9-42.ELsmp on an AMD
> > Athlon 64 X2
> > Dual Core Processor 4200+.  (it's actually running redhat 4.1, alas.)
> >
> > --
> > ken
> > http://myriadicity.net
> >
> > > On 19/08/07, Ken Manheimer <ken.manheimer at gmail.com> wrote:
> > > > hi, all.  i'm using mod_python with a downloads/uploads handler,
> > > > tramline ( http://infrae.com/products/tramline ) with a content
> > > > management system (plone).  when the tramline input and output filters
> > > > are hooked in (using SetInputFilter and SetOutputFilter) and i visit
> > > > the zope/plone site via a redirect, i get infinite repeated calls to
> > > > the input filter.  (i can observe the this by setting PythonEnablePdb
> > > > - from the perspective of the web browser, no page is returned.)  i
> > > > can provide more details, and realize that this may be a tramline
> > > > problem, but it seems like a behavior that might be familiar to
> > > > mod_python experts, so i thought i'd run it by you all first.
> > > >
> > > > things like mpinfo and mptest.py work fine.  visiting the regular,
> > > > file-based mockup site yields no problems - only the embedded zope
> > > > site, via a rewrite rule:
> > > >
> > > >   RewriteRule ^/testbed(.*)
> > > > http://127.0.0.1:8080/VirtualHostBase/http/%{HTTP_HOST}:80/VirtualHostRoot/_vh_testbed/$1
> > > > [L,P]
> > > >
> > > > (the elaborate VirtualHostRoot stuff is for a zope virtual hosting provision.)
> > > >
> > > > does any of this sound familiar to anyone?  suggestions about
> > > > debugging it?  (stepping through the input and output filters using
> > > > PythonEnablePdb yields little or no illumination - they just keep
> > > > getting invoked.  i don't know what to look for tracing added to
> > > > importer.py FilterDispatch, which i tried instead of using
> > > > PythonEnablePdb.)
> > > >
> > > > any help would be appreciated!


More information about the Mod_python mailing list