Signed-off-by: Shi Lei <shi_lei@xxxxxxxxxxxxxx> --- src/conf/domain_conf.c | 164 ++++++++++++++++++++++++++--------------- src/conf/domain_conf.h | 14 ++-- 2 files changed, 114 insertions(+), 64 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 54b4da9..ebd8ac3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14363,9 +14363,9 @@ virDomainGraphicsVNCDefParseXMLHook(xmlNodePtr node G_GNUC_UNUSED, void *parent G_GNUC_UNUSED, void *opaque, const char *port, + const char *autoport, const char *websocket G_GNUC_UNUSED, const char *websocketGenerated G_GNUC_UNUSED, - const char *autoport, const char *sharePolicy G_GNUC_UNUSED) { unsigned int flags = *((unsigned int *) opaque); @@ -28049,6 +28049,110 @@ virDomainSpiceGLDefFormat(virBufferPtr buf, virDomainGraphicsDefPtr def) virBufferAddLit(buf, "/>\n"); } +bool +virDomainGraphicsVNCDefCheckAttrHook(const virDomainGraphicsVNCDef *def G_GNUC_UNUSED, + const void *parent, + void *opaque, + bool value) +{ + bool ret = false; + virDomainGraphicsDefPtr graphics = (virDomainGraphicsDefPtr) parent; + virDomainGraphicsListenDefPtr glisten = virDomainGraphicsGetListen(graphics, 0); + unsigned int flags = 0; + if (opaque) + flags = *((unsigned int *) opaque); + + if (!glisten) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing listen element for graphics")); + return false; + } + + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + if (glisten->socket && + !((glisten->autoGenerated || glisten->fromConfig) && + (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) { + ret = true; + } + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + /* Always output 'autoport' under these conditions */ + ret = true; + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; + } + + return ret || value; +} + +int +virDomainGraphicsVNCDefFormatAttrHook(const virDomainGraphicsVNCDef *def, + const void *parent, + const void *opaque, + virBufferPtr portBuf, + virBufferPtr autoportBuf, + virBufferPtr websocketBuf, + virBufferPtr listenBuf, + virBufferPtr socketBuf) +{ + virDomainGraphicsDefPtr graphics = (virDomainGraphicsDefPtr) parent; + virDomainGraphicsListenDefPtr glisten = virDomainGraphicsGetListen(graphics, 0); + unsigned int flags = 0; + if (opaque) + flags = *((unsigned int *) opaque); + + if (!glisten) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing listen element for graphics")); + return -1; + } + + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + /* To not break migration we shouldn't print the 'socket' attribute + * if it's auto-generated or if it's based on config option from + * qemu.conf. If the socket is provided by user we need to print it + * into migratable XML. */ + if (glisten->socket && + !((glisten->autoGenerated || glisten->fromConfig) && + (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) { + virBufferEscapeString(socketBuf, " socket='%s'", glisten->socket); + } + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + if (def->port && + (!def->autoport || !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))) + virBufferAsprintf(portBuf, " port='%d'", + def->port); + else if (def->autoport) + virBufferAddLit(portBuf, " port='-1'"); + + virBufferAsprintf(autoportBuf, " autoport='%s'", + def->autoport ? "yes" : "no"); + + if (def->websocketGenerated && + (flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) + virBufferAddLit(websocketBuf, " websocket='-1'"); + else if (def->websocket) + virBufferAsprintf(websocketBuf, " websocket='%d'", def->websocket); + + virDomainGraphicsListenDefFormatAddr(listenBuf, glisten, flags); + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; + } + + return 0; +} + static int virDomainGraphicsDefFormat(virBufferPtr buf, virDomainGraphicsDefPtr def, @@ -28069,64 +28173,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf, switch (def->type) { case VIR_DOMAIN_GRAPHICS_TYPE_VNC: - if (!glisten) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("missing listen element for graphics")); + if (virDomainGraphicsVNCDefFormatAttr(buf, &def->data.vnc, def, &flags) < 0) return -1; - } - - switch (glisten->type) { - case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: - /* To not break migration we shouldn't print the 'socket' attribute - * if it's auto-generated or if it's based on config option from - * qemu.conf. If the socket is provided by user we need to print it - * into migratable XML. */ - if (glisten->socket && - !((glisten->autoGenerated || glisten->fromConfig) && - (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) { - virBufferEscapeString(buf, " socket='%s'", glisten->socket); - } - break; - - case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: - case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: - if (def->data.vnc.port && - (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))) - virBufferAsprintf(buf, " port='%d'", - def->data.vnc.port); - else if (def->data.vnc.autoport) - virBufferAddLit(buf, " port='-1'"); - - virBufferAsprintf(buf, " autoport='%s'", - def->data.vnc.autoport ? "yes" : "no"); - - if (def->data.vnc.websocketGenerated && - (flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) - virBufferAddLit(buf, " websocket='-1'"); - else if (def->data.vnc.websocket) - virBufferAsprintf(buf, " websocket='%d'", def->data.vnc.websocket); - - if (flags & VIR_DOMAIN_DEF_FORMAT_STATUS) - virBufferAsprintf(buf, " websocketGenerated='%s'", - def->data.vnc.websocketGenerated ? "yes" : "no"); - - virDomainGraphicsListenDefFormatAddr(buf, glisten, flags); - break; - case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: - case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: - break; - } - - if (def->data.vnc.keymap) - virBufferEscapeString(buf, " keymap='%s'", - def->data.vnc.keymap); - - if (def->data.vnc.sharePolicy) - virBufferAsprintf(buf, " sharePolicy='%s'", - virDomainGraphicsVNCSharePolicyTypeToString( - def->data.vnc.sharePolicy)); - - virDomainGraphicsAuthDefFormatAttr(buf, &def->data.vnc.auth, def, &flags); break; case VIR_DOMAIN_GRAPHICS_TYPE_SDL: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e262246..f4cc504 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1682,15 +1682,17 @@ struct _virDomainGraphicsSDLDef { /* genparse, genformat:separate */ virTristateBool gl; /* xmlattr:gl/enable */ }; -struct _virDomainGraphicsVNCDef { /* genparse:withhook */ - int port; /* xmlattr */ +struct _virDomainGraphicsVNCDef { /* genparse:withhook, genformat:separate */ + int port; /* xmlattr, formathook */ bool portReserved; - int websocket; /* xmlattr */ - bool websocketGenerated; /* xmlattr */ - bool autoport; /* xmlattr */ + bool autoport; /* xmlattr, formathook */ + int websocket; /* xmlattr, formathook */ + bool websocketGenerated; /* xmlattr, formatflag:%VIR_DOMAIN_DEF_FORMAT_STATUS */ + char *_listen; /* xmlattr:listen, formathook */ + char *_socket; /* xmlattr:socket, formathook */ char *keymap; /* xmlattr */ - virDomainGraphicsAuthDef auth; /* xmlgroup */ virDomainGraphicsVNCSharePolicy sharePolicy; /* xmlattr */ + virDomainGraphicsAuthDef auth; /* xmlgroup */ }; struct _virDomainGraphicsRDPDef { -- 2.25.1