Posting my findings with the hope that it would be of help to someone out there.

system and backtick both fork a child process. Backtick differs from system in that it opens a pipe for gathering the child process/command’s output. And this is what perl doc on fork has to say about file descriptors:

Any filehandles open at the time of the fork() will be dup()-ed. Thus, the files can be closed independently in the parent and child, but beware that the dup()-ed handles will still share the same seek pointer. Changing the seek position in the parent will change it in the child and vice-versa. One can avoid this by opening files that need distinct seek pointers separately in the child. On some operating systems, notably Solaris and Unixware, calling exit() from a child process will flush and close open filehandles in the parent, thereby corrupting the filehandles. On these systems, calling_exit() is suggested instead. _exit() is available in Perl through the POSIX module. Please consult your system's manpages for more information on this

So, whatever file descriptors/handles were open at the time of executing system/backtick are inherited by the child process/command. Which means processes like ntpd/dhcpd/named etc inherit all of the parent perl process' open file descriptors including any pipes opened as part of backtick.

Somehow ntpd, in my case, also inherited the write-end of the pipe which is the reason the parent process, which had the read-end of the pipe, was stuck in read(2) indefinitely because ntpd is a long running process. Now, the parent process closes the write-end of the pipe before forking but the whole operation of opening the pipe and closing the write-end is not atomic so .......

perl process

backtick

pipe()

<---------- GAP HERE

close() write-end of pipe

The solution I used was to write a perl wrapper script which closes all fds except 0/1/2 and then exec the command, like this:

`closed.pl service xyz restart`;

There are multiple ways of closing fds. I used the tips from the following discussion : http://www.perlmonks.org/?node_id=476086

Here's a link which describes a similar issue : http://tdistler.com/2010/06/18/stop-stealing-my-file-descriptors


In reply to Re^3: parent process stuck in read(2) on pipe opened to child process using backtick by onong
in thread parent process stuck in read(2) on pipe opened to child process using backtick by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.