[PATCH 16/24] qemuBuildChardevCommand: Split creation of the command and setup of other objects

Peter Krempa pkrempa at redhat.com
Thu Dec 9 12:30:51 UTC 2021


Completely seprate the creation of the commandline string from the setup
of other objects instantiated on the commandline.

'qemuBuildChardevCommand' will aggregate the setup of individual
parameters such as -add-fd and setup of TLS and the -chardev parameter
itself while the code formatting the commandline will be moved into
qemuBuildChardevStr.

'fdset' names are then stored in qemuDomainChrSourcePrivate.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_command.c | 204 ++++++++++++++++++++++++++--------------
 src/qemu/qemu_domain.c  |   6 ++
 src/qemu/qemu_domain.h  |   5 +
 3 files changed, 145 insertions(+), 70 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 26cb25a70c..910508e725 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1318,16 +1318,15 @@ qemuBuildChrChardevReconnectStr(virBuffer *buf,
 }


-static int
-qemuBuildChardevCommand(virCommand *cmd,
-                        virQEMUDriverConfig *cfg,
-                        const virDomainChrSourceDef *dev,
-                        const char *charAlias,
-                        virQEMUCaps *qemuCaps)
+static char *
+qemuBuildChardevStr(const virDomainChrSourceDef *dev,
+                    const char *charAlias)
 {
+
     qemuDomainChrSourcePrivate *chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
-    bool telnet;
+    const char *path;
+    virTristateSwitch append;

     switch ((virDomainChrType) dev->type) {
     case VIR_DOMAIN_CHR_TYPE_NULL:
@@ -1351,27 +1350,19 @@ qemuBuildChardevCommand(virCommand *cmd,

     case VIR_DOMAIN_CHR_TYPE_FILE:
         virBufferAsprintf(&buf, "file,id=%s", charAlias);
+        path = dev->data.file.path;
+        append = dev->data.file.append;

-        if (chrSourcePriv->fd != -1) {
-            g_autofree char *fdset = NULL;
-            size_t idx;
-
-            virCommandPassFDIndex(cmd, chrSourcePriv->fd,
-                                  VIR_COMMAND_PASS_FD_CLOSE_PARENT, &idx);
-            fdset = qemuBuildFDSet(chrSourcePriv->fd, idx);
-            chrSourcePriv->fd = -1;
-
-            virCommandAddArg(cmd, "-add-fd");
-            virCommandAddArg(cmd, fdset);
+        if (chrSourcePriv->fdset) {
+            path = chrSourcePriv->fdset;
+            append = VIR_TRISTATE_SWITCH_ON;
+        }

-            virBufferAsprintf(&buf, ",path=/dev/fdset/%zu,append=on", idx);
-        } else {
-            virBufferAddLit(&buf, ",path=");
-            virQEMUBuildBufferEscapeComma(&buf, dev->data.file.path);
-            if (dev->data.file.append != VIR_TRISTATE_SWITCH_ABSENT) {
-                virBufferAsprintf(&buf, ",append=%s",
-                                  virTristateSwitchTypeToString(dev->data.file.append));
-            }
+        virBufferAddLit(&buf, ",path=");
+        virQEMUBuildBufferEscapeComma(&buf, path);
+        if (append != VIR_TRISTATE_SWITCH_ABSENT) {
+            virBufferAsprintf(&buf, ",append=%s",
+                              virTristateSwitchTypeToString(append));
         }
         break;

@@ -1405,14 +1396,16 @@ qemuBuildChardevCommand(virCommand *cmd,
                           bindHost, bindService);
         break;
     }
+
     case VIR_DOMAIN_CHR_TYPE_TCP:
-        telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
         virBufferAsprintf(&buf,
-                          "socket,id=%s,host=%s,port=%s%s",
+                          "socket,id=%s,host=%s,port=%s",
                           charAlias,
                           dev->data.tcp.host,
-                          dev->data.tcp.service,
-                          telnet ? ",telnet=on" : "");
+                          dev->data.tcp.service);
+
+        if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+            virBufferAddLit(&buf, ",telnet=on");

         if (dev->data.tcp.listen) {
             virBufferAddLit(&buf, ",server=on");
@@ -1422,6 +1415,77 @@ qemuBuildChardevCommand(virCommand *cmd,

         qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect);

+        if (chrSourcePriv->tlsCredsAlias)
+            virBufferAsprintf(&buf, ",tls-creds=%s", chrSourcePriv->tlsCredsAlias);
+        break;
+
+    case VIR_DOMAIN_CHR_TYPE_UNIX:
+        virBufferAsprintf(&buf, "socket,id=%s", charAlias);
+        if (chrSourcePriv->passedFD != -1) {
+            virBufferAsprintf(&buf, ",fd=%d", chrSourcePriv->passedFD);
+        } else {
+            virBufferAddLit(&buf, ",path=");
+            virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path);
+        }
+
+        if (dev->data.nix.listen) {
+            virBufferAddLit(&buf, ",server=on");
+            if (!chrSourcePriv->wait)
+                virBufferAddLit(&buf, ",wait=off");
+        }
+
+        qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect);
+        break;
+
+    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+        virBufferAsprintf(&buf, "spicevmc,id=%s,name=%s", charAlias,
+                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
+        break;
+
+    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
+        virBufferAsprintf(&buf, "spiceport,id=%s,name=%s", charAlias,
+                          dev->data.spiceport.channel);
+        break;
+
+    case VIR_DOMAIN_CHR_TYPE_NMDM:
+    case VIR_DOMAIN_CHR_TYPE_LAST:
+    default:
+        break;
+    }
+
+    if (dev->logfile) {
+        path = dev->logfile;
+        append = dev->logappend;
+
+        if (chrSourcePriv->logFdset) {
+            path = chrSourcePriv->logFdset;
+            append = VIR_TRISTATE_SWITCH_ON;
+        }
+
+        virBufferAddLit(&buf, ",logfile=");
+        virQEMUBuildBufferEscapeComma(&buf, path);
+        if (append != VIR_TRISTATE_SWITCH_ABSENT) {
+            virBufferAsprintf(&buf, ",logappend=%s",
+                              virTristateSwitchTypeToString(append));
+        }
+    }
+
+    return virBufferContentAndReset(&buf);
+}
+
+
+static int
+qemuBuildChardevCommand(virCommand *cmd,
+                        virQEMUDriverConfig *cfg,
+                        const virDomainChrSourceDef *dev,
+                        const char *charAlias,
+                        virQEMUCaps *qemuCaps)
+{
+    qemuDomainChrSourcePrivate *chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
+    g_autofree char *charstr = NULL;
+
+    switch ((virDomainChrType) dev->type) {
+    case VIR_DOMAIN_CHR_TYPE_TCP:
         if (dev->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES) {
             g_autofree char *objalias = NULL;
             const char *tlsCertEncSecAlias = NULL;
@@ -1450,38 +1514,44 @@ qemuBuildChardevCommand(virCommand *cmd,
                 return -1;
             }

-            virBufferAsprintf(&buf, ",tls-creds=%s", objalias);
+            chrSourcePriv->tlsCredsAlias = g_steal_pointer(&objalias);
         }
         break;

-    case VIR_DOMAIN_CHR_TYPE_UNIX:
-        virBufferAsprintf(&buf, "socket,id=%s", charAlias);
+    case VIR_DOMAIN_CHR_TYPE_FILE:
         if (chrSourcePriv->fd != -1) {
-            virBufferAsprintf(&buf, ",fd=%d", chrSourcePriv->fd);
+            g_autofree char *fdset = NULL;
+            size_t idx;

-            virCommandPassFD(cmd, chrSourcePriv->fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+            virCommandPassFDIndex(cmd, chrSourcePriv->fd,
+                                  VIR_COMMAND_PASS_FD_CLOSE_PARENT, &idx);
+            fdset = qemuBuildFDSet(chrSourcePriv->fd, idx);
             chrSourcePriv->fd = -1;
-        } else {
-            virBufferAddLit(&buf, ",path=");
-            virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path);
-        }
-        if (dev->data.nix.listen) {
-            virBufferAddLit(&buf, ",server=on");
-            if (!chrSourcePriv->wait)
-                virBufferAddLit(&buf, ",wait=off");
-        }

-        qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect);
+            virCommandAddArg(cmd, "-add-fd");
+            virCommandAddArg(cmd, fdset);
+
+            chrSourcePriv->fdset = g_strdup_printf("/dev/fdset/%zu", idx);
+        }
         break;

