[libvirt] [PATCH v1 06/11] conf: Make graphics's GL a standalone structure

Erik Skultety eskultet at redhat.com
Wed Jun 27 13:34:43 UTC 2018


Since we support gl with SPICE and SDL with future VNC enablement in
sight (egl-headless), let's separate the gl-related attributes into a
standalone structure.

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 src/conf/domain_conf.c      | 137 +++++++++++++++++++++++++-------------------
 src/conf/domain_conf.h      |  12 +++-
 src/qemu/qemu_cgroup.c      |  10 ++--
 src/qemu/qemu_command.c     |  66 ++++++++++++---------
 src/qemu/qemu_domain.c      |   7 ++-
 src/security/security_dac.c |   7 ++-
 6 files changed, 138 insertions(+), 101 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 09d9bac739..6bfa3ca130 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1420,8 +1420,6 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
         break;
 
     case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
-        VIR_FREE(def->data.spice.rendernode);
-        VIR_FREE(def->data.spice.keymap);
         virDomainGraphicsAuthDefClear(&def->data.spice.auth);
         break;
 
@@ -1429,6 +1427,8 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
         break;
     }
 
+    virDomainGraphicsGLDefFree(def->gl);
+
     for (i = 0; i < def->nListens; i++)
         virDomainGraphicsListenDefClear(&def->listens[i]);
     VIR_FREE(def->listens);
@@ -1436,6 +1436,18 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
     VIR_FREE(def);
 }
 
