提交 6bc99a77 编写于 作者: D Daniel P. Berrange

Allow a pre-opened FD to be be pass to virExec for stdout/err

上级 60ed1d2a
Wed Aug 20 09:59:54 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/util.c: Allow a pre-opened FD to be passed in for childs
stdout/err
* src/openvz_driver.c, src/qemu_driver.c: Initialize FDs to
-1 before calling virExec()
Wed Aug 20 09:35:33 BST 2008 Daniel P. Berrange <berrange@redhat.com> Wed Aug 20 09:35:33 BST 2008 Daniel P. Berrange <berrange@redhat.com>
Avoid signal race in virExec() Avoid signal race in virExec()
......
...@@ -736,7 +736,9 @@ static int openvzGetNodeInfo(virConnectPtr conn, ...@@ -736,7 +736,9 @@ static int openvzGetNodeInfo(virConnectPtr conn,
static int openvzListDomains(virConnectPtr conn, int *ids, int nids) { static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
int got = 0; int got = 0;
int veid, pid, outfd, errfd; int veid, pid;
int outfd = -1;
int errfd = -1;
int ret; int ret;
char buf[32]; char buf[32];
char *endptr; char *endptr;
...@@ -772,7 +774,7 @@ static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) { ...@@ -772,7 +774,7 @@ static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) {
static int openvzListDefinedDomains(virConnectPtr conn, static int openvzListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
int got = 0; int got = 0;
int veid, pid, outfd, errfd, ret; int veid, pid, outfd = -1, errfd = -1, ret;
char vpsname[OPENVZ_NAME_MAX]; char vpsname[OPENVZ_NAME_MAX];
char buf[32]; char buf[32];
char *endptr; char *endptr;
......
...@@ -949,6 +949,9 @@ static int qemudStartVMDaemon(virConnectPtr conn, ...@@ -949,6 +949,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"), qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
errno, strerror(errno)); errno, strerror(errno));
vm->stdout_fd = -1;
vm->stderr_fd = -1;
ret = virExecNonBlock(conn, argv, &vm->pid, ret = virExecNonBlock(conn, argv, &vm->pid,
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd); vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd);
if (ret == 0) { if (ret == 0) {
......
...@@ -118,6 +118,8 @@ _virExec(virConnectPtr conn, ...@@ -118,6 +118,8 @@ _virExec(virConnectPtr conn,
int pid, null, i; int pid, null, i;
int pipeout[2] = {-1,-1}; int pipeout[2] = {-1,-1};
int pipeerr[2] = {-1,-1}; int pipeerr[2] = {-1,-1};
int childout = -1;
int childerr = -1;
sigset_t oldmask, newmask; sigset_t oldmask, newmask;
struct sigaction sig_action; struct sigaction sig_action;
...@@ -140,39 +142,66 @@ _virExec(virConnectPtr conn, ...@@ -140,39 +142,66 @@ _virExec(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if ((outfd != NULL && pipe(pipeout) < 0) || if (outfd != NULL) {
(errfd != NULL && pipe(pipeerr) < 0)) { if (*outfd == -1) {
if (pipe(pipeout) < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot create pipe: %s"), strerror(errno)); _("cannot create pipe: %s"), strerror(errno));
goto cleanup; goto cleanup;
} }
if (outfd) { if (non_block &&
if(non_block &&
virSetNonBlock(pipeout[0]) == -1) { virSetNonBlock(pipeout[0]) == -1) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Failed to set non-blocking file descriptor flag")); _("Failed to set non-blocking file descriptor flag"));
goto cleanup; goto cleanup;
} }
if(virSetCloseExec(pipeout[0]) == -1) { if (virSetCloseExec(pipeout[0]) == -1) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Failed to set close-on-exec file descriptor flag")); _("Failed to set close-on-exec file descriptor flag"));
goto cleanup; goto cleanup;
} }
childout = pipeout[1];
} else {
childout = *outfd;
}
#ifndef ENABLE_DEBUG
} else {
childout = null;
#endif
}
if (errfd != NULL) {
if (*errfd == -1) {
if (pipe(pipeerr) < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Failed to create pipe: %s"), strerror(errno));
goto cleanup;
} }
if (errfd) {
if(non_block && if (non_block &&
virSetNonBlock(pipeerr[0]) == -1) { virSetNonBlock(pipeerr[0]) == -1) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Failed to set non-blocking file descriptor flag")); _("Failed to set non-blocking file descriptor flag"));
goto cleanup; goto cleanup;
} }
if(virSetCloseExec(pipeerr[0]) == -1) {
if (virSetCloseExec(pipeerr[0]) == -1) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Failed to set close-on-exec file descriptor flag")); _("Failed to set close-on-exec file descriptor flag"));
goto cleanup; goto cleanup;
} }
childerr = pipeerr[1];
} else {
childerr = *errfd;
}
#ifndef ENABLE_DEBUG
} else {
childerr = null;
#endif
} }
if ((pid = fork()) < 0) { if ((pid = fork()) < 0) {
...@@ -183,11 +212,11 @@ _virExec(virConnectPtr conn, ...@@ -183,11 +212,11 @@ _virExec(virConnectPtr conn,
if (pid) { /* parent */ if (pid) { /* parent */
close(null); close(null);
if (outfd) { if (outfd && *outfd == -1) {
close(pipeout[1]); close(pipeout[1]);
*outfd = pipeout[0]; *outfd = pipeout[0];
} }
if (errfd) { if (errfd && *errfd == -1) {
close(pipeerr[1]); close(pipeerr[1]);
*errfd = pipeerr[0]; *errfd = pipeerr[0];
} }
...@@ -250,35 +279,25 @@ _virExec(virConnectPtr conn, ...@@ -250,35 +279,25 @@ _virExec(virConnectPtr conn,
_("failed to setup stdin file handle: %s"), strerror(errno)); _("failed to setup stdin file handle: %s"), strerror(errno));
_exit(1); _exit(1);
} }
#ifndef ENABLE_DEBUG if (childout > 0 &&
if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0) { dup2(childout, STDOUT_FILENO) < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("failed to setup stdout file handle: %s"), strerror(errno)); _("failed to setup stdout file handle: %s"), strerror(errno));
_exit(1); _exit(1);
} }
if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0) { if (childerr > 0 &&
ReportError(conn, VIR_ERR_INTERNAL_ERROR, dup2(childerr, STDERR_FILENO) < 0) {
_("failed to setup stderr file handle: %s"), strerror(errno));
_exit(1);
}
#else /* ENABLE_DEBUG */
if (pipeout[1] > 0 && dup2(pipeout[1], STDOUT_FILENO) < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("failed to setup stderr file handle: %s"), strerror(errno)); _("failed to setup stderr file handle: %s"), strerror(errno));
_exit(1); _exit(1);
} }
if (pipeerr[1] > 0 && dup2(pipeerr[1], STDERR_FILENO) < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("failed to setup stdout file handle: %s"), strerror(errno));
_exit(1);
}
#endif /* ENABLE_DEBUG */
close(null); close(null);
if (pipeout[1] > 0) if (childout > 0)
close(pipeout[1]); close(childout);
if (pipeerr[1] > 0) if (childerr > 0 &&
close(pipeerr[1]); childerr != childout)
close(childerr);
execvp(argv[0], (char **) argv); execvp(argv[0], (char **) argv);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册