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(a)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