[libvirt] [PATCH v1 7/8] qemu: Introduce qemuBuildChrDeviceStr

Michal Privoznik mprivozn at redhat.com
Mon May 6 15:34:38 UTC 2013


The function being introduced is responsible for creating command
line argument for '-device' for given character device. Based on
the chardev type, it calls appropriate qemuBuild.*ChrDeviceStr(),
e.g.  qemuBuildSerialChrDeviceStr() for serial chardev and so on.
---
 src/qemu/qemu_command.c | 196 ++++++++++++++++++++++++++++++++++++++----------
 src/qemu/qemu_command.h |  11 ++-
 2 files changed, 160 insertions(+), 47 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9f4041c..215e6e4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7437,12 +7437,9 @@ qemuBuildCommandLine(virConnectPtr conn,
                 virCommandAddArg(cmd, devstr);
                 VIR_FREE(devstr);
 
-                virCommandAddArg(cmd, "-device");
-                if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps,
-                                                     def->os.arch,
-                                                     def->os.machine)))
+                if (qemuBuildChrDeviceStr(&devstr, def, serial, qemuCaps) < 0)
                    goto error;
-                virCommandAddArg(cmd, devstr);
+                virCommandAddArgList(cmd, "-device", devstr, NULL);
                 VIR_FREE(devstr);
             } else {
                 virCommandAddArg(cmd, "-serial");
@@ -7474,10 +7471,10 @@ qemuBuildCommandLine(virConnectPtr conn,
                 virCommandAddArg(cmd, devstr);
                 VIR_FREE(devstr);
 
-                virCommandAddArg(cmd, "-device");
-                virCommandAddArgFormat(cmd, "isa-parallel,chardev=char%s,id=%s",
-                                       parallel->info.alias,
-                                       parallel->info.alias);
+                if (qemuBuildChrDeviceStr(&devstr, def, parallel, qemuCaps) < 0)
+                   goto error;
+                virCommandAddArgList(cmd, "-device", devstr, NULL);
+                VIR_FREE(devstr);
             } else {
                 virCommandAddArg(cmd, "-parallel");
                 if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
@@ -7491,8 +7488,6 @@ qemuBuildCommandLine(virConnectPtr conn,
     for (i = 0 ; i < def->nchannels ; i++) {
         virDomainChrDefPtr channel = def->channels[i];
         char *devstr;
-        char *addr;
-        int port;
 
         switch (channel->targetType) {
         case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
@@ -7511,17 +7506,10 @@ qemuBuildCommandLine(virConnectPtr conn,
             virCommandAddArg(cmd, devstr);
             VIR_FREE(devstr);
 
-            addr = virSocketAddrFormat(channel->target.addr);
-            if (!addr)
+            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
                 goto error;
-            port = virSocketAddrGetPort(channel->target.addr);
-
-            virCommandAddArg(cmd, "-netdev");
-            virCommandAddArgFormat(cmd,
-                                   "user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s",
-                                   addr, port, channel->info.alias,
-                                   channel->info.alias);
-            VIR_FREE(addr);
+            virCommandAddArgList(cmd, "-netdev", devstr, NULL);
+            VIR_FREE(devstr);
             break;
 
         case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
@@ -7547,11 +7535,9 @@ qemuBuildCommandLine(virConnectPtr conn,
                 VIR_FREE(devstr);
             }
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel,
-                                                           qemuCaps)))
+            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
+            virCommandAddArgList(cmd, "-device", devstr, NULL);
             VIR_FREE(devstr);
             break;
         }
@@ -7584,10 +7570,9 @@ qemuBuildCommandLine(virConnectPtr conn,
             virCommandAddArg(cmd, devstr);
             VIR_FREE(devstr);
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildSclpDevStr(console)))
+            if (qemuBuildChrDeviceStr(&devstr, def, console, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
+            virCommandAddArgList(cmd, "-device", devstr, NULL);
             VIR_FREE(devstr);
             break;
 
@@ -7606,11 +7591,9 @@ qemuBuildCommandLine(virConnectPtr conn,
             virCommandAddArg(cmd, devstr);
             VIR_FREE(devstr);
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildVirtioSerialPortDevStr(console,
-                                                           qemuCaps)))
+            if (qemuBuildChrDeviceStr(&devstr, def, console, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
+            virCommandAddArgList(cmd, "-device", devstr, NULL);
             VIR_FREE(devstr);
             break;
 
@@ -8273,11 +8256,12 @@ error:
 /* This function generates the correct '-device' string for character
  * devices of each architecture.
  */
-char *
-qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
-                      virQEMUCapsPtr qemuCaps,
-                      virArch arch,
-                      char *machine)
+static int
+qemuBuildSerialChrDeviceStr(char **deviceStr,
+                            virDomainChrDefPtr serial,
+                            virQEMUCapsPtr qemuCaps,
+                            virArch arch,
+                            char *machine)
 {
     virBuffer cmd = VIR_BUFFER_INITIALIZER;
 
@@ -8309,7 +8293,7 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
             }
 
             if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0)
-               goto error;
+                goto error;
         }
     }
 
