May 18, 2009

Bugzilla Fables: Serving Two Masters

You may know this: spending a few hard days, or even minutes, figuring out a bug and in the end the result is a one line change. What an injustice! So let's expand one such case for the amusement and education of the audience. Fable #501758:

For certain tasks, YaST uses external helpers (agents) communicating via pipes. One of them was causing YaST to hang when cleaning up. Actually no, it was two of them. Either one was not enough, but if two of them had been used, they would both keep on running and YaST would not exit.

It turns out the bug is in YaST not closing unnecessary file descriptors before spawning the agents. So the second child inherits a copy of the pipe that controls the first child. Then YaST closes the first child's commands pipe, expecting it to see EOF and exit. But the pipe is still open in the second child, uselessly. And they all wait. And wait...(*)

Moral: close unnecessary FDs before exec.

If you wonder why we did not see the problem earlier, it is because both agents contained another bug, a banal one of not responding to an explicit Exit message.

*) Actually, only YaST wait(2)s. The other two read(2) ;-)