This will allow us to use it for nbdkit logging in upcoming commits.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
Reviewed-by: Peter Krempa <pkrempa(a)redhat.com>
---
po/POTFILES | 1 +
src/qemu/meson.build | 1 +
src/qemu/qemu_domain.c | 247 ++--------------------------------
src/qemu/qemu_domain.h | 27 +---
src/qemu/qemu_logcontext.c | 264 +++++++++++++++++++++++++++++++++++++
src/qemu/qemu_logcontext.h | 38 ++++++
src/qemu/qemu_process.c | 44 +++----
7 files changed, 346 insertions(+), 276 deletions(-)
create mode 100644 src/qemu/qemu_logcontext.c
create mode 100644 src/qemu/qemu_logcontext.h
diff --git a/po/POTFILES b/po/POTFILES
index 6167f98ac5..3a51aea5cb 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -174,6 +174,7 @@ src/qemu/qemu_hostdev.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_interface.c
src/qemu/qemu_interop_config.c
+src/qemu/qemu_logcontext.c
src/qemu/qemu_migration.c
src/qemu/qemu_migration_cookie.c
src/qemu/qemu_migration_params.c
diff --git a/src/qemu/meson.build b/src/qemu/meson.build
index 9be6996195..6d7a1bfbb0 100644
--- a/src/qemu/meson.build
+++ b/src/qemu/meson.build
@@ -21,6 +21,7 @@ qemu_driver_sources = [
'qemu_hotplug.c',
'qemu_interface.c',
'qemu_interop_config.c',
+ 'qemu_logcontext.c',
'qemu_migration.c',
'qemu_migration_cookie.c',
'qemu_migration_params.c',
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d79f9879df..23608f95bd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -455,21 +455,8 @@ qemuDomainObjFromDomain(virDomainPtr domain)
}
-struct _qemuDomainLogContext {
- GObject parent;
-
- int writefd;
- int readfd; /* Only used if manager == NULL */
- off_t pos;
- ino_t inode; /* Only used if manager != NULL */
- char *path;
- virLogManager *manager;
-};
-
-G_DEFINE_TYPE(qemuDomainLogContext, qemu_domain_log_context, G_TYPE_OBJECT);
static virClass *qemuDomainSaveCookieClass;
-static void qemuDomainLogContextFinalize(GObject *obj);
static void qemuDomainSaveCookieDispose(void *obj);
@@ -482,32 +469,8 @@ qemuDomainOnceInit(void)
return 0;
}
-static void qemu_domain_log_context_init(qemuDomainLogContext *logctxt G_GNUC_UNUSED)
-{
-}
-
-static void qemu_domain_log_context_class_init(qemuDomainLogContextClass *klass)
-{
- GObjectClass *obj = G_OBJECT_CLASS(klass);
-
- obj->finalize = qemuDomainLogContextFinalize;
-}
-
VIR_ONCE_GLOBAL_INIT(qemuDomain);
-static void
-qemuDomainLogContextFinalize(GObject *object)
-{
- qemuDomainLogContext *ctxt = QEMU_DOMAIN_LOG_CONTEXT(object);
- VIR_DEBUG("ctxt=%p", ctxt);
-
- virLogManagerFree(ctxt->manager);
- VIR_FREE(ctxt->path);
- VIR_FORCE_CLOSE(ctxt->writefd);
- VIR_FORCE_CLOSE(ctxt->readfd);
- G_OBJECT_CLASS(qemu_domain_log_context_parent_class)->finalize(object);
-}
-
/* qemuDomainGetMasterKeyFilePath:
* @libDir: Directory path to domain lib files
*
@@ -6882,7 +6845,7 @@ static void G_GNUC_PRINTF(5, 6)
qemuDomainObjTaintMsg(virQEMUDriver *driver,
virDomainObj *obj,
virDomainTaintFlags taint,
- qemuDomainLogContext *logCtxt,
+ qemuLogContext *logCtxt,
const char *fmt, ...)
{
virErrorPtr orig_err = NULL;
@@ -6935,12 +6898,12 @@ qemuDomainObjTaintMsg(virQEMUDriver *driver,
goto cleanup;
if (logCtxt) {
- rc = qemuDomainLogContextWrite(logCtxt,
- "%s: Domain id=%d is tainted:
%s%s%s%s\n",
- timestamp,
- obj->def->id,
- virDomainTaintTypeToString(taint),
- extraprefix, extramsg, extrasuffix);
+ rc = qemuLogContextWrite(logCtxt,
+ "%s: Domain id=%d is tainted: %s%s%s%s\n",
+ timestamp,
+ obj->def->id,
+ virDomainTaintTypeToString(taint),
+ extraprefix, extramsg, extrasuffix);
} else {
rc = qemuDomainLogAppendMessage(driver, obj,
"%s: Domain id=%d is tainted:
%s%s%s%s\n",
@@ -6961,7 +6924,7 @@ qemuDomainObjTaintMsg(virQEMUDriver *driver,
void qemuDomainObjTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainTaintFlags taint,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
qemuDomainObjTaintMsg(driver, obj, taint, logCtxt, NULL);
qemuDomainSaveStatus(obj);
@@ -6970,7 +6933,7 @@ void qemuDomainObjTaint(virQEMUDriver *driver,
static void
qemuDomainObjCheckMachineTaint(virQEMUDriver *driver,
virDomainObj *obj,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
qemuDomainObjPrivate *priv = obj->privateData;
virQEMUCaps *qemuCaps = priv->qemuCaps;
@@ -6988,7 +6951,7 @@ qemuDomainObjCheckMachineTaint(virQEMUDriver *driver,
static void
qemuDomainObjCheckCPUTaint(virQEMUDriver *driver,
virDomainObj *obj,
- qemuDomainLogContext *logCtxt,
+ qemuLogContext *logCtxt,
bool incomingMigration)
{
qemuDomainObjPrivate *priv = obj->privateData;
@@ -7020,7 +6983,7 @@ qemuDomainObjCheckCPUTaint(virQEMUDriver *driver,
void qemuDomainObjCheckTaint(virQEMUDriver *driver,
virDomainObj *obj,
- qemuDomainLogContext *logCtxt,
+ qemuLogContext *logCtxt,
bool incomingMigration)
{
size_t i;
@@ -7076,7 +7039,7 @@ void qemuDomainObjCheckTaint(virQEMUDriver *driver,
void qemuDomainObjCheckDiskTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainDiskDef *disk,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
if (disk->rawio == VIR_TRISTATE_BOOL_YES)
qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES,
@@ -7093,7 +7056,7 @@ void qemuDomainObjCheckDiskTaint(virQEMUDriver *driver,
void qemuDomainObjCheckHostdevTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainHostdevDef *hostdev,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
if (!virHostdevIsSCSIDevice(hostdev))
return;
@@ -7106,7 +7069,7 @@ void qemuDomainObjCheckHostdevTaint(virQEMUDriver *driver,
void qemuDomainObjCheckNetTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainNetDef *net,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
/* script is only useful for NET_TYPE_ETHERNET (qemu) and
* NET_TYPE_BRIDGE (xen), but could be (incorrectly) specified for
@@ -7118,163 +7081,6 @@ void qemuDomainObjCheckNetTaint(virQEMUDriver *driver,
}
-qemuDomainLogContext *qemuDomainLogContextNew(virQEMUDriver *driver,
- virDomainObj *vm,
- const char *basename)
-{
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
- qemuDomainLogContext *ctxt =
QEMU_DOMAIN_LOG_CONTEXT(g_object_new(QEMU_TYPE_DOMAIN_LOG_CONTEXT, NULL));
-
- VIR_DEBUG("Context new %p stdioLogD=%d", ctxt, cfg->stdioLogD);
- ctxt->writefd = -1;
- ctxt->readfd = -1;
-
- ctxt->path = g_strdup_printf("%s/%s.log", cfg->logDir, basename);
-
- if (cfg->stdioLogD) {
- ctxt->manager = virLogManagerNew(driver->privileged);
- if (!ctxt->manager)
- goto error;
-
- ctxt->writefd = virLogManagerDomainOpenLogFile(ctxt->manager,
- "qemu",
- vm->def->uuid,
- vm->def->name,
- ctxt->path,
- 0,
- &ctxt->inode,
- &ctxt->pos);
- if (ctxt->writefd < 0)
- goto error;
- } else {
- if ((ctxt->writefd = open(ctxt->path, O_WRONLY | O_CREAT | O_APPEND,
S_IRUSR | S_IWUSR)) < 0) {
- virReportSystemError(errno, _("failed to create logfile %1$s"),
- ctxt->path);
- goto error;
- }
- if (virSetCloseExec(ctxt->writefd) < 0) {
- virReportSystemError(errno, _("failed to set close-on-exec flag on
%1$s"),
- ctxt->path);
- goto error;
- }
-
- /* For unprivileged startup we must truncate the file since
- * we can't rely on logrotate. We don't use O_TRUNC since
- * it is better for SELinux policy if we truncate afterwards */
- if (!driver->privileged &&
- ftruncate(ctxt->writefd, 0) < 0) {
- virReportSystemError(errno, _("failed to truncate %1$s"),
- ctxt->path);
- goto error;
- }
-
- if ((ctxt->readfd = open(ctxt->path, O_RDONLY)) < 0) {
- virReportSystemError(errno, _("failed to open logfile %1$s"),
- ctxt->path);
- goto error;
- }
- if (virSetCloseExec(ctxt->readfd) < 0) {
- virReportSystemError(errno, _("failed to set close-on-exec flag on
%1$s"),
- ctxt->path);
- goto error;
- }
-
- if ((ctxt->pos = lseek(ctxt->writefd, 0, SEEK_END)) < 0) {
- virReportSystemError(errno, _("failed to seek in log file %1$s"),
- ctxt->path);
- goto error;
- }
- }
-
- return ctxt;
-
- error:
- g_clear_object(&ctxt);
- return NULL;
-}
-
-
-int qemuDomainLogContextWrite(qemuDomainLogContext *ctxt,
- const char *fmt, ...)
-{
- va_list argptr;
- g_autofree char *message = NULL;
- int ret = -1;
-
- va_start(argptr, fmt);
-
- message = g_strdup_vprintf(fmt, argptr);
- if (!ctxt->manager &&
- lseek(ctxt->writefd, 0, SEEK_END) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to seek to end of domain logfile"));
- goto cleanup;
- }
- if (safewrite(ctxt->writefd, message, strlen(message)) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to write to domain logfile"));
- goto cleanup;
- }
-
- ret = 0;
-
- cleanup:
- va_end(argptr);
- return ret;
-}
-
-
-ssize_t qemuDomainLogContextRead(qemuDomainLogContext *ctxt,
- char **msg)
-{
- char *buf;
- size_t buflen;
-
- VIR_DEBUG("Context read %p manager=%p inode=%llu pos=%llu",
- ctxt, ctxt->manager,
- (unsigned long long)ctxt->inode,
- (unsigned long long)ctxt->pos);
-
- if (ctxt->manager) {
- buf = virLogManagerDomainReadLogFile(ctxt->manager,
- ctxt->path,
- ctxt->inode,
- ctxt->pos,
- 1024 * 128,
- 0);
- if (!buf)
- return -1;
- buflen = strlen(buf);
- } else {
- ssize_t got;
-
- buflen = 1024 * 128;
-
- /* Best effort jump to start of messages */
- ignore_value(lseek(ctxt->readfd, ctxt->pos, SEEK_SET));
-
- buf = g_new0(char, buflen);
-
- got = saferead(ctxt->readfd, buf, buflen - 1);
- if (got < 0) {
- VIR_FREE(buf);
- virReportSystemError(errno, "%s",
- _("Unable to read from log file"));
- return -1;
- }
-
- buf[got] = '\0';
-
- buf = g_renew(char, buf, got + 1);
- buflen = got;
- }
-
- *msg = buf;
-
- return buflen;
-}
-
-
/**
* qemuDomainLogAppendMessage:
*
@@ -7332,31 +7138,6 @@ qemuDomainLogAppendMessage(virQEMUDriver *driver,
}
-int qemuDomainLogContextGetWriteFD(qemuDomainLogContext *ctxt)
-{
- return ctxt->writefd;
-}
-
-
-void qemuDomainLogContextMarkPosition(qemuDomainLogContext *ctxt)
-{
- if (ctxt->manager)
- virLogManagerDomainGetLogFilePosition(ctxt->manager,
- ctxt->path,
- 0,
- &ctxt->inode,
- &ctxt->pos);
- else
- ctxt->pos = lseek(ctxt->writefd, 0, SEEK_END);
-}
-
-
-virLogManager *qemuDomainLogContextGetManager(qemuDomainLogContext *ctxt)
-{
- return ctxt->manager;
-}
-
-
/* Locate an appropriate 'qemu-img' binary. */
const char *
qemuFindQemuImgBinary(virQEMUDriver *driver)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a262555c8c..ddd20e67b4 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -32,13 +32,13 @@
#include "qemu_domainjob.h"
#include "qemu_conf.h"
#include "qemu_capabilities.h"
+#include "qemu_logcontext.h"
#include "qemu_migration_params.h"
#include "qemu_nbdkit.h"
#include "qemu_slirp.h"
#include "qemu_fd.h"
#include "virchrdev.h"
#include "virobject.h"
-#include "logging/log_manager.h"
#include "virdomainmomentobjlist.h"
#include "virenum.h"
#include "vireventthread.h"
@@ -479,9 +479,6 @@ struct qemuProcessEvent {
void qemuProcessEventFree(struct qemuProcessEvent *event);
-#define QEMU_TYPE_DOMAIN_LOG_CONTEXT qemu_domain_log_context_get_type()
-G_DECLARE_FINAL_TYPE(qemuDomainLogContext, qemu_domain_log_context, QEMU,
DOMAIN_LOG_CONTEXT, GObject);
-
typedef struct _qemuDomainSaveCookie qemuDomainSaveCookie;
struct _qemuDomainSaveCookie {
virObject parent;
@@ -634,39 +631,27 @@ char *qemuDomainDefFormatLive(virQEMUDriver *driver,
void qemuDomainObjTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainTaintFlags taint,
- qemuDomainLogContext *logCtxt);
+ qemuLogContext *logCtxt);
char **qemuDomainObjGetTainting(virQEMUDriver *driver,
virDomainObj *obj);
void qemuDomainObjCheckTaint(virQEMUDriver *driver,
virDomainObj *obj,
- qemuDomainLogContext *logCtxt,
+ qemuLogContext *logCtxt,
bool incomingMigration);
void qemuDomainObjCheckDiskTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainDiskDef *disk,
- qemuDomainLogContext *logCtxt);
+ qemuLogContext *logCtxt);
void qemuDomainObjCheckHostdevTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainHostdevDef *disk,
- qemuDomainLogContext *logCtxt);
+ qemuLogContext *logCtxt);
void qemuDomainObjCheckNetTaint(virQEMUDriver *driver,
virDomainObj *obj,
virDomainNetDef *net,
- qemuDomainLogContext *logCtxt);
-
-qemuDomainLogContext *qemuDomainLogContextNew(virQEMUDriver *driver,
- virDomainObj *vm,
- const char *basename);
-int qemuDomainLogContextWrite(qemuDomainLogContext *ctxt,
- const char *fmt, ...) G_GNUC_PRINTF(2, 3);
-ssize_t qemuDomainLogContextRead(qemuDomainLogContext *ctxt,
- char **msg);
-int qemuDomainLogContextGetWriteFD(qemuDomainLogContext *ctxt);
-void qemuDomainLogContextMarkPosition(qemuDomainLogContext *ctxt);
-
-virLogManager *qemuDomainLogContextGetManager(qemuDomainLogContext *ctxt);
+ qemuLogContext *logCtxt);
int qemuDomainLogAppendMessage(virQEMUDriver *driver,
virDomainObj *vm,
diff --git a/src/qemu/qemu_logcontext.c b/src/qemu/qemu_logcontext.c
new file mode 100644
index 0000000000..0121ae5173
--- /dev/null
+++ b/src/qemu/qemu_logcontext.c
@@ -0,0 +1,264 @@
+/*
+ * qemu_logcontext.c: QEMU log context
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "qemu_logcontext.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "virutil.h"
+
+#include <fcntl.h>
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+VIR_LOG_INIT("qemu.qemu_logcontext");
+
+
+struct _qemuLogContext {
+ GObject parent;
+
+ int writefd;
+ int readfd; /* Only used if manager == NULL */
+ off_t pos;
+ ino_t inode; /* Only used if manager != NULL */
+ char *path;
+ virLogManager *manager;
+};
+
+G_DEFINE_TYPE(qemuLogContext, qemu_log_context, G_TYPE_OBJECT);
+
+static void
+qemuLogContextFinalize(GObject *obj);
+
+
+static void
+qemu_log_context_init(qemuLogContext *logctxt G_GNUC_UNUSED)
+{
+}
+
+
+static void
+qemu_log_context_class_init(qemuLogContextClass *klass)
+{
+ GObjectClass *obj = G_OBJECT_CLASS(klass);
+
+ obj->finalize = qemuLogContextFinalize;
+}
+
+
+static void
+qemuLogContextFinalize(GObject *object)
+{
+ qemuLogContext *ctxt = QEMU_LOG_CONTEXT(object);
+ VIR_DEBUG("ctxt=%p", ctxt);
+
+ virLogManagerFree(ctxt->manager);
+ VIR_FREE(ctxt->path);
+ VIR_FORCE_CLOSE(ctxt->writefd);
+ VIR_FORCE_CLOSE(ctxt->readfd);
+ G_OBJECT_CLASS(qemu_log_context_parent_class)->finalize(object);
+}
+
+
+qemuLogContext *
+qemuLogContextNew(virQEMUDriver *driver,
+ virDomainObj *vm,
+ const char *basename)
+{
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ qemuLogContext *ctxt = QEMU_LOG_CONTEXT(g_object_new(QEMU_TYPE_LOG_CONTEXT, NULL));
+
+ VIR_DEBUG("Context new %p stdioLogD=%d", ctxt, cfg->stdioLogD);
+ ctxt->writefd = -1;
+ ctxt->readfd = -1;
+
+ ctxt->path = g_strdup_printf("%s/%s.log", cfg->logDir, basename);
+
+ if (cfg->stdioLogD) {
+ ctxt->manager = virLogManagerNew(driver->privileged);
+ if (!ctxt->manager)
+ goto error;
+
+ ctxt->writefd = virLogManagerDomainOpenLogFile(ctxt->manager,
+ "qemu",
+ vm->def->uuid,
+ vm->def->name,
+ ctxt->path,
+ 0,
+ &ctxt->inode,
+ &ctxt->pos);
+ if (ctxt->writefd < 0)
+ goto error;
+ } else {
+ if ((ctxt->writefd = open(ctxt->path, O_WRONLY | O_CREAT | O_APPEND,
S_IRUSR | S_IWUSR)) < 0) {
+ virReportSystemError(errno, _("failed to create logfile %1$s"),
+ ctxt->path);
+ goto error;
+ }
+ if (virSetCloseExec(ctxt->writefd) < 0) {
+ virReportSystemError(errno, _("failed to set close-on-exec flag on
%1$s"),
+ ctxt->path);
+ goto error;
+ }
+
+ /* For unprivileged startup we must truncate the file since
+ * we can't rely on logrotate. We don't use O_TRUNC since
+ * it is better for SELinux policy if we truncate afterwards */
+ if (!driver->privileged &&
+ ftruncate(ctxt->writefd, 0) < 0) {
+ virReportSystemError(errno, _("failed to truncate %1$s"),
+ ctxt->path);
+ goto error;
+ }
+
+ if ((ctxt->readfd = open(ctxt->path, O_RDONLY)) < 0) {
+ virReportSystemError(errno, _("failed to open logfile %1$s"),
+ ctxt->path);
+ goto error;
+ }
+ if (virSetCloseExec(ctxt->readfd) < 0) {
+ virReportSystemError(errno, _("failed to set close-on-exec flag on
%1$s"),
+ ctxt->path);
+ goto error;
+ }
+
+ if ((ctxt->pos = lseek(ctxt->writefd, 0, SEEK_END)) < 0) {
+ virReportSystemError(errno, _("failed to seek in log file %1$s"),
+ ctxt->path);
+ goto error;
+ }
+ }
+
+ return ctxt;
+
+ error:
+ g_clear_object(&ctxt);
+ return NULL;
+}
+
+
+int
+qemuLogContextWrite(qemuLogContext *ctxt,
+ const char *fmt, ...)
+{
+ va_list argptr;
+ g_autofree char *message = NULL;
+ int ret = -1;
+
+ va_start(argptr, fmt);
+
+ message = g_strdup_vprintf(fmt, argptr);
+ if (!ctxt->manager &&
+ lseek(ctxt->writefd, 0, SEEK_END) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to seek to end of domain logfile"));
+ goto cleanup;
+ }
+ if (safewrite(ctxt->writefd, message, strlen(message)) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to write to domain logfile"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ va_end(argptr);
+ return ret;
+}
+
+
+ssize_t
+qemuLogContextRead(qemuLogContext *ctxt,
+ char **msg)
+{
+ char *buf;
+ size_t buflen;
+
+ VIR_DEBUG("Context read %p manager=%p inode=%llu pos=%llu",
+ ctxt, ctxt->manager,
+ (unsigned long long)ctxt->inode,
+ (unsigned long long)ctxt->pos);
+
+ if (ctxt->manager) {
+ buf = virLogManagerDomainReadLogFile(ctxt->manager,
+ ctxt->path,
+ ctxt->inode,
+ ctxt->pos,
+ 1024 * 128,
+ 0);
+ if (!buf)
+ return -1;
+ buflen = strlen(buf);
+ } else {
+ ssize_t got;
+
+ buflen = 1024 * 128;
+
+ /* Best effort jump to start of messages */
+ ignore_value(lseek(ctxt->readfd, ctxt->pos, SEEK_SET));
+
+ buf = g_new0(char, buflen);
+
+ got = saferead(ctxt->readfd, buf, buflen - 1);
+ if (got < 0) {
+ VIR_FREE(buf);
+ virReportSystemError(errno, "%s",
+ _("Unable to read from log file"));
+ return -1;
+ }
+
+ buf[got] = '\0';
+
+ buf = g_renew(char, buf, got + 1);
+ buflen = got;
+ }
+
+ *msg = buf;
+
+ return buflen;
+}
+
+
+int
+qemuLogContextGetWriteFD(qemuLogContext *ctxt)
+{
+ return ctxt->writefd;
+}
+
+
+void
+qemuLogContextMarkPosition(qemuLogContext *ctxt)
+{
+ if (ctxt->manager)
+ virLogManagerDomainGetLogFilePosition(ctxt->manager,
+ ctxt->path,
+ 0,
+ &ctxt->inode,
+ &ctxt->pos);
+ else
+ ctxt->pos = lseek(ctxt->writefd, 0, SEEK_END);
+}
+
+
+virLogManager *
+qemuLogContextGetManager(qemuLogContext *ctxt)
+{
+ return ctxt->manager;
+}
diff --git a/src/qemu/qemu_logcontext.h b/src/qemu/qemu_logcontext.h
new file mode 100644
index 0000000000..6ad60b7b4a
--- /dev/null
+++ b/src/qemu/qemu_logcontext.h
@@ -0,0 +1,38 @@
+/*
+ * qemu_logcontext.h: QEMU log context
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include "qemu_conf.h"
+#include "logging/log_manager.h"
+
+#define QEMU_TYPE_LOG_CONTEXT qemu_log_context_get_type()
+G_DECLARE_FINAL_TYPE(qemuLogContext, qemu_log_context, QEMU, LOG_CONTEXT, GObject);
+
+qemuLogContext *qemuLogContextNew(virQEMUDriver *driver,
+ virDomainObj *vm,
+ const char *basename);
+int qemuLogContextWrite(qemuLogContext *ctxt,
+ const char *fmt, ...) G_GNUC_PRINTF(2, 3);
+ssize_t qemuLogContextRead(qemuLogContext *ctxt,
+ char **msg);
+int qemuLogContextGetWriteFD(qemuLogContext *ctxt);
+void qemuLogContextMarkPosition(qemuLogContext *ctxt);
+
+virLogManager *qemuLogContextGetManager(qemuLogContext *ctxt);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e0385d11be..e03d0d8b4d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1831,7 +1831,7 @@ qemuProcessMonitorReportLogError(qemuMonitor *mon,
static void
qemuProcessMonitorLogFree(void *opaque)
{
- qemuDomainLogContext *logCtxt = opaque;
+ qemuLogContext *logCtxt = opaque;
g_clear_object(&logCtxt);
}
@@ -1857,7 +1857,7 @@ static int
qemuConnectMonitor(virQEMUDriver *driver,
virDomainObj *vm,
int asyncJob,
- qemuDomainLogContext *logCtxt,
+ qemuLogContext *logCtxt,
bool reconnect)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -1921,7 +1921,7 @@ qemuConnectMonitor(virQEMUDriver *driver,
* Returns 0 on success or -1 on error
*/
static int
-qemuProcessReadLog(qemuDomainLogContext *logCtxt,
+qemuProcessReadLog(qemuLogContext *logCtxt,
char **msg,
size_t max)
{
@@ -1931,7 +1931,7 @@ qemuProcessReadLog(qemuDomainLogContext *logCtxt,
char *filter_next;
size_t skip;
- if ((got = qemuDomainLogContextRead(logCtxt, &buf)) < 0)
+ if ((got = qemuLogContextRead(logCtxt, &buf)) < 0)
return -1;
/* Filter out debug messages from intermediate libvirt process */
@@ -1974,7 +1974,7 @@ qemuProcessReadLog(qemuDomainLogContext *logCtxt,
static int
-qemuProcessReportLogError(qemuDomainLogContext *logCtxt,
+qemuProcessReportLogError(qemuLogContext *logCtxt,
const char *msgprefix)
{
g_autofree char *logmsg = NULL;
@@ -1999,7 +1999,7 @@ qemuProcessMonitorReportLogError(qemuMonitor *mon G_GNUC_UNUSED,
const char *msg,
void *opaque)
{
- qemuDomainLogContext *logCtxt = opaque;
+ qemuLogContext *logCtxt = opaque;
qemuProcessReportLogError(logCtxt, msg);
}
@@ -2300,7 +2300,7 @@ static int
qemuProcessWaitForMonitor(virQEMUDriver *driver,
virDomainObj *vm,
int asyncJob,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
int ret = -1;
g_autoptr(GHashTable) info = NULL;
@@ -4664,7 +4664,7 @@ static void
qemuLogOperation(virDomainObj *vm,
const char *msg,
virCommand *cmd,
- qemuDomainLogContext *logCtxt)
+ qemuLogContext *logCtxt)
{
g_autofree char *timestamp = NULL;
qemuDomainObjPrivate *priv = vm->privateData;
@@ -4678,20 +4678,20 @@ qemuLogOperation(virDomainObj *vm,
if ((timestamp = virTimeStringNow()) == NULL)
return;
- if (qemuDomainLogContextWrite(logCtxt,
- "%s: %s %s, qemu version: %d.%d.%d%s, kernel: %s,
hostname: %s\n",
- timestamp, msg, VIR_LOG_VERSION_STRING,
- (qemuVersion / 1000000) % 1000,
- (qemuVersion / 1000) % 1000,
- qemuVersion % 1000,
- NULLSTR_EMPTY(package),
- uts.release,
- NULLSTR_EMPTY(hostname)) < 0)
+ if (qemuLogContextWrite(logCtxt,
+ "%s: %s %s, qemu version: %d.%d.%d%s, kernel: %s,
hostname: %s\n",
+ timestamp, msg, VIR_LOG_VERSION_STRING,
+ (qemuVersion / 1000000) % 1000,
+ (qemuVersion / 1000) % 1000,
+ qemuVersion % 1000,
+ NULLSTR_EMPTY(package),
+ uts.release,
+ NULLSTR_EMPTY(hostname)) < 0)
return;
if (cmd) {
g_autofree char *args = virCommandToString(cmd, true);
- qemuDomainLogContextWrite(logCtxt, "%s\n", args);
+ qemuLogContextWrite(logCtxt, "%s\n", args);
}
}
@@ -7566,7 +7566,7 @@ qemuProcessLaunch(virConnectPtr conn,
int ret = -1;
int rv;
int logfile = -1;
- g_autoptr(qemuDomainLogContext) logCtxt = NULL;
+ g_autoptr(qemuLogContext) logCtxt = NULL;
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virCommand) cmd = NULL;
struct qemuProcessHookData hookData;
@@ -7616,11 +7616,11 @@ qemuProcessLaunch(virConnectPtr conn,
hookData.cfg = cfg;
VIR_DEBUG("Creating domain log file");
- if (!(logCtxt = qemuDomainLogContextNew(driver, vm, vm->def->name))) {
+ if (!(logCtxt = qemuLogContextNew(driver, vm, vm->def->name))) {
virLastErrorPrefixMessage("%s", _("can't connect to
virtlogd"));
goto cleanup;
}
- logfile = qemuDomainLogContextGetWriteFD(logCtxt);
+ logfile = qemuLogContextGetWriteFD(logCtxt);
if (qemuProcessGenID(vm, flags) < 0)
goto cleanup;
@@ -7656,7 +7656,7 @@ qemuProcessLaunch(virConnectPtr conn,
qemuDomainObjCheckTaint(driver, vm, logCtxt, incoming != NULL);
- qemuDomainLogContextMarkPosition(logCtxt);
+ qemuLogContextMarkPosition(logCtxt);
if (qemuProcessEnableDomainNamespaces(driver, vm) < 0)
goto cleanup;
--
2.41.0