@@ -8318,13 +8302,143 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
         goto error;
     }
 
-    return virBufferContentAndReset(&cmd);
+    *deviceStr = virBufferContentAndReset(&cmd);
+    return 0;
 
- error:
+error:
     virBufferFreeAndReset(&cmd);
-    return NULL;
+    return -1;
+}
+
+static int
+qemuBuildParallelChrDeviceStr(char **deviceStr,
+                              virDomainChrDefPtr chr)
+{
+    if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
+                    chr->info.alias, chr->info.alias) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+    return 0;
+}
+
+static int
+qemuBuildChannelChrDeviceStr(char **deviceStr,
+                             virDomainChrDefPtr chr,
+                             virQEMUCapsPtr qemuCaps)
+{
+    int ret = -1;
+    char *addr = NULL;
+    int port;
+
+    switch ((enum virDomainChrChannelTargetType) chr->targetType) {
+    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
+
+        addr = virSocketAddrFormat(chr->target.addr);
+        if (!addr)
+            return ret;
+        port = virSocketAddrGetPort(chr->target.addr);
+
+        if (virAsprintf(deviceStr,
+                        "user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s",
+                        addr, port, chr->info.alias, chr->info.alias) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        break;
+
+    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
+        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
+                goto cleanup;
+        break;
+
+    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
+    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unsupported channel target type %d"),
+                       chr->targetType);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(addr);
+    return ret;
+}
+
+static int
+qemuBuildConsoleChrDeviceStr(char **deviceStr,
+                             virDomainChrDefPtr chr,
+                             virQEMUCapsPtr qemuCaps)
+{
+    int ret = -1;
+
+    switch (chr->targetType) {
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
+        if (!(*deviceStr = qemuBuildSclpDevStr(chr)))
+            goto cleanup;
+        break;
+
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
+        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
+            goto cleanup;
+        break;
+
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
+        break;
+
+    default:
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unsupported console target type %d"),
+                       chr->targetType);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    return ret;
+}
+
+int
+qemuBuildChrDeviceStr(char **deviceStr,
+                      virDomainDefPtr vmdef,
+                      virDomainChrDefPtr chr,
+                      virQEMUCapsPtr qemuCaps)
+{
+    int ret = -1;
+
+    switch ((enum virDomainChrDeviceType) chr->deviceType) {
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
+        ret = qemuBuildSerialChrDeviceStr(deviceStr, chr, qemuCaps,
+                                          vmdef->os.arch,
+                                          vmdef->os.machine);
+        break;
+
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
+        ret = qemuBuildParallelChrDeviceStr(deviceStr, chr);
+        break;
+
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
+        ret = qemuBuildChannelChrDeviceStr(deviceStr, chr, qemuCaps);
+        break;
+
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
+        ret = qemuBuildConsoleChrDeviceStr(deviceStr, chr, qemuCaps);
+        break;
+
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Chardev deviceType %d is not handled"),
+                       chr->deviceType);
+        break;
+    }
+
+    return ret;
 }
 
+
 /*
  * This method takes a string representing a QEMU command line ARGV set
  * optionally prefixed by a list of environment variables. It then tries
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index ba8ea8e..140b007 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -61,12 +61,11 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    enum virNetDevVPortProfileOp vmop)
     ATTRIBUTE_NONNULL(1);
 
-/* Generate string for arch-specific '-device' parameter */
-char *
-qemuBuildChrDeviceStr (virDomainChrDefPtr serial,
-                       virQEMUCapsPtr qemuCaps,
-                       virArch arch,
-                       char *machine);
+/* Generate '-device' string for chardev device */
+int qemuBuildChrDeviceStr(char **deviceStr,
+                          virDomainDefPtr vmdef,
+                          virDomainChrDefPtr chr,
+                          virQEMUCapsPtr qemuCaps);
 
 /* With vlan == -1, use netdev syntax, else old hostnet */
 char * qemuBuildHostNetStr(virDomainNetDefPtr net,
-- 
1.8.1.5




More information about the libvir-list mailing list