[libvirt] [PATCH v2 7/8] qemu: use virtlogd for character device log files

Daniel P. Berrange berrange at redhat.com
Mon Feb 29 13:33:39 UTC 2016


If use of virtlogd is enabled, then use it for backing the
character device log files too. This avoids the possibility
of a guest denial of service by writing too much data to
the log file.
---
 src/qemu/qemu_command.c  | 128 ++++++++++++++++++++++++++++++++++++++---------
 src/qemu/qemu_command.h  |   9 +++-
 src/qemu/qemu_domain.c   |   6 +++
 src/qemu/qemu_domain.h   |   3 ++
 src/qemu/qemu_driver.c   |   2 +-
 src/qemu/qemu_process.c  |   4 +-
 tests/qemuxml2argvtest.c |   2 +-
 7 files changed, 124 insertions(+), 30 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 490e991..e04e55e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -60,6 +60,7 @@
 #if defined(__linux__)
 # include <linux/capability.h>
 #endif
+#include "logging/log_manager.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -3900,10 +3901,62 @@ qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
     return NULL;
 }
 
+static int
+qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
+                           virCommandPtr cmd,
+                           virDomainDefPtr def,
+                           virBufferPtr buf,
+                           const char *filearg, const char *fileval,
+                           const char *appendarg, int appendval)
+{
+    if (logManager) {
+        char *fdset, *fdpath;
+        int flags = 0;
+        int logfd;
+
+        if (appendval == VIR_TRISTATE_SWITCH_OFF)
+            flags |= VIR_LOG_MANAGER_PROTOCOL_DOMAIN_OPEN_LOG_FILE_TRUNCATE;
+
+        if ((logfd = virLogManagerDomainOpenLogFile(logManager,
+                                                    "qemu",
+                                                    def->uuid,
+                                                    def->name,
+                                                    fileval,
+                                                    flags,
+                                                    NULL, NULL)) < 0)
+            return -1;
+
+        virCommandPassFD(cmd, logfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+        if (!(fdset = qemuVirCommandGetFDSet(cmd, logfd)))
+            return -1;
+
+        virCommandAddArg(cmd, "-add-fd");
+        virCommandAddArg(cmd, fdset);
+        VIR_FREE(fdset);
+
+        if (!(fdpath = qemuVirCommandGetDevSet(cmd, logfd)))
+            return -1;
+
+        virBufferAsprintf(buf, ",%s=%s,%s=on", filearg, fdpath, appendarg);
+        VIR_FREE(fdpath);
+    } else {
+        virBufferAsprintf(buf, ",%s=%s", filearg, fileval);
+        if (appendval != VIR_TRISTATE_SWITCH_ABSENT) {
+            virBufferAsprintf(buf, ",%s=%s", appendarg,
+                              virTristateSwitchTypeToString(appendval));
+        }
+    }
+
+    return 0;
+}
+
 /* This function outputs a -chardev command line option which describes only the
  * host side of the character device */
 static char *
-qemuBuildChrChardevStr(const virDomainChrSourceDef *dev,
+qemuBuildChrChardevStr(virLogManagerPtr logManager,
+                       virCommandPtr cmd,
+                       virDomainDefPtr def,
+                       const virDomainChrSourceDef *dev,
                        const char *alias,
                        virQEMUCapsPtr qemuCaps)
 {
@@ -4026,11 +4079,10 @@ qemuBuildChrChardevStr(const virDomainChrSourceDef *dev,
                            _("logfile not supported in this QEMU binary"));
             goto error;
         }
-        virBufferAsprintf(&buf, ",logfile=%s", dev->logfile);
-        if (dev->logappend != VIR_TRISTATE_SWITCH_ABSENT) {
-            virBufferAsprintf(&buf, ",logappend=%s",
-                              virTristateSwitchTypeToString(dev->logappend));
-        }
+        if (qemuBuildChrChardevFileStr(logManager, cmd, def, &buf,
+                                       "logfile", dev->logfile,
+                                       "logappend", dev->logappend) < 0)
+            goto error;
     }
 
     if (virBufferCheckError(&buf) < 0)
@@ -4146,7 +4198,9 @@ qemuBuildChrArgStr(const virDomainChrSourceDef *dev,
 
 
 static int
-qemuBuildMonitorCommandLine(virCommandPtr cmd,
+qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
+                            virCommandPtr cmd,
+                            virDomainDefPtr def,
                             virQEMUCapsPtr qemuCaps,
                             const virDomainChrSourceDef *monitor_chr,
                             bool monitor_json)
@@ -4159,7 +4213,8 @@ qemuBuildMonitorCommandLine(virCommandPtr cmd,
     /* Use -chardev if it's available */
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) {
 
-        if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
+        if (!(chrdev = qemuBuildChrChardevStr(logManager, cmd, def,
+                                              monitor_chr, "monitor",
                                               qemuCaps)))
             return -1;
         virCommandAddArg(cmd, "-chardev");
@@ -4301,7 +4356,10 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev)
 
 
 static int
-qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
+qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
+                             virCommandPtr cmd,
+                             virDomainDefPtr def,
+                             virDomainRNGDefPtr rng,
                              virQEMUCapsPtr qemuCaps,
                              char **chr)
 {
@@ -4314,7 +4372,8 @@ qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
         return 0;
 
     case VIR_DOMAIN_RNG_BACKEND_EGD:
-        if (!(*chr = qemuBuildChrChardevStr(rng->source.chardev,
+        if (!(*chr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                            rng->source.chardev,
                                             rng->info.alias, qemuCaps)))
             return -1;
     }
@@ -6620,7 +6679,10 @@ qemuBuildShmemDevStr(virDomainDefPtr def,
 }
 
 char *
-qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
+qemuBuildShmemBackendStr(virLogManagerPtr logManager,
+                         virCommandPtr cmd,
+                         virDomainDefPtr def,
+                         virDomainShmemDefPtr shmem,
                          virQEMUCapsPtr qemuCaps)
 {
     char *devstr = NULL;
@@ -6631,13 +6693,16 @@ qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
                     shmem->name) < 0)
         return NULL;
 
-    devstr = qemuBuildChrChardevStr(&shmem->server.chr, shmem->info.alias, qemuCaps);
+    devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                    &shmem->server.chr,
+                                    shmem->info.alias, qemuCaps);
 
     return devstr;
 }
 
 static int
