提交 6cc4fe2c 编写于 作者: D Daniel P. Berrange 提交者: Eric Blake

Move virProcess{Kill, Abort, TranslateStatus} into virprocess.{c, h}

Continue consolidation of process functions by moving some
helpers out of command.{c,h} into virprocess.{c,h}
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 9467ab60)
Signed-off-by: NEric Blake <eblake@redhat.com>

Conflicts:
	src/lxc/lxc_controller.c
	src/util/command.c
	src/util/virprocess.c
	tests/testutils.c
上级 ea877ca7
......@@ -36,6 +36,7 @@
#include "virterror_internal.h"
#include "virfile.h"
#include "virpidfile.h"
#include "virprocess.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
......
......@@ -46,6 +46,7 @@
#include "virfile.h"
#include "virtypedparam.h"
#include "virdbus.h"
#include "virprocess.h"
#include "remote_protocol.h"
#include "qemu_protocol.h"
......
......@@ -141,6 +141,7 @@ src/util/virnetdevvportprofile.c
src/util/virnetlink.c
src/util/virnodesuspend.c
src/util/virpidfile.c
src/util/virprocess.c
src/util/virrandom.c
src/util/virsocketaddr.c
src/util/virterror.c
......
......@@ -140,12 +140,9 @@ virCommandSetPreExecHook;
virCommandSetWorkingDirectory;
virCommandToString;
virCommandTransferFD;
virProcessTranslateStatus;
virCommandWait;
virCommandWriteArgLog;
virFork;
virProcessAbort;
virProcessWait;
virRun;
......@@ -1454,7 +1451,11 @@ virPidFileDeletePath;
# virprocess.h
virProcessAbort;
virProcessKill;
virProcessTranslateStatus;
virProcessWait;
# virrandom.h
virRandomBits;
......
......@@ -64,6 +64,7 @@
#include "virfile.h"
#include "command.h"
#include "virnetdev.h"
#include "virprocess.h"
#define VIR_FROM_THIS VIR_FROM_LXC
......
......@@ -71,6 +71,7 @@
#include "command.h"
#include "processinfo.h"
#include "nodeinfo.h"
#include "virprocess.h"
#define VIR_FROM_THIS VIR_FROM_LXC
......
......@@ -43,6 +43,7 @@
#include "virfile.h"
#include "event.h"
#include "threads.h"
#include "virprocess.h"
#include "passfd.h"
......
......@@ -40,6 +40,7 @@
#include "logging.h"
#include "virfile.h"
#include "virpidfile.h"
#include "virprocess.h"
#include "buf.h"
#include "ignore-value.h"
......@@ -1647,31 +1648,6 @@ virCommandToString(virCommandPtr cmd)
}
/**
* virProcessTranslateStatus:
* @status: child exit status to translate
*
* Translate an exit status into a malloc'd string. Generic helper
* for virCommandRun(), virCommandWait(), virRun(), and virProcessWait()
* status argument, as well as raw waitpid().
*/
char *
virProcessTranslateStatus(int status)
{
char *buf;
if (WIFEXITED(status)) {
ignore_value(virAsprintf(&buf, _("exit status %d"),
WEXITSTATUS(status)));
} else if (WIFSIGNALED(status)) {
ignore_value(virAsprintf(&buf, _("fatal signal %d"),
WTERMSIG(status)));
} else {
ignore_value(virAsprintf(&buf, _("invalid value %d"), status));
}
return buf;
}
/*
* Manage input and output to the child process.
*/
......@@ -2206,55 +2182,6 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid)
}
/**
* virProcessWait:
* @pid: child to wait on
* @exitstatus: optional status collection
*
* Wait for a child process to complete.
* Return -1 on any error waiting for
* completion. Returns 0 if the command
* finished with the exit status set. If @exitstatus is NULL, then the
* child must exit with status 0 for this to succeed.
*/
int
virProcessWait(pid_t pid, int *exitstatus)
{
int ret;
int status;
if (pid <= 0) {
virReportSystemError(EINVAL, _("unable to wait for process %lld"),
(long long) pid);
return -1;
}
/* Wait for intermediate process to exit */
while ((ret = waitpid(pid, &status, 0)) == -1 &&
errno == EINTR);
if (ret == -1) {
virReportSystemError(errno, _("unable to wait for process %lld"),
(long long) pid);
return -1;
}
if (exitstatus == NULL) {
if (status != 0) {
char *st = virProcessTranslateStatus(status);
virCommandError(VIR_ERR_INTERNAL_ERROR,
_("Child process (%lld) status unexpected: %s"),
(long long) pid, NULLSTR(st));
VIR_FREE(st);
return -1;
}
} else {
*exitstatus = status;
}
return 0;
}
/**
* virCommandWait:
* @cmd: command to wait on
......@@ -2319,67 +2246,6 @@ virCommandWait(virCommandPtr cmd, int *exitstatus)
#ifndef WIN32
/**
* virProcessAbort:
* @pid: child process to kill
*
* Abort a child process if PID is positive and that child is still
* running, without issuing any errors or affecting errno. Designed
* for error paths where some but not all paths to the cleanup code
* might have started the child process. If @pid is 0 or negative,
* this does nothing.
*/
void
virProcessAbort(pid_t pid)
{
int saved_errno;
int ret;
int status;
char *tmp = NULL;
if (pid <= 0)
return;
/* See if intermediate process has exited; if not, try a nice
* SIGTERM followed by a more severe SIGKILL.
*/
saved_errno = errno;
VIR_DEBUG("aborting child process %d", pid);
while ((ret = waitpid(pid, &status, WNOHANG)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
} else if (ret == 0) {
VIR_DEBUG("trying SIGTERM to child process %d", pid);
kill(pid, SIGTERM);
usleep(10 * 1000);
while ((ret = waitpid(pid, &status, WNOHANG)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
} else if (ret == 0) {
VIR_DEBUG("trying SIGKILL to child process %d", pid);
kill(pid, SIGKILL);
while ((ret = waitpid(pid, &status, 0)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
}
}
}
VIR_DEBUG("failed to reap child %lld, abandoning it", (long long) pid);
cleanup:
VIR_FREE(tmp);
errno = saved_errno;
}
/**
* virCommandAbort:
* @cmd: command to abort
......@@ -2399,13 +2265,6 @@ virCommandAbort(virCommandPtr cmd)
cmd->reap = false;
}
#else /* WIN32 */
void
virProcessAbort(pid_t pid)
{
/* Not yet ported to mingw. Any volunteers? */
VIR_DEBUG("failed to reap child %lld, abandoning it", (long long)pid);
}
void
virCommandAbort(virCommandPtr cmd ATTRIBUTE_UNUSED)
{
......
......@@ -137,9 +137,6 @@ void virCommandWriteArgLog(virCommandPtr cmd,
char *virCommandToString(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
char *virProcessTranslateStatus(int exitstatus) ATTRIBUTE_RETURN_CHECK;
int virCommandExec(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
int virCommandRun(virCommandPtr cmd,
......@@ -148,9 +145,6 @@ int virCommandRun(virCommandPtr cmd,
int virCommandRunAsync(virCommandPtr cmd,
pid_t *pid) ATTRIBUTE_RETURN_CHECK;
int virProcessWait(pid_t pid,
int *exitstatus) ATTRIBUTE_RETURN_CHECK;
int virCommandWait(virCommandPtr cmd,
int *exitstatus) ATTRIBUTE_RETURN_CHECK;
......@@ -162,8 +156,6 @@ int virCommandHandshakeWait(virCommandPtr cmd)
int virCommandHandshakeNotify(virCommandPtr cmd)
ATTRIBUTE_RETURN_CHECK;
void virProcessAbort(pid_t pid);
void virCommandAbort(virCommandPtr cmd);
void virCommandFree(virCommandPtr cmd);
......
......@@ -78,6 +78,7 @@
#include "command.h"
#include "nonblocking.h"
#include "passfd.h"
#include "virprocess.h"
#ifndef NSIG
# define NSIG 32
......
......@@ -24,8 +24,165 @@
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include "virprocess.h"
#include "virterror_internal.h"
#include "memory.h"
#include "logging.h"
#include "util.h"
#include "ignore-value.h"
#define virReportError(code, ...) \
virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
#define VIR_FROM_THIS VIR_FROM_NONE
/**
* virProcessTranslateStatus:
* @status: child exit status to translate
*
* Translate an exit status into a malloc'd string. Generic helper
* for virCommandRun(), virCommandWait(), virRun(), and virProcessWait()
* status argument, as well as raw waitpid().
*/
char *
virProcessTranslateStatus(int status)
{
char *buf;
if (WIFEXITED(status)) {
ignore_value(virAsprintf(&buf, _("exit status %d"),
WEXITSTATUS(status)));
} else if (WIFSIGNALED(status)) {
ignore_value(virAsprintf(&buf, _("fatal signal %d"),
WTERMSIG(status)));
} else {
ignore_value(virAsprintf(&buf, _("invalid value %d"), status));
}
return buf;
}
#ifndef WIN32
/**
* virProcessAbort:
* @pid: child process to kill
*
* Abort a child process if PID is positive and that child is still
* running, without issuing any errors or affecting errno. Designed
* for error paths where some but not all paths to the cleanup code
* might have started the child process. If @pid is 0 or negative,
* this does nothing.
*/
void
virProcessAbort(pid_t pid)
{
int saved_errno;
int ret;
int status;
char *tmp = NULL;
if (pid <= 0)
return;
/* See if intermediate process has exited; if not, try a nice
* SIGTERM followed by a more severe SIGKILL.
*/
saved_errno = errno;
VIR_DEBUG("aborting child process %d", pid);
while ((ret = waitpid(pid, &status, WNOHANG)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
} else if (ret == 0) {
VIR_DEBUG("trying SIGTERM to child process %d", pid);
kill(pid, SIGTERM);
usleep(10 * 1000);
while ((ret = waitpid(pid, &status, WNOHANG)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
} else if (ret == 0) {
VIR_DEBUG("trying SIGKILL to child process %d", pid);
kill(pid, SIGKILL);
while ((ret = waitpid(pid, &status, 0)) == -1 &&
errno == EINTR);
if (ret == pid) {
tmp = virProcessTranslateStatus(status);
VIR_DEBUG("process has ended: %s", tmp);
goto cleanup;
}
}
}
VIR_DEBUG("failed to reap child %lld, abandoning it", (long long) pid);
cleanup:
VIR_FREE(tmp);
errno = saved_errno;
}
#else
void
virProcessAbort(pid_t pid)
{
/* Not yet ported to mingw. Any volunteers? */
VIR_DEBUG("failed to reap child %lld, abandoning it", (long long)pid);
}
#endif
/**
* virProcessWait:
* @pid: child to wait on
* @exitstatus: optional status collection
*
* Wait for a child process to complete.
* Return -1 on any error waiting for
* completion. Returns 0 if the command
* finished with the exit status set. If @exitstatus is NULL, then the
* child must exit with status 0 for this to succeed.
*/
int
virProcessWait(pid_t pid, int *exitstatus)
{
int ret;
int status;
if (pid <= 0) {
virReportSystemError(EINVAL, _("unable to wait for process %lld"),
(long long) pid);
return -1;
}
/* Wait for intermediate process to exit */
while ((ret = waitpid(pid, &status, 0)) == -1 &&
errno == EINTR);
if (ret == -1) {
virReportSystemError(errno, _("unable to wait for process %lld"),
(long long) pid);
return -1;
}
if (exitstatus == NULL) {
if (status != 0) {
char *st = virProcessTranslateStatus(status);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Child process (%lld) unexpected %s"),
(long long) pid, NULLSTR(st));
VIR_FREE(st);
return -1;
}
} else {
*exitstatus = status;
}
return 0;
}
/* send signal to a single process */
int virProcessKill(pid_t pid, int sig)
......
......@@ -26,6 +26,17 @@
# include "internal.h"
char *
virProcessTranslateStatus(int status);
void
virProcessAbort(pid_t pid);
int
virProcessWait(pid_t pid, int *exitstatus)
ATTRIBUTE_RETURN_CHECK;
int virProcessKill(pid_t pid, int sig);
#endif /* __VIR_PROCESS_H__ */
......@@ -35,6 +35,7 @@
#include "logging.h"
#include "command.h"
#include "virrandom.h"
#include "virprocess.h"
#if TEST_OOM_TRACE
# include <execinfo.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册