When virNetDaemonQuit is called from libvirtd's shutdown handler (daemonShutdownHandler) we need to perform the quit in multiple steps. The first part is to "request" the quit and notify the NetServer's of the impending quit which causes the NetServers to Drain their pending queue and tell workers to quit and the second is wait for any currently running worker jobs to complete. Once the workers are complete, then we can cause the quit to occur. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/rpc/virnetdaemon.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index e5b376ced..6aee712a5 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -73,6 +73,7 @@ struct _virNetDaemon { virHashTablePtr servers; virJSONValuePtr srvObject; + bool quitRequested; bool quit; unsigned int autoShutdownTimeout; @@ -779,6 +780,32 @@ daemonServerProcessClients(void *payload, return 0; } + +static int +daemonServerWorkerCount(void *payload, + const void *key ATTRIBUTE_UNUSED, + void *opaque) +{ + size_t *workerCount = opaque; + virNetServerPtr srv = payload; + + *workerCount += virNetServerWorkerCount(srv); + + return 0; +} + + +static bool +daemonServerWorkersDone(virNetDaemonPtr dmn) +{ + size_t workerCount = 0; + + virHashForEach(dmn->servers, daemonServerWorkerCount, &workerCount); + + return workerCount == 0; +} + + void virNetDaemonRun(virNetDaemonPtr dmn) { @@ -843,6 +870,9 @@ virNetDaemonRun(virNetDaemonPtr dmn) virObjectLock(dmn); virHashForEach(dmn->servers, daemonServerProcessClients, NULL); + + if (dmn->quitRequested && daemonServerWorkersDone(dmn)) + dmn->quit = true; } cleanup: @@ -868,7 +898,7 @@ virNetDaemonQuit(virNetDaemonPtr dmn) virObjectLock(dmn); VIR_DEBUG("Quit requested %p", dmn); - dmn->quit = true; + dmn->quitRequested = true; virHashForEach(dmn->servers, daemonServerQuitRequested, NULL); virObjectUnlock(dmn); -- 2.13.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list