-qemuBuildShmemCommandLine(virCommandPtr cmd,
+qemuBuildShmemCommandLine(virLogManagerPtr logManager,
+                          virCommandPtr cmd,
                           virDomainDefPtr def,
                           virDomainShmemDefPtr shmem,
                           virQEMUCapsPtr qemuCaps)
@@ -6650,7 +6715,8 @@ qemuBuildShmemCommandLine(virCommandPtr cmd,
     VIR_FREE(devstr);
 
     if (shmem->server.enabled) {
-        if (!(devstr = qemuBuildShmemBackendStr(shmem, qemuCaps)))
+        if (!(devstr = qemuBuildShmemBackendStr(logManager, cmd, def,
+                                                shmem, qemuCaps)))
             return -1;
 
         virCommandAddArgList(cmd, "-chardev", devstr, NULL);
@@ -7020,6 +7086,7 @@ qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
 virCommandPtr
 qemuBuildCommandLine(virConnectPtr conn,
                      virQEMUDriverPtr driver,
+                     virLogManagerPtr logManager,
                      virDomainDefPtr def,
                      virDomainChrSourceDefPtr monitor_chr,
                      bool monitor_json,
@@ -7170,7 +7237,8 @@ qemuBuildCommandLine(virConnectPtr conn,
     if (qemuBuildSgaCommandLine(cmd, def, qemuCaps) < 0)
         goto error;
 
-    if (qemuBuildMonitorCommandLine(cmd, qemuCaps, monitor_chr,
+    if (qemuBuildMonitorCommandLine(logManager, cmd, def,
+                                    qemuCaps, monitor_chr,
                                     monitor_json) < 0)
         goto error;
 
@@ -7932,7 +8000,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
             }
 
-            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
+            if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                  &smartcard->data.passthru,
                                                   smartcard->info.alias,
                                                   qemuCaps))) {
                 virBufferFreeAndReset(&opt);
@@ -7976,7 +8045,8 @@ qemuBuildCommandLine(virConnectPtr conn,
 
         /* Use -chardev with -device if they are available */
         if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
-            if (!(devstr = qemuBuildChrChardevStr(&serial->source,
+            if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                  &serial->source,
                                                   serial->info.alias,
                                                   qemuCaps)))
                 goto error;
@@ -8012,7 +8082,8 @@ qemuBuildCommandLine(virConnectPtr conn,
             /* Use -chardev with -device if they are available */
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-                if (!(devstr = qemuBuildChrChardevStr(&parallel->source,
+                if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                      &parallel->source,
                                                       parallel->info.alias,
                                                       qemuCaps)))
                     goto error;
@@ -8045,7 +8116,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
             }
 
-            if (!(devstr = qemuBuildChrChardevStr(&channel->source,
+            if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                  &channel->source,
                                                   channel->info.alias,
                                                   qemuCaps)))
                 goto error;
@@ -8090,7 +8162,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                  * the newer -chardev interface.  */
                 ;
             } else {
-                if (!(devstr = qemuBuildChrChardevStr(&channel->source,
+                if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                      &channel->source,
                                                       channel->info.alias,
                                                       qemuCaps)))
                     goto error;
@@ -8124,7 +8197,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
             }
 
-            if (!(devstr = qemuBuildChrChardevStr(&console->source,
+            if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                  &console->source,
                                                   console->info.alias,
                                                   qemuCaps)))
                 goto error;
@@ -8143,7 +8217,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
             }
 
-            if (!(devstr = qemuBuildChrChardevStr(&console->source,
+            if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                                  &console->source,
                                                   console->info.alias,
                                                   qemuCaps)))
                 goto error;
@@ -8487,7 +8562,8 @@ qemuBuildCommandLine(virConnectPtr conn,
         virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
         char *devstr;
 
-        if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr,
+        if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def,
+                                              &redirdev->source.chr,
                                               redirdev->info.alias,
                                               qemuCaps))) {
             goto error;
@@ -8713,7 +8789,8 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
 
         /* possibly add character device for backend */
-        if (qemuBuildRNGBackendChrdevStr(rng, qemuCaps, &tmp) < 0)
+        if (qemuBuildRNGBackendChrdevStr(logManager, cmd, def,
+                                         rng, qemuCaps, &tmp) < 0)
             goto error;
 
         if (tmp) {
@@ -8858,7 +8935,8 @@ qemuBuildCommandLine(virConnectPtr conn,
     }
 
     for (i = 0; i < def->nshmems; i++) {
-        if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps))
+        if (qemuBuildShmemCommandLine(logManager, cmd,
+                                      def, def->shmems[i], qemuCaps))
             goto error;
     }
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index fb684d0..160425e 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -32,6 +32,7 @@
 # include "qemu_domain.h"
 # include "qemu_domain_address.h"
 # include "qemu_capabilities.h"
+# include "logging/log_manager.h"
 
 /* Config type for XML import/export conversions */
 # define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
@@ -59,6 +60,7 @@ char *qemuBuildObjectCommandlineFromJSON(const char *type,
 
 virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    virQEMUDriverPtr driver,
+                                   virLogManagerPtr logManager,
                                    virDomainDefPtr def,
                                    virDomainChrSourceDefPtr monitor_chr,
                                    bool monitor_json,
@@ -72,7 +74,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    virBitmapPtr nodeset,
                                    size_t *nnicindexes,
                                    int **nicindexes)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(10);
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11);
 
 /* Generate '-device' string for chardev device */
 int
