[libvirt] [PATCH] logging: inhibit virtlogd shutdown while log files are open

Daniel P. Berrange berrange at redhat.com
Tue Nov 24 13:10:38 UTC 2015


The virtlogd daemon is launched with a 30 second timeout for
unprivileged users. Unfortunately the timeout is only inhibited
while RPC clients are connected, and they only connect for a
short while to open the log file descriptor. We need to hold
an inhibition for as long as the log file descriptor itself
is open.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/logging/log_daemon.c  | 19 +++++++++++++++++--
 src/logging/log_handler.c | 33 +++++++++++++++++++++++++++------
 src/logging/log_handler.h | 11 +++++++++--
 3 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c
index 7a1afec..3fda9ca 100644
--- a/src/logging/log_daemon.c
+++ b/src/logging/log_daemon.c
@@ -124,6 +124,17 @@ virLogDaemonFree(virLogDaemonPtr logd)
 }
 
 
+static void
+virLogDaemonInhibitor(bool inhibit, void *opaque)
+{
+    virLogDaemonPtr daemon = opaque;
+
+    if (inhibit)
+        virNetDaemonAddShutdownInhibition(daemon->dmn);
+    else
+        virNetDaemonRemoveShutdownInhibition(daemon->dmn);
+}
+
 static virLogDaemonPtr
 virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
 {
@@ -152,7 +163,9 @@ virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
         virNetDaemonAddServer(logd->dmn, logd->srv) < 0)
         goto error;
 
-    if (!(logd->handler = virLogHandlerNew(privileged)))
+    if (!(logd->handler = virLogHandlerNew(privileged,
+                                           virLogDaemonInhibitor,
+                                           logd)))
         goto error;
 
     return logd;
@@ -210,7 +223,9 @@ virLogDaemonNewPostExecRestart(virJSONValuePtr object, bool privileged)
     }
 
     if (!(logd->handler = virLogHandlerNewPostExecRestart(child,
-                                                          privileged)))
+                                                          privileged,
+                                                          virLogDaemonInhibitor,
+                                                          logd)))
         goto error;
 
     return logd;
diff --git a/src/logging/log_handler.c b/src/logging/log_handler.c
index 2acbca7..a4f0395 100644
--- a/src/logging/log_handler.c
+++ b/src/logging/log_handler.c
@@ -59,6 +59,9 @@ struct _virLogHandler {
     bool privileged;
     virLogHandlerLogFilePtr *files;
     size_t nfiles;
+
+    virLogHandlerShutdownInhibitor inhibitor;
+    void *opaque;
 };
 
 static virClassPtr virLogHandlerClass;
@@ -165,13 +168,16 @@ virLogHandlerDomainLogFileEvent(int watch,
     return;
 
  error:
+    handler->inhibitor(false, handler->opaque);
     virLogHandlerLogFileClose(handler, logfile);
     virObjectUnlock(handler);
 }
 
 
 virLogHandlerPtr
