[Fedora-xen] [patch 2/4] elilo multiboot support (grubby: add LT_HYPER)

Aron Griffis aron at hp.com
Wed Jun 7 21:37:39 UTC 2006


This patch adds support for the LT_HYPER line type.  Whereas grub uses
a kernel=hypervisor module=kernel module=initrd, elilo uses
vmm=hypervisor image=kernel initrd=initrd.  Adding LT_HYPER support,
and extending it backward to grub, makes dealing with this a lot
easier.

configFileInfo->mbHyperFirst is added to differentiate between grub
wanting the hypervisor listed first, and elilo wanting the kernel
listed first (image= is the entry separator so it's very important)

configFileInfo->mbInitRdIsModule is added to handle grub wanting the
initrd listed as a module when multibooting

The logic in addNewKernel is considerably rewritten (and cleaned up!)
to be more generic and handle elilo alongside grub.

Signed-off-by: Aron Griffis <aron at hp.com>

 grubby.c |  463 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 285 insertions(+), 178 deletions(-)

--- grubby.c.1	2006-06-07 15:31:45.000000000 -0400
+++ grubby.c	2006-06-07 16:14:33.000000000 -0400
@@ -49,9 +49,10 @@
     char * indent;
 };
 
-enum lineType_e { LT_WHITESPACE, LT_TITLE, LT_KERNEL, LT_INITRD, LT_DEFAULT,
-       LT_UNKNOWN, LT_ROOT, LT_FALLBACK, LT_KERNELARGS, LT_BOOT,
-       LT_BOOTROOT, LT_LBA, LT_MBMODULE, LT_OTHER, LT_GENERIC };
+enum lineType_e { LT_WHITESPACE, LT_TITLE, LT_KERNEL, LT_INITRD, LT_HYPER, 
+    LT_DEFAULT, LT_MBMODULE, LT_ROOT, LT_FALLBACK, LT_KERNELARGS, LT_BOOT, 
+    LT_BOOTROOT, LT_LBA, LT_OTHER, LT_GENERIC, LT_UNKNOWN
+};
 
 struct singleLine {
     char * indent;
@@ -72,11 +73,12 @@
 
 #define GRUB_CONFIG_NO_DEFAULT	    (1 << 0)	/* don't write out default=0 */
 
-#define KERNEL_KERNEL	    (1 << 0)
-#define KERNEL_INITRD	    (1 << 2)
-#define KERNEL_TITLE	    (1 << 3)
-#define KERNEL_ARGS	    (1 << 4)
-#define KERNEL_MB           (1 << 5)
+/* These defines are (only) used in addNewKernel() */
+#define NEED_KERNEL  (1 << 0)
+#define NEED_INITRD  (1 << 2)
+#define NEED_TITLE   (1 << 3)
+#define NEED_ARGS    (1 << 4)
+#define NEED_MB      (1 << 5)
 
 #define MAIN_DEFAULT	    (1 << 0)
 #define DEFAULT_SAVED       -2
@@ -97,6 +99,8 @@
     int argsInQuotes;
     int maxTitleLength;
     int titleBracketed;
+    int mbHyperFirst;
+    int mbInitRdIsModule;
 };
 
 struct keywordTypes grubKeywords[] = {
@@ -107,6 +111,7 @@
     { "kernel",	    LT_KERNEL,	    ' ' },
     { "initrd",	    LT_INITRD,	    ' ' },
     { "module",     LT_MBMODULE,    ' ' },
+    { "kernel",     LT_HYPER,       ' ' },
     { NULL,	    0, 0 },
 };
 
@@ -120,6 +125,8 @@
     0,					    /* argsInQuotes */
     0,					    /* maxTitleLength */
     0,                                      /* titleBracketed */
+    1,                                      /* mbHyperFirst */
+    1,                                      /* mbInitRdIsModule */
 };
 
 struct keywordTypes yabootKeywords[] = {
@@ -173,6 +180,17 @@
     { NULL,	    0, 0 },
 };
 
