提交 1b4bb7d4 编写于 作者: D Daniel P. Berrange

Allow non-blocking/daemon mode to be specified via virExec flags

上级 6bc99a77
Wed Aug 20 10:16:54 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/util.c, src/util.h: Allow flags to be passed to specify
non-blocking, or daemon mode
* src/qemu_driver.c, src/openvz_driver.c, src/storage_backend.c:
Switch to virExec() with VIR_EXEC_NONBLOCK flag
Wed Aug 20 09:59:54 BST 2008 Daniel P. Berrange <berrange@redhat.com> 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 * src/util.c: Allow a pre-opened FD to be passed in for childs
......
...@@ -744,7 +744,7 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) { ...@@ -744,7 +744,7 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
char *endptr; char *endptr;
const char *cmd[] = {VZLIST, "-ovpsid", "-H" , NULL}; const char *cmd[] = {VZLIST, "-ovpsid", "-H" , NULL};
ret = virExec(conn, cmd, &pid, -1, &outfd, &errfd); ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
if(ret == -1) { if(ret == -1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZLIST); _("Could not exec %s"), VZLIST);
...@@ -781,7 +781,7 @@ static int openvzListDefinedDomains(virConnectPtr conn, ...@@ -781,7 +781,7 @@ static int openvzListDefinedDomains(virConnectPtr conn,
const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL}; const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
/* the -S options lists only stopped domains */ /* the -S options lists only stopped domains */
ret = virExec(conn, cmd, &pid, -1, &outfd, &errfd); ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
if(ret == -1) { if(ret == -1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZLIST); _("Could not exec %s"), VZLIST);
......
...@@ -952,8 +952,9 @@ static int qemudStartVMDaemon(virConnectPtr conn, ...@@ -952,8 +952,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
vm->stdout_fd = -1; vm->stdout_fd = -1;
vm->stderr_fd = -1; vm->stderr_fd = -1;
ret = virExecNonBlock(conn, argv, &vm->pid, ret = virExec(conn, argv, NULL, &vm->pid,
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd); vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
VIR_EXEC_NONBLOCK);
if (ret == 0) { if (ret == 0) {
vm->def->id = driver->nextvmid++; vm->def->id = driver->nextvmid++;
vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING; vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
...@@ -1200,7 +1201,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn, ...@@ -1200,7 +1201,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0) if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
return -1; return -1;
ret = virExecNonBlock(conn, argv, &network->dnsmasqPid, -1, NULL, NULL); ret = virExec(conn, argv, NULL, &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
for (i = 0; argv[i]; i++) for (i = 0; argv[i]; i++)
VIR_FREE(argv[i]); VIR_FREE(argv[i]);
......
...@@ -403,7 +403,7 @@ virStorageBackendRunProgRegex(virConnectPtr conn, ...@@ -403,7 +403,7 @@ virStorageBackendRunProgRegex(virConnectPtr conn,
/* Run the program and capture its output */ /* Run the program and capture its output */
if (virExec(conn, prog, &child, -1, &fd, NULL) < 0) { if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
goto cleanup; goto cleanup;
} }
...@@ -537,7 +537,7 @@ virStorageBackendRunProgNul(virConnectPtr conn, ...@@ -537,7 +537,7 @@ virStorageBackendRunProgNul(virConnectPtr conn,
v[i] = NULL; v[i] = NULL;
/* Run the program and capture its output */ /* Run the program and capture its output */
if (virExec(conn, prog, &child, -1, &fd, NULL) < 0) { if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
goto cleanup; goto cleanup;
} }
......
...@@ -111,11 +111,14 @@ static int virSetNonBlock(int fd) { ...@@ -111,11 +111,14 @@ static int virSetNonBlock(int fd) {
return 0; return 0;
} }
static int int
_virExec(virConnectPtr conn, virExec(virConnectPtr conn,
const char *const*argv, const char *const*argv,
int *retpid, int infd, int *outfd, int *errfd, int non_block) { const char *const*envp,
int pid, null, i; int *retpid,
int infd, int *outfd, int *errfd,
int flags) {
int pid, null, i, openmax;
int pipeout[2] = {-1,-1}; int pipeout[2] = {-1,-1};
int pipeerr[2] = {-1,-1}; int pipeerr[2] = {-1,-1};
int childout = -1; int childout = -1;
...@@ -150,7 +153,7 @@ _virExec(virConnectPtr conn, ...@@ -150,7 +153,7 @@ _virExec(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (non_block && if ((flags & VIR_EXEC_NONBLOCK) &&
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"));
...@@ -181,7 +184,7 @@ _virExec(virConnectPtr conn, ...@@ -181,7 +184,7 @@ _virExec(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (non_block && if ((flags & VIR_EXEC_NONBLOCK) &&
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"));
...@@ -268,10 +271,40 @@ _virExec(virConnectPtr conn, ...@@ -268,10 +271,40 @@ _virExec(virConnectPtr conn,
return -1; return -1;
} }
if (pipeout[0] > 0) openmax = sysconf (_SC_OPEN_MAX);
close(pipeout[0]); for (i = 3; i < openmax; i++)
if (pipeerr[0] > 0) if (i != infd &&
close(pipeerr[0]); i != null &&
i != childout &&
i != childerr)
close(i);
if (flags & VIR_EXEC_DAEMON) {
if (setsid() < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot become session leader: %s"),
strerror(errno));
_exit(1);
}
if (chdir("/") < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot change to root directory: %s"),
strerror(errno));
_exit(1);
}
pid = fork();
if (pid < 0) {
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot fork child process: %s"),
strerror(errno));
_exit(1);
}
if (pid > 0)
_exit(0);
}
if (dup2(infd >= 0 ? infd : null, STDIN_FILENO) < 0) { if (dup2(infd >= 0 ? infd : null, STDIN_FILENO) < 0) {
...@@ -299,7 +332,10 @@ _virExec(virConnectPtr conn, ...@@ -299,7 +332,10 @@ _virExec(virConnectPtr conn,
childerr != childout) childerr != childout)
close(childerr); close(childerr);
execvp(argv[0], (char **) argv); if (envp)
execve(argv[0], (char **) argv, (char**)envp);
else
execvp(argv[0], (char **) argv);
ReportError(conn, VIR_ERR_INTERNAL_ERROR, ReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot execute binary '%s': %s"), _("cannot execute binary '%s': %s"),
...@@ -329,22 +365,6 @@ _virExec(virConnectPtr conn, ...@@ -329,22 +365,6 @@ _virExec(virConnectPtr conn,
return -1; return -1;
} }
int
virExec(virConnectPtr conn,
const char *const*argv,
int *retpid, int infd, int *outfd, int *errfd) {
return(_virExec(conn, argv, retpid, infd, outfd, errfd, 0));
}
int
virExecNonBlock(virConnectPtr conn,
const char *const*argv,
int *retpid, int infd, int *outfd, int *errfd) {
return(_virExec(conn, argv, retpid, infd, outfd, errfd, 1));
}
/** /**
* @conn connection to report errors against * @conn connection to report errors against
* @argv NULL terminated argv to run * @argv NULL terminated argv to run
...@@ -366,7 +386,7 @@ virRun(virConnectPtr conn, ...@@ -366,7 +386,7 @@ virRun(virConnectPtr conn,
int *status) { int *status) {
int childpid, exitstatus, ret; int childpid, exitstatus, ret;
if ((ret = virExec(conn, argv, &childpid, -1, NULL, NULL)) < 0) if ((ret = virExec(conn, argv, NULL, &childpid, -1, NULL, NULL, VIR_EXEC_NONE)) < 0)
return ret; return ret;
while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR); while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR);
......
...@@ -27,10 +27,20 @@ ...@@ -27,10 +27,20 @@
#include "util-lib.h" #include "util-lib.h"
#include "verify.h" #include "verify.h"
int virExec(virConnectPtr conn, const char *const*argv, int *retpid, enum {
int infd, int *outfd, int *errfd); VIR_EXEC_NONE = 0,
int virExecNonBlock(virConnectPtr conn, const char *const*argv, int *retpid, VIR_EXEC_NONBLOCK = (1 << 0),
int infd, int *outfd, int *errfd); VIR_EXEC_DAEMON = (1 << 1),
};
int virExec(virConnectPtr conn,
const char *const*argv,
const char *const*envp,
int *retpid,
int infd,
int *outfd,
int *errfd,
int flags);
int virRun(virConnectPtr conn, const char *const*argv, int *status); int virRun(virConnectPtr conn, const char *const*argv, int *status);
int __virFileReadAll(const char *path, int __virFileReadAll(const char *path,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册