mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Allow non-blocking/daemon mode to be specified via virExec flags
This commit is contained in:
parent
6bc99a7775
commit
1b4bb7d4ab
@ -1,3 +1,10 @@
|
||||
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>
|
||||
|
||||
* 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) {
|
||||
char *endptr;
|
||||
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) {
|
||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not exec %s"), VZLIST);
|
||||
@ -781,7 +781,7 @@ static int openvzListDefinedDomains(virConnectPtr conn,
|
||||
const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
|
||||
|
||||
/* 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) {
|
||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not exec %s"), VZLIST);
|
||||
|
@ -952,8 +952,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
||||
vm->stdout_fd = -1;
|
||||
vm->stderr_fd = -1;
|
||||
|
||||
ret = virExecNonBlock(conn, argv, &vm->pid,
|
||||
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd);
|
||||
ret = virExec(conn, argv, NULL, &vm->pid,
|
||||
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
|
||||
VIR_EXEC_NONBLOCK);
|
||||
if (ret == 0) {
|
||||
vm->def->id = driver->nextvmid++;
|
||||
vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
|
||||
@ -1200,7 +1201,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
|
||||
if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
|
||||
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++)
|
||||
VIR_FREE(argv[i]);
|
||||
|
@ -403,7 +403,7 @@ virStorageBackendRunProgRegex(virConnectPtr conn,
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -537,7 +537,7 @@ virStorageBackendRunProgNul(virConnectPtr conn,
|
||||
v[i] = NULL;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
74
src/util.c
74
src/util.c
@ -111,11 +111,14 @@ static int virSetNonBlock(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_virExec(virConnectPtr conn,
|
||||
int
|
||||
virExec(virConnectPtr conn,
|
||||
const char *const*argv,
|
||||
int *retpid, int infd, int *outfd, int *errfd, int non_block) {
|
||||
int pid, null, i;
|
||||
const char *const*envp,
|
||||
int *retpid,
|
||||
int infd, int *outfd, int *errfd,
|
||||
int flags) {
|
||||
int pid, null, i, openmax;
|
||||
int pipeout[2] = {-1,-1};
|
||||
int pipeerr[2] = {-1,-1};
|
||||
int childout = -1;
|
||||
@ -150,7 +153,7 @@ _virExec(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (non_block &&
|
||||
if ((flags & VIR_EXEC_NONBLOCK) &&
|
||||
virSetNonBlock(pipeout[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
@ -181,7 +184,7 @@ _virExec(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (non_block &&
|
||||
if ((flags & VIR_EXEC_NONBLOCK) &&
|
||||
virSetNonBlock(pipeerr[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
@ -268,10 +271,40 @@ _virExec(virConnectPtr conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pipeout[0] > 0)
|
||||
close(pipeout[0]);
|
||||
if (pipeerr[0] > 0)
|
||||
close(pipeerr[0]);
|
||||
openmax = sysconf (_SC_OPEN_MAX);
|
||||
for (i = 3; i < openmax; i++)
|
||||
if (i != infd &&
|
||||
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) {
|
||||
@ -299,6 +332,9 @@ _virExec(virConnectPtr conn,
|
||||
childerr != childout)
|
||||
close(childerr);
|
||||
|
||||
if (envp)
|
||||
execve(argv[0], (char **) argv, (char**)envp);
|
||||
else
|
||||
execvp(argv[0], (char **) argv);
|
||||
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
@ -329,22 +365,6 @@ _virExec(virConnectPtr conn,
|
||||
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
|
||||
* @argv NULL terminated argv to run
|
||||
@ -366,7 +386,7 @@ virRun(virConnectPtr conn,
|
||||
int *status) {
|
||||
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;
|
||||
|
||||
while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR);
|
||||
|
18
src/util.h
18
src/util.h
@ -27,10 +27,20 @@
|
||||
#include "util-lib.h"
|
||||
#include "verify.h"
|
||||
|
||||
int virExec(virConnectPtr conn, const char *const*argv, int *retpid,
|
||||
int infd, int *outfd, int *errfd);
|
||||
int virExecNonBlock(virConnectPtr conn, const char *const*argv, int *retpid,
|
||||
int infd, int *outfd, int *errfd);
|
||||
enum {
|
||||
VIR_EXEC_NONE = 0,
|
||||
VIR_EXEC_NONBLOCK = (1 << 0),
|
||||
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 __virFileReadAll(const char *path,
|
||||
|
Loading…
x
Reference in New Issue
Block a user