[comp.databases] INFORMIX bug?

jwas@PacBell.COM (Joe Wasik) (11/20/90)

We have this rather annoying problem with Informix-4GL.  When an Informix-4GL
application runs and accesses a database, it starts a back-end named sqlexec.
This back-end is supposed to die when the Informix-4GL application terminates,
but it doesn't.  In our case, since the Informix-4GL application starts up
other background jobs, the sqlexec program hangs around until those other jobs
are finished and it then interferes with the logoff process.

This is rather bizarre behavior.  Those other jobs are simple Unix scripts an
have nothing to do with Informix' database.  What on earth is sqlexec waiting
for?

This question has been asked before on this net without resolution, so we've
implemented our own solution.  Before the Informix-4GL program ends, it
executes something like the following (not actual code):

system("nohup kill -16 `ps -u ${LOGNAME} | cut -1-6 | grep " sqlexec$"` &")
(Not shown: a check to ensure that there is only one sqlexec).

In case anyone else had this problem, this solution does work.  The user
when logging off now drops out of the system instead of hanging or getting
the "login:" prompt.

This problem only occurred on our 3B15.  We do not pay our $5000+++ on this
machine so that we can ask a question of Informix.  We tried to reproduce it
on one where we do pay the bucks, but elsewhere sqlexec dies when it should.
So...  no help from Informix.

We still have some questions though (from the general public) ...  Is a signal
16 (found by trial and error) an appropriate way to kill sqlexec?  Are we
doing any harm to our database by terminating sqlexec with kill?

Thanks.

-- 
Joe Wasik - PacBell, 2600 Camino Ramon, 4e750, San Ramon, CA 94583  415-823-2422
jcwasik@clib.pacbell.com or {att,bellcore,sun,ames,pyramid}!pacbell!clib!jcwasik
iraq += kuwait; numcountries--; price_oil *= 2; us_public = screwed;

markj@informix.com (Mark Jeske(Chicago Consultan)t) (11/21/90)

In article <8330@pbhyf.PacBell.COM> jwas@PacBell.COM (Joe Wasik) writes:
>We have this rather annoying problem with Informix-4GL.  When an Informix-4GL
>application runs and accesses a database, it starts a back-end named sqlexec.
>This back-end is supposed to die when the Informix-4GL application terminates,
>but it doesn't.  In our case, since the Informix-4GL application starts up
>other background jobs, the sqlexec program hangs around until those other jobs
>are finished and it then interferes with the logoff process.
>
>This is rather bizarre behavior.  Those other jobs are simple Unix scripts an
>have nothing to do with Informix' database.  What on earth is sqlexec waiting
>for?
>
>This question has been asked before on this net without resolution, so we've
>implemented our own solution.  Before the Informix-4GL program ends, it
>executes something like the following (not actual code):
>
>system("nohup kill -16 `ps -u ${LOGNAME} | cut -1-6 | grep " sqlexec$"` &")
>(Not shown: a check to ensure that there is only one sqlexec).
>
>In case anyone else had this problem, this solution does work.  The user
>when logging off now drops out of the system instead of hanging or getting
>the "login:" prompt.
>
>We still have some questions though (from the general public) ...  Is a signal
>16 (found by trial and error) an appropriate way to kill sqlexec?  Are we
>doing any harm to our database by terminating sqlexec with kill?
>

I would try the following in your code before you exit.

  close database
  call sqlexit()

I know sqlexit is not documented, but it should kill your sqlexec process.
If that doesn't work, it would use a kill -13 sigpipe signal on
the sqlexec.  We trap for this signal and clean up gracefully, I'm
not sure about the -16.

Mark Jeske (Chicago consulting)
markj@infmx.com
708-699-5850

jwas@PacBell.COM (Joe Wasik) (11/22/90)

In article <1990Nov20.221658.19496@informix.com> markj@informix.com (Mark Jeske(Chicago Consultan)t) writes:
>>In our case, since the Informix-4GL application starts up
>>other background jobs, the sqlexec program hangs around until those other jobs
>>are finished and it then interferes with the logoff process.

>I would try the following in your code before you exit.
>
>  close database
>  call sqlexit()

While I admit I hadn't even considered doing a close, it's now been tried
and unfortunately it doesn't work.

In fact, the sqlexit() function also appears to wait.  It seems to be waiting
for confirmation that sqlexec back-end has died.  It doesn't get it, so the
program hangs at the sqlexit() function.  An interrupt allows it to continue,
but without killing the sqlexec back-end.

Thanks to all those who send advice.  Nope, signals 1,2,3,13,15 don't work
either.  Signal 9 does, but is obviously undesirable.  Signal 16 works.

Does anyone in Informix-Land know whether the sqlexec back-end does an orderly
exit upon getting signal 16?

Thanks.

-- 
Joe Wasik - PacBell, 2600 Camino Ramon, 4e750, San Ramon, CA 94583  415-823-2422
jcwasik@clib.pacbell.com or {att,bellcore,sun,ames,pyramid}!pacbell!clib!jcwasik
iraq += kuwait; numcountries--; price_oil *= 2; us_public = screwed;


-- 
Joe Wasik - PacBell, 2600 Camino Ramon, 4e750, San Ramon, CA 94583  415-823-2422
jcwasik@clib.pacbell.com or {att,bellcore,sun,ames,pyramid}!pacbell!clib!jcwasik
iraq += kuwait; numcountries--; price_oil *= 2; us_public = screwed;

peter@gongolo.SUBLINK.org (Peter Komanns) (11/24/90)

