When a child is forked then it inherits parent's file descriptors, if child closes the file descriptor what will happen ?
It inherits a copy of the file descriptor. So closing the descriptor in the child will close it for the child, but not the parent, and vice versa.
If child starts writing what shall happen to the file at the parent's end ? Who manages these inconsistencies , kernel or user ?
It's exactly (as in, exactly literally) the same as two processes writing to the same file. The kernel schedules the processes independently, so you will likely get interleaved data in the file.
However, POSIX (to which *nix systems largely or completely conform), stipulates that read()
and write()
functions from the C API (which map to system calls) are "atomic with respect to each other [...] when they operate on regular files or symbolic links". The GNU C manually also provisionally promises this with regard to pipes (note the default PIPE_BUF
, which is part of the proviso, is 64 kiB). This means that calls in other languages/tools, such as use of echo
or cat
, should be included in that contract, so if two indepenedent process try to write "hello" and "world" simultaneously to the same pipe, what will come out the other end is either "helloworld" or "worldhello", and never something like "hweolrllod".
when a process call close function to close a particular open file through file descriptor.The file table of process decrement the reference count by one.But since parent and child both are holding the same file(there refrence count is 2 and after close it reduces to 1)since it is not zero so process still continue to use file without any problem.
There are TWO processes, the parent and the child. There is no "reference count" common to both of them. They are independent. WRT what happens when one of them closes a file descriptor, see the answer to the first question.
The program in question will have to be altered or, simply, restarted.
What appears to be happening is that the program is opening a file handle for writing to the log, and keeping that selfsame file handle open for the duration. If the file is removed, as you describe it is "held" in abeyance and indeed is still written to until the file handle is closed.
If you can alter the program to change it from (pseudocode):
LogFileHandle = OpenFileHandle( Logfile, 'wa' )
UpdateLog( log_entry ) {
LogFileHandle.Write( log_entry )
}
do_literally_everything_forever()
LogFileHandle.Close()
to (pseudocode):
UpdateLog( log_entry ) {
LogFileHandle = OpenFileHandle( Logfile, 'wa' )
LogFileHandle.Write( log_entry )
LogFileHandle.Close()
}
do_literally_everything_forever()
That will solve the issue.
If you cannot, then rather than rebooting the entire system, a file which has been rm
ed will be well and truly gone once all processes holding open a file handle have been closed (or, more specifically, their file handles have been closed).
Most well-written daemons will incidentally cycle their file handles if sent SIGHUP (read your program's documentation!). But simply stopping (or terminating) and restarting the program will also release any open file handles.
Best Answer
When you delete a file you really remove a link to the file (to the inode). If someone already has that file open, they get to keep the file descriptor they have. The file remains on disk, taking up space, and can be written to and read from if you have access to it.
The
unlink
function is defined with this behaviour by POSIX:This piece of advice because of that behaviour. The daemon will have the file open, and won't notice that it has been deleted (unless it was monitoring it specifically, which is uncommon). It will keep blithely writing to the existing file descriptor it has: you'll keep taking up (more) space on disk, but you won't be able to see any of the messages it writes, so you're really in the worst of both worlds. If you truncate the file to zero length instead then the space is freed up immediately, and any new messages will be appended at the new end of the file where you can see them.
Eventually, when the daemon terminates or
close
s the file, the space will be freed up. Nobody new can open the file in the mean time (other than through system-specific reflective interfaces like Linux's/proc/x/fd/...
). It's also guaranteed that:So you don't lose your disk space permanently, but you don't gain anything by deleting the file and you lose access to new messages.