diff --git a/ChangeLog b/ChangeLog index 29f1818d6d..f5c5af06a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Aug 26 16:36:15 CEST 2006 Daniel Veillard + + * src/sexpr.c src/sexpr.h src/xend_internal.c src/xml.c: applied + patch from Jeremy Katz to add graphical console for PV Xen guests + Sat Aug 26 00:17:24 CEST 2006 Daniel Veillard * docs/site.xsl docs/*.html: add links to virt-manager diff --git a/src/sexpr.c b/src/sexpr.c index baf034142c..f3966da579 100644 --- a/src/sexpr.c +++ b/src/sexpr.c @@ -486,3 +486,27 @@ sexpr_node(struct sexpr *sexpr, const char *node) return (n && n->car->kind == SEXPR_VALUE) ? n->car->value : NULL; } + +/** + * sexpr_fmt_node: + * @sexpr: a pointer to a parsed S-Expression + * @fmt: a path for the node to lookup in the S-Expression + * @... extra data to build the path + * + * Search a node value in the S-Expression based on its path + * NOTE: path are limited to 4096 bytes. + * + * Returns the value of the node or NULL if not found. + */ +const char * +sexpr_fmt_node(struct sexpr *sexpr, const char *fmt, ...) +{ + va_list ap; + char node[4096]; + + va_start(ap, fmt); + vsnprintf(node, sizeof(node), fmt, ap); + va_end(ap); + + return sexpr_node(sexpr, node); +} diff --git a/src/sexpr.h b/src/sexpr.h index 3026ee54fb..6c9048715c 100644 --- a/src/sexpr.h +++ b/src/sexpr.h @@ -45,5 +45,6 @@ void sexpr_free(struct sexpr *sexpr); /* lookup in S-Expressions */ const char *sexpr_node(struct sexpr *sexpr, const char *node); +const char *sexpr_fmt_node(struct sexpr *sexpr, const char *fmt, ...); struct sexpr *sexpr_lookup(struct sexpr *sexpr, const char *node); #endif diff --git a/src/xend_internal.c b/src/xend_internal.c index c398797a9c..48a5c5bde3 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -1618,23 +1618,23 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root) virBufferAdd(&buf, " \n", 18); virBufferAdd(&buf, " \n", 12); } + } - /* Graphics device */ - tmp = sexpr_node(root, "domain/image/hvm/vnc"); - if (tmp != NULL) { - if (tmp[0] == '1') { - int port = xenStoreDomainGetVNCPort(conn, domid); - if (port == -1) - port = 5900 + domid; - virBufferVSprintf(&buf, " \n", port); - } + /* Graphics device */ + tmp = sexpr_fmt_node(root, "domain/image/%s/vnc", hvm ? "hvm" : "linux"); + if (tmp != NULL) { + if (tmp[0] == '1') { + int port = xenStoreDomainGetVNCPort(conn, domid); + if (port == -1) + port = 5900 + domid; + virBufferVSprintf(&buf, " \n", port); } + } - tmp = sexpr_node(root, "domain/image/hvm/sdl"); - if (tmp != NULL) { - if (tmp[0] == '1') - virBufferAdd(&buf, " \n", 27 ); - } + tmp = sexpr_fmt_node(root, "domain/image/%s/sdl", hvm ? "hvm" : "linux"); + if (tmp != NULL) { + if (tmp[0] == '1') + virBufferAdd(&buf, " \n", 27 ); } tty = xenStoreDomainGetConsolePath(conn, domid); diff --git a/src/xml.c b/src/xml.c index d724ad6fec..cc6d9dd887 100644 --- a/src/xml.c +++ b/src/xml.c @@ -570,6 +570,40 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags) #endif /* 0 - UNUSED */ #ifndef PROXY +/** + * virtDomainParseXMLGraphicsDesc: + * @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 virDomainParseXMLGraphicsDesc(xmlNodePtr node, virBufferPtr buf) +{ + xmlChar *graphics_type = NULL; + + graphics_type = xmlGetProp(node, BAD_CAST "type"); + if (graphics_type != NULL) { + if (xmlStrEqual(graphics_type, BAD_CAST "sdl")) { + virBufferAdd(buf, "(sdl 1)", 7); + // 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, "(vnc 1)", 7); + xmlFree(graphics_type); + } + return 0; +} + + /** * virDomainParseXMLOSDescHVM: * @node: node containing HVM OS description @@ -591,7 +625,7 @@ virDomainParseXMLOSDescHVM(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr const xmlChar *type = NULL; const xmlChar *loader = NULL; const xmlChar *boot_dev = NULL; - xmlChar *graphics_type = NULL; + int res; cur = node->children; while (cur != NULL) { @@ -733,24 +767,11 @@ virDomainParseXMLOSDescHVM(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr /* 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)) { - virXMLError(VIR_ERR_NO_OS, "", 0); /* TODO: error */ - goto error; - } - - graphics_type = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type"); - if (graphics_type != NULL) { - if (xmlStrEqual(graphics_type, BAD_CAST "sdl")) { - virBufferAdd(buf, "(sdl 1)", 7); - // TODO: - // Need to understand sdl options - // - //virBufferAdd(buf, "(display localhost:10.0)", 24); - //virBufferAdd(buf, "(xauthority /root/.Xauthority)", 30); + (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { + res = virDomainParseXMLGraphicsDesc(obj->nodesetval->nodeTab[0], buf); + if (res != 0) { + goto error; } - else if (xmlStrEqual(graphics_type, BAD_CAST "vnc")) - virBufferAdd(buf, "(vnc 1)", 7); - xmlFree(graphics_type); } xmlXPathFreeObject(obj); @@ -767,6 +788,7 @@ error: * virDomainParseXMLOSDescPV: * @node: node containing PV OS description * @buf: a buffer for the result S-Expr + * @ctxt: a path context representing the XML description * * Parse the OS part of the XML description for a paravirtualized domain * and add it to the S-Expr in buf. This is a temporary interface as the @@ -776,14 +798,16 @@ error: * Returns 0 in case of success, -1 in case of error. */ static int -virDomainParseXMLOSDescPV(xmlNodePtr node, virBufferPtr buf) +virDomainParseXMLOSDescPV(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr ctxt) { xmlNodePtr cur, txt; + xmlXPathObjectPtr obj = NULL; const xmlChar *type = NULL; const xmlChar *root = NULL; const xmlChar *kernel = NULL; const xmlChar *initrd = NULL; const xmlChar *cmdline = NULL; + int res; cur = node->children; while (cur != NULL) { @@ -840,6 +864,19 @@ virDomainParseXMLOSDescPV(xmlNodePtr node, virBufferPtr buf) virBufferVSprintf(buf, "(root '%s')", (const char *) root); if (cmdline != NULL) 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); + if (res != 0) { + goto error; + } + } + xmlXPathFreeObject(obj); + + error: virBufferAdd(buf, "))", 2); return (0); } @@ -1177,7 +1214,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) } if ((tmpobj == NULL) || !xmlStrEqual(tmpobj->stringval, BAD_CAST "hvm")) { - res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf); + res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf, ctxt); } else { hvm = 1; res = virDomainParseXMLOSDescHVM(obj->nodesetval->nodeTab[0], &buf, ctxt);