Previously I sent a patch to handle parsing of the new PVFB syntax. This patch provides the counterpart - generating the new syntax when creating paravirt guests. We only enable the new style syntax if using xendConfigVersion 3 or later (ie, 3.0.4), and only for PV guests. HVM and older PV guests still use old style syntax. In this I also added support for vnclisten & vncpasswd parameters mapped to the 'listen' and 'passwd' attributes on the XML <graphics> tag. Regards, Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
? src/core.19662 Index: src/xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.80 diff -u -p -r1.80 xend_internal.c --- src/xend_internal.c 7 Dec 2006 18:23:19 -0000 1.80 +++ src/xend_internal.c 11 Dec 2006 17:36:52 -0000 @@ -1745,9 +1745,14 @@ xend_parse_sexp_desc(virConnectPtr conn, virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27); } else if (tmp && !strcmp(tmp, "vnc")) { int port = xenStoreDomainGetVNCPort(conn, domid); + const char *listenAddr = sexpr_node(node, "device/vfb/vnclisten"); if (port == -1) port = 5900 + domid; - virBufferVSprintf(&buf, " <graphics type='vnc' port='%d'/>\n", port); + if (listenAddr) { + virBufferVSprintf(&buf, " <graphics type='vnc' port='%d' listen='%s'/>\n", port, listenAddr); + } else { + virBufferVSprintf(&buf, " <graphics type='vnc' port='%d'/>\n", port); + } } } } @@ -1787,9 +1792,13 @@ xend_parse_sexp_desc(virConnectPtr conn, if (tmp != NULL) { if (tmp[0] == '1') { int port = xenStoreDomainGetVNCPort(conn, domid); + const char *listenAddr = sexpr_fmt_node(root, "domain/image/%s/vnclisten", hvm ? "hvm" : "linux"); if (port == -1) port = 5900 + domid; - virBufferVSprintf(&buf, " <graphics type='vnc' port='%d'/>\n", port); + if (listenAddr) + virBufferVSprintf(&buf, " <graphics type='vnc' port='%d' listen='%s'/>\n", port, listenAddr); + else + virBufferVSprintf(&buf, " <graphics type='vnc' port='%d'/>\n", port); } } Index: src/xml.c =================================================================== RCS file: /data/cvs/libvirt/src/xml.c,v retrieving revision 1.52 diff -u -p -r1.52 xml.c --- src/xml.c 27 Nov 2006 23:16:59 -0000 1.52 +++ src/xml.c 11 Dec 2006 17:36:54 -0000 @@ -572,7 +572,7 @@ virDomainGetXMLDesc(virDomainPtr domain, #ifndef PROXY /** - * virtDomainParseXMLGraphicsDesc: + * virtDomainParseXMLGraphicsDescOld: * @node: node containing graphics description * @buf: a buffer for the result S-Expr * @xendConfigVersion: xend configuration file format @@ -584,7 +584,7 @@ virDomainGetXMLDesc(virDomainPtr domain, * * Returns 0 in case of success, -1 in case of error */ -static int virDomainParseXMLGraphicsDesc(xmlNodePtr node, virBufferPtr buf, int xendConfigVersion) +static int virDomainParseXMLGraphicsDescOld(xmlNodePtr node, virBufferPtr buf, int xendConfigVersion) { xmlChar *graphics_type = NULL; @@ -602,6 +602,8 @@ static int virDomainParseXMLGraphicsDesc virBufferAdd(buf, "(vnc 1)", 7); if (xendConfigVersion >= 2) { xmlChar *vncport = xmlGetProp(node, BAD_CAST "port"); + xmlChar *vnclisten = xmlGetProp(node, BAD_CAST "listen"); + xmlChar *vncpasswd = xmlGetProp(node, BAD_CAST "passwd"); if (vncport != NULL) { long port = strtol((const char *)vncport, NULL, 10); if (port == -1) @@ -610,8 +612,73 @@ static int virDomainParseXMLGraphicsDesc virBufferVSprintf(buf, "(vncdisplay %d)", port - 5900); xmlFree(vncport); } + if (vnclisten != NULL) { + virBufferVSprintf(buf, "(vnclisten %s)", vnclisten); + xmlFree(vnclisten); + } + if (vncpasswd != NULL) { + virBufferVSprintf(buf, "(vncpasswd %s)", vncpasswd); + xmlFree(vncpasswd); + } + } + } + xmlFree(graphics_type); + } + return 0; +} + + +/** + * virtDomainParseXMLGraphicsDescNew: + * @node: node containing graphics description + * @buf: a buffer for the result S-Expr + * + * Parse the graphics part of the XML description and add it to the S-Expr + * in buf. This is a temporary interface as the S-Expr interface will be + * replaced by XML-RPC in the future. However the XML format should stay + * valid over time. + * + * Returns 0 in case of success, -1 in case of error + */ +static int virDomainParseXMLGraphicsDescNew(xmlNodePtr node, virBufferPtr buf) +{ + xmlChar *graphics_type = NULL; + + graphics_type = xmlGetProp(node, BAD_CAST "type"); + if (graphics_type != NULL) { + virBufferAdd(buf, "(device (vkbd))", 15); + virBufferAdd(buf, "(device (vfb ", 13); + if (xmlStrEqual(graphics_type, BAD_CAST "sdl")) { + virBufferAdd(buf, "(type sdl)", 10); + // TODO: + // Need to understand sdl options + // + //virBufferAdd(buf, "(display localhost:10.0)", 24); + //virBufferAdd(buf, "(xauthority /root/.Xauthority)", 30); + } + else if (xmlStrEqual(graphics_type, BAD_CAST "vnc")) { + virBufferAdd(buf, "(type vnc)", 10); + xmlChar *vncport = xmlGetProp(node, BAD_CAST "port"); + xmlChar *vnclisten = xmlGetProp(node, BAD_CAST "listen"); + xmlChar *vncpasswd = xmlGetProp(node, BAD_CAST "passwd"); + if (vncport != NULL) { + long port = strtol((const char *)vncport, NULL, 10); + if (port == -1) + virBufferAdd(buf, "(vncunused 1)", 13); + else if (port > 5900) + virBufferVSprintf(buf, "(vncdisplay %d)", port - 5900); + xmlFree(vncport); + } + if (vnclisten != NULL) { + virBufferVSprintf(buf, "(vnclisten %s)", vnclisten); + xmlFree(vnclisten); + } + if (vncpasswd != NULL) { + virBufferVSprintf(buf, "(vncpasswd %s)", vncpasswd); + xmlFree(vncpasswd); } } + virBufferAdd(buf, "))", 2); xmlFree(graphics_type); } return 0; @@ -792,7 +859,7 @@ virDomainParseXMLOSDescHVM(xmlNodePtr no obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt); if ((obj != NULL) && (obj->type == XPATH_NODESET) && (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - res = virDomainParseXMLGraphicsDesc(obj->nodesetval->nodeTab[0], buf, xendConfigVersion); + res = virDomainParseXMLGraphicsDescOld(obj->nodesetval->nodeTab[0], buf, xendConfigVersion); if (res != 0) { goto error; } @@ -896,15 +963,18 @@ virDomainParseXMLOSDescPV(xmlNodePtr nod virBufferVSprintf(buf, "(args '%s')", (const char *) cmdline); /* Is a graphics device specified? */ - obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - res = virDomainParseXMLGraphicsDesc(obj->nodesetval->nodeTab[0], buf, xendConfigVersion); - if (res != 0) { - goto error; + /* Old style config before merge of PVFB */ + if (xendConfigVersion < 3) { + obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt); + if ((obj != NULL) && (obj->type == XPATH_NODESET) && + (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { + res = virDomainParseXMLGraphicsDescOld(obj->nodesetval->nodeTab[0], buf, xendConfigVersion); + if (res != 0) { + goto error; + } } + xmlXPathFreeObject(obj); } - xmlXPathFreeObject(obj); error: virBufferAdd(buf, "))", 2); @@ -1408,6 +1478,21 @@ virDomainParseXMLDesc(const char *xmldes } xmlXPathFreeObject(obj); + /* New style PVFB config - 3.0.4 merge */ + if (xendConfigVersion >= 3 && !hvm) { + obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt); + if ((obj != NULL) && (obj->type == XPATH_NODESET) && + (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { + for (i = 0; i < obj->nodesetval->nodeNr; i++) { + res = virDomainParseXMLGraphicsDescNew(obj->nodesetval->nodeTab[i], &buf); + if (res != 0) { + goto error; + } + } + } + xmlXPathFreeObject(obj); + } + virBufferAdd(&buf, ")", 1); /* closes (vm */ buf.content[buf.use] = 0;