diff --git a/ChangeLog b/ChangeLog index 2ebf0ac6ea..b0c46167c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sat Sep 29 14:23:41 EST 2007 Daniel P. Berrange + + * src/sexpr.h, src/sexpr.c, src/xml.c, src/xend_internal.c: Allow + bootloader tag to be empty, to indicate use of default configured + bootloader path. + Sat Sep 29 14:05:41 EST 2007 Daniel P. Berrange * src/sexpr.h, src/sexpr.c, src/virsh.c, src/xend_internal.c: diff --git a/src/sexpr.c b/src/sexpr.c index ed7910e4e7..8412f22c26 100644 --- a/src/sexpr.c +++ b/src/sexpr.c @@ -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 char *node) return NULL; } - if (sexpr->kind != SEXPR_CONS || sexpr->u.s.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->u.s.cdr->kind != SEXPR_CONS) return NULL; - return sexpr->u.s.cdr; + return s->u.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; } /** diff --git a/src/sexpr.h b/src/sexpr.h index ecd9f4bdf1..eb82479a70 100644 --- a/src/sexpr.h +++ b/src/sexpr.h @@ -50,4 +50,5 @@ const char *sexpr_node(struct sexpr *sexpr, const char *node); 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 diff --git a/src/xend_internal.c b/src/xend_internal.c index d8a0da3780..2a488ccd19 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -1402,6 +1402,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi 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) { @@ -1414,7 +1417,8 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi 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; } } diff --git a/src/xml.c b/src/xml.c index 0287e50fce..a916aac8eb 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1179,6 +1179,14 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int */ 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);