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: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
e5e2b65cf8
commit
9467ab6074
@ -36,6 +36,7 @@
|
|||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virpidfile.h"
|
#include "virpidfile.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virtypedparam.h"
|
#include "virtypedparam.h"
|
||||||
#include "virdbus.h"
|
#include "virdbus.h"
|
||||||
|
#include "virprocess.h"
|
||||||
#include "remote_protocol.h"
|
#include "remote_protocol.h"
|
||||||
#include "qemu_protocol.h"
|
#include "qemu_protocol.h"
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ src/util/virnetdevvportprofile.c
|
|||||||
src/util/virnetlink.c
|
src/util/virnetlink.c
|
||||||
src/util/virnodesuspend.c
|
src/util/virnodesuspend.c
|
||||||
src/util/virpidfile.c
|
src/util/virpidfile.c
|
||||||
|
src/util/virprocess.c
|
||||||
src/util/virrandom.c
|
src/util/virrandom.c
|
||||||
src/util/virsocketaddr.c
|
src/util/virsocketaddr.c
|
||||||
src/util/virterror.c
|
src/util/virterror.c
|
||||||
|
@ -162,12 +162,9 @@ virCommandSetPreExecHook;
|
|||||||
virCommandSetWorkingDirectory;
|
virCommandSetWorkingDirectory;
|
||||||
virCommandToString;
|
virCommandToString;
|
||||||
virCommandTransferFD;
|
virCommandTransferFD;
|
||||||
virProcessTranslateStatus;
|
|
||||||
virCommandWait;
|
virCommandWait;
|
||||||
virCommandWriteArgLog;
|
virCommandWriteArgLog;
|
||||||
virFork;
|
virFork;
|
||||||
virProcessAbort;
|
|
||||||
virProcessWait;
|
|
||||||
virRun;
|
virRun;
|
||||||
|
|
||||||
|
|
||||||
@ -1709,7 +1706,11 @@ virPidFileDeletePath;
|
|||||||
|
|
||||||
|
|
||||||
# virprocess.h
|
# virprocess.h
|
||||||
|
virProcessAbort;
|
||||||
virProcessKill;
|
virProcessKill;
|
||||||
|
virProcessTranslateStatus;
|
||||||
|
virProcessWait;
|
||||||
|
|
||||||
|
|
||||||
# virrandom.h
|
# virrandom.h
|
||||||
virRandom;
|
virRandom;
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "virnetdev.h"
|
#include "virnetdev.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
#include "processinfo.h"
|
#include "processinfo.h"
|
||||||
#include "nodeinfo.h"
|
#include "nodeinfo.h"
|
||||||
#include "virrandom.h"
|
#include "virrandom.h"
|
||||||
|
#include "virprocess.h"
|
||||||
#include "rpc/virnetserver.h"
|
#include "rpc/virnetserver.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#include "passfd.h"
|
#include "passfd.h"
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virpidfile.h"
|
#include "virpidfile.h"
|
||||||
|
#include "virprocess.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
@ -1686,31 +1687,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.
|
* Manage input and output to the child process.
|
||||||
*/
|
*/
|
||||||
@ -2256,55 +2232,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);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virCommandWait:
|
* virCommandWait:
|
||||||
* @cmd: command to wait on
|
* @cmd: command to wait on
|
||||||
@ -2369,67 +2296,6 @@ virCommandWait(virCommandPtr cmd, int *exitstatus)
|
|||||||
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#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:
|
* virCommandAbort:
|
||||||
* @cmd: command to abort
|
* @cmd: command to abort
|
||||||
@ -2449,13 +2315,6 @@ virCommandAbort(virCommandPtr cmd)
|
|||||||
cmd->reap = false;
|
cmd->reap = false;
|
||||||
}
|
}
|
||||||
#else /* WIN32 */
|
#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
|
void
|
||||||
virCommandAbort(virCommandPtr cmd ATTRIBUTE_UNUSED)
|
virCommandAbort(virCommandPtr cmd ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -140,9 +140,6 @@ void virCommandWriteArgLog(virCommandPtr cmd,
|
|||||||
|
|
||||||
char *virCommandToString(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
|
char *virCommandToString(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
|
||||||
char *virProcessTranslateStatus(int exitstatus) ATTRIBUTE_RETURN_CHECK;
|
|
||||||
|
|
||||||
int virCommandExec(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
|
int virCommandExec(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
int virCommandRun(virCommandPtr cmd,
|
int virCommandRun(virCommandPtr cmd,
|
||||||
@ -151,9 +148,6 @@ int virCommandRun(virCommandPtr cmd,
|
|||||||
int virCommandRunAsync(virCommandPtr cmd,
|
int virCommandRunAsync(virCommandPtr cmd,
|
||||||
pid_t *pid) ATTRIBUTE_RETURN_CHECK;
|
pid_t *pid) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
int virProcessWait(pid_t pid,
|
|
||||||
int *exitstatus) ATTRIBUTE_RETURN_CHECK;
|
|
||||||
|
|
||||||
int virCommandWait(virCommandPtr cmd,
|
int virCommandWait(virCommandPtr cmd,
|
||||||
int *exitstatus) ATTRIBUTE_RETURN_CHECK;
|
int *exitstatus) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
@ -165,8 +159,6 @@ int virCommandHandshakeWait(virCommandPtr cmd)
|
|||||||
int virCommandHandshakeNotify(virCommandPtr cmd)
|
int virCommandHandshakeNotify(virCommandPtr cmd)
|
||||||
ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
void virProcessAbort(pid_t pid);
|
|
||||||
|
|
||||||
void virCommandAbort(virCommandPtr cmd);
|
void virCommandAbort(virCommandPtr cmd);
|
||||||
|
|
||||||
void virCommandFree(virCommandPtr cmd);
|
void virCommandFree(virCommandPtr cmd);
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "nonblocking.h"
|
#include "nonblocking.h"
|
||||||
#include "passfd.h"
|
#include "passfd.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#ifndef NSIG
|
#ifndef NSIG
|
||||||
# define NSIG 32
|
# define NSIG 32
|
||||||
|
@ -24,8 +24,161 @@
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#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 */
|
/* send signal to a single process */
|
||||||
int virProcessKill(pid_t pid, int sig)
|
int virProcessKill(pid_t pid, int sig)
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
|
|
||||||
# include "internal.h"
|
# 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);
|
int virProcessKill(pid_t pid, int sig);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __VIR_PROCESS_H__ */
|
#endif /* __VIR_PROCESS_H__ */
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "virrandom.h"
|
#include "virrandom.h"
|
||||||
#include "dirname.h"
|
#include "dirname.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#if TEST_OOM_TRACE
|
#if TEST_OOM_TRACE
|
||||||
# include <execinfo.h>
|
# include <execinfo.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user