virSecurityManagerNew;
virSecurityManagerNewDAC;
virSecurityManagerNewStack;
+virSecurityManagerPostFork;
+virSecurityManagerPreFork;
virSecurityManagerReleaseLabel;
virSecurityManagerReserveLabel;
virSecurityManagerRestoreAllLabel;
virDomainObjPtr vm;
virQEMUDriverPtr driver;
virBitmapPtr nodemask;
+ virQEMUDriverConfigPtr cfg;
};
static int qemuProcessHook(void *data)
struct qemuProcessHookData *h = data;
int ret = -1;
int fd;
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(h->driver);
+ /* This method cannot use any mutexes, which are not
+ * protected across fork()
+ */
+
+ virSecurityManagerPostFork(h->driver->securityManager);
/* Some later calls want pid present */
h->vm->pid = getpid();
if (virSecurityManagerSetSocketLabel(h->driver->securityManager, h->vm->def) < 0)
goto cleanup;
if (virDomainLockProcessStart(h->driver->lockManager,
- cfg->uri,
+ h->cfg->uri,
h->vm,
/* QEMU is always paused initially */
true,
if (virSecurityManagerClearSocketLabel(h->driver->securityManager, h->vm->def) < 0)
goto cleanup;
- if (qemuProcessLimits(cfg) < 0)
+ if (qemuProcessLimits(h->cfg) < 0)
goto cleanup;
/* This must take place before exec(), so that all QEMU
ret = 0;
cleanup:
- virObjectUnref(cfg);
+ virObjectUnref(h->cfg);
VIR_DEBUG("Hook complete ret=%d", ret);
return ret;
}
hookData.conn = conn;
hookData.vm = vm;
hookData.driver = driver;
+ hookData.cfg = virObjectRef(cfg);
VIR_DEBUG("Beginning VM startup process");
virCommandDaemonize(cmd);
virCommandRequireHandshake(cmd);
+ virSecurityManagerPreFork(driver->securityManager);
ret = virCommandRun(cmd, NULL);
+ virSecurityManagerPostFork(driver->securityManager);
/* wait for qemu process to show up */
if (ret == 0) {
requireConfined);
}
+
+/*
+ * Must be called before fork()'ing to ensure mutex state
+ * is sane for the child to use
+ */
+void virSecurityManagerPreFork(virSecurityManagerPtr mgr)
+{
+ virObjectLock(mgr);
+}
+
+
+/*
+ * Must be called after fork()'ing in both parent and child
+ * to ensure mutex state is sane for the child to use
+ */
+void virSecurityManagerPostFork(virSecurityManagerPtr mgr)
+{
+ virObjectUnlock(mgr);
+}
+
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
{
return mgr->privateData;