+
+void
+virDomainGraphicsGLDefFree(virDomainGraphicsGLDefPtr def)
+{
+    if (!def)
+        return;
+
+    VIR_FREE(def->rendernode);
+    VIR_FREE(def);
+}
+
+
 const char *virDomainInputDefGetPath(virDomainInputDefPtr input)
 {
     switch ((virDomainInputType) input->type) {
@@ -13555,6 +13567,48 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
 }
 
 
+static int
+virDomainGraphicsGLDefParseXML(virDomainGraphicsDefPtr def,
+                               xmlNodePtr node)
+{
+    virDomainGraphicsGLDefPtr gl = NULL;
+    char *enable = NULL;
+    int ret = -1;
+
+    if (!node)
+        return 0;
+
+    if (VIR_ALLOC(gl) < 0)
+        return -1;
+
+    if (!(enable = virXMLPropString(node, "enable"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("'enable' attribute is mandatory for graphics "
+                         "<gl> element"));
+        goto cleanup;
+    }
+
+    if ((gl->enable =
+         virTristateBoolTypeFromString(enable)) <= 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown value for attribute enable '%s'"),
+                       enable);
+        goto cleanup;
+    }
+
+    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)
+       gl->rendernode = virXMLPropString(node, "rendernode");
+
+    VIR_STEAL_PTR(def->gl, gl);
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(enable);
+    virDomainGraphicsGLDefFree(gl);
+    return ret;
+}
+
+
 static int
 virDomainGraphicsDefParseXMLVNC(virDomainGraphicsDefPtr def,
                                 xmlNodePtr node,
@@ -13644,8 +13698,6 @@ virDomainGraphicsDefParseXMLSDL(virDomainGraphicsDefPtr def,
 {
     xmlNodePtr save = ctxt->node;
     char *enable = NULL;
-    int enableVal;
-    xmlNodePtr glNode;
     char *fullscreen = virXMLPropString(node, "fullscreen");
     int ret = -1;
 
@@ -13668,23 +13720,9 @@ virDomainGraphicsDefParseXMLSDL(virDomainGraphicsDefPtr def,
     def->data.sdl.xauth = virXMLPropString(node, "xauth");
     def->data.sdl.display = virXMLPropString(node, "display");
 
-    glNode = virXPathNode("./gl", ctxt);
-    if (glNode) {
-        enable = virXMLPropString(glNode, "enable");
-        if (!enable) {
-            virReportError(VIR_ERR_XML_ERROR, "%s",
-                           _("sdl gl element missing enable"));
-            goto cleanup;
-        }
-
-        enableVal = virTristateBoolTypeFromString(enable);
-        if (enableVal < 0) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("unknown enable value '%s'"), enable);
-            goto cleanup;
-        }
-        def->data.sdl.gl = enableVal;
-    }
+    if (virDomainGraphicsGLDefParseXML(def,
+                                       virXPathNode("./gl[1]", ctxt)) < 0)
+        goto cleanup;
 
     ret = 0;
  cleanup:
@@ -14026,31 +14064,6 @@ virDomainGraphicsDefParseXMLSpice(virDomainGraphicsDefPtr def,
                 VIR_FREE(enable);
 
                 def->data.spice.filetransfer = enableVal;
-            } else if (virXMLNodeNameEqual(cur, "gl")) {
-                char *enable = virXMLPropString(cur, "enable");
-                char *rendernode = virXMLPropString(cur, "rendernode");
-                int enableVal;
-
-                if (!enable) {
-                    virReportError(VIR_ERR_XML_ERROR, "%s",
-                                   _("spice gl element missing enable"));
-                    VIR_FREE(rendernode);
-                    goto error;
-                }
-
-                if ((enableVal =
-                     virTristateBoolTypeFromString(enable)) <= 0) {
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("unknown enable value '%s'"), enable);
-                    VIR_FREE(enable);
-                    VIR_FREE(rendernode);
-                    goto error;
-                }
-                VIR_FREE(enable);
-
-                def->data.spice.gl = enableVal;
-                def->data.spice.rendernode = rendernode;
-
             } else if (virXMLNodeNameEqual(cur, "mouse")) {
                 char *mode = virXMLPropString(cur, "mode");
                 int modeVal;
@@ -14071,6 +14084,9 @@ virDomainGraphicsDefParseXMLSpice(virDomainGraphicsDefPtr def,
                 VIR_FREE(mode);
 
                 def->data.spice.mousemode = modeVal;
+            } else if (virXMLNodeNameEqual(cur, "gl")) {
+                if (virDomainGraphicsGLDefParseXML(def, cur) < 0)
+                    goto error;
             }
         }
         cur = cur->next;
@@ -26148,18 +26164,25 @@ virDomainGraphicsListenDefFormatAddr(virBufferPtr buf,
         virBufferAsprintf(buf, " listen='%s'", glisten->address);
 }
 
+
 static void
-virDomainSpiceGLDefFormat(virBufferPtr buf, virDomainGraphicsDefPtr def)
+virDomainGraphicsGLDefFormat(virBufferPtr buf, virDomainGraphicsDefPtr def)
 {
-    if (def->data.spice.gl == VIR_TRISTATE_BOOL_ABSENT)
+    virDomainGraphicsGLDefPtr gl = def->gl;
+
+    if (!gl)
         return;
 
     virBufferAsprintf(buf, "<gl enable='%s'",
-                      virTristateBoolTypeToString(def->data.spice.gl));
-    virBufferEscapeString(buf, " rendernode='%s'", def->data.spice.rendernode);
+                      virTristateBoolTypeToString(gl->enable));
+
+    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)
+        virBufferEscapeString(buf, " rendernode='%s'", gl->rendernode);
+
     virBufferAddLit(buf, "/>\n");
 }
 
