[libvirt] [PATCH v4 7/9] qemu: Introduce qemuBuildChrDeviceStr

Michal Privoznik mprivozn at redhat.com
Wed Jul 10 17:02:57 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 | 202 +++++++++++++++++++++++++++++++++++++-----------
 src/qemu/qemu_command.h |  12 +--
 2 files changed, 163 insertions(+), 51 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6cf46a2..063d76b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6593,6 +6593,21 @@ cleanup:
     return ret;
 }
 
+static int
+qemuBuildChrDeviceCommandLine(virCommandPtr cmd,
+                              virDomainDefPtr def,
+                              virDomainChrDefPtr chr,
+                              virQEMUCapsPtr qemuCaps)
+{
+    char *devstr = NULL;
+
+    if (qemuBuildChrDeviceStr(&devstr, def, chr, qemuCaps) < 0)
+        return -1;
+
+    virCommandAddArgList(cmd, "-device", devstr, NULL);
+    return 0;
+}
+
 qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
     .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
 };
@@ -7670,13 +7685,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 virCommandAddArg(cmd, devstr);
                 VIR_FREE(devstr);
 
-                virCommandAddArg(cmd, "-device");
-                if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps,
-                                                     def->os.arch,
-                                                     def->os.machine)))
+                if (qemuBuildChrDeviceCommandLine(cmd, def, serial, qemuCaps) < 0)
                    goto error;
-                virCommandAddArg(cmd, devstr);
-                VIR_FREE(devstr);
             } else {
                 virCommandAddArg(cmd, "-serial");
                 if (!(devstr = qemuBuildChrArgStr(&serial->source, NULL)))
@@ -7707,10 +7717,8 @@ 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 (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
+                    goto error;
             } else {
                 virCommandAddArg(cmd, "-parallel");
                 if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
@@ -7724,8 +7732,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:
@@ -7744,17 +7750,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:
@@ -7780,12 +7779,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 VIR_FREE(devstr);
             }
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel,
-                                                           qemuCaps)))
+            if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
-            VIR_FREE(devstr);
             break;
         }
     }
@@ -7817,11 +7812,8 @@ qemuBuildCommandLine(virConnectPtr conn,
             virCommandAddArg(cmd, devstr);
             VIR_FREE(devstr);
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildSclpDevStr(console)))
+            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
-            VIR_FREE(devstr);
             break;
 
         case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
@@ -7839,12 +7831,8 @@ qemuBuildCommandLine(virConnectPtr conn,
             virCommandAddArg(cmd, devstr);
             VIR_FREE(devstr);
 
-            virCommandAddArg(cmd, "-device");
-            if (!(devstr = qemuBuildVirtioSerialPortDevStr(console,
-                                                           qemuCaps)))
+            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
                 goto error;
-            virCommandAddArg(cmd, devstr);
-            VIR_FREE(devstr);
             break;
 
         case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
@@ -8534,11 +8522,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;
 
@@ -8570,7 +8559,7 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
             }
 
             if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0)
-               goto error;
+                goto error;
         }
     }
 
@@ -8579,13 +8568,136 @@ 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:
+        return ret;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(addr);
+    return ret;
+}
+
+static int
+qemuBuildConsoleChrDeviceStr(char **deviceStr,
+                             virDomainChrDefPtr chr,
+                             virQEMUCapsPtr qemuCaps)
+{
+    int ret = -1;
+
+    switch ((enum virDomainChrConsoleTargetType) 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:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ:
+    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST:
+        break;
+    }
+
+    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;
+
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
+        return ret;
+    }
+
+    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 e92c78a..88d7099 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -75,12 +75,12 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    qemuBuildCommandLineCallbacksPtr callbacks)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11);
 
-/* 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