#include "virterror_internal.h"
#include "util.h"
#include "virfile.h"
+#include "virpidfile.h"
+#include "virprocess.h"
#include "nodeinfo.h"
#include "cpu/cpu.h"
#include "domain_conf.h"
virMutex lock;
virHashTablePtr binaries;
char *libDir;
+ char *runDir;
};
static int
qemuCapsInitQMP(qemuCapsPtr caps,
- const char *libDir)
+ const char *libDir,
+ const char *runDir)
{
int ret = -1;
virCommandPtr cmd = NULL;
virDomainChrSourceDef config;
char *monarg = NULL;
char *monpath = NULL;
+ char *pidfile = NULL;
+ /* the ".sock" sufix is important to avoid a possible clash with a qemu
+ * domain called "capabilities"
+ */
if (virAsprintf(&monpath, "%s/%s", libDir, "capabilities.monitor.sock") < 0) {
virReportOOMError();
goto cleanup;
goto cleanup;
}
+ /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
+ * with a qemu domain called "capabilities"
+ */
+ if (virAsprintf(&pidfile, "%s/%s", runDir, "capabilities.pidfile") < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
memset(&config, 0, sizeof(config));
config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
config.data.nix.path = monpath;
"-nographic",
"-M", "none",
"-qmp", monarg,
+ "-pidfile", pidfile,
"-daemonize",
NULL);
virCommandAddEnvPassCommon(cmd);
virCommandFree(cmd);
VIR_FREE(monarg);
VIR_FREE(monpath);
+
+ if (pidfile) {
+ char ebuf[1024];
+ pid_t pid;
+ int rc;
+
+ if ((rc = virPidFileReadPath(pidfile, &pid)) < 0) {
+ VIR_DEBUG("Failed to read pidfile %s: %d",
+ pidfile, virStrerror(-rc, ebuf, sizeof(ebuf)));
+ } else {
+ VIR_DEBUG("Killing QMP caps process %lld", (long long) pid);
+ if (virProcessKill(pid, SIGKILL) < 0 && errno != ESRCH)
+ VIR_ERROR(_("Failed to kill process %lld: %s"),
+ (long long) pid,
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ }
+ unlink(pidfile);
+ VIR_FREE(pidfile);
+ }
return ret;
}
qemuCapsPtr qemuCapsNewForBinary(const char *binary,
- const char *libDir)
+ const char *libDir,
+ const char *runDir)
{
qemuCapsPtr caps = qemuCapsNew();
struct stat sb;
goto error;
}
- if ((rv = qemuCapsInitQMP(caps, libDir)) < 0)
+ if ((rv = qemuCapsInitQMP(caps, libDir, runDir)) < 0)
goto error;
if (!caps->usedQMP &&
qemuCapsCachePtr
-qemuCapsCacheNew(const char *libDir)
+qemuCapsCacheNew(const char *libDir, const char *runDir)
{
qemuCapsCachePtr cache;
if (!(cache->binaries = virHashCreate(10, qemuCapsHashDataFree)))
goto error;
- if (!(cache->libDir = strdup(libDir))) {
+ if (!(cache->libDir = strdup(libDir)) ||
+ !(cache->runDir = strdup(runDir))) {
virReportOOMError();
goto error;
}
if (!ret) {
VIR_DEBUG("Creating capabilities for %s",
binary);
- ret = qemuCapsNewForBinary(binary, cache->libDir);
+ ret = qemuCapsNewForBinary(binary, cache->libDir, cache->runDir);
if (ret) {
VIR_DEBUG("Caching capabilities %p for %s",
ret, binary);
return;
VIR_FREE(cache->libDir);
+ VIR_FREE(cache->runDir);
virHashFree(cache->binaries);
virMutexDestroy(&cache->lock);
VIR_FREE(cache);
qemuCapsPtr qemuCapsNew(void);
qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps);
qemuCapsPtr qemuCapsNewForBinary(const char *binary,
- const char *libDir);
+ const char *libDir,
+ const char *runDir);
int qemuCapsProbeQMP(qemuCapsPtr caps,
qemuMonitorPtr mon);
bool qemuCapsIsValid(qemuCapsPtr caps);
-qemuCapsCachePtr qemuCapsCacheNew(const char *libDir);
+qemuCapsCachePtr qemuCapsCacheNew(const char *libDir, const char *runDir);
qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary);
qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary);
void qemuCapsCacheFree(qemuCapsCachePtr cache);