Cygrunsrv and spawned processes

Frank Seesink frank@mail.wvnet.edu
Thu Dec 4 21:59:00 GMT 2003


Igor Pechtchanski wrote:

> On Thu, 4 Dec 2003, Frank Seesink wrote:
> 
> 
>>QUESTION:
>>
>>If you have a Cygwin application binary which spawns a child process
>>using spawnlp() in P_NOWAIT mode, is there a way to install that
>>application as an NT service using cygrunsrv such that both the parent
>>and child process die cleanly?
>>
>>DETAILS:
>>
>>I have Googled and searched the Cygwin mailing lists for insight but
>>have failed to yield a solid solution.  So here goes:
>>
>>I have been working with the Jabber/XMPP folks (www.jabber.org) to make
>>Jabberd, their IM server, run under Cygwin as it does under *nix.  With
>>v1.4.3, I believe I have achieved a good measure of success.  The only
>>Cygwin-specific items in Jabberd now are that
>>
>>1.  modules (a.k.a., shared libraries) are compiled as .dll and not .so
>>2.  due to limitations in Cygwin's support for certain network functions
>>     (support for inet_ntoa() but lack of inet_ntop()) as well as the
>>     lack of BIND--the DNS resolver portion of Jabberd was rewritten (by
>>     someone else awhile ago), and instead of working as a shared library
>>     as it does under *nix, it now fires off a child process via
>>     spawnlp() using the _P_NOWAIT mode.
>>
>>Unfortunately, I am running into an issue when I attempt to setup
>>Jabberd to run as an NT service via cygrunsrv.
>>
>>In a nutshell, if I run Cygwin BASH and fire up Jabberd manually:
>>
>>        $ cd /usr/local/jabber
>>        $ ./jabberd/jabberd.exe
>>
>>All works well.  I look in Windows Task Manager and see two (2)
>>processes:  jabberd.exe and jabadns.exe (the resolver).  Jabberd is
>>running in interactive mode, meaning in the BASH window I can do nothing
>>until I kill the process by typing CTRL-C (SIGINT).  When I do this,
>>both processes die cleanly.  Life is good.  (NOTE:  I do NOT exit BASH.
>>  I simply hit CTRL-C to send a SIGINT to jabberd.exe, which apparently
>>in turn kills jabadns.exe; then I have my command prompt back).
>>
>>However, when I configure Jabberd as an NT service using cygrunsrv and
>>then use
>>
>>        net start jabberd
>>        net stop jabberd
>>
>>to start/stop the server, though startup works fine and both processes
>>initiate, when I stop Jabberd only jabberd.exe dies.  jabadns.exe is
>>left behind.  The only way to kill it is via kill (if you do a 'ps' to
>>find the PID, etc.) or via the Windows Task Manager.  Basically, I must
>>kill jabadns.exe by hand.  If I repeat the above commands to start/stop
>>Jabberd repeatedly, I'm left with one jabadns.exe 'zombie' process for
>>each invocation.
>>
>>I have read the relevant portion in
>>/usr/share/doc/Cygwin/cygrunsrv.README where it states:
>>____________________________________________________________
>>...
>>General Notes:
>>
>>There's currently one caveat, though. If the application behaves as
>>a "normal" unix daemon and exits after forking a child, cygrunsrv
>>will immediately stop the service (but the actual daemon keeps running
>>in the background).  This means that you cannot then STOP the daemon
>>using cygrunsrv, but you must explicit kill it via 'kill -9 <daemon_pid>'
>>
>>If you fail to do this, you will probably see something like this in
>>the Windows Application Event Log:
>>   Cygwin Apache : Win32 Process Id = 0xFE : Cygwin Process Id = 0xFE :
>>   `Cygwin Apache' service started.
>>immediately followed by
>>   Cygwin Apache : Win32 Process Id = 0xFE : Cygwin Process Id = 0xFE :
>>   `Cygwin Apache' service stopped.
>>but 'ps -eaf | grep httpd' shows that httpd IS still running.
>>
>>To avoid this problem, you must start the application so that it
>>doesn't fork a daemon but stays resident instead.  sshd
>>for example has to be called with the -D option.  squid must be
>>called with the -N option.
>>...
>>____________________________________________________________
>>
>>This makes me believe that cygrunsrv is killing off the server process
>>but the signal is not propogating to the spawned child process.  I am
>>trying to understand why this works from the BASH shell but not via
>>cygrunsrv, and more importantly, what I'd like to find out is if there
>>is a way to make it work properly as an NT service (that is, have both
>>processes die cleanly as they do in BASH).
>>
>>I'm guessing those running Apache, sshd, etc., aren't running into this
>>issue, or I would've found more relevant info.  And unless I'm wrong,
>>these apps do spawn child processes of their own.
>>
>>Note that 'cygrunsrv --install' is run with an executable (jabberd.exe),
>>not a shell script or anything else.  And jabberd.exe is set to run in
>>interactive, NOT background (daemon), mode.  So I would expect the kill
>>signal to propogate as it apparently does at the BASH shell level.
>>
>>* Is this a limitation in cygrunsrv that is inherent?
>>* Is it a bug/limitation in cygrunsrv that is being worked on and,
>>   hopefully sometime soon, will be fixed?
>>* Is there an alternative solution that WILL have the signal propogate
>>   so the child process dies cleanly?
>>
>>I have tried my hand at configuring a shell to run a script which runs
>>Jabberd, but no luck.  Had trouble finding examples via Google, so had
>>to wing it.  Hopefully I'm just missing something simple, but wanted to
>>ask if anyone might be able to help.
> 
> 
> Frank,
> 
> When you press Ctrl-C in bash, the application gets SIGINT.  When you stop
> the service installed by cygrunsrv, by default the signal is SIGTERM,
> which the application may not handle gracefully.  Try the '--termsig INT'
> ('-s 2') cygrunsrv option.
> 	Igor

