Index: sexpr.c =================================================================== RCS file: /data/cvs/libvirt/src/sexpr.c,v retrieving revision 1.7 diff -u -p -r1.7 sexpr.c --- sexpr.c 4 Jul 2007 09:16:23 -0000 1.7 +++ sexpr.c 28 Sep 2007 22:01:28 -0000 @@ -404,17 +404,18 @@ string2sexpr(const char *buffer) /** - * sexpr_lookup: + * sexpr_lookup_key: * @sexpr: a pointer to a parsed S-Expression * @node: a path for the sub expression to lookup in the S-Expression * * Search a sub expression in the S-Expression based on its path + * Returns the key node, rather than the data node. * NOTE: path are limited to 4096 bytes. * * Returns the pointer to the sub expression or NULL if not found. */ -struct sexpr * -sexpr_lookup(struct sexpr *sexpr, const char *node) +static struct sexpr * +sexpr_lookup_key(struct sexpr *sexpr, const char *node) { char buffer[4096], *ptr, *token; @@ -463,10 +464,57 @@ sexpr_lookup(struct sexpr *sexpr, const return NULL; } - if (sexpr->kind != SEXPR_CONS || sexpr->cdr->kind != SEXPR_CONS) + return sexpr; +} + +/** + * sexpr_lookup: + * @sexpr: a pointer to a parsed S-Expression + * @node: a path for the sub expression to lookup in the S-Expression + * + * Search a sub expression in the S-Expression based on its path. + * NOTE: path are limited to 4096 bytes. + * + * Returns the pointer to the sub expression or NULL if not found. + */ +struct sexpr * +sexpr_lookup(struct sexpr *sexpr, const char *node) +{ + struct sexpr *s = sexpr_lookup_key(sexpr, node); + + if (s == NULL) + return NULL; + + if (s->kind != SEXPR_CONS || s->cdr->kind != SEXPR_CONS) return NULL; - return sexpr->cdr; + return s->cdr; +} + +/** + * sexpr_has: + * @sexpr: a pointer to a parsed S-Expression + * @node: a path for the sub expression to lookup in the S-Expression + * + * Search a sub expression in the S-Expression based on its path. + * NOTE: path are limited to 4096 bytes. + * NB, even if the key was found sexpr_lookup may return NULL if + * the corresponding value was empty + * + * Returns true if the key was found, false otherwise + */ +int +sexpr_has(struct sexpr *sexpr, const char *node) +{ + struct sexpr *s = sexpr_lookup_key(sexpr, node); + + if (s == NULL) + return 0; + + if (s->kind != SEXPR_CONS) + return 0; + + return 1; } /** Index: sexpr.h =================================================================== RCS file: /data/cvs/libvirt/src/sexpr.h,v retrieving revision 1.4 diff -u -p -r1.4 sexpr.h --- sexpr.h 16 Mar 2007 15:03:21 -0000 1.4 +++ sexpr.h 28 Sep 2007 22:01:28 -0000 @@ -50,4 +50,5 @@ const char *sexpr_node(struct sexpr *sex const char *sexpr_fmt_node(struct sexpr *sexpr, const char *fmt, ...) ATTRIBUTE_FORMAT(printf,2,3); struct sexpr *sexpr_lookup(struct sexpr *sexpr, const char *node); +int sexpr_has(struct sexpr *sexpr, const char *node); #endif Index: xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.141 diff -u -p -r1.141 xend_internal.c --- xend_internal.c 28 Sep 2007 14:28:13 -0000 1.141 +++ xend_internal.c 28 Sep 2007 22:01:28 -0000 @@ -1403,6 +1403,9 @@ xend_parse_sexp_desc(virConnectPtr conn, if (tmp != NULL) { bootloader = 1; virBufferVSprintf(&buf, " %s\n", tmp); + } else if (sexpr_has(root, "domain/bootloader")) { + bootloader = 1; + virBufferVSprintf(&buf, " \n"); } tmp = sexpr_node(root, "domain/bootloader_args"); if (tmp != NULL && bootloader) { @@ -1415,7 +1418,8 @@ xend_parse_sexp_desc(virConnectPtr conn, if (domid != 0) { if (sexpr_lookup(root, "domain/image")) { hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0; - xend_parse_sexp_desc_os(conn, root, &buf, hvm, bootloader); + if (xend_parse_sexp_desc_os(conn, root, &buf, hvm, bootloader) < 0) + goto error; } } Index: xml.c =================================================================== RCS file: /data/cvs/libvirt/src/xml.c,v retrieving revision 1.89 diff -u -p -r1.89 xml.c --- xml.c 12 Sep 2007 15:41:51 -0000 1.89 +++ xml.c 28 Sep 2007 22:01:28 -0000 @@ -1179,6 +1179,14 @@ virDomainParseXMLDesc(virConnectPtr conn */ bootloader = 1; free(str); + } else if (virXPathNumber("count(/domain/bootloader)", ctxt, &f) == 0 && + (f > 0)) { + virBufferVSprintf(&buf, "(bootloader)"); + /* + * if using a bootloader, the kernel and initrd strings are not + * significant and should be discarded + */ + bootloader = 1; } str = virXPathString("string(/domain/bootloader_args[1])", ctxt);