On 07/12/2011 03:00 PM, Eric Blake wrote:
Since libvirt is multi-threaded, we should use FD_CLOEXEC as much
as possible in the parent, and only relax fds to inherited after
forking, to avoid leaking an fd created in one thread to a fork
run in another thread. This gets us closer to that ideal, by
making virCommand automatically clear FD_CLOEXEC on fds intended
for the child, as well as avoiding a window of time with non-cloexec
pipes created for capturing output.
* src/util/command.c (virExecWithHook): Use CLOEXEC in parent. In
child, guarantee that all fds to pass to child are inheritable.
(getDevNull): Use CLOEXEC.
(prepareStdFd): New helper function.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Simplify caller.
---
src/qemu/qemu_command.c | 16 --------------
src/util/command.c | 51 ++++++++++++++++++++++++-----------------------
2 files changed, 26 insertions(+), 41 deletions(-)
Squash this in as well:
diff --git c/src/util/command.c w/src/util/command.c
index 24681e6..177847b 100644
--- c/src/util/command.c
+++ w/src/util/command.c
@@ -1654,7 +1654,7 @@ virCommandRun(virCommandPtr cmd, int *exitstatus)
/* If we have an input buffer, we need
* a pipe to feed the data to the child */
if (cmd->inbuf) {
- if (pipe(infd) < 0) {
+ if (pipe2(infd, O_CLOEXEC) < 0) {
virReportSystemError(errno, "%s",
_("unable to open pipe"));
cmd->has_error = -1;
@@ -2103,11 +2103,11 @@ void virCommandRequireHandshake(virCommandPtr cmd)
return;
}
- if (pipe(cmd->handshakeWait) < 0) {
+ if (pipe2(cmd->handshakeWait, O_CLOEXEC) < 0) {
cmd->has_error = errno;
return;
}
- if (pipe(cmd->handshakeNotify) < 0) {
+ if (pipe2(cmd->handshakeNotify, O_CLOEXEC) < 0) {
VIR_FORCE_CLOSE(cmd->handshakeWait[0]);
VIR_FORCE_CLOSE(cmd->handshakeWait[1]);
cmd->has_error = errno;
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org