Hey Igor!

Actually, already tried that.  No dice.  Tried configuring cygrunsrv 
with TERM, with INT, even QUIT and HUP.  Probably should've mentioned 
that, but was trying to keep from cluttering up the message more than I 
did. :-)

It really seems as if this executable--when run from the shell--works as 
you would expect, but when fired up by cygrunsrv does not.  I'm 
scratching my head as to why, but I do know for sure that cygrunsrv does 
NOT give you a full Cygwin shell environment for your app to run in.  I 
found this out while doing all this.  Basically, here's the layout for 
Jabberd file-wise:

MAIN/WORKING DIRECTORY:
/usr/local/jabber/ -- main directory, where Jabber code is compiled,
                       where you run app from,
                       where jabber.xml file (config file) is located
MAIN EXECUTABLE:
/usr/local/jabber/jabberd/jabberd.exe

VARIOUS MODULES/DLLs:
/usr/local/jabber/dialback/dialback.dll
/usr/local/jabber/dnsrv/dnsrv.dll
/usr/local/jsm/jsm.dll
/usr/local/pthsock/pthsock_client.dll
/usr/local/xdb_file/xdb_file.dll

DNS resolver executable:
/usr/local/bin/jabadns.exe

NOTE:  jabber.xml file specifies location of shared modules using 
relative paths (e.g., ./dialback/dialback.dll).

When run from BASH shell, firing up jabberd.exe finds and executes 
/usr/local/bin/jabadns.exe.  However, if I do not add a -e switch to 
cygrunsrv to add /usr/local/bin to PATH, firing up jabberd.exe fails to 
find jabadns.exe.  Either that or I have to copy jabadns.exe into 
/usr/local/jabber (the working directory).

This tells me that cygrunsrv is not giving you a full environment within 
which to run the app.  I've looked into spawnlp() and the P_NOWAIT mode, 
and it appears to be designed to allow processes to run concurrently. 
But if it was truly detaching the jabadns.exe process from the main 
process, I would expect jabadns.exe not to die even when Jabberd is run 
from the BASH shell.  But that's just it.  It does die properly.  So 
what's missing from the cygrunsrv environment that exists in the BASH 
shell I wonder.

Anyway, I'm grasping at straws.  I'd just love to get this working 
properly without leftover processes building up.  Any more 
thoughts/ideas I can try?  I'll give anything a whack. :-)



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list