bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bugs #10967] gdnc daemon/file descriptor problem on NetBSD 1.6.2


From: Richard Frith-Macdonald
Subject: [bugs #10967] gdnc daemon/file descriptor problem on NetBSD 1.6.2
Date: Sun, 21 Nov 2004 03:49:12 -0500
User-agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.5.5 (KHTML, like Gecko) Safari/125.11

This mail is an automated notification from the bugs tracker
 of the project: GNUstep.

/**************************************************************************/
[bugs #10967] Latest Modifications:

Changes by: 
                Richard Frith-Macdonald <rfm@gnu.org>
'Date: 
                Sun 11/21/2004 at 08:43 (GMT)

            What     | Removed                   | Added
---------------------------------------------------------------------------
          Resolution | None                      | Fixed
         Assigned to | None                      | CaS
              Status | Open                      | In Test


------------------ Additional Follow-up Comments ----------------------------
Attempted fix now in place in CVS ... please test.

The problem turns out to be that -
1. Closing all file descriptors messes up the pth threading library.
2. Good practice is to close unnecessary descriptors in a daemon.
3. There is no obvious way to find out which descriptors pth uses.

The solution I decided upon was, rather than simply forking to produce the
daemon, to fork and the exec the program again ... thus reinitialising the
threading system for the newly exec'ed program.

However, to re-exec the program we need to determine the path to the 
executable.  This required two bugfixes in NSBundle -
1. Ensure that the -executablePath method works for the main bundle.
2. Ensure that the +mainBundle method returns a bundle rather than nil.

This should all be working now ... I've tested it on my Debian GNU/Linux 
system, but of course it needs to be tested on a BSD system using the pth 
library, and I don't have that system to test on.








/**************************************************************************/
[bugs #10967] Full Item Snapshot:

URL: <http://savannah.gnu.org/bugs/?func=detailitem&item_id=10967>
Project: GNUstep
Submitted by: Riccardo mottola
On: Thu 11/11/2004 at 10:55

Category:  Base/Foundation
Severity:  5 - Average
Item Group:  Bug
Resolution:  Fixed
Privacy:  Public
Assigned to:  CaS
Status:  In Test


Summary:  gdnc daemon/file descriptor problem on NetBSD 1.6.2

Original Submission:  On NetBSD 1.6.2 gdnc fails to run: as soon as a client 
connects, it aborts. the culprit seems to be this code part:

  for (c = 0; c < FD_SETSIZE; c++)
    {
      if (is_daemon || (c != 2))
        {
          (void)close(c); 
        }
    }

it seems that too many fs's get closed and then threads break with a strange 
error message (already reported in another bug report, so almost for sure the 
two bugs are related to the same problem).

substtituting FD_SETSIZE with <= 2 works.

I never used FD_SETSIZE as in the code abce and the NetBSD manpage even states 
that FD_SETSIZE could be user set.

Alexander M. suggest to use the syscall daemon() on the system which have it to 
make the daemon. It is a BSD-style call, but linux seems to have it too.

Follow-up Comments
------------------


-------------------------------------------------------
Date: Sun 11/21/2004 at 08:43       By: Richard Frith-Macdonald <CaS>
Attempted fix now in place in CVS ... please test.

The problem turns out to be that -
1. Closing all file descriptors messes up the pth threading library.
2. Good practice is to close unnecessary descriptors in a daemon.
3. There is no obvious way to find out which descriptors pth uses.

The solution I decided upon was, rather than simply forking to produce the
daemon, to fork and the exec the program again ... thus reinitialising the
threading system for the newly exec'ed program.

However, to re-exec the program we need to determine the path to the 
executable.  This required two bugfixes in NSBundle -
1. Ensure that the -executablePath method works for the main bundle.
2. Ensure that the +mainBundle method returns a bundle rather than nil.

This should all be working now ... I've tested it on my Debian GNU/Linux 
system, but of course it needs to be tested on a BSD system using the pth 
library, and I don't have that system to test on.



-------------------------------------------------------
Date: Thu 11/11/2004 at 22:01       By: Richard Frith-Macdonald <CaS>
I downloaded the source to the pth library ... and it looks like this problem 
is a feature of pth rather than a BSD specific thing.
It seems that the pth library uses a pipe for internal signalling/scheduling,
so if we close that pipe we will mess up the library. 
Unfortunately, the library does not assign the pipe any particular descriptor 
numbers, so we can't be sure which descriptors ar those needed for pth.

That being the case, I don't think there is any good solution to the problem 
... perhaps the least bad would be to use a similar mechanism to windows, fork, 
close descriptors, then exec to a new copy of the process with an extra 
argument to prevent it forking recursively.


-------------------------------------------------------
Date: Thu 11/11/2004 at 14:36       By: Riccardo mottola <rmottola>
The exact error is

**Pth** SCHEDULER INTERNAL ERROR: no more thread(s) available to schedule!?!?

which comes from pth, googling around I found that other got the same problem 
in daemons, but since their code is quite different I couldn't gather more info 
for now.

The upcoming 2.0 beta which has native kernel threads doesn't suffer this 
problem, so I think it is not a NetBSD problem per se, but an interaction of 
NetBSD and Pth. 

-------------------------------------------------------
Date: Thu 11/11/2004 at 14:21       By: Richard Frith-Macdonald <CaS>
The loop to close all descriptors is based on very old BSD unix source code for 
daemons ... so I think it, or variants of it are pretty widely used.  Certainly 
this sort of technique is commonly recommended to ensure that unused resources 
are released in a fork()ed process under unix.

A more modern alternative might be to do
int limit = getdtablesize();
for (c = 0; c < limit; c++) ...

The worst that *should* happen if you loop round closing all file descriptors 
is that it takes a long time (if the set size you use is very large), as a 
close() call should either close a descriptor and succeed, or return an error 
status.
A version which won't take too long might be  to do
int limit = getdtablesize();
if (limit > 10000) limit = 10000;
for (c = 0; c < limit; c++) ...

It may be that some 'feature' in recent BSDs does not like particular 
descriptors being closed.  Perhaps the threading implementation uses file 
descriptors for something ...

Perhaps searching the web for the actual error message (whatever it is) will 
provide a hint as to which descriptor(s) need to be left open on NetBSD, then 
we can easily modify the code to treat those descriptors specially.

Failing that, we *could* just restrict ourselves to closing 0,1,2 ... but 
depending on what launches gdnc, that might leave files held open when they 
shouldn't be.













For detailed info, follow this link:
<http://savannah.gnu.org/bugs/?func=detailitem&item_id=10967>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/







reply via email to

[Prev in Thread] Current Thread [Next in Thread]