+
 static int
 virDomainGraphicsDefFormat(virBufferPtr buf,
                            virDomainGraphicsDefPtr def,
@@ -26247,18 +26270,12 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
         if (def->data.sdl.fullscreen)
             virBufferAddLit(buf, " fullscreen='yes'");
 
-        if (!children && def->data.sdl.gl != VIR_TRISTATE_BOOL_ABSENT) {
+        if (!children && def->gl) {
             virBufferAddLit(buf, ">\n");
             virBufferAdjustIndent(buf, 2);
             children = true;
         }
 
-        if (def->data.sdl.gl != VIR_TRISTATE_BOOL_ABSENT) {
-            virBufferAsprintf(buf, "<gl enable='%s'",
-                              virTristateBoolTypeToString(def->data.sdl.gl));
-            virBufferAddLit(buf, "/>\n");
-        }
-
         break;
 
     case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
@@ -26405,8 +26422,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
         if (!children && (def->data.spice.image || def->data.spice.jpeg ||
                           def->data.spice.zlib || def->data.spice.playback ||
                           def->data.spice.streaming || def->data.spice.copypaste ||
-                          def->data.spice.mousemode || def->data.spice.filetransfer ||
-                          def->data.spice.gl)) {
+                          def->data.spice.mousemode || def->data.spice.filetransfer)) {
             virBufferAddLit(buf, ">\n");
             virBufferAdjustIndent(buf, 2);
             children = true;
@@ -26436,9 +26452,10 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
             virBufferAsprintf(buf, "<filetransfer enable='%s'/>\n",
                               virTristateBoolTypeToString(def->data.spice.filetransfer));
 
-        virDomainSpiceGLDefFormat(buf, def);
     }
 
+    virDomainGraphicsGLDefFormat(buf, def);
+
     if (children) {
         virBufferAdjustIndent(buf, -2);
         virBufferAddLit(buf, "</graphics>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0924fc4f3c..20dc1334c4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1598,6 +1598,13 @@ struct _virDomainGraphicsListenDef {
     bool autoGenerated;
 };
 
+typedef struct _virDomainGraphicsGLDef virDomainGraphicsGLDef;
+typedef virDomainGraphicsGLDef *virDomainGraphicsGLDefPtr;
+struct _virDomainGraphicsGLDef {
+    virTristateBool enable;
+    char *rendernode;       /* SPICE only */
+};
+
 struct _virDomainGraphicsDef {
     /* Port value discipline:
      * Value -1 is legacy syntax indicating that it should be auto-allocated.
@@ -1620,7 +1627,6 @@ struct _virDomainGraphicsDef {
             char *display;
             char *xauth;
             bool fullscreen;
-            virTristateBool gl;
         } sdl;
         struct {
             int port;
@@ -1650,8 +1656,6 @@ struct _virDomainGraphicsDef {
             int streaming;
             virTristateBool copypaste;
             virTristateBool filetransfer;
-            virTristateBool gl;
-            char *rendernode;
         } spice;
     } data;
     /* nListens, listens, and *port are only useful if type is vnc,
@@ -1659,6 +1663,7 @@ struct _virDomainGraphicsDef {
      * simplify parsing code.*/
     size_t nListens;
     virDomainGraphicsListenDefPtr listens;
+    virDomainGraphicsGLDefPtr gl;
 };
 
 typedef enum {
@@ -2837,6 +2842,7 @@ int virDomainObjWaitUntil(virDomainObjPtr vm,
 void virDomainPanicDefFree(virDomainPanicDefPtr panic);
 void virDomainResourceDefFree(virDomainResourceDefPtr resource);
 void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
+void virDomainGraphicsGLDefFree(virDomainGraphicsGLDefPtr def);
 const char *virDomainInputDefGetPath(virDomainInputDefPtr input);
 void virDomainInputDefFree(virDomainInputDefPtr def);
 virDomainDiskDefPtr virDomainDiskDefNew(virDomainXMLOptionPtr xmlopt);
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index c8fba7f9e6..81e86fa973 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -489,20 +489,20 @@ qemuSetupGraphicsCgroup(virDomainObjPtr vm,
                         virDomainGraphicsDefPtr gfx)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    const char *rendernode = gfx->data.spice.rendernode;
     int ret;
 
     if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
         return 0;
 
     if (gfx->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE ||
-        gfx->data.spice.gl != VIR_TRISTATE_BOOL_YES ||
-        !rendernode)
+        !gfx->gl ||
+        gfx->gl->enable != VIR_TRISTATE_BOOL_YES ||
+        !gfx->gl->rendernode)
         return 0;
 
-    ret = virCgroupAllowDevicePath(priv->cgroup, rendernode,
+    ret = virCgroupAllowDevicePath(priv->cgroup, gfx->gl->rendernode,
                                    VIR_CGROUP_DEVICE_RW, false);
-    virDomainAuditCgroupPath(vm, priv->cgroup, "allow", rendernode,
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow", gfx->gl->rendernode,
                              "rw", ret);
     return ret;
 }
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 195d03e373..ef0be95b0f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7740,7 +7740,8 @@ qemuBuildGraphicsSDLCommandLine(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
     virCommandAddArg(cmd, "-display");
     virBufferAddLit(&opt, "sdl");
 
-    if (graphics->data.sdl.gl != VIR_TRISTATE_BOOL_ABSENT) {
+    if (graphics->gl &&
+        graphics->gl->enable != VIR_TRISTATE_BOOL_ABSENT) {
         if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL_GL)) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("OpenGL for SDL is not supported with this QEMU "
@@ -7749,7 +7750,7 @@ qemuBuildGraphicsSDLCommandLine(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
         }
 
         virBufferAsprintf(&opt, ",gl=%s",
-                          virTristateSwitchTypeToString(graphics->data.sdl.gl));
+                          virTristateSwitchTypeToString(graphics->gl->enable));
 
     }
 
@@ -7886,6 +7887,35 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
 }
 
 
+static int
+qemuBuildGraphicsSPICEGLCommandLine(virDomainGraphicsGLDefPtr gl,
+                                    virBufferPtr opt,
+                                    virQEMUCapsPtr qemuCaps)
+{
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_GL)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("This QEMU doesn't support spice OpenGL"));
+        return -1;
+    }
+
+    virBufferAddLit(opt, "gl=on,");
+
+    if (gl->rendernode) {
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("This QEMU doesn't support spice OpenGL rendernode"));
+            return -1;
+        }
+
+        virBufferAddLit(opt, "rendernode=");
+        virQEMUBuildBufferEscapeComma(opt, gl->rendernode);
+        virBufferAddLit(opt, ",");
+    }
+
+    return 0;
+}
+
+
 static int
 qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
                                   virCommandPtr cmd,
