72 lines
2.5 KiB
Diff
72 lines
2.5 KiB
Diff
|
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||
|
Subject: PATCH: Fix permissions problem starting QEMU
|
||
|
|
||
|
There is a minor bug when running QEMU non-root, and having
|
||
|
capng enabled. libvirt is unable to write the PID file in
|
||
|
/var/run/libvirt/qemu, since its now owned by 'qemu', but
|
||
|
libvirtd has dropped all capabilties at this point. The fix
|
||
|
is to delay dropping capabilities until after the PID file
|
||
|
has been created. We should also be sure to kill the child
|
||
|
if writing the PID file fails
|
||
|
|
||
|
* src/util.c: Don't drop capabilities until after the PID file has
|
||
|
been written. Kill off child if writing the PID file fails
|
||
|
|
||
|
* src/qemu_driver.c: Remove bogus trailing '/' in state dir
|
||
|
|
||
|
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||
|
index 9fb8506..26897d3 100644
|
||
|
--- a/src/qemu_driver.c
|
||
|
+++ b/src/qemu_driver.c
|
||
|
@@ -468,7 +468,7 @@ qemudStartup(int privileged) {
|
||
|
goto out_of_memory;
|
||
|
|
||
|
if (virAsprintf(&qemu_driver->stateDir,
|
||
|
- "%s/run/libvirt/qemu/", LOCAL_STATE_DIR) == -1)
|
||
|
+ "%s/run/libvirt/qemu", LOCAL_STATE_DIR) == -1)
|
||
|
goto out_of_memory;
|
||
|
} else {
|
||
|
uid_t uid = geteuid();
|
||
|
diff --git a/src/util.c b/src/util.c
|
||
|
index ee64b28..39aae24 100644
|
||
|
--- a/src/util.c
|
||
|
+++ b/src/util.c
|
||
|
@@ -513,12 +513,6 @@ __virExec(virConnectPtr conn,
|
||
|
if ((hook)(data) != 0)
|
||
|
_exit(1);
|
||
|
|
||
|
- /* The hook above may need todo something privileged, so
|
||
|
- * we delay clearing capabilities until now */
|
||
|
- if ((flags & VIR_EXEC_CLEAR_CAPS) &&
|
||
|
- virClearCapabilities() < 0)
|
||
|
- _exit(1);
|
||
|
-
|
||
|
/* Daemonize as late as possible, so the parent process can detect
|
||
|
* the above errors with wait* */
|
||
|
if (flags & VIR_EXEC_DAEMON) {
|
||
|
@@ -543,6 +537,9 @@ __virExec(virConnectPtr conn,
|
||
|
|
||
|
if (pid > 0) {
|
||
|
if (pidfile && virFileWritePidPath(pidfile,pid)) {
|
||
|
+ kill(pid, SIGTERM);
|
||
|
+ usleep(500*1000);
|
||
|
+ kill(pid, SIGTERM);
|
||
|
virReportSystemError(conn, errno,
|
||
|
"%s", _("could not write pidfile"));
|
||
|
_exit(1);
|
||
|
@@ -551,6 +548,12 @@ __virExec(virConnectPtr conn,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /* The steps above may need todo something privileged, so
|
||
|
+ * we delay clearing capabilities until the last minute */
|
||
|
+ if ((flags & VIR_EXEC_CLEAR_CAPS) &&
|
||
|
+ virClearCapabilities() < 0)
|
||
|
+ _exit(1);
|
||
|
+
|
||
|
if (envp)
|
||
|
execve(argv[0], (char **) argv, (char**)envp);
|
||
|
else
|
||
|
|
||
|
|