@@ -180,7 +182,10 @@ int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
 char *qemuBuildShmemDevStr(virDomainDefPtr def,
                            virDomainShmemDefPtr shmem,
                            virQEMUCapsPtr qemuCaps);
-char *qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
+char *qemuBuildShmemBackendStr(virLogManagerPtr logManager,
+                               virCommandPtr cmd,
+                               virDomainDefPtr def,
+                               virDomainShmemDefPtr shmem,
                                virQEMUCapsPtr qemuCaps);
 
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3fc1513..3d045cc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2609,6 +2609,12 @@ void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt)
 }
 
 
+virLogManagerPtr qemuDomainLogContextGetManager(qemuDomainLogContextPtr ctxt)
+{
+    return ctxt->manager;
+}
+
+
 void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt)
 {
     bool lastRef;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 8359b1a..f6ce19c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -35,6 +35,7 @@
 # include "qemu_capabilities.h"
 # include "virchrdev.h"
 # include "virobject.h"
+# include "logging/log_manager.h"
 
 # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS      \
     (VIR_DOMAIN_XML_SECURE |                \
@@ -377,6 +378,8 @@ void qemuDomainLogContextMarkPosition(qemuDomainLogContextPtr ctxt);
 void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt);
 void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt);
 
+virLogManagerPtr qemuDomainLogContextGetManager(qemuDomainLogContextPtr ctxt);
+
 const char *qemuFindQemuImgBinary(virQEMUDriverPtr driver);
 
 int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 45ff3c0..1afafd6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7159,7 +7159,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
         }
     }
 
-    if (!(cmd = qemuBuildCommandLine(conn, driver, def,
+    if (!(cmd = qemuBuildCommandLine(conn, driver, NULL, def,
                                      &monConfig, monitor_json, qemuCaps,
                                      NULL, NULL,
                                      VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e760182..03b7418 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4993,7 +4993,9 @@ qemuProcessLaunch(virConnectPtr conn,
     }
 
     VIR_DEBUG("Building emulator command line");
-    if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig,
+    if (!(cmd = qemuBuildCommandLine(conn, driver,
+                                     qemuDomainLogContextGetManager(logCtxt),
+                                     vm->def, priv->monConfig,
                                      priv->monJSON, priv->qemuCaps,
                                      incoming ? incoming->launchURI : NULL,
                                      snapshot, vmop,
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ff93329..4c760ee 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -347,7 +347,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
         testFailed = true;
 
     if (!testFailed &&
-        !(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr,
+        !(cmd = qemuBuildCommandLine(conn, &driver, NULL, vmdef, &monitor_chr,
                                      (flags & FLAG_JSON), extraFlags,
                                      migrateURI, NULL,
                                      VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
-- 
2.5.0




More information about the libvir-list mailing list