[libvirt] PATCH: Allow specific FDs to be kept open in virExec()
Daniel P. Berrange
berrange at redhat.com
Tue Aug 26 09:41:18 UTC 2008
On Thu, Aug 21, 2008 at 02:58:30PM +0100, Daniel P. Berrange wrote:
> With my recent patches to virExec(), all FDs except stdin/out/err are closed
> before the child is exec'd to prevent accidental leaks. Of course I forgot
> the one key place where we need to propagate FDs... The TAP devices passed
> to QEMU.
>
> This patch adds a 'keepfd' parameter to virExec() which allows the caller
> to specify a bitset of file descriptors to keep open, and updates the
> callers to use this as required. The QEMU driver specifies any TAP fds
> and the LXC driver specifies its PTY this way removing a previous hack.
>
> QEMU networking works again with fix....
Changed to use fd_set from sys/select
Index: src/lxc_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_driver.c,v
retrieving revision 1.24
diff -u -p -r1.24 lxc_driver.c
--- src/lxc_driver.c 22 Aug 2008 15:35:37 -0000 1.24
+++ src/lxc_driver.c 26 Aug 2008 09:11:42 -0000
@@ -621,6 +621,10 @@ static int lxcControllerStart(virConnect
const char **largv = NULL;
pid_t child;
int status;
+ fd_set keepfd;
+ char appPtyStr[30];
+
+ FD_ZERO(&keepfd);
#define ADD_ARG_SPACE \
do { \
@@ -644,11 +648,13 @@ static int lxcControllerStart(virConnect
goto no_memory; \
} while (0)
+ snprintf(appPtyStr, sizeof(appPtyStr), "%d", appPty);
+
ADD_ARG_LIT(vm->def->emulator);
ADD_ARG_LIT("--name");
ADD_ARG_LIT(vm->def->name);
ADD_ARG_LIT("--console");
- ADD_ARG_LIT("0"); /* Passing console master PTY as FD 0 */
+ ADD_ARG_LIT(appPtyStr);
ADD_ARG_LIT("--background");
for (i = 0 ; i < nveths ; i++) {
@@ -658,10 +664,12 @@ static int lxcControllerStart(virConnect
ADD_ARG(NULL);
- vm->stdin_fd = appPty; /* Passing console master PTY as FD 0 */
+ vm->stdin_fd = -1;
vm->stdout_fd = vm->stderr_fd = logfd;
- if (virExec(conn, largv, NULL, &child,
+ FD_SET(appPty, &keepfd);
+
+ if (virExec(conn, largv, NULL, &keepfd, &child,
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
VIR_EXEC_NONE) < 0)
goto cleanup;
Index: src/openvz_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_driver.c,v
retrieving revision 1.43
diff -u -p -r1.43 openvz_driver.c
--- src/openvz_driver.c 20 Aug 2008 20:48:36 -0000 1.43
+++ src/openvz_driver.c 26 Aug 2008 09:11:43 -0000
@@ -807,7 +807,8 @@ static int openvzListDomains(virConnectP
char *endptr;
const char *cmd[] = {VZLIST, "-ovpsid", "-H" , NULL};
- ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
+ ret = virExec(conn, cmd, NULL, NULL,
+ &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
if(ret == -1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZLIST);
@@ -844,7 +845,8 @@ static int openvzListDefinedDomains(virC
const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
/* the -S options lists only stopped domains */
- ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
+ ret = virExec(conn, cmd, NULL, NULL,
+ &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
if(ret == -1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZLIST);
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.111
diff -u -p -r1.111 qemu_driver.c
--- src/qemu_driver.c 20 Aug 2008 20:48:36 -0000 1.111
+++ src/qemu_driver.c 26 Aug 2008 09:11:45 -0000
@@ -847,6 +847,9 @@ static int qemudStartVMDaemon(virConnect
int *tapfds = NULL;
int ntapfds = 0;
int qemuCmdFlags;
+ fd_set keepfd;
+
+ FD_ZERO(&keepfd);
if (virDomainIsActive(vm)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -950,7 +953,10 @@ static int qemudStartVMDaemon(virConnect
vm->stdout_fd = -1;
vm->stderr_fd = -1;
- ret = virExec(conn, argv, NULL, &vm->pid,
+ for (i = 0 ; i < ntapfds ; i++)
+ FD_SET(tapfds[i], &keepfd);
+
+ ret = virExec(conn, argv, NULL, &keepfd, &vm->pid,
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
VIR_EXEC_NONBLOCK);
if (ret == 0) {
@@ -1219,7 +1225,8 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
return -1;
- ret = virExec(conn, argv, NULL, &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
+ ret = virExec(conn, argv, NULL, NULL,
+ &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
for (i = 0; argv[i]; i++)
VIR_FREE(argv[i]);
Index: src/storage_backend.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend.c,v
retrieving revision 1.19
diff -u -p -r1.19 storage_backend.c
--- src/storage_backend.c 20 Aug 2008 09:24:14 -0000 1.19
+++ src/storage_backend.c 26 Aug 2008 09:11:46 -0000
@@ -403,7 +403,8 @@ virStorageBackendRunProgRegex(virConnect
/* Run the program and capture its output */
- if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
+ if (virExec(conn, prog, NULL, NULL,
+ &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
goto cleanup;
}
@@ -537,7 +538,8 @@ virStorageBackendRunProgNul(virConnectPt
v[i] = NULL;
/* Run the program and capture its output */
- if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
+ if (virExec(conn, prog, NULL, NULL,
+ &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
goto cleanup;
}
Index: src/util.c
===================================================================
RCS file: /data/cvs/libvirt/src/util.c,v
retrieving revision 1.53
diff -u -p -r1.53 util.c
--- src/util.c 20 Aug 2008 19:42:36 -0000 1.53
+++ src/util.c 26 Aug 2008 09:11:47 -0000
@@ -132,6 +132,7 @@ int
virExec(virConnectPtr conn,
const char *const*argv,
const char *const*envp,
+ const fd_set *keepfd,
int *retpid,
int infd, int *outfd, int *errfd,
int flags) {
@@ -293,7 +294,9 @@ virExec(virConnectPtr conn,
if (i != infd &&
i != null &&
i != childout &&
- i != childerr)
+ i != childerr &&
+ (!keepfd ||
+ !FD_ISSET(i, keepfd)))
close(i);
if (flags & VIR_EXEC_DAEMON) {
@@ -403,7 +406,8 @@ virRun(virConnectPtr conn,
int *status) {
int childpid, exitstatus, ret;
- if ((ret = virExec(conn, argv, NULL, &childpid, -1, NULL, NULL, VIR_EXEC_NONE)) < 0)
+ if ((ret = virExec(conn, argv, NULL, NULL,
+ &childpid, -1, NULL, NULL, VIR_EXEC_NONE)) < 0)
return ret;
while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR);
Index: src/util.h
===================================================================
RCS file: /data/cvs/libvirt/src/util.h,v
retrieving revision 1.25
diff -u -p -r1.25 util.h
--- src/util.h 20 Aug 2008 19:42:36 -0000 1.25
+++ src/util.h 26 Aug 2008 09:11:47 -0000
@@ -26,6 +26,7 @@
#include "util-lib.h"
#include "verify.h"
+#include <sys/select.h>
enum {
VIR_EXEC_NONE = 0,
@@ -36,6 +37,7 @@ enum {
int virExec(virConnectPtr conn,
const char *const*argv,
const char *const*envp,
+ const fd_set *keepfd,
int *retpid,
int infd,
int *outfd,
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
More information about the libvir-list
mailing list