-    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
-        virBufferAsprintf(&buf, "spicevmc,id=%s,name=%s", charAlias,
-                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
+    case VIR_DOMAIN_CHR_TYPE_UNIX:
+        if (chrSourcePriv->fd != -1) {
+            virCommandPassFD(cmd, chrSourcePriv->fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+            chrSourcePriv->passedFD = chrSourcePriv->fd;
+            chrSourcePriv->fd = -1;
+        }
         break;

+    case VIR_DOMAIN_CHR_TYPE_NULL:
+    case VIR_DOMAIN_CHR_TYPE_VC:
+    case VIR_DOMAIN_CHR_TYPE_PTY:
+    case VIR_DOMAIN_CHR_TYPE_DEV:
+    case VIR_DOMAIN_CHR_TYPE_PIPE:
+    case VIR_DOMAIN_CHR_TYPE_STDIO:
+    case VIR_DOMAIN_CHR_TYPE_UDP:
+    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
     case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
-        virBufferAsprintf(&buf, "spiceport,id=%s,name=%s", charAlias,
-                          dev->data.spiceport.channel);
         break;

     case VIR_DOMAIN_CHR_TYPE_NMDM:
@@ -1493,31 +1563,25 @@ qemuBuildChardevCommand(virCommand *cmd,
         return -1;
     }

-    if (dev->logfile) {
-        if (chrSourcePriv->logfd != -1) {
-            g_autofree char *fdset = NULL;
-            size_t idx;
+    if (chrSourcePriv->logfd != -1) {
+        g_autofree char *fdset = NULL;
+        size_t idx;

-            virCommandPassFDIndex(cmd, chrSourcePriv->logfd,
-                                  VIR_COMMAND_PASS_FD_CLOSE_PARENT, &idx);
-            fdset = qemuBuildFDSet(chrSourcePriv->logfd, idx);
-            chrSourcePriv->logfd = -1;
+        virCommandPassFDIndex(cmd, chrSourcePriv->logfd,
+                              VIR_COMMAND_PASS_FD_CLOSE_PARENT, &idx);
+        fdset = qemuBuildFDSet(chrSourcePriv->logfd, idx);
+        chrSourcePriv->logfd = -1;

-            virCommandAddArg(cmd, "-add-fd");
-            virCommandAddArg(cmd, fdset);
+        virCommandAddArg(cmd, "-add-fd");
+        virCommandAddArg(cmd, fdset);

-            virBufferAsprintf(&buf, ",logfile=/dev/fdset/%zu,logappend=on", idx);
-        } else {
-            virBufferAddLit(&buf, ",logfile=");
-            virQEMUBuildBufferEscapeComma(&buf, dev->logfile);
-            if (dev->logappend != VIR_TRISTATE_SWITCH_ABSENT) {
-                virBufferAsprintf(&buf, ",logappend=%s",
-                                  virTristateSwitchTypeToString(dev->logappend));
-            }
-        }
+        chrSourcePriv->logFdset = g_strdup_printf("/dev/fdset/%zu", idx);
     }

-    virCommandAddArgList(cmd, "-chardev", virBufferCurrentContent(&buf), NULL);
+    if (!(charstr = qemuBuildChardevStr(dev, charAlias)))
+        return -1;
+
+    virCommandAddArgList(cmd, "-chardev", charstr, NULL);

     return 0;
 }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e6d6bf10f1..a2ee160128 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -853,6 +853,8 @@ qemuDomainChrSourcePrivateNew(void)
     priv->fd = -1;
     priv->logfd = -1;

+    priv->passedFD = -1;
+
     return (virObject *) priv;
 }

@@ -865,6 +867,10 @@ qemuDomainChrSourcePrivateDispose(void *obj)
     VIR_FORCE_CLOSE(priv->fd);
     VIR_FORCE_CLOSE(priv->logfd);

+    g_free(priv->fdset);
+    g_free(priv->logFdset);
+    g_free(priv->tlsCredsAlias);
+
     g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
 }

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 2d93cf2253..d07def3d85 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -345,6 +345,11 @@ struct _qemuDomainChrSourcePrivate {
     int fd; /* file descriptor of the chardev source */
     int logfd; /* file descriptor of the logging source */
     bool wait; /* wait for incomming connections on chardev */
+
+    char *fdset; /* fdset path corresponding to the passed filedescriptor */
+    char *logFdset; /* fdset path corresponding to the passed filedescriptor for logfile */
+    int passedFD; /* filedescriptor number when fdset passing it directly */
+    char *tlsCredsAlias; /* alias of the x509 tls credentials object */
 };


-- 
2.31.1




More information about the libvir-list mailing list