<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:large"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 22, 2021 at 12:45 PM Michal Privoznik <<a href="mailto:mprivozn@redhat.com">mprivozn@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If libvirtd is sent SIGTERM while it is still initializing, it<br>
may crash. The following scenario was observed (using 'stress' to<br>
slow down CPU so much that the window where the problem exists is<br>
bigger):<br>
<br>
1) The main thread is already executing virNetDaemonRun() and is<br>
   in virEventRunDefaultImpl().<br>
2) The thread that's supposed to run daemonRunStateInit() is<br>
   spawned already, but daemonRunStateInit() is in its very early<br>
   stage (in the stack trace I see it's executing<br>
   virIdentityGetSystem()).<br>
<br>
If SIGTERM (or any other signal that we don't override handler<br>
for) arrives at this point, the main thread jumps out from<br>
virEventRunDefaultImpl() and enters virStateShutdownPrepare()<br>
(via shutdownPrepareCb which was set earlier). This iterates<br>
through stateShutdownPrepare() callbacks of state drivers and<br>
reaching qemuStateShutdownPrepare() eventually only to<br>
dereference qemu_driver. But since thread 2) has not been<br>
scheduled/not proceeded yet, qemu_driver was not allocated yet.<br>
<br>
Solution is simple - just check if qemu_driver is not NULL. But<br>
doing so only in qemuStateShutdownPrepare() would push the<br>
problem down to virStateShutdownWait(), well<br>
qemuStateShutdownWait(). Therefore, duplicate the trick there<br>
too.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:large">I guess this is a partial solution. Initialization may be in a state when</div><div class="gmail_default" style="font-size:large">qemu_driver is initialized but qemu_driver->workerPool is still NULL</div><div class="gmail_default" style="font-size:large">for example.</div><br></div><div><div class="gmail_default" style="font-size:large">Maybe we'd better delay shutdown until initialization is finished?</div><div class="gmail_default" style="font-size:large"><br></div><div class="gmail_default" style="font-size:large">Nikolay</div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Resolves: <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1895359#c14Signed-off-by" rel="noreferrer" target="_blank">https://bugzilla.redhat.com/show_bug.cgi?id=1895359#c14<br>
Signed-off-by</a>: Michal Privoznik <<a href="mailto:mprivozn@redhat.com" target="_blank">mprivozn@redhat.com</a>><br>
---<br>
 src/qemu/qemu_driver.c | 6 ++++++<br>
 1 file changed, 6 insertions(+)<br>
<br>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c<br>
index 027617deef..ca4f366323 100644<br>
--- a/src/qemu/qemu_driver.c<br>
+++ b/src/qemu/qemu_driver.c<br>
@@ -1072,6 +1072,9 @@ qemuStateStop(void)<br>
 static int<br>
 qemuStateShutdownPrepare(void)<br>
 {<br>
+    if (!qemu_driver)<br>
+        return 0;<br>
+<br>
     virThreadPoolStop(qemu_driver->workerPool);<br>
     return 0;<br>
 }<br>
@@ -1091,6 +1094,9 @@ qemuDomainObjStopWorkerIter(virDomainObjPtr vm,<br>
 static int<br>
 qemuStateShutdownWait(void)<br>
 {<br>
+    if (!qemu_driver)<br>
+        return 0;<br>
+<br>
     virDomainObjListForEach(qemu_driver->domains, false,<br>
                             qemuDomainObjStopWorkerIter, NULL);<br>
     virThreadPoolDrain(qemu_driver->workerPool);<br>
-- <br>
2.26.2<br>
<br>
</blockquote></div></div>