-virLogHandlerNew(bool privileged)
+virLogHandlerNew(bool privileged,
+                 virLogHandlerShutdownInhibitor inhibitor,
+                 void *opaque)
 {
     virLogHandlerPtr handler;
 
@@ -182,6 +188,8 @@ virLogHandlerNew(bool privileged)
         goto error;
 
     handler->privileged = privileged;
+    handler->inhibitor = inhibitor;
+    handler->opaque = opaque;
 
     return handler;
 
@@ -191,7 +199,8 @@ virLogHandlerNew(bool privileged)
 
 
 static virLogHandlerLogFilePtr
-virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
+virLogHandlerLogFilePostExecRestart(virLogHandlerPtr handler,
+                                    virJSONValuePtr object)
 {
     virLogHandlerLogFilePtr file;
     const char *path;
@@ -199,6 +208,8 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
     if (VIR_ALLOC(file) < 0)
         return NULL;
 
+    handler->inhibitor(true, handler->opaque);
+
     if ((path = virJSONValueObjectGetString(object, "path")) == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Missing file path in JSON document"));
@@ -226,6 +237,7 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
     return file;
 
  error:
+    handler->inhibitor(false, handler->opaque);
     virLogHandlerLogFileFree(file);
     return NULL;
 }
@@ -233,14 +245,18 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
 
 virLogHandlerPtr
 virLogHandlerNewPostExecRestart(virJSONValuePtr object,
-                                bool privileged)
+                                bool privileged,
+                                virLogHandlerShutdownInhibitor inhibitor,
+                                void *opaque)
 {
     virLogHandlerPtr handler;
     virJSONValuePtr files;
     ssize_t n;
     size_t i;
 
-    if (!(handler = virLogHandlerNew(privileged)))
+    if (!(handler = virLogHandlerNew(privileged,
+                                     inhibitor,
+                                     opaque)))
         return NULL;
 
     if (!(files = virJSONValueObjectGet(object, "files"))) {
@@ -259,7 +275,7 @@ virLogHandlerNewPostExecRestart(virJSONValuePtr object,
         virLogHandlerLogFilePtr file;
         virJSONValuePtr child = virJSONValueArrayGet(files, i);
 
-        if (!(file = virLogHandlerLogFilePostExecRestart(child)))
+        if (!(file = virLogHandlerLogFilePostExecRestart(handler, child)))
             goto error;
 
         if (VIR_APPEND_ELEMENT_COPY(handler->files, handler->nfiles, file) < 0)
@@ -290,8 +306,10 @@ virLogHandlerDispose(void *obj)
     virLogHandlerPtr handler = obj;
     size_t i;
 
-    for (i = 0; i < handler->nfiles; i++)
+    for (i = 0; i < handler->nfiles; i++) {
+        handler->inhibitor(false, handler->opaque);
         virLogHandlerLogFileFree(handler->files[i]);
+    }
     VIR_FREE(handler->files);
 }
 
@@ -341,6 +359,8 @@ virLogHandlerDomainOpenLogFile(virLogHandlerPtr handler,
 
     virObjectLock(handler);
 
+    handler->inhibitor(true, handler->opaque);
+
     if (!(path = virLogHandlerGetLogFilePathForDomain(handler,
                                                       driver,
                                                       domuuid,
@@ -400,6 +420,7 @@ virLogHandlerDomainOpenLogFile(virLogHandlerPtr handler,
     VIR_FREE(path);
     VIR_FORCE_CLOSE(pipefd[0]);
     VIR_FORCE_CLOSE(pipefd[1]);
+    handler->inhibitor(false, handler->opaque);
     virLogHandlerLogFileFree(file);
     virObjectUnlock(handler);
     return -1;
diff --git a/src/logging/log_handler.h b/src/logging/log_handler.h
index 1ad755e..e41ac7f 100644
--- a/src/logging/log_handler.h
+++ b/src/logging/log_handler.h
@@ -30,9 +30,16 @@ typedef struct _virLogHandler virLogHandler;
 typedef virLogHandler *virLogHandlerPtr;
 
 
-virLogHandlerPtr virLogHandlerNew(bool privileged);
+typedef void (*virLogHandlerShutdownInhibitor)(bool inhibit,
+                                               void *opaque);
+
+virLogHandlerPtr virLogHandlerNew(bool privileged,
+                                  virLogHandlerShutdownInhibitor inhibitor,
+                                  void *opaque);
 virLogHandlerPtr virLogHandlerNewPostExecRestart(virJSONValuePtr child,
-                                                 bool privileged);
+                                                 bool privileged,
+                                                 virLogHandlerShutdownInhibitor inhibitor,
+                                                 void *opaque);
 
 void virLogHandlerFree(virLogHandlerPtr handler);
 
-- 
2.5.0




More information about the libvir-list mailing list