Re: [PATCH 7/9] rpc: Alter virNetDaemonQuit processing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 01/19/2018 12:23 PM, John Ferlan wrote:
> 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(-)
> 

sigh - too quick with the send and neglected to run the so what happens
when I have nothing pending check/test...  Attached is a patch that
would be merged with this one.

John
> 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);
> 

>From 3bd60d0ee355e3d4d95d41c540f7262930803aab Mon Sep 17 00:00:00 2001
From: John Ferlan <jferlan@xxxxxxxxxx>
Date: Fri, 19 Jan 2018 13:13:02 -0500
Subject: [PATCH] merge with patch.

<sigh> continued testing found that if there's no workers pending,
then we could end up with no workers, but waiting for something to
happen that never will because when checked there were still workers
that were in the process of quitting, but hadn't quite all quit yet.

So set up a the dummy timeout with a 1/2 second timer to force/allow
the quitRequested logic to continue checking for completed workers.

Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx>
---
 src/rpc/virnetdaemon.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c
index 6aee712a5..412b362aa 100644
--- a/src/rpc/virnetdaemon.c
+++ b/src/rpc/virnetdaemon.c
@@ -806,11 +806,20 @@ daemonServerWorkersDone(virNetDaemonPtr dmn)
 }
 
 
+static void
+virNetDaemonQuitTimer(int timer ATTRIBUTE_UNUSED,
+                      void *opaque ATTRIBUTE_UNUSED)
+{
+    /* nothing to be done here */
+}
+
+
 void
 virNetDaemonRun(virNetDaemonPtr dmn)
 {
     int timerid = -1;
     bool timerActive = false;
+    int quitTimer = -1;
 
     virObjectLock(dmn);
 
@@ -862,6 +871,12 @@ virNetDaemonRun(virNetDaemonPtr dmn)
         }
 
         virObjectUnlock(dmn);
+
+        /* HACK: Add a dummy timeout to break event loop */
+        if (dmn->quitRequested)
+            quitTimer = virEventAddTimeout(500, virNetDaemonQuitTimer,
+                                           NULL, NULL);
+
         if (virEventRunDefaultImpl() < 0) {
             virObjectLock(dmn);
             VIR_DEBUG("Loop iteration error, exiting");
@@ -877,6 +892,8 @@ virNetDaemonRun(virNetDaemonPtr dmn)
 
  cleanup:
     virObjectUnlock(dmn);
+    if (quitTimer != -1)
+        virEventRemoveTimeout(quitTimer);
 }
 
 
-- 
2.13.6

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux