Convert the places which create/open log files to use the new
qemuDomainLogContextPtr object instead.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/qemu/qemu_domain.c | 100 +++++-------------------------------------------
src/qemu/qemu_domain.h | 2 -
src/qemu/qemu_process.c | 78 +++++++++++++++++--------------------
3 files changed, 46 insertions(+), 134 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e92f8b4..f3bb8d4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2406,108 +2406,29 @@ void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt)
}
-static int
-qemuDomainOpenLogHelper(virQEMUDriverConfigPtr cfg,
- virDomainObjPtr vm,
- int oflags,
- mode_t mode)
-{
- char *logfile;
- int fd = -1;
- bool trunc = false;
-
- if (virAsprintf(&logfile, "%s/%s.log", cfg->logDir,
vm->def->name) < 0)
- return -1;
-
- /* To make SELinux happy we always need to open in append mode.
- * So we fake O_TRUNC by calling ftruncate after open instead
- */
- if (oflags & O_TRUNC) {
- oflags &= ~O_TRUNC;
- oflags |= O_APPEND;
- trunc = true;
- }
-
- if ((fd = open(logfile, oflags, mode)) < 0) {
- virReportSystemError(errno, _("failed to create logfile %s"),
- logfile);
- goto cleanup;
- }
- if (virSetCloseExec(fd) < 0) {
- virReportSystemError(errno, _("failed to set close-on-exec flag on
%s"),
- logfile);
- VIR_FORCE_CLOSE(fd);
- goto cleanup;
- }
- if (trunc &&
- ftruncate(fd, 0) < 0) {
- virReportSystemError(errno, _("failed to truncate %s"),
- logfile);
- VIR_FORCE_CLOSE(fd);
- goto cleanup;
- }
-
- cleanup:
- VIR_FREE(logfile);
- return fd;
-}
-
-
-int
-qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm,
- bool append)
-{
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- int oflags;
- int ret;
-
- oflags = O_CREAT | O_WRONLY;
- /* Only logrotate files in /var/log, so only append if running privileged */
- if (virQEMUDriverIsPrivileged(driver) || append)
- oflags |= O_APPEND;
- else
- oflags |= O_TRUNC;
-
- ret = qemuDomainOpenLogHelper(cfg, vm, oflags, S_IRUSR | S_IWUSR);
- virObjectUnref(cfg);
- return ret;
-}
-
-
-int
-qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm)
-{
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- int fd;
-
- fd = qemuDomainOpenLogHelper(cfg, vm, O_RDONLY, 0);
- virObjectUnref(cfg);
- if (fd < 0)
- return -1;
-
- return fd;
-}
-
-
int qemuDomainAppendLog(virQEMUDriverPtr driver,
virDomainObjPtr obj,
int logFD,
const char *fmt, ...)
{
- int fd = logFD;
va_list argptr;
char *message = NULL;
int ret = -1;
+ qemuDomainLogContextPtr logCtxt = NULL;
va_start(argptr, fmt);
- if ((fd == -1) &&
- (fd = qemuDomainCreateLog(driver, obj, true)) < 0)
- goto cleanup;
+ if (logFD == -1) {
+ logCtxt = qemuDomainLogContextNew(driver, obj,
+ QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH);
+ if (!logCtxt)
+ goto cleanup;
+ logFD = qemuDomainLogContextGetWriteFD(logCtxt);
+ }
if (virVasprintf(&message, fmt, argptr) < 0)
goto cleanup;
- if (safewrite(fd, message, strlen(message)) < 0) {
+ if (safewrite(logFD, message, strlen(message)) < 0) {
virReportSystemError(errno, _("Unable to write to domain logfile %s"),
obj->def->name);
goto cleanup;
@@ -2518,8 +2439,7 @@ int qemuDomainAppendLog(virQEMUDriverPtr driver,
cleanup:
va_end(argptr);
- if (fd != logFD)
- VIR_FORCE_CLOSE(fd);
+ qemuDomainLogContextFree(logCtxt);
VIR_FREE(message);
return ret;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index fa0b14c..51820d8 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -371,8 +371,6 @@ off_t qemuDomainLogContextGetPosition(qemuDomainLogContextPtr ctxt);
void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt);
void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt);
-int qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm, bool append);
-int qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm);
int qemuDomainAppendLog(virQEMUDriverPtr driver,
virDomainObjPtr vm,
int logFD,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c09e9dc..e433548 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1907,16 +1907,18 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
virDomainObjPtr vm,
int asyncJob,
virQEMUCapsPtr qemuCaps,
- off_t pos)
+ qemuDomainLogContextPtr logCtxt)
{
int ret = -1;
virHashTablePtr info = NULL;
qemuDomainObjPrivatePtr priv;
int logfd = -1;
+ off_t pos = -1;
- if (pos != (off_t)-1 &&
- (logfd = qemuDomainOpenLog(driver, vm)) < 0)
- goto cleanup;
+ if (logCtxt) {
+ logfd = qemuDomainLogContextGetReadFD(logCtxt);
+ pos = qemuDomainLogContextGetPosition(logCtxt);
+ }
VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
if (qemuConnectMonitor(driver, vm, asyncJob, logfd, pos) < 0)
@@ -1953,9 +1955,6 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
ret = -1;
}
-
- VIR_FORCE_CLOSE(logfd);
-
return ret;
}
@@ -4114,9 +4113,8 @@ int qemuProcessStart(virConnectPtr conn,
{
int ret = -1;
int rv;
- off_t pos = -1;
- char ebuf[1024];
int logfile = -1;
+ qemuDomainLogContextPtr logCtxt = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCommandPtr cmd = NULL;
struct qemuProcessHookData hookData;
@@ -4354,8 +4352,10 @@ int qemuProcessStart(virConnectPtr conn,
}
VIR_DEBUG("Creating domain log file");
- if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
+ if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
+ QEMU_DOMAIN_LOG_CONTEXT_MODE_START)))
goto error;
+ logfile = qemuDomainLogContextGetWriteFD(logCtxt);
if (vm->def->virtType == VIR_DOMAIN_VIRT_KVM) {
VIR_DEBUG("Checking for KVM availability");
@@ -4522,11 +4522,7 @@ int qemuProcessStart(virConnectPtr conn,
qemuDomainObjCheckTaint(driver, vm, logfile);
- if ((pos = lseek(logfile, 0, SEEK_END)) < 0) {
- VIR_WARN("Unable to seek to end of logfile: %s",
- virStrerror(errno, ebuf, sizeof(ebuf)));
- pos = 0;
- }
+ qemuDomainLogContextMarkPosition(logCtxt);
VIR_DEBUG("Clear emulator capabilities: %d",
cfg->clearEmulatorCapabilities);
@@ -4620,11 +4616,11 @@ int qemuProcessStart(virConnectPtr conn,
VIR_DEBUG("Waiting for handshake from child");
if (virCommandHandshakeWait(cmd) < 0) {
/* Read errors from child that occurred between fork and exec. */
- int logfd = qemuDomainOpenLog(driver, vm);
+ int logfd = qemuDomainLogContextGetReadFD(logCtxt);
+ off_t pos = qemuDomainLogContextGetPosition(logCtxt);
if (logfd >= 0) {
qemuProcessReportLogError(logfd, pos,
_("Process exited prior to exec"));
- VIR_FORCE_CLOSE(logfd);
}
goto error;
}
@@ -4691,7 +4687,7 @@ int qemuProcessStart(virConnectPtr conn,
goto error;
VIR_DEBUG("Waiting for monitor to show up");
- if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, pos) < 0)
+ if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, logCtxt) <
0)
goto error;
/* Failure to connect to agent shouldn't be fatal */
@@ -4854,7 +4850,7 @@ int qemuProcessStart(virConnectPtr conn,
cleanup:
virCommandFree(cmd);
- VIR_FORCE_CLOSE(logfile);
+ qemuDomainLogContextFree(logCtxt);
virObjectUnref(cfg);
virObjectUnref(caps);
VIR_FREE(nicindexes);
@@ -4868,6 +4864,9 @@ int qemuProcessStart(virConnectPtr conn,
* pretend we never started it */
if (priv->mon)
qemuMonitorSetDomainLog(priv->mon, -1, -1);
+ /* Must close log now to allow ProcessSto to re-open it */
+ qemuDomainLogContextFree(logCtxt);
+ logCtxt = NULL;
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
goto cleanup;
@@ -4919,11 +4918,11 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virDomainDefPtr def;
virNetDevVPortProfilePtr vport = NULL;
size_t i;
- int logfile = -1;
char *timestamp;
char *tmppath = NULL;
char ebuf[1024];
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainLogContextPtr logCtxt = NULL;
VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%llu flags=%x",
vm, vm->def->name, vm->def->id,
@@ -4952,12 +4951,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
/* Wake up anything waiting on domain condition */
virDomainObjBroadcast(vm);
- if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) {
- /* To not break the normal domain shutdown process, skip the
- * timestamp log writing if failed on opening log file. */
- VIR_WARN("Unable to open logfile: %s",
- virStrerror(errno, ebuf, sizeof(ebuf)));
- } else {
+ if ((logCtxt = qemuDomainLogContextNew(driver, vm,
+ QEMU_DOMAIN_LOG_CONTEXT_MODE_STOP))) {
+ int logfile = qemuDomainLogContextGetWriteFD(logCtxt);
if ((timestamp = virTimeStringNow()) != NULL) {
if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 ||
safewrite(logfile, SHUTDOWN_POSTFIX,
@@ -4968,10 +4964,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
VIR_FREE(timestamp);
}
-
- if (VIR_CLOSE(logfile) < 0)
- VIR_WARN("Unable to close logfile: %s",
- virStrerror(errno, ebuf, sizeof(ebuf)));
+ qemuDomainLogContextFree(logCtxt);
}
/* Clear network bandwidth */
@@ -5232,6 +5225,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
size_t i;
char ebuf[1024];
int logfile = -1;
+ qemuDomainLogContextPtr logCtxt = NULL;
char *timestamp;
qemuDomainObjPrivatePtr priv = vm->privateData;
bool running = true;
@@ -5326,8 +5320,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
goto error;
VIR_DEBUG("Creating domain log file");
- if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
+ if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
+ QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH)))
goto error;
+ logfile = qemuDomainLogContextGetWriteFD(logCtxt);
VIR_DEBUG("Determining emulator version");
virObjectUnref(priv->qemuCaps);
@@ -5356,22 +5352,20 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
goto error;
}
- if ((timestamp = virTimeStringNow()) == NULL) {
+ if ((timestamp = virTimeStringNow()) == NULL)
goto error;
- } else {
- if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 ||
- safewrite(logfile, ATTACH_POSTFIX, strlen(ATTACH_POSTFIX)) < 0) {
- VIR_WARN("Unable to write timestamp to logfile: %s",
- virStrerror(errno, ebuf, sizeof(ebuf)));
- }
- VIR_FREE(timestamp);
+ if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 ||
+ safewrite(logfile, ATTACH_POSTFIX, strlen(ATTACH_POSTFIX)) < 0) {
+ VIR_WARN("Unable to write timestamp to logfile: %s",
+ virStrerror(errno, ebuf, sizeof(ebuf)));
}
+ VIR_FREE(timestamp);
qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_EXTERNAL_LAUNCH, logfile);
VIR_DEBUG("Waiting for monitor to show up");
- if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps, -1)
< 0)
+ if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps,
NULL) < 0)
goto error;
/* Failure to connect to agent shouldn't be fatal */
@@ -5449,7 +5443,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
goto error;
}
- VIR_FORCE_CLOSE(logfile);
+ qemuDomainLogContextFree(logCtxt);
VIR_FREE(seclabel);
VIR_FREE(sec_managers);
virObjectUnref(cfg);
@@ -5466,7 +5460,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
if (active && virAtomicIntDecAndTest(&driver->nactive) &&
driver->inhibitCallback)
driver->inhibitCallback(false, driver->inhibitOpaque);
- VIR_FORCE_CLOSE(logfile);
+ qemuDomainLogContextFree(logCtxt);
VIR_FREE(seclabel);
VIR_FREE(sec_managers);
if (seclabelgen)
--
2.5.0