tags:

views:

284

answers:

1

I have a process "x" which uses "system" C function to start ntpd daemon. I observed that ntpd are passed the open file descriptors of "x". ntpd holds on to the file descriptors even after original file is deleted. for ex: Some log files used by "x" are rotated out after sometime, but "ntpd" has file handle opened for these deleted files. Will it cause any problem?

Alternatively I thought of setting "FD_CLOEXEC" flag for all the file descriptors before calling "system" function. But as we are running as an extension library to third process "x"( "x" loads our library based on some condition), there is no easy way to know about all the file descriptors process has opened. One way is to read /proc//fd and set "FD_CLOEXEC" for each file handle and reset it back after "system" function returns. I'm using Linux 2.6.16. Is there any other easy way to find all the file handlers?

Thanks,

+3  A: 

Yes, it will cause a problem. The disk space used by the deleted files will not be released for reuse until the last open file descriptor is in fact closed.

Ideally, you would ensure that FD_CLOEXEC is set on all file descriptors; with POSIX 2008, you can do that when the file is opened with the O_CLOEXEC flag, even. But if you are part of another process and not in charge of its code, then it is not at all easy. Your choices are brute force and ignorance. You can cycle through all the descriptors you think might be open and close them - ignoring errors from descriptors that are already closed. That's brute force. Or you can ignore the files that are open, and hope that the system doesn't jam too badly. Maybe you can limit your search by checking how many files you can have open at once.

Jonathan Leffler
Thanks Jonathan,Ideally I'd have expected an additional parameter "inheritHandle" as part of fork() so that it is easy to decide passing file handles at the time of process creation time. "CreateProcess" in windows has such parameter. I dont know why no one thought of this in Linux?
kumar
@kumar: The difficulty is in controlling which file descriptors are critical to keep open - for example, stdin, stdout, stderr are often carefully set and should be kept open - and which should be closed. There are systems where it is crucial to keep certain descriptors open across 'exec()' calls - Purify and X11 are two examples. So, the difficulty would be "how do you specify which file descriptors should be closed". Having said that, it wouldn't be dreadfully hard to come up with a scheme - the `select()` and `poll()` system calls handle lists of descriptors (in different ways).
Jonathan Leffler
@Jonathan: Could you explain the need to keep fds open accros `exec()` calls, in the case of X11? IMHO it's generally unneeded, even detrimental.
jpalecek
BTW the approach you classify as "brute force" is routinely used by linux applications.
jpalecek
@jpalecek: I know - and I've seen it done on file descriptors up to 32K-1 (in software that actually could, in theory, have that many file descriptors open)! That doesn't make for 'fast'.
Jonathan Leffler
@jpalecek: with X11, my understanding (which could be faulty) is that the display descriptor needs to be kept open for child processes to use. Let's put it another way: on a Solaris machine when I used X11, there was always an extra fd open over and above the first three. I never tracked down why, but it didn't appear when not logged in using X11, so ... I assumed it was 'necessary' for X11 (when it may just have been an accident, of course).
Jonathan Leffler
@Jonathan: Actually, your understanding is wrong. It is true that X11 applications need one fd atop the first three, but this fd is not (and must not) be shared. There's quite a lot of state associated with the connection (eg. you need to remember all the yet unresolved requests to be able to match error messages with them, the requests are numbered sequentially) and that would not work if two different programs poked in the connection.
jpalecek
@jpalacek: OK - thanks; I live and learn (and that's where reading and contributing to SO helps). Now, the comment I wrote is too old to edit, and comments don't support <s>strike through</s> tags - what to do? Edit answer to include relevant portions of the comments, or just leave alone? Probably leave alone. Thanks for the info.
Jonathan Leffler