In article <8335@pbhyf.PacBell.COM>, jwas@PacBell.COM (Joe Wasik) writes:
> In article <1990Nov20.221658.19496@informix.com> markj@informix.com (Mark Jeske(Chicago Consultan)t) writes:
> >>In our case, since the Informix-4GL application starts up
> >>other background jobs, the sqlexec program hangs around until those other jobs
> >>are finished and it then interferes with the logoff process.
> 
> >I would try the following in your code before you exit.
> >
> >  close database
> >  call sqlexit()
> 
> While I admit I hadn't even considered doing a close, it's now been tried
> and unfortunately it doesn't work.
> 
> In fact, the sqlexit() function also appears to wait.  It seems to be waiting
> for confirmation that sqlexec back-end has died.  It doesn't get it, so the
> program hangs at the sqlexit() function.  An interrupt allows it to continue,
> but without killing the sqlexec back-end.
The back-end processor "sqlexec" uses a pipe() call to be activated, and
uses two SHORT variables, called  "_sqlpin" and "_sqpout".
In order to properly close the piping process you have to manage these
file (pipe) descriptors.
In fact, the same error ( sqlexec doesn't want to die ) occurs when:
 - you fork() your process and want the father to exit
 - you exec() another SQL based process
 - you system() another SQL process in the background ("&" at the end
   of the command).

I fixed this bug using fcntl() and setting the close-on-exec flag for
both the pipe descriptors above AND using sqlexit(),
and all works correctly.

Those two extern (global) variables aro undocumented, of course.

****************************************************************************
        Peter Komanns - SINDATA srl - Vimercate - ITALY
Phone (voice) +39,39,6083733                 (fax)+39,39,60,83,957
SUBLINK:peter@cucciolo BANG:.!rutgers!deejay!yachaya!gongolo!cucciolo!peter
****************************************************************************

hugh@fivegl.co.nz (Hugh Grierson) (11/26/90)

In article <8330@pbhyf.PacBell.COM> jwas@PacBell.COM (Joe Wasik) writes:
>We have this rather annoying problem with Informix-4GL.  When an Informix-4GL
>application runs and accesses a database, it starts a back-end named sqlexec.
>This back-end is supposed to die when the Informix-4GL application terminates,
>but it doesn't.  In our case, since the Informix-4GL application starts up
>other background jobs, the sqlexec program hangs around until those other jobs
>are finished and it then interferes with the logoff process.
>...

A guess - is it possible that 4GL is not closing the write-end of its pipe
to sqlexec after fork()ing, and is not using the close-on-exec flag.  Then 
no matter what you do in the parent 4GL program, sqlexec will not know that the
pipe has closed, and possibly may not terminate.  I can't test this theory,
as the behaviour is correct on our machine, but you could try it by running
a C program something like this from your 4GL program (with "without 
waiting"):

	/* untested */
	/* apologies for incorrectness/unportability */
	#include <stdio.h>
	main()
	{
	    int i;
	    for (i=3; i<_NFILE; i++)
		close(i);
	    sleep(100000);
	}

Let me know...

-- 
                               | Hugh Grierson         | hugh@fivegl.co.nz 
                               | 5GL International Ltd | PH:  +64.9.3021621
                               | Auckland, New Zealand | FAX: +64.9.3021617

roberto@neptune.UUCP (Robert Owings) (11/27/90)

In article <1990Nov20.221658.19496@informix.com> markj@informix.com (Mark Jeske(Chicago Consultan)t) writes:
>In our case, since the Informix-4GL application starts up
>other background jobs, the sqlexec program hangs around until those other jobs
>are finished and it then interferes with the logoff process.


Informix's code exec's the sqlexec process when the $datebase call
is made using a simple pipe()/fork()/exec() combo...  unfortunately informix
doesn't set the close on exec flags.

Check your namelist for these two symblols: spqin sqpout
	nm -x YOUREXECUTABLE | egrep '^sqpin|^sqpout'

	then add a function after your $database that does this

	#include <fcntl.h>
	extern short int _sqpin;		/* Global informix symbol - MAGIC MAGIC */
	extern short int _sqpout;		/* Global informix symbol - MAGIC MAGIC */

	set_to_exit()
	{
		/*
		 * don't check errors, if it doesn't work we're no
		 * worse off than before.
		 */
		
		(void)fcntl(_sqpin, FSETFD, 1);
		(void)fcntl(_sqpout, FSETFD, 1);
	}


If the above symbols aren't in your namelist.  Fire up the debugger
of your choice, place a breakpoint at the beginning of pipe(),
run till breakpoint, then check the stack trace for the address of pipe()'s
argument.  Grep thru the namelist for the address and modify the
above code appropriately (praying all the while that informix didn't
declare these static in your release).


This function can occur at any point after the $database.  Since you
are using 4gl, you may not be able to place it close to the $database
so you might want to put it near the exec() to your other processes.


roberto

*** My opinions are my own... use them at your own risk. ***

harry@wsl.UUCP (Henry M. Moreau on wsl) (11/27/90)

In article <8335@pbhyf.PacBell.COM> jwas@PacBell.COM (Joe Wasik) writes:
>
>While I admit I hadn't even considered doing a close, it's now been tried
>and unfortunately it doesn't work.
>

I can't admit to knowing a lot about how 4GL talks to sqlexec, but the problem
you describe sounds like it could be something to do with an inherited
file descriptor.

If sqlexec reads its commands from some file descriptor, say on a pipe,
and your 4GL program forks off processes that inherit this
file descriptor then sqlexec will keep expecting input on the file descriptor
until all processes that could write on it terminate or close the file
descriptor.

If this is what's happening then your child process will have to close
the file descriptor explicitly itself.  If my diagnosis is correct, then 
yes, there is a bug in Informix - the file descriptor should have
had its CLOSE-ON-EXEC flag set in 4GL.