+struct keywordTypes eliloKeywords[] = {
+    { "label",	    LT_TITLE,	    '=' },
+    { "root",	    LT_ROOT,	    '=' },
+    { "default",    LT_DEFAULT,	    '=' },
+    { "image",	    LT_KERNEL,	    '=' },
+    { "initrd",	    LT_INITRD,	    '=' },
+    { "append",	    LT_KERNELARGS,  '=' },
+    { "vmm",	    LT_HYPER,       '=' },
+    { NULL,	    0, 0 },
+};
+
 struct keywordTypes siloKeywords[] = {
     { "label",	    LT_TITLE,	    '=' },
     { "root",	    LT_ROOT,	    '=' },
@@ -196,7 +214,7 @@
 
 struct configFileInfo eliloConfigType = {
     "/boot/efi/EFI/redhat/elilo.conf",	    /* defaultConfig */
-    liloKeywords,			    /* keywords */
+    eliloKeywords,			    /* keywords */
     0,					    /* defaultIsIndex */
     0,					    /* defaultSupportSaved */
     LT_KERNEL,				    /* entrySeparator */
@@ -204,6 +222,8 @@
     1,					    /* argsInQuotes */
     0,					    /* maxTitleLength */
     0,                                      /* titleBracketed */
+    0,                                      /* mbHyperFirst */
+    0,                                      /* mbInitRdIsModule */
 };
 
 struct configFileInfo liloConfigType = {
@@ -216,6 +236,8 @@
     1,					    /* argsInQuotes */
     15,					    /* maxTitleLength */
     0,                                      /* titleBracketed */
+    0,                                      /* mbHyperFirst */
+    0,                                      /* mbInitRdIsModule */
 };
 
 struct configFileInfo yabootConfigType = {
@@ -228,6 +250,8 @@
     1,					    /* argsInQuotes */
     15,					    /* maxTitleLength */
     0,                                      /* titleBracketed */
+    0,                                      /* mbHyperFirst */
+    0,                                      /* mbInitRdIsModule */
 };
 
 struct configFileInfo siloConfigType = {
@@ -240,6 +264,8 @@
     1,					    /* argsInQuotes */
     15,					    /* maxTitleLength */
     0,                                      /* titleBracketed */
+    0,                                      /* mbHyperFirst */
+    0,                                      /* mbInitRdIsModule */
 };
 
 struct configFileInfo ziplConfigType = {
@@ -252,6 +278,8 @@
     1,					    /* argsInQuotes */
     15,					    /* maxTitleLength */
     1,                                      /* titleBracketed */
+    0,                                      /* mbHyperFirst */
+    0,                                      /* mbInitRdIsModule */
 };
 
 struct grubConfig {
@@ -656,11 +684,46 @@
 	if (line->type == LT_DEFAULT && line->numElements == 2) {
 	    cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
 	    defaultLine = line;
+
+        } else if (line->type == LT_KERNEL) {
+	    /* if by some freak chance this is multiboot and the "module"
+	     * lines came earlier in the template, make sure to use LT_HYPER 
+	     * instead of LT_KERNEL now
+	     */
+	    if (entry->multiboot) {
+		struct singleLine * l;
+		for (l = entry->lines; l; l = l->next) {
+		    if (l->type == LT_MBMODULE) {
+			line->type = LT_HYPER;	/* caught it! */
+			break;
+		    }
+		}
+	    }
+
         } else if (line->type == LT_MBMODULE) {
+	    /* go back and fix the LT_KERNEL line to indicate LT_HYPER
+	     * instead, now that we know this is a multiboot entry.
+	     * This only applies to grub, but that's the only place we
+	     * should find LT_MBMODULE lines anyway.
+	     */
+	    struct singleLine * l;
+	    for (l = entry->lines; l; l = l->next) {
+		if (l->type == LT_HYPER)
+		    break;
+		else if (l->type == LT_KERNEL) {
+		    l->type = LT_HYPER;
+		    break;
+		}
+	    }
             entry->multiboot = 1;
+
+	} else if (line->type == LT_HYPER) {
+	    entry->multiboot = 1;
+
 	} else if (line->type == LT_FALLBACK && line->numElements == 2) {
 	    cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);
 	    if (*end) cfg->fallbackImage = -1;
+
 	} else if (line->type == LT_TITLE && line->numElements > 1) {
 	    /* make the title a single argument (undoing our parsing) */
 	    len = 0;
@@ -685,6 +748,7 @@
 		    line->elements[line->numElements - 1].indent;
 	    line->elements[1].item = buf;
 	    line->numElements = 2;
+
 	} else if (line->type == LT_KERNELARGS && cfi->argsInQuotes) {
 	    /* Strip off any " which may be present; they'll be put back
 	       on write. This is one of the few (the only?) places that grubby
@@ -702,7 +766,6 @@
 		if (line->elements[last].item[len] == '"')
 		    line->elements[last].item[len] = '\0';
 	    }
-
 	}
 
 	/* If we find a generic config option which should live at the
@@ -964,7 +1027,7 @@
 
     if (skipRemoved && entry->skip) return 0;
 
-    line = getLineByType(LT_KERNEL, entry->lines);
+    line = getLineByType2(LT_KERNEL, LT_HYPER, entry->lines);
     if (!line || line->numElements < 2) return 0;
 
     if (flags & GRUBBY_BADIMAGE_OKAY) return 1;
@@ -1061,7 +1124,7 @@
 	entry = findEntryByIndex(config, indexVars[i]);
 	if (!entry) return NULL;
 
-	line = getLineByType(LT_KERNEL, entry->lines);
+	line = getLineByType2(LT_KERNEL, LT_HYPER, entry->lines);
 	if (!line) return NULL;
 
 	if (index) *index = indexVars[i];
@@ -1104,7 +1167,10 @@
 	}
 
 	for (entry = findEntryByIndex(config, i); entry; entry = entry->next, i++) {
-	    line = getLineByType(checkType, entry->lines);
+	    if (checkType == LT_KERNEL)
+		line = getLineByType2(LT_KERNEL, LT_HYPER, entry->lines);
+	    else
+		line = getLineByType(checkType, entry->lines);
 
 	    if (line && line->numElements >= 2 && !entry->skip) {
                 rootspec = getRootSpecifier(line->elements[1].item);
@@ -1134,7 +1200,7 @@
 
     /* make sure this entry has a kernel identifier; this skips non-Linux
        boot entries (could find netbsd etc, though, which is unfortunate) */
-    line = getLineByType(LT_KERNEL, entry->lines);
+    line = getLineByType2(LT_KERNEL, LT_HYPER, entry->lines);
     if (!line) {
 	if (!index) index = &i;
 	(*index)++;
@@ -1307,7 +1373,7 @@
 
     printf("index=%d\n", index);
 
-    line = getLineByType(LT_KERNEL, entry->lines);
+    line = getLineByType2(LT_KERNEL, LT_HYPER, entry->lines);
     printf("kernel=%s\n", line->elements[1].item);
 
     if (line->numElements >= 3) {
@@ -1496,7 +1562,8 @@
 	insertElement(newLine, val, 1);
 
 	/* but try to keep the rootspec from the template... sigh */
-	if (tmplLine->type == LT_KERNEL ||
+	if (tmplLine->type == LT_HYPER ||
+	    tmplLine->type == LT_KERNEL ||
 	    tmplLine->type == LT_MBMODULE ||
 	    tmplLine->type == LT_INITRD) 
 	{
@@ -2112,13 +2179,9 @@
 		 char * newKernelArgs, char * newKernelInitrd,
                  char * newMBKernel, char * newMBKernelArgs) {
     struct singleEntry * new;
-    struct singleLine * newLine = NULL, * tmplLine = NULL, * lastLine = NULL;
+    struct singleLine * newLine = NULL, * tmplLine = NULL;
     int needs;
-    char * indent = NULL;
-    char * rootspec = NULL;
     char * chptr;
-    int i;
-    enum lineType_e type;
 
     if (!newKernelPath) return 0;
 
@@ -2148,66 +2211,113 @@
     config->entries = new;
 
     /* copy/update from the template */
-    needs = KERNEL_KERNEL | KERNEL_INITRD | KERNEL_TITLE;
+    needs = NEED_KERNEL | NEED_TITLE;
+    if (newKernelInitrd)
+	needs |= NEED_INITRD;
     if (newMBKernel) {
-        needs |= KERNEL_MB;
+        needs |= NEED_MB;
         new->multiboot = 1;
     }
 
     if (template) {
 	for (tmplLine = template->lines; tmplLine; tmplLine = tmplLine->next) {
-	    /* remember the indention level; we may need it for new lines */
-	    if (tmplLine->numElements)
-		indent = tmplLine->indent;
-
 	    /* skip comments */
 	    chptr = tmplLine->indent;
 	    while (*chptr && isspace(*chptr)) chptr++;
 	    if (*chptr == '#') continue;
 
-	    /* we don't need an initrd here */
-	    if (tmplLine->type == LT_INITRD && !newKernelInitrd) continue;
-
-            if (tmplLine->type == LT_KERNEL &&
-                !template->multiboot && (needs & KERNEL_MB)) {
-                struct singleLine *l;
-                needs &= ~ KERNEL_MB;
-
-                l = addLine(new, config->cfi, LT_KERNEL, 
-                                  config->secondaryIndent, 
-                                  newMBKernel + strlen(prefix));
-                
-                tmplLine = lastLine;
-                if (!new->lines) {
-                    new->lines = l;
-                } else {
-                    newLine->next = l;
-                    newLine = l;
-                }
-                continue;
-            } else if (tmplLine->type == LT_KERNEL &&
-                       template->multiboot && !new->multiboot) {
-                continue; /* don't need multiboot kernel here */
-            }
+	    if (tmplLine->type == LT_KERNEL && 
+		tmplLine->numElements >= 2) {
+		if (!template->multiboot && (needs & NEED_MB)) {
+		    /* it's not a multiboot template and this is the kernel
+		     * line.  Try to be intelligent about inserting the
+		     * hypervisor at the same time.
+		     */
+		    if (config->cfi->mbHyperFirst) {
+			/* insert the hypervisor first */
+			newLine = addLine(new, config->cfi, LT_HYPER, 
+					  tmplLine->indent,
+					  newMBKernel + strlen(prefix));
+			/* set up for adding the kernel line */
+			free(tmplLine->indent);
+			tmplLine->indent = strdup(config->secondaryIndent);
+			needs &= ~NEED_MB;
+		    }
+		    if (needs & NEED_KERNEL) {
+			/* use addLineTmpl to preserve line elements,
+			 * otherwise we could just call addLine.  Unfortunately
+			 * this means making some changes to the template
+			 * such as the indent change above and the type
+			 * change below.
+			 */
+			struct keywordTypes * mbm_kw = 
+			    getKeywordByType(LT_MBMODULE, config->cfi);
+			if (mbm_kw) {
+			    tmplLine->type = LT_MBMODULE;
+			    free(tmplLine->elements[0].item);
+			    tmplLine->elements[0].item = strdup(mbm_kw->key);
+			}
+			newLine = addLineTmpl(new, tmplLine, newLine,
+					      newKernelPath + strlen(prefix));
+			needs &= ~NEED_KERNEL;
+		    }
+		    if (needs & NEED_MB) { /* !mbHyperFirst */
+			newLine = addLine(new, config->cfi, LT_HYPER, 
+					  config->secondaryIndent,
+					  newMBKernel + strlen(prefix));
+			needs &= ~NEED_MB;
+		    }
+		} else if (needs & NEED_KERNEL) {
+		    newLine = addLineTmpl(new, tmplLine, newLine, 
+					  newKernelPath + strlen(prefix));
+		    needs &= ~NEED_KERNEL;
+		}
 
-	    if (!new->lines) {
-		newLine = malloc(sizeof(*newLine));
-		new->lines = newLine;
-	    } else {
-		newLine->next = malloc(sizeof(*newLine));
-		newLine = newLine->next;
-	    }
+	    } else if (tmplLine->type == LT_HYPER && 
+		       tmplLine->numElements >= 2) {
+		if (new->multiboot) {
+		    if (needs & NEED_MB) {
+			newLine = addLineTmpl(new, tmplLine, newLine, 
+					      newMBKernel + strlen(prefix));
+			needs &= ~NEED_MB;
+		    }
+		} else if (needs & NEED_KERNEL) {
+		    /* template is multi but new is not,
+		     * insert the kernel where the hypervisor was before
+		     */
+		    tmplLine->type = LT_KERNEL;
+		    free(tmplLine->elements[0].item);
+		    tmplLine->elements[0].item = 
+			strdup(getKeywordByType(LT_KERNEL, config->cfi)->key);
+		    newLine = addLineTmpl(new, tmplLine, newLine, 
+					  newKernelPath + strlen(prefix));
+		    needs &= ~NEED_KERNEL;
+		}
 
+	    } else if (tmplLine->type == LT_MBMODULE && 
+		       tmplLine->numElements >= 2) {
+		if (new->multiboot) {
+		    if (needs & NEED_KERNEL) {
+			newLine = addLineTmpl(new, tmplLine, newLine, 
+					      newKernelPath + 
+					      strlen(prefix));
+			needs &= ~NEED_KERNEL;
+		    } else if (config->cfi->mbInitRdIsModule &&
+			       (needs & NEED_INITRD)) {
+			newLine = addLineTmpl(new, tmplLine, newLine,
+					      newKernelInitrd);
+			needs &= ~NEED_INITRD;
+		    }
+		} else if (needs & NEED_INITRD) {
+		    /* template is multi but new is not,
+		     * insert the initrd where the module was before
+		     */
+		    newLine = addLine(new, config->cfi, LT_INITRD,
+				      config->secondaryIndent, 
+				      newKernelInitrd + strlen(prefix));
+		    needs &= ~NEED_INITRD;
+		}
 
-	    newLine->indent = strdup(tmplLine->indent);
-	    newLine->next = NULL;
-	    newLine->type = tmplLine->type;
-	    newLine->numElements = tmplLine->numElements;
-	    newLine->elements = malloc(sizeof(*newLine->elements) * 
-					    newLine->numElements);
-	    for (i = 0; i < newLine->numElements; i++) {
-		newLine->elements[i].item = strdup(tmplLine->elements[i].item);
-		newLine->elements[i].indent = 
 				strdup(tmplLine->elements[i].indent);
 	    }
 
@@ -2257,127 +2367,124 @@
                                                        strlen(prefix));
                 }
 	    } else if (tmplLine->type == LT_INITRD && 
-			    tmplLine->numElements >= 2) {
-		needs &= ~KERNEL_INITRD;
-		free(newLine->elements[1].item);
-                if (new->multiboot && !template->multiboot) {
-                    free(newLine->elements[0].item);
-                    newLine->elements[0].item = strdup("module");
-                    newLine->type = LT_MBMODULE;
-                }
-                rootspec = getRootSpecifier(tmplLine->elements[1].item);
-                if (rootspec != NULL) {
-                    newLine->elements[1].item = sdupprintf("%s%s",
-                                                           rootspec,
-                                                           newKernelInitrd + 
-                                                           strlen(prefix));
-                } else {
-                    newLine->elements[1].item = strdup(newKernelInitrd + 
-                                                       strlen(prefix));
-                }
-            } else if (tmplLine->type == LT_MBMODULE && 
-                       tmplLine->numElements >= 2 && (needs & KERNEL_INITRD)) {
-		needs &= ~KERNEL_INITRD;
-                if (!new->multiboot && template->multiboot) {
-                    free(newLine->elements[0].item);
-                    newLine->elements[0].item = strdup("initrd");
-                    newLine->type = LT_INITRD;
-                }
-		free(newLine->elements[1].item);
-                rootspec = getRootSpecifier(tmplLine->elements[1].item);
-                if (rootspec != NULL) {
-                    newLine->elements[1].item = sdupprintf("%s%s",
-                                                           rootspec,
-                                                           newKernelInitrd + 
-                                                           strlen(prefix));
-                } else {
-                    newLine->elements[1].item = strdup(newKernelInitrd + 
-                                                       strlen(prefix));
-                }
-	    } else if (tmplLine->type == LT_TITLE && 
-			    tmplLine->numElements >= 2) {
-		needs &= ~KERNEL_TITLE;
-
-		for (i = 1; i < newLine->numElements; i++) {
-		    free(newLine->elements[i].item);
-		    free(newLine->elements[i].indent);
+		       tmplLine->numElements >= 2 && 
+		       (needs & NEED_INITRD)) {
+		if (new->multiboot && !template->multiboot &&
+		    config->cfi->mbInitRdIsModule) {
+		    /* make sure we don't insert the module initrd
+		     * before the module kernel... if we don't do it here,
+		     * it will be inserted following the template.
+		     */
+		    if (!needs & NEED_KERNEL) {
+			newLine = addLine(new, config->cfi, LT_MBMODULE,
+					  config->secondaryIndent, 
+					  newKernelInitrd + strlen(prefix));
+			needs &= ~NEED_INITRD;
+		    }
+		} else {
+		    newLine = addLineTmpl(new, tmplLine, newLine,
+					  newKernelInitrd + strlen(prefix));
+		    needs &= ~NEED_INITRD;
 		}
 
-		newLine->elements[1].item = strdup(newKernelTitle);
-		newLine->elements[1].indent = strdup("");
-		newLine->numElements = 2;
 	    } else if (tmplLine->type == LT_TITLE && 
-                       config->cfi->titleBracketed && 
-                       tmplLine->numElements == 1) {
-                needs &= ~KERNEL_TITLE;
-                free(newLine->elements[0].item);
-                free(newLine->elements[0].indent);
-                newLine->elements = malloc(sizeof(*newLine->elements) * 
-                                           newLine->numElements);
-
-                newLine->elements[0].item = malloc(strlen(newKernelTitle) + 3);
-                sprintf(newLine->elements[0].item, "[%s]", newKernelTitle);
-                newLine->elements[0].indent = strdup("");
-                newLine->numElements = 1;
-            }
+		       (needs & NEED_TITLE)) {
+		if (tmplLine->numElements >= 2) {
+		    newLine = addLineTmpl(new, tmplLine, newLine, 
+					  newKernelTitle);
+		    needs &= ~NEED_TITLE;
+		} else if (tmplLine->numElements == 1 &&
+			   config->cfi->titleBracketed) {
+		    /* addLineTmpl doesn't handle titleBracketed */
+		    newLine = addLine(new, config->cfi, LT_TITLE,
+				      tmplLine->indent, newKernelTitle);
+		    needs &= ~NEED_TITLE;
+		}
+
+	    } else {
+		/* pass through other lines from the template */
+		newLine = addLineTmpl(new, tmplLine, newLine, NULL);
+	    }
 	}
+
     } else {
-	for (i = 0; config->cfi->keywords[i].key; i++) {
-	    if ((config->cfi->keywords[i].type == config->cfi->entrySeparator) || (config->cfi->keywords[i].type == LT_OTHER)) 
+	/* don't have a template, so start the entry with the 
+	 * appropriate starting line 
+	 */
+	switch (config->cfi->entrySeparator) {
+	    case LT_KERNEL:
+		if (new->multiboot && config->cfi->mbHyperFirst) {
+		    /* fall through to LT_HYPER */
+		} else {
+		    newLine = addLine(new, config->cfi, LT_KERNEL,
+				      config->primaryIndent,
+				      newKernelPath + strlen(prefix));
+		    needs &= ~NEED_KERNEL;
+		    break;
+		}
+
+	    case LT_HYPER:
+		newLine = addLine(new, config->cfi, LT_HYPER,
+				  config->primaryIndent,
+				  newMBKernel + strlen(prefix));
+		needs &= ~NEED_MB;
 		break;
-        }
 
-	switch (config->cfi->keywords[i].type) {
-	    case LT_KERNEL:  needs &= ~KERNEL_KERNEL, 
-			     chptr = newKernelPath + strlen(prefix);
-			     type = LT_KERNEL; break;
-	    case LT_TITLE:   needs &= ~KERNEL_TITLE, chptr = newKernelTitle;
-			     type = LT_TITLE; break;
-	    default:	    
-                /* zipl strikes again */
-                if (config->cfi->titleBracketed) {
-                    needs &= ~KERNEL_TITLE;
-                    chptr = newKernelTitle;
-                    type = LT_TITLE;
-                    break;
-                } else {
-                    abort();
-                }
-	}
+	    case LT_TITLE:
+		newLine = addLine(new, config->cfi, LT_TITLE,
+				  config->primaryIndent, newKernelTitle);
+		needs &= ~NEED_TITLE;
+		break;
 
-	newLine = addLine(new, config->cfi, type, config->primaryIndent, chptr);
-	new->lines = newLine;
+	    default:
+		abort();
+	}
     } 
 
-    if (new->multiboot) {
-        if (needs & KERNEL_MB)
-            newLine = addLine(new, config->cfi, LT_KERNEL, 
-                              config->secondaryIndent, 
-                              newMBKernel + strlen(prefix));
-        if (needs & KERNEL_KERNEL)
-            newLine = addLine(new, config->cfi, LT_MBMODULE, 
-                              config->secondaryIndent, 
-                              newKernelPath + strlen(prefix));
-        /* don't need to check for title as it's guaranteed to have been
-         * done as we only do multiboot with grub which uses title as
-         * a separator */
-        if (needs & KERNEL_INITRD && newKernelInitrd)
-            newLine = addLine(new, config->cfi, LT_MBMODULE, 
-                              config->secondaryIndent, 
-                              newKernelInitrd + strlen(prefix));
-    } else {
-        if (needs & KERNEL_KERNEL)
-            newLine = addLine(new, config->cfi, LT_KERNEL, 
-                              config->secondaryIndent, 
-                              newKernelPath + strlen(prefix));
-        if (needs & KERNEL_TITLE)
-            newLine = addLine(new, config->cfi, LT_TITLE, 
-                              config->secondaryIndent, 
-                              newKernelTitle);
-        if (needs & KERNEL_INITRD && newKernelInitrd)
-            newLine = addLine(new, config->cfi, LT_INITRD, 
-                              config->secondaryIndent, 
-                              newKernelInitrd + strlen(prefix));
+    /* add the remainder of the lines, i.e. those that either
+     * weren't present in the template, or in the case of no template,
+     * all the lines following the entrySeparator.
+     */
+    if (needs & NEED_TITLE) {
+	newLine = addLine(new, config->cfi, LT_TITLE, 
+			  config->secondaryIndent, 
+			  newKernelTitle);
+	needs &= ~NEED_TITLE;
+    }
+    if ((needs & NEED_MB) && config->cfi->mbHyperFirst) {
+	newLine = addLine(new, config->cfi, LT_HYPER, 
+			  config->secondaryIndent, 
+			  newMBKernel + strlen(prefix));
+	needs &= ~NEED_MB;
+    }
+    if (needs & NEED_KERNEL) {
+	newLine = addLine(new, config->cfi, 
+			  (new->multiboot && getKeywordByType(LT_MBMODULE, 
+							      config->cfi)) ?
+			  LT_MBMODULE : LT_KERNEL, 
+			  config->secondaryIndent, 
+			  newKernelPath + strlen(prefix));
+	needs &= ~NEED_KERNEL;
+    }
+    if (needs & NEED_MB) {
+	newLine = addLine(new, config->cfi, LT_HYPER, 
+			  config->secondaryIndent,
+			  newMBKernel + strlen(prefix));
+	needs &= ~NEED_MB;
+    }
+    if (needs & NEED_INITRD) {
+	newLine = addLine(new, config->cfi,
+			  (new->multiboot && getKeywordByType(LT_MBMODULE,
+							      config->cfi)) ?
+			  LT_MBMODULE : LT_INITRD, 
+			  config->secondaryIndent, 
+			  newKernelInitrd + strlen(prefix));
+	needs &= ~NEED_INITRD;
+    }
+
+    if (needs) {
+	printf(_("grubby: needs=%d, aborting\n"), needs);
+	abort();
     }
 
     if (updateImage(config, "0", prefix, newKernelArgs, NULL, 




More information about the Fedora-xen mailing list