static int
qemuCapsInitQMP(qemuCapsPtr caps,
const char *libDir,
- const char *runDir,
uid_t runUid,
gid_t runGid)
{
/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
* with a qemu domain called "capabilities"
+ * Normally we'd use runDir for pid files, but because we're using
+ * -daemonize we need QEMU to be allowed to create them, rather
+ * than libvirtd. So we're using libDir which QEMU can write to
*/
- if (virAsprintf(&pidfile, "%s/%s", runDir, "capabilities.pidfile") < 0) {
+ if (virAsprintf(&pidfile, "%s/%s", libDir, "capabilities.pidfile") < 0) {
virReportOOMError();
goto cleanup;
}
VIR_DEBUG("Try to get caps via QMP caps=%p", caps);
+ /*
+ * We explicitly need to use -daemonize here, rather than
+ * virCommandDaemonize, because we need to synchronize
+ * with QEMU creating its monitor socket API. Using
+ * daemonize guarantees control won't return to libvirt
+ * until the socket is present.
+ */
cmd = virCommandNewArgList(caps->binary,
"-S",
"-no-user-config",
"-nographic",
"-M", "none",
"-qmp", monarg,
+ "-pidfile", pidfile,
+ "-daemonize",
NULL);
virCommandAddEnvPassCommon(cmd);
virCommandClearCaps(cmd);
hookData.runUid = runUid;
hookData.runGid = runGid;
virCommandSetPreExecHook(cmd, qemuCapsHook, &hookData);
- virCommandSetPidFile(cmd, pidfile);
- virCommandDaemonize(cmd);
if (virCommandRun(cmd, &status) < 0)
goto cleanup;
qemuCapsPtr qemuCapsNewForBinary(const char *binary,
const char *libDir,
- const char *runDir,
uid_t runUid,
gid_t runGid)
{
goto error;
}
- if ((rv = qemuCapsInitQMP(caps, libDir, runDir, runUid, runGid)) < 0)
+ if ((rv = qemuCapsInitQMP(caps, libDir, runUid, runGid)) < 0)
goto error;
if (!caps->usedQMP &&
qemuCapsCachePtr
-qemuCapsCacheNew(const char *libDir, const char *runDir,
- uid_t runUid, gid_t runGid)
+qemuCapsCacheNew(const char *libDir,
+ uid_t runUid,
+ gid_t runGid)
{
qemuCapsCachePtr cache;
if (!(cache->binaries = virHashCreate(10, qemuCapsHashDataFree)))
goto error;
- if (!(cache->libDir = strdup(libDir)) ||
- !(cache->runDir = strdup(runDir))) {
+ if (!(cache->libDir = strdup(libDir))) {
virReportOOMError();
goto error;
}
if (!ret) {
VIR_DEBUG("Creating capabilities for %s",
binary);
- ret = qemuCapsNewForBinary(binary, cache->libDir, cache->runDir,
+ ret = qemuCapsNewForBinary(binary, cache->libDir,
cache->runUid, cache->runGid);
if (ret) {
VIR_DEBUG("Caching capabilities %p for %s",
return;
VIR_FREE(cache->libDir);
- VIR_FREE(cache->runDir);
virHashFree(cache->binaries);
virMutexDestroy(&cache->lock);
VIR_FREE(cache);