From 640b58abdf2c5e97476dd6e2be475cfab311e9ad Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Wed, 30 Mar 2016 12:38:39 +0200 Subject: [PATCH] virlog: Take a special care of syslog when setting new set of log outputs Now that we're in the critical section, syslog connection can be re-opened by issuing openlog, which is something that cannot be done beforehand, since syslog keeps its file descriptor private and changing the tag earlier might introduce a log inconsistency if something went wrong with preparing a new set of logging outputs in order to replace the existing one. Signed-off-by: Erik Skultety --- src/util/virlog.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/util/virlog.c b/src/util/virlog.c index 92ef794084..9c98588f89 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -1794,16 +1794,37 @@ virLogFindOutput(virLogOutputPtr *outputs, size_t noutputs, int virLogDefineOutputs(virLogOutputPtr *outputs, size_t noutputs) { + int ret = -1; + int id; + char *tmp = NULL; + if (virLogInitialize() < 0) return -1; virLogLock(); virLogResetOutputs(); + + /* syslog needs to be special-cased, since it keeps the fd in private */ + if ((id = virLogFindOutput(outputs, noutputs, VIR_LOG_TO_SYSLOG, + current_ident)) != -1) { + /* nothing can go wrong now (except for malloc) and since we're also + * holding the lock so it's safe to call openlog and change the message + * tag + */ + if (VIR_STRDUP_QUIET(tmp, outputs[id]->name) < 0) + goto cleanup; + VIR_FREE(current_ident); + current_ident = tmp; + openlog(current_ident, 0, 0); + } + virLogOutputs = outputs; virLogNbOutputs = noutputs; - virLogUnlock(); - return 0; + ret = 0; + cleanup: + virLogUnlock(); + return ret; }