@@ -8089,31 +8119,6 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
         }
     }
 
-    if (graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) {
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_GL)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("This QEMU doesn't support spice OpenGL"));
-            goto error;
-        }
-
-        /* spice.gl is a TristateBool, but qemu expects on/off: use
-         * TristateSwitch helper */
-        virBufferAsprintf(&opt, "gl=%s,",
-                          virTristateSwitchTypeToString(graphics->data.spice.gl));
-
-        if (graphics->data.spice.rendernode) {
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("This QEMU doesn't support spice OpenGL rendernode"));
-                goto error;
-            }
-
-            virBufferAddLit(&opt, "rendernode=");
-            virQEMUBuildBufferEscapeComma(&opt, graphics->data.spice.rendernode);
-            virBufferAddLit(&opt, ",");
-        }
-    }
-
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) {
         /* If qemu supports seamless migration turn it
          * unconditionally on. If migration destination
@@ -8122,10 +8127,17 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
         virBufferAddLit(&opt, "seamless-migration=on,");
     }
 
+    /* OpenGL magic */
+    if (graphics->gl &&
+        graphics->gl->enable == VIR_TRISTATE_BOOL_YES &&
+        qemuBuildGraphicsSPICEGLCommandLine(graphics->gl, &opt, qemuCaps) < 0)
+        goto error;
+
     virBufferTrim(&opt, ",", -1);
 
     virCommandAddArg(cmd, "-spice");
     virCommandAddArgBuffer(cmd, &opt);
+
     if (graphics->data.spice.keymap)
         virCommandAddArgList(cmd, "-k",
                              graphics->data.spice.keymap, NULL);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f8a662f747..948b9b7fd0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11290,11 +11290,12 @@ qemuDomainSetupGraphics(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
                         virDomainGraphicsDefPtr gfx,
                         const struct qemuDomainCreateDeviceData *data)
 {
-    const char *rendernode = gfx->data.spice.rendernode;
+    const char *rendernode = NULL;
 
     if (gfx->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE ||
-        gfx->data.spice.gl != VIR_TRISTATE_BOOL_YES ||
-        !rendernode)
+        !gfx->gl ||
+        gfx->gl->enable != VIR_TRISTATE_BOOL_YES ||
+        !gfx->gl->rendernode)
         return 0;
 
     return qemuDomainCreateDevice(rendernode, data, false);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 4b623dcf39..e8757f04e8 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1431,10 +1431,11 @@ virSecurityDACSetGraphicsLabel(virSecurityManagerPtr mgr,
         return -1;
 
     if (gfx->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
-        gfx->data.spice.gl == VIR_TRISTATE_BOOL_YES &&
-        gfx->data.spice.rendernode) {
+        gfx->gl &&
+        gfx->gl->enable == VIR_TRISTATE_BOOL_YES &&
+        gfx->gl->rendernode) {
         if (virSecurityDACSetOwnership(priv, NULL,
-                                       gfx->data.spice.rendernode,
+                                       gfx->gl->rendernode,
                                        user, group) < 0)
             return -1;
     }
-- 
2.14.4




More information about the libvir-list mailing list