]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: use virtlogd for character device log files
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 23 Feb 2016 13:05:09 +0000 (13:05 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 10 Mar 2016 15:41:52 +0000 (15:41 +0000)
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
src/qemu/qemu_command.h
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c
src/qemu/qemu_process.c
tests/qemuxml2argvtest.c

index 93aeaa258d51ae2b457dbf459bb0faea13a65b02..3ce708f5230487f8bdd3897cbd5b0ec4c06166cf 100644 (file)
@@ -60,6 +60,7 @@
 #if defined(__linux__)
 # include <linux/capability.h>
 #endif
+#include "logging/log_manager.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -3909,10 +3910,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)
 {
@@ -4035,11 +4088,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)
@@ -4155,7 +4207,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)
@@ -4168,7 +4222,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");
@@ -4310,7 +4365,10 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev)
 
 
 static int
-qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
+qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
+                             virCommandPtr cmd,
+                             virDomainDefPtr def,
+                             virDomainRNGDefPtr rng,
                              virQEMUCapsPtr qemuCaps,
                              char **chr)
 {
@@ -4323,7 +4381,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;
     }
@@ -6644,7 +6703,10 @@ qemuBuildShmemDevStr(virDomainDefPtr def,
 }
 
 char *
-qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
+qemuBuildShmemBackendStr(virLogManagerPtr logManager,
+                         virCommandPtr cmd,
+                         virDomainDefPtr def,
+                         virDomainShmemDefPtr shmem,
                          virQEMUCapsPtr qemuCaps)
 {
     char *devstr = NULL;
@@ -6655,13 +6717,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)
@@ -6674,7 +6739,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);
@@ -7045,6 +7111,7 @@ qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
 virCommandPtr
 qemuBuildCommandLine(virConnectPtr conn,
                      virQEMUDriverPtr driver,
+                     virLogManagerPtr logManager,
                      virDomainDefPtr def,
                      virDomainChrSourceDefPtr monitor_chr,
                      bool monitor_json,
@@ -7197,7 +7264,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;
 
@@ -7959,7 +8027,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);
@@ -8003,7 +8072,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;
@@ -8039,7 +8109,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;
@@ -8072,7 +8143,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;
@@ -8116,7 +8188,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;
@@ -8150,7 +8223,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;
@@ -8169,7 +8243,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;
@@ -8522,7 +8597,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;
@@ -8748,7 +8824,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) {
@@ -8893,7 +8970,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;
     }
 
index c63c7bc9ee713df8804e8ec2d41f0da39bcdab16..79b319ccb9050ca0b321c079c130f05afe15ba3a 100644 (file)
@@ -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,
@@ -74,8 +76,8 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    int **nicindexes,
                                    const char *domainLibDir,
                                    const char *domainChannelTargetDir)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(10)
-    ATTRIBUTE_NONNULL(16) ATTRIBUTE_NONNULL(17);
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11)
+    ATTRIBUTE_NONNULL(17) ATTRIBUTE_NONNULL(18);
 
 /* Generate '-device' string for chardev device */
 int
@@ -183,7 +185,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);
 
 
index e859d8ff933ef20a218ea93c3ab53daf1d6a0813..594063e8f67250d5c48f1162171041f5cd9118ac 100644 (file)
@@ -2710,6 +2710,12 @@ void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt)
 }
 
 
+virLogManagerPtr qemuDomainLogContextGetManager(qemuDomainLogContextPtr ctxt)
+{
+    return ctxt->manager;
+}
+
+
 void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt)
 {
     bool lastRef;
index b6f493e5b325f1ac2132518f241fb96b2e795e92..5976455d9a9a9b04f52fb2d5504bc2e44c11ebb4 100644 (file)
@@ -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 |                \
@@ -385,6 +386,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,
index 91f5f518eaebcb5a90f74a95d6c8aca4aebe561d..a0d6596aef7ba7b5abf70734821572e9b86cab58 100644 (file)
@@ -7106,7 +7106,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,
index cd7861e72809ab6adc39e60fa60c06e5bf08caa5..14e4629e66f9dccb8f06356ca0b47576da13fa74 100644 (file)
@@ -5063,7 +5063,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,
index d54c93f0cd1ea39a199dc2119efddccae2710952..4f6291dd52e392f2f950c342c432bf29b20d51f2 100644 (file)
@@ -353,7 +353,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,