[Twisted-Python] Unable to start twistd service on Ubuntu 10.04 when using pseudo terminal

Žiga Seilnacht ziga.seilnacht at gmail.com
Thu Sep 30 11:52:16 EDT 2010


Garret Heaton wrote:
> I've simplified this issue down and am able to reproduce it without
> Twisted: http://gist.github.com/603154
> Still not sure what the cause is, so if anyone has any ideas I'd love to
> hear them. Thanks!

The behavior that you are seeing seems to be related to the change in
the 2.6.32 kernel, where they changed the child-runs-first scheduler
parameter to false. Setting that parameter to 1 with:

$ sudo sysctl -w kernel.sched_child_runs_first=1

and rebooting the computer restores the behavior that you saw on the
old kernel for me. See http://lwn.net/Articles/352863/ for more details.

Parent (which is the controlling process when ran with -t) exiting before
the child starts causes the child to receive SIGHUP signal immediately as
it starts running, before it has time to disassociate itself from the
parent's process group. It seems to me that this might be an actual bug
in twistd, it should block the SIGHUP signal across the fork() calls.

Your test program has an additional assumption that the child will run
before the parent; the child in your program tries to write to stdout,
i.e. the controlling terminal, which gets closed once the parent exits.

The modified test program below works for me regardless of the setting
of the kernel.sched_child_runs_first parameter.

Hope this helps,

import os
import signal

f = open("test_fork.out", "w")

def daemonize():
     # See http://www.faqs.org/faqs/unix-faq/programmer/faq/ - Section 1.7
     print >> f, '--- %s: daemonizing' % os.getpid()

     signal.signal(signal.SIGHUP, signal.SIG_IGN)
     if os.fork(): # launch child and...
         print >> f, '--- %s: kill parent 1' % os.getpid()
         os._exit(0) # kill off parent
     print >> f, '--- %s: old sid: %r' % (os.getpid(), os.getsid(os.getpid()))
     print >> f, '--- %s: new sid: %r' % (os.getpid(), os.getsid(os.getpid()))
     if os.fork(): # launch child and...
         print >> f, '--- %s: kill parent 2' % os.getpid()
         os._exit(0) # kill off parent again.

     signal.signal(signal.SIGHUP, signal.SIG_DFL)
     print >> f, '--- %s: daemonizing done' % os.getpid()

if __name__ == "__main__":
     print >> f, 'starting as %d' % os.getpid()
     print >> f, 'stopping as %s' % os.getpid()

More information about the Twisted-Python mailing list