logging: inhibit virtlogd shutdown while log files are open

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@redhat.com>
This commit is contained in:
Daniel P. Berrange 2015-11-24 11:47:41 +00:00
parent 0d968ad715
commit df34363d58
3 changed files with 53 additions and 10 deletions

View File

@ -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 static virLogDaemonPtr
virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged) virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
{ {
@ -152,7 +163,9 @@ virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
virNetDaemonAddServer(logd->dmn, logd->srv) < 0) virNetDaemonAddServer(logd->dmn, logd->srv) < 0)
goto error; goto error;
if (!(logd->handler = virLogHandlerNew(privileged))) if (!(logd->handler = virLogHandlerNew(privileged,
virLogDaemonInhibitor,
logd)))
goto error; goto error;
return logd; return logd;
@ -210,7 +223,9 @@ virLogDaemonNewPostExecRestart(virJSONValuePtr object, bool privileged)
} }
if (!(logd->handler = virLogHandlerNewPostExecRestart(child, if (!(logd->handler = virLogHandlerNewPostExecRestart(child,
privileged))) privileged,
virLogDaemonInhibitor,
logd)))
goto error; goto error;
return logd; return logd;

View File

@ -59,6 +59,9 @@ struct _virLogHandler {
bool privileged; bool privileged;
virLogHandlerLogFilePtr *files; virLogHandlerLogFilePtr *files;
size_t nfiles; size_t nfiles;
virLogHandlerShutdownInhibitor inhibitor;
void *opaque;
}; };
static virClassPtr virLogHandlerClass; static virClassPtr virLogHandlerClass;
@ -165,13 +168,16 @@ virLogHandlerDomainLogFileEvent(int watch,
return; return;
error: error:
handler->inhibitor(false, handler->opaque);
virLogHandlerLogFileClose(handler, logfile); virLogHandlerLogFileClose(handler, logfile);
virObjectUnlock(handler); virObjectUnlock(handler);
} }
virLogHandlerPtr virLogHandlerPtr
virLogHandlerNew(bool privileged) virLogHandlerNew(bool privileged,
virLogHandlerShutdownInhibitor inhibitor,
void *opaque)
{ {
virLogHandlerPtr handler; virLogHandlerPtr handler;
@ -182,6 +188,8 @@ virLogHandlerNew(bool privileged)
goto error; goto error;
handler->privileged = privileged; handler->privileged = privileged;
handler->inhibitor = inhibitor;
handler->opaque = opaque;
return handler; return handler;
@ -191,7 +199,8 @@ virLogHandlerNew(bool privileged)
static virLogHandlerLogFilePtr static virLogHandlerLogFilePtr
virLogHandlerLogFilePostExecRestart(virJSONValuePtr object) virLogHandlerLogFilePostExecRestart(virLogHandlerPtr handler,
virJSONValuePtr object)
{ {
virLogHandlerLogFilePtr file; virLogHandlerLogFilePtr file;
const char *path; const char *path;
@ -199,6 +208,8 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
if (VIR_ALLOC(file) < 0) if (VIR_ALLOC(file) < 0)
return NULL; return NULL;
handler->inhibitor(true, handler->opaque);
if ((path = virJSONValueObjectGetString(object, "path")) == NULL) { if ((path = virJSONValueObjectGetString(object, "path")) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing file path in JSON document")); _("Missing file path in JSON document"));
@ -226,6 +237,7 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
return file; return file;
error: error:
handler->inhibitor(false, handler->opaque);
virLogHandlerLogFileFree(file); virLogHandlerLogFileFree(file);
return NULL; return NULL;
} }
@ -233,14 +245,18 @@ virLogHandlerLogFilePostExecRestart(virJSONValuePtr object)
virLogHandlerPtr virLogHandlerPtr
virLogHandlerNewPostExecRestart(virJSONValuePtr object, virLogHandlerNewPostExecRestart(virJSONValuePtr object,
bool privileged) bool privileged,
virLogHandlerShutdownInhibitor inhibitor,
void *opaque)
{ {
virLogHandlerPtr handler; virLogHandlerPtr handler;
virJSONValuePtr files; virJSONValuePtr files;
ssize_t n; ssize_t n;
size_t i; size_t i;
if (!(handler = virLogHandlerNew(privileged))) if (!(handler = virLogHandlerNew(privileged,
inhibitor,
opaque)))
return NULL; return NULL;
if (!(files = virJSONValueObjectGet(object, "files"))) { if (!(files = virJSONValueObjectGet(object, "files"))) {
@ -259,7 +275,7 @@ virLogHandlerNewPostExecRestart(virJSONValuePtr object,
virLogHandlerLogFilePtr file; virLogHandlerLogFilePtr file;
virJSONValuePtr child = virJSONValueArrayGet(files, i); virJSONValuePtr child = virJSONValueArrayGet(files, i);
if (!(file = virLogHandlerLogFilePostExecRestart(child))) if (!(file = virLogHandlerLogFilePostExecRestart(handler, child)))
goto error; goto error;
if (VIR_APPEND_ELEMENT_COPY(handler->files, handler->nfiles, file) < 0) if (VIR_APPEND_ELEMENT_COPY(handler->files, handler->nfiles, file) < 0)
@ -290,8 +306,10 @@ virLogHandlerDispose(void *obj)
virLogHandlerPtr handler = obj; virLogHandlerPtr handler = obj;
size_t i; 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]); virLogHandlerLogFileFree(handler->files[i]);
}
VIR_FREE(handler->files); VIR_FREE(handler->files);
} }
@ -341,6 +359,8 @@ virLogHandlerDomainOpenLogFile(virLogHandlerPtr handler,
virObjectLock(handler); virObjectLock(handler);
handler->inhibitor(true, handler->opaque);
if (!(path = virLogHandlerGetLogFilePathForDomain(handler, if (!(path = virLogHandlerGetLogFilePathForDomain(handler,
driver, driver,
domuuid, domuuid,
@ -400,6 +420,7 @@ virLogHandlerDomainOpenLogFile(virLogHandlerPtr handler,
VIR_FREE(path); VIR_FREE(path);
VIR_FORCE_CLOSE(pipefd[0]); VIR_FORCE_CLOSE(pipefd[0]);
VIR_FORCE_CLOSE(pipefd[1]); VIR_FORCE_CLOSE(pipefd[1]);
handler->inhibitor(false, handler->opaque);
virLogHandlerLogFileFree(file); virLogHandlerLogFileFree(file);
virObjectUnlock(handler); virObjectUnlock(handler);
return -1; return -1;

View File

@ -30,9 +30,16 @@ typedef struct _virLogHandler virLogHandler;
typedef virLogHandler *virLogHandlerPtr; 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, virLogHandlerPtr virLogHandlerNewPostExecRestart(virJSONValuePtr child,
bool privileged); bool privileged,
virLogHandlerShutdownInhibitor inhibitor,
void *opaque);
void virLogHandlerFree(virLogHandlerPtr handler); void virLogHandlerFree(virLogHandlerPtr handler);