Linux-Development-Apps Digest #358, Volume #7 Wed, 25 Apr 01 10:13:11 EDT Contents: Re: why some processes are defunct? (Ferenc Wagner) Re: How to get a number of processors (Chris) Re: generic way to close a child process's inherited file descriptors? (nathan wagner) Re: generic way to close a spawned child inherited file descriptors? (nathan wagner) Re: why some processes are defunct? (Chris) Re: why some processes are defunct? (Chris) Re: generic way to close a spawned child inherited file descriptors? (Chris) Re: generic way to close a spawned child inherited file descriptors? (William Morris) Re: void main() (was Re: linux c++ problem) (Richard Bos) A problem with module programming . (hushui) Re: A problem with module programming . ("Zoran Cutura") Oracle Install Problem (Norman Dunbar) ---------------------------------------------------------------------------- From: Ferenc Wagner <[EMAIL PROTECTED]> Subject: Re: why some processes are defunct? Date: 25 Apr 2001 11:26:40 +0200 Chris <[EMAIL PROTECTED]> writes: >>> void chld(int i) { >>> while (waitpid(-1, NULL, WNOHANG) > 0) >>> printf("reaped 1 child\n"); >>> } >> >> This solution makes me way of race conditions. What if >> the parent yields its timeslice after waitpid() fails >> once and a child terminates right then? > > Errm. In that case, surely you would receive another > SIGCHLD? > [...] > I think that the sequence of events is like this: > > A child terminates; SIGCHLD is raised and the > SIGCHLD handler called. > > During the execution of the SIGCHLD handler, > with SIGCHLD blocked, another child terminates. > SIGCHLD is now pending, and will be caught when > the currently-executing SIGCHLD handler returns. > > What do you suggest as an alternative for the handler? Let me add an interesting point, which confuses me: info libc "Merged Signals" has a longish example right about SIGCHLD. From that it seems to me that waitpid() can be interrupted by a signal, and thus return EINTR, so that in the while loop you have to take care of that, too. On the other hand, man waitpid says in its ERRORS section: ERESTARTSYS if WNOHANG was not set and an unblocked signal or a SIGCHLD was caught. This error is returned by the system call. The library interface is not allowed to return ERESTARTSYS, but will return EINTR. It clearly contradicts the assumption drawn from info's code example, because WNOHANG is set in that case. The man page seems to make more sense to me, but I'm interested about the real world. Particularly, what happens with waitpid if SIGCHLD is blocked during the call? Strict logic based on the above quote from the manual implies that SIGCHLD would be caught even in a SIGCHLD signal handler! Or am I mistaken? Feri. ------------------------------ From: Chris <[EMAIL PROTECTED]> Crossposted-To: comp.os.linux.development.system Subject: Re: How to get a number of processors Date: Wed, 25 Apr 2001 10:53:14 +0100 Dave Blake wrote: > > Chris <[EMAIL PROTECTED]> wrote: > > Dave Blake wrote: > > > > Parsing /proc is the only way on a linux system. The kernel API > > > does not support the POSIX sysconf standard, although the glibc > > > maintainers do support it (I think by parsing /proc). > > > > I was incorrect in stating that it was a system call; it > > is not, either on Linux or Solaris. > > I think that it is a system call on Solaris. And the glibc > maintainers spent some time trying to make it a system call on > linux. It's in (3C) on Solaris. > > How glibc does the business is not really important, so > > long as it works. > > > > > And I think that /proc/stat is going to prove more resistant to > > > change than /proc/cpuinfo, but neither are above change. I do > > > know that the procps package does need to know the number of > > > CPUs for a few things, and it parses /proc/stat to get this > > > info. > > > > This is a terrible idea, because it is gratuitously > > non-portable. > > Look - if the kernel maintainers change /proc/stat in some > subtle way, it will break the sysconf call. If your program > looks at /proc/stat, you can fix it rather easily. If glibc is > broken, it will take a LOT longer to fix. And the changes will > take a LOT longer to propagate since most people rarely if ever > upgrade glibc. That is not what portability means. Portability means that your program stands a fighting chance of running on *another* system, rather than that it will run on Linux in the future. Your argument about glibc is spurious, for two reasons. Firstly, you shouldn't duplicate code; if there needs to be code to read /proc/stat to count the number of CPUS in the system, there should be only one instance of it, so that there is only one thing to correct. The second is that there is no reason that developers of random applications should track kernel changes of this sort; far better to let the glibc maintainers-- who really need to track the kernel-- do it for you. They are also, probably, less likely to screw it up. You cannot be seriously suggesting that your program should, on Linux, parse /proc/stat, whereas on another system it does it The Right Way(TM)? -- Chris Lightfoot -- chris at ex dash parrot dot com -- www.ex-parrot.com/~chris/ If you see a long line of rats streaming off of a ship, the correct assumption is not `Gosh, I bet that's a real nice boat now that those rats are gone.' (Mike Sphar) ------------------------------ From: [EMAIL PROTECTED] (nathan wagner) Subject: Re: generic way to close a child process's inherited file descriptors? Date: 25 Apr 2001 09:31:14 GMT Reply-To: [EMAIL PROTECTED] On 24 Apr 2001 20:31:13 -0400, Eric P. McCoy <[EMAIL PROTECTED]> wrote: >[EMAIL PROTECTED] (steve burkett) writes: > >> is there a **generic** way to either: >> (1) disallow the forked client from inheriting open file >> descriptors? > >Try looking at fcntl() and the FD_CLOEXEC flag. > >> (2) or, once in the client, to close all inherited file descriptors? > >Write a cleanup function that does it, and call that function right >before the exec...(). I read "once in the client" to mean once in the exec()ed client. In which case you could use sysconf(3) to determine the maximum number of open file descriptors, then loop over and close each one. /* untested */ maxfd = sysconf(_SC_OPEN_MAX); while(maxfd--) close(maxfd); As far as i know, there is no good way to determine the largest open file descriptor. The first solution (setting the close on exec flag in the parent) is probably better. -- Chance is irrelevant. We will succeed. -- Seven of Nine ------------------------------ From: [EMAIL PROTECTED] (nathan wagner) Subject: Re: generic way to close a spawned child inherited file descriptors? Date: 25 Apr 2001 09:34:07 GMT Reply-To: [EMAIL PROTECTED] On Wed, 25 Apr 2001 08:02:52 GMT, William Morris <[EMAIL PROTECTED]> wrote: >Perhaps try looping through all possible fds (0..OPEN_MAX) and closing >them between fork() and execlp(). It does seem rather an ugly way of doing >things and indeed, doesn't close any streams using these fds. Could you expand upon this? I am under the impression that calling close(2) on a file descriptor closes it. Perhaps i don't know what a stream is. -- Chance is irrelevant. We will succeed. -- Seven of Nine ------------------------------ From: Chris <[EMAIL PROTECTED]> Subject: Re: why some processes are defunct? Date: Wed, 25 Apr 2001 11:28:58 +0100 Ferenc Wagner wrote: > > Chris <[EMAIL PROTECTED]> writes: > > >>> void chld(int i) { > >>> while (waitpid(-1, NULL, WNOHANG) > 0) > >>> printf("reaped 1 child\n"); > >>> } > >> > >> This solution makes me way of race conditions. What if > >> the parent yields its timeslice after waitpid() fails > >> once and a child terminates right then? > > > > Errm. In that case, surely you would receive another > > SIGCHLD? > > [...] > > I think that the sequence of events is like this: > > > > A child terminates; SIGCHLD is raised and the > > SIGCHLD handler called. > > > > During the execution of the SIGCHLD handler, > > with SIGCHLD blocked, another child terminates. > > SIGCHLD is now pending, and will be caught when > > the currently-executing SIGCHLD handler returns. > > > > What do you suggest as an alternative for the handler? > > Let me add an interesting point, which confuses me: > > info libc "Merged Signals" > > has a longish example right about SIGCHLD. From that it > seems to me that waitpid() can be interrupted by a signal, > and thus return EINTR, so that in the while loop you have to > take care of that, too. > > On the other hand, man waitpid says in its ERRORS section: > > ERESTARTSYS > if WNOHANG was not set and an unblocked signal or a > SIGCHLD was caught. This error is returned by the > system call. The library interface is not allowed > to return ERESTARTSYS, but will return EINTR. > > It clearly contradicts the assumption drawn from info's code > example, because WNOHANG is set in that case. The man page > seems to make more sense to me, but I'm interested about the > real world. Particularly, what happens with waitpid if > SIGCHLD is blocked during the call? Strict logic based on > the above quote from the manual implies that SIGCHLD would > be caught even in a SIGCHLD signal handler! > > Or am I mistaken? You can select this behaviour by using the flag SA_NODEFER when you call sigaction. But I don't suppose that this guarantees `reliability' (in the sense that the signal handler is called as many times as a signal is raised), and it certainly won't make writing the signal handler any more fun. I think the point is that if, say, SIGTERM, is received while waitpid is waiting, then waitpid will return -1 and the library will set errno to EINTR. This is the behaviour which the info example suggests. Hence, I _think_ you want something like: (untested!) void chld(int i) { while (1) { pid_t p; p = waitpid(-1, NULL, WNOHANG); if (p > 0) { /* Reaped child */ } else if (p == 0 /* No child */ || p == -1 && errno != EINTR) /* Error other than interrupted */ return; /* Done */ } /*NOTREACHED*/ } -- Chris Lightfoot -- chris at ex dash parrot dot com -- www.ex-parrot.com/~chris/ ``The male shall be deemed to embrace the female.'' (from the constitution of a university Methodist Society) ------------------------------ From: Chris <[EMAIL PROTECTED]> Subject: Re: why some processes are defunct? Date: Wed, 25 Apr 2001 12:19:56 +0100 Josef Moellers wrote: > > Alexander Burger wrote: > > > > Josef Moellers <[EMAIL PROTECTED]> wrote: > > > Alexander Burger wrote: > > >> > > >> Eric P. McCoy <[EMAIL PROTECTED]> wrote: > > >> > Is there a way of waiting on children that ensures that they will > > >> > _never_ become zombies, under any circumstances? > > >> > > >> If you are not interested in the child's exit status, you can simply call > > >> > > >> signal(SIGCLD,SIG_IGN); > > >> > > >> before the fork(). > > >> > > >> Then the children of that process will never become zombies. > > > > > Since this is _linux_: > > > "According to POSIX (B.3.3.1.3) you must not set the action for SIGCHLD > > > to SIG_IGN." (from man 2 signal). > > > > Yes, but I'm talking about SIGCLD, and _not_ SIGCHLD. > > Again, since we are discussing Linux in this group, from the manual > page: > SIGCLD -,-,18 A synonym for SIGCHLD Note (from waitpid(2))-- The Single Unix Specification describes a flag SA_NOCLD WAIT (not present under Linux) such that if either this flag is set, or the action for SIGCHLD is set to SIG_IGN (which, by the way, is not allowed by POSIX), then chil dren that exit do not become zombies and a call to wait() or waitpid() will block until all children have exited, and then fail with errno set to ECHILD. This does appear to work on Linux, though it's plenty ugly. -- Chris Lightfoot -- chris at ex dash parrot dot com -- www.ex-parrot.com/~chris/ Everybody has a right to pronounce foreign names as he chooses (Churchill) ------------------------------ From: Chris <[EMAIL PROTECTED]> Subject: Re: generic way to close a spawned child inherited file descriptors? Date: Wed, 25 Apr 2001 12:44:08 +0100 nathan wagner wrote: > > On Wed, 25 Apr 2001 08:02:52 GMT, > William Morris <[EMAIL PROTECTED]> wrote: > > >Perhaps try looping through all possible fds (0..OPEN_MAX) and closing > >them between fork() and execlp(). It does seem rather an ugly way of doing > >things and indeed, doesn't close any streams using these fds. > > Could you expand upon this? I am under the impression that calling > close(2) on a file descriptor closes it. Perhaps i don't know what a > stream is. I think he means stdio streams (`FILE *fp'). -- Chris Lightfoot -- chris at ex dash parrot dot com -- www.ex-parrot.com/~chris/ Plane Too Close to Ground, Crash Probe Told (newspaper headline) ------------------------------ From: William Morris <[EMAIL PROTECTED]> Subject: Re: generic way to close a spawned child inherited file descriptors? Date: Wed, 25 Apr 2001 11:49:21 GMT >>Perhaps try looping through all possible fds (0..OPEN_MAX) and closing >>them between fork() and execlp(). It does seem rather an ugly way of doing >>things and indeed, doesn't close any streams using these fds. > Could you expand upon this? I am under the impression that calling > close(2) on a file descriptor closes it. Perhaps i don't know what a > stream is. You are correct in that close(2) does close an fd. However, things like stdin, stdout, stderr are streams (type FILE *), as is anything opened with fopen(3). stdio streams have an underlying fd, but stdio manages access to the fd in a convenient manner (eg line buffering). If you do fclose( stdout ); the stream and the underlying fd are closed (and the buffer released, etc). If you just do close( fileno( stdout )); you are closing the fd associated with stdout, but the stream remains "open" although now unusable (printf() after this close() call does nothing). Hope this helps. Regards -- William Morris [EMAIL PROTECTED] ------------------------------ From: [EMAIL PROTECTED] (Richard Bos) Subject: Re: void main() (was Re: linux c++ problem) Date: Wed, 25 Apr 2001 12:26:03 GMT Rene Herman <[EMAIL PROTECTED]> wrote: > > No. The standard says "It _shall_ be defined with a return type of > > int ..." (emphasis mine). In section 4/2 "Conformance," we have: > > > > If a "shall" or "shall not" requirement that appears outside of a > > constraint is violated, the behavior is undefined. > > I still seem to be having trouble understanding why the standard is > saying that it isn't implementation-defined but undefined. Please note > that I'm not arguing that it is, this is meant as an "honest question". If the result of void main() were implementation-defined, all implementations would have to support it one way or another. However, implementations are free to not support void main() at all. Thus, the Standard does not put any requirements whatsoever on the result of a program containing a void main() (as it _does_ do for int main(void) and int main(int argc, char **argv)); and thus, the behaviour of void main() is undefined. Richard ------------------------------ From: hushui <[EMAIL PROTECTED]> Subject: A problem with module programming . Date: 25 Apr 2001 12:01:26 GMT I write a simple program to show "hello world " in kernel mode . It can be insoded successfully . But when I use rmmod it, it always return error : module hello.o is not loaded ?? Why ??? Once it is loaded and excuted ,it can expire from memory automatically?? Thank you . ------------------------------ From: "Zoran Cutura" <[EMAIL PROTECTED]> Subject: Re: A problem with module programming . Date: Wed, 25 Apr 2001 15:15:37 +0200 Reply-To: [EMAIL PROTECTED] Once upon a while "hushui" <[EMAIL PROTECTED]> wrote: > I write a simple program to show "hello world " in kernel mode > . It can be insoded successfully . But when I use rmmod it, it > always return error : module hello.o is not loaded ?? Why ??? > Once it is loaded and excuted ,it can expire from memory > automatically?? Thank you . Your module may be called hello instead of hello.o! -- Z ([EMAIL PROTECTED]) "LISP is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days." -- Eric S. Raymond ------------------------------ From: Norman Dunbar <[EMAIL PROTECTED]> Subject: Oracle Install Problem Date: Wed, 25 Apr 2001 14:07:06 +0100 Brad, not sure if this will help or not, but I believe that there is a not on Oracle Metalink which says that for RedHat the GCC libraries have to be downgraded to fix this problem. The note is 121176.1 on http://metalink.oracle.com Norman. PS. I don't hang out here very often, so email me direct if you need more info. PPS. Here is the text from the above note ............ Doc ID: Note:121176.1 Subject: Oracle doesn't start on RedHat Linux 7.0 after relinking Type: ALERT Status: REVIEWED Content Type: TEXT/PLAIN Creation Date: 03-OCT-2000 Last Revision Date: 20-MAR-2001 ************************************************************************ ****** This article is being delivered in Draft form before publishing standards have been applied, and may contain errors. Please use the MetaLink "Feedback" button to advise Oracle of any issues related to this article or this process. ************************************************************************ ****** Oracle does not start on RedHat Linux 7.0 after relinking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Versions Affected ~~~~~~~~~~~~~~~~~ Product & Oracle versions affected 8.1.6.1, 8.1.7 (verified) 8.0.5.x, 8.0.6.x, 8.1.5.x (not verified) Platforms Affected ~~~~~~~~~~~~~~~~~~ RedHat Linux 7.0 and any glibc-2.1.9x or glibc-2.2 based distribution. Note that mainly due to this issue, certification of such distributions is still pending as of March 2001. This note is intended to provide functionality in advance of the real certification, which will likely result in a different approach than this. Description ~~~~~~~~~~~ After upgrading from earlier versions of RedHat Linux to RedHat 7.0 Oracle fails to start up after being relinked. The reason is a generic incompatibility across different major versions of GNU libc that does not guarantee that a binary linked against a version of glibc will keep working if relinked in an environment of a later major glibc release. Since Oracle 8.1.6.1 is linked against glibc-2.1.3 and RedHat 7.0 ships with glibc-2.1.9x, we experience the described problem. This will also happen with 8.0.5, 8.0.6 and 8.1.7; the w/a here described only applies to 8.1.6.1, but its core also works for 8.1.7. This note will be updated shortly to include the 8.1.7 workaround (currently being reviewed). There will be no w/a for 8.0.5 since it already requires an older compatibility package than the one that is needed for 8.0.6; customers needing to upgrade to newer distributions will also need to upgrade to more recent Oracle versions. Likelihood of Occurrence ~~~~~~~~~~~~~~~~~~~~~~~~ This problem will occur after relinking Oracle to install patches or kernel options or to deinstall them. It will NOT occur if Oracle is not relinked after the OS upgrade. Possible Symptoms ~~~~~~~~~~~~~~~~~ Starting up the database fails with ORA-3113 after some time spent looping in semop() and a core file is generated. The stack trace taken with GDB on a 8.1.6.1 core is the following: (gdb) where #0 0x404c74e1 in __kill () from /lib/libc.so.6 #1 0x8469156 in slcra () #2 0x846cd01 in ssexhd () #3 0x4048ed60 in pthread_sighandler (signo=11, ctx={gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43, __dsh = 0, edi = 3221208616, esi = 3221208744, ebp = 3221208516, esp = 3221207644, ebx = 3221207676, edx = 0, ecx = 3221207676, eax = 0, trapno = 14, err = 4, eip = 138857746, cs = 35, __csh = 0, eflags = 2163270, esp_at_signal = 3221207644, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0, cr2 = 8}) at signals.c:97 #4 <signal handler called> #5 0x846cd12 in ssexhd () #6 0x4048ed60 in pthread_sighandler (signo=11, ctx={gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43, __dsh = 0, edi = 3221209840, esi = 3221209968, ebp = 3221209740, esp = 3221208868, ebx = 3221208900, edx = 0, ecx = 3221208900, eax = 0, trapno = 14, err = 4, eip = 138857746, cs = 35, __csh = 0, eflags = 2163351, esp_at_signal = 3221208868, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0, cr2 = 8}) at signals.c:97 #7 <signal handler called> #8 0x846cd12 in ssexhd () #9 0x4048ed60 in pthread_sighandler (signo=11, ctx={gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43, __dsh = 0, edi = 3221211064, esi = 3221211192, ebp = 3221210964, esp = 3221210092, ebx = 3221210124, edx = 0, ecx = 3221210124, eax = 0, trapno = 14, err = 4, eip = 138857746, cs = 35, __csh = 0, eflags = 2163347, esp_at_signal = 3221210092, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0, cr2 = 8}) at signals.c:97 #10 <signal handler called> #11 0x846cd12 in ssexhd () #12 0x4048ed60 in pthread_sighandler (signo=11, ctx={gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43, __dsh = 0, edi = 153736192, esi = 3221213276, ebp = 3221211380, esp = 3221211320, ebx = 3575600, edx = 3221211332, ecx = 1745, eax = 502, trapno = 14, err = 6, eip = 145158780, cs = 35, __csh = 0, eflags = 2163219, esp_at_signal = 3221211320, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 2147483648, cr2 = 1745}) at signals.c:97 #13 <signal handler called> #14 0x8a6f27c in sskgmstat () Workaround ~~~~~~~~~~ (for 8.1.6.1 on RedHat 7.0) Install the following packages: compat-egcs-6.2-1.1.2.9 compat-glibc-6.2-2.1.3.2 and modify all occurences of CC and LINK definitions in all env_*.mk makefiles in the $ORACLE_HOME software tree from either $(LDCCOM) or gcc to i386-glibc21-linux-gcc. To better illustrate the needed changes, the lines such as CC=cc LINK=$(LDCCOM) LINK=$(PURECMDS) gcc $(LDFLAGS) $(COMPOBJS) will become CC=i386-glibc21-linux-gcc LINK=i386-glibc21-linux-gcc LINK=$(PURECMDS) i386-glibc21-linux-gcc $(LDFLAGS) $(COMPOBJS) You will also need to modify the genclntsh shell script and substitute LD="ld -shared -L${ORACLE_HOME}/lib" LD_RUNTIME="-R${ORACLE_HOME}/lib" LD_OPT="-h ${CLNT_LIB}" with LD="i386-glibc21-linux-gcc -shared -L${ORACLE_HOME}/lib" LD_RUNTIME="-Wl,-R${ORACLE_HOME}/lib" LD_OPT="-Wl,-h${CLNT_LIB}" Finally, rebuild libclntsh.so by running 'genclntsh' and relink oracle, svrmgrl etc. using the usual relink commands. You'll get warnings in the relink process but they can be ignored. This has been tested on env_rdbms.mk, env_sqlplus.mk, env_network.mk, env_oemagent.mk, env_precomp.mk but should be working on any env*.mk makefile. Other possible workarounds: --------------------------- - downgrade to RedHat 6.2 - get a copy of the oracle kernel and utilities such as svrmgrl, imp, exp etc. from a RedHat 6.2 box and place them in $ORACLE_HOME/bin - if you haven't relinked multiple times, it's enough to copy back the old binary versions in $ORACLE_HOME/bin (such as oracleO, impO etc.) to oracle, imp etc. Note that the two latter workarounds will not allow you to relink the Oracle kernel and/or utilities - the resulting binaries will not run under a glibc-2.1.9x system. Patches ~~~~~~~ n/a References ~~~~~~~~~~ n/a ________________________________________________________________________ ______ Oracle Support Services . ======================================================================== ======== Copyright (c) 1995,2000 Oracle Corporation. All Rights Reserved. Legal Notices and Terms of Use. ======================================================================== ======== Norman Dunbar EMail: [EMAIL PROTECTED] Database/Unix administrator Phone: 0113 289 6265 Lynx Financial Systems Ltd. Fax: 0113 201 7265 URL: http://www.LynxFinancialSystems.com ======================================================================== ======== =====Original Message===== From: Brad Rogers [mailto:[EMAIL PROTECTED]] Posted At: Tuesday, April 24, 2001 10:02 PM Posted To: apps Conversation: Oracle Install Problem Subject: Oracle Install Problem I have failed miserably at installing Oracle 8i enterprise edition on my Linux box. I am running SUSE7.1, 2.4 kernel, with 128 RAM, and KDE. <SNIP> ------------------------------ ** FOR YOUR REFERENCE ** The service address, to which questions about the list itself and requests to be added to or deleted from it should be directed, is: Internet: [EMAIL PROTECTED] You can send mail to the entire list by posting to the comp.os.linux.development.apps newsgroup. Linux may be obtained via one of these FTP sites: ftp.funet.fi pub/Linux tsx-11.mit.edu pub/linux sunsite.unc.edu pub/Linux End of Linux-Development-Apps Digest ******************************