diff --git a/ChangeLog b/ChangeLog index 2ebf0ac6ea016df432af1ca9e1522493d7d626fa..b0c46167c528e97abd6e4a5e810610aca427e9b5 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 ed7910e4e7087ac2102a96e326fc7c0b6f6d0219..8412f22c26162ac69e747fcbb4b3a245a760e312 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 ecd9f4bdf1560c5abcff7307d0c8815edff9b340..eb82479a70ca0c6985e0d81463a6169440a17742 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 d8a0da378058e787ba0422337fa32712a492c078..2a488ccd1920aba7f40810714f4a2fbd9c819ecb 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 0287e50fceb6c50033ffe24c9b7a8b283bfd9faa..a916aac8ebb9bb76279d9fc62e585a62fe5ab468 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);