Blob Blame History Raw
From c72361536b151a2b9bd839bd528671bafbd5dee2 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Fri, 30 Aug 2013 12:41:32 -0400
Subject: [PATCH] qemu: Fix specifying char devs for ARM

QEMU ARM boards don't give us any way to explicitly wire in
a -chardev, so use the old style -serial options.

Unfortunately this isn't as simple as just turning off the CHARDEV flag
for qemu-system-arm, as upcoming virtio support _will_ use device/chardev.
---
 src/qemu/qemu_capabilities.c | 18 ++++++++++++++++++
 src/qemu/qemu_capabilities.h |  4 ++++
 src/qemu/qemu_command.c      |  3 +--
 src/qemu/qemu_process.c      | 37 ++++++++++++++++++++++---------------
 4 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7888e2d..72df793 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2827,3 +2827,21 @@ virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps)
 {
     return qemuCaps->usedQMP;
 }
+
+bool
+virQEMUCapsSupportsChardev(virDomainDefPtr def,
+                           virQEMUCapsPtr qemuCaps,
+                           virDomainChrDefPtr chr ATTRIBUTE_UNUSED)
+{
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
+        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
+        return false;
+
+    /* This may not be true for all ARM machine types, but at least
+     * the only supported serial devices of vexpress and versatile
+     * don't have the -chardev property wired up. */
+    if (def->os.arch != VIR_ARCH_ARMV7L)
+        return false;
+
+    return true;
+}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 69f3395..5180ee9 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -275,4 +275,8 @@ int virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps, const char *str);
 VIR_ENUM_DECL(virQEMUCaps);
 
 bool virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps);
+bool virQEMUCapsSupportsChardev(virDomainDefPtr def,
+                                virQEMUCapsPtr qemuCaps,
+                                virDomainChrDefPtr chr);
+
 #endif /* __QEMU_CAPABILITIES_H__*/
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9dfdb73..a8e532c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8493,8 +8493,7 @@ qemuBuildCommandLine(virConnectPtr conn,
             char *devstr;
 
             /* Use -chardev with -device if they are available */
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
-                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+            if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
                 virCommandAddArg(cmd, "-chardev");
                 if (!(devstr = qemuBuildChrChardevStr(&serial->source,
                                                       serial->info.alias,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dfe8142..abe0060 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1604,22 +1604,25 @@ qemuProcessExtractTTYPath(const char *haystack,
 }
 
 static int
-qemuProcessLookupPTYs(virDomainChrDefPtr *devices,
+qemuProcessLookupPTYs(virDomainDefPtr def,
+                      virQEMUCapsPtr qemuCaps,
+                      virDomainChrDefPtr *devices,
                       int count,
-                      virHashTablePtr paths,
-                      bool chardevfmt)
+                      virHashTablePtr paths)
 {
     size_t i;
-    const char *prefix = chardevfmt ? "char" : "";
 
     for (i = 0; i < count; i++) {
         virDomainChrDefPtr chr = devices[i];
+        bool chardevfmt = virQEMUCapsSupportsChardev(def, qemuCaps, chr);
+
         if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
             char id[32];
             const char *path;
 
             if (snprintf(id, sizeof(id), "%s%s",
-                         prefix, chr->info.alias) >= sizeof(id))
+                         chardevfmt ? "char" : "",
+                         chr->info.alias) >= sizeof(id))
                 return -1;
 
             path = (const char *) virHashLookup(paths, id);
@@ -1653,19 +1656,21 @@ qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
                                      virQEMUCapsPtr qemuCaps,
                                      virHashTablePtr paths)
 {
-    bool chardevfmt = virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV);
     size_t i = 0;
 
-    if (qemuProcessLookupPTYs(vm->def->serials, vm->def->nserials,
-                              paths, chardevfmt) < 0)
+    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
+                              vm->def->serials, vm->def->nserials,
+                              paths) < 0)
         return -1;
 
-    if (qemuProcessLookupPTYs(vm->def->parallels, vm->def->nparallels,
-                              paths, chardevfmt) < 0)
+    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
+                              vm->def->parallels, vm->def->nparallels,
+                              paths) < 0)
         return -1;
 
-    if (qemuProcessLookupPTYs(vm->def->channels, vm->def->nchannels,
-                              paths, chardevfmt) < 0)
+    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
+                              vm->def->channels, vm->def->nchannels,
+                              paths) < 0)
         return -1;
     /* For historical reasons, console[0] can be just an alias
      * for serial[0]. That's why we need to update it as well. */
@@ -1683,8 +1688,9 @@ qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
         }
     }
 
-    if (qemuProcessLookupPTYs(vm->def->consoles + i, vm->def->nconsoles - i,
-                              paths, chardevfmt) < 0)
+    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
+                              vm->def->consoles + i, vm->def->nconsoles - i,
+                              paths) < 0)
         return -1;
 
     return 0;
@@ -1774,7 +1780,8 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
     virHashTablePtr paths = NULL;
     qemuDomainObjPrivatePtr priv;
 
-    if (!virQEMUCapsUsedQMP(qemuCaps) && pos != -1) {
+    if (!virQEMUCapsUsedQMP(qemuCaps)
+        && pos != -1) {
         if ((logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
             return -1;