[Libvir] PATCH: Allow emptry bootloader

Daniel P. Berrange berrange at redhat.com
Fri Sep 28 22:12:41 UTC 2007


Latest XenD allows for default bootloader to be used if one is not defined
for a paravirt OS. libvirt doesn't currently cope with this (see Solaris
thread), since it requires either a bootloader or kernel to always be
present.

The attached patch allows for an emptry bootloader element to indicate that
the domain should use the default.

<domain type='xen' id='-1'>
  <name>rhel5pv</name>
  <uuid>614d7eb0-c6b1-5235-ac39-361b20f6cd49</uuid>
  <bootloader/>
  <os>
    <type>linux</type>
  </os>
   ...snip...
</domain>


The current API for looking up nodes in the SEXPR did not allow for the 
scenario where you might want to lookup a node with no content, eg

       (bootloader )

This distinction is needed here, so I added an sexpr_has() method to check
for this.

Second, it fixes a long standing bug where we'd record an error about the
missing kernel or bootloader, but then continue generating (malformed) XML
anyway. With this patch, it will correctly fail if the empty bootloader
field is missing from the SEXPR.

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  -=| 
-------------- next part --------------
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, "  <bootloader>%s</bootloader>\n", tmp);
+    } else if (sexpr_has(root, "domain/bootloader")) {
+        bootloader = 1;
+        virBufferVSprintf(&buf, "  <bootloader/>\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);


More information about the libvir-list mailing list