[Fedora-xen] [patch 3/4] elilo multiboot support (grubby: args)
Aron Griffis
aron at hp.com
Wed Jun 7 21:38:21 UTC 2006
elilo handles hypervisor args by putting a "--" separator on the
append line, like this:
append="hyper args -- kernel args"
This patch modifies updateActualImage() to handle this situation,
including removing the hypervisor args plus separator when a multiboot
template is used to construct a non-multiboot entry.
Signed-off-by: Aron Griffis <aron at hp.com>
grubby.c | 279 ++++++++++++++++++++++++++++-----------------------------------
1 file changed, 128 insertions(+), 151 deletions(-)
--- grubby.c.2 2006-06-07 16:14:33.000000000 -0400
+++ grubby.c 2006-06-07 16:16:44.000000000 -0400
@@ -101,6 +101,7 @@
int titleBracketed;
int mbHyperFirst;
int mbInitRdIsModule;
+ int mbConcatArgs;
};
struct keywordTypes grubKeywords[] = {
@@ -127,6 +128,7 @@
0, /* titleBracketed */
1, /* mbHyperFirst */
1, /* mbInitRdIsModule */
+ 0, /* mbConcatArgs */
};
struct keywordTypes yabootKeywords[] = {
@@ -224,6 +226,7 @@
0, /* titleBracketed */
0, /* mbHyperFirst */
0, /* mbInitRdIsModule */
+ 1, /* mbConcatArgs */
};
struct configFileInfo liloConfigType = {
@@ -238,6 +241,7 @@
0, /* titleBracketed */
0, /* mbHyperFirst */
0, /* mbInitRdIsModule */
+ 0, /* mbConcatArgs */
};
struct configFileInfo yabootConfigType = {
@@ -252,6 +256,7 @@
0, /* titleBracketed */
0, /* mbHyperFirst */
0, /* mbInitRdIsModule */
+ 0, /* mbConcatArgs */
};
struct configFileInfo siloConfigType = {
@@ -266,6 +271,7 @@
0, /* titleBracketed */
0, /* mbHyperFirst */
0, /* mbInitRdIsModule */
+ 0, /* mbConcatArgs */
};
struct configFileInfo ziplConfigType = {
@@ -280,6 +286,7 @@
1, /* titleBracketed */
0, /* mbHyperFirst */
0, /* mbInitRdIsModule */
+ 0, /* mbConcatArgs */
};
struct grubConfig {
@@ -1754,14 +1761,13 @@
struct singleEntry * entry;
struct singleLine * line, * rootLine;
int index = 0;
- int i, j, k;
+ int i, k;
const char ** newArgs, ** oldArgs;
const char ** arg;
- const char * chptr;
- int useKernelArgs = 0;
- int useRoot = 0;
+ int useKernelArgs, useRoot;
int firstElement;
int *usedElements, *usedArgs;
+ int doreplace;
if (!image) return 0;
@@ -1788,54 +1794,102 @@
}
}
- for (i = 0; cfg->cfi->keywords[i].key; i++)
- if (cfg->cfi->keywords[i].type == LT_KERNELARGS) break;
- if (cfg->cfi->keywords[i].key)
- useKernelArgs = 1;
+ useKernelArgs = (getKeywordByType(LT_KERNELARGS, cfg->cfi)
+ && (!multibootArgs || cfg->cfi->mbConcatArgs));
- for (i = 0; cfg->cfi->keywords[i].key; i++)
- if (cfg->cfi->keywords[i].type == LT_ROOT) break;
+ useRoot = (getKeywordByType(LT_ROOT, cfg->cfi)
+ && !multibootArgs);
- if (cfg->cfi->keywords[i].key)
- useRoot = 1;
+ for (k = 0, arg = newArgs; *arg; arg++, k++) ;
+ usedArgs = calloc(k, sizeof(*usedArgs));
- k = 0;
- for (arg = newArgs; *arg; arg++)
- k++;
- usedArgs = calloc(k, sizeof(int));
+ for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
- while ((entry = findEntryByPath(cfg, image, prefix, &index))) {
- index++;
+ if (multibootArgs && !entry->multiboot)
+ continue;
- line = entry->lines;
- while (line && line->type != LT_KERNEL) line = line->next;
- if (!line) continue;
- firstElement = 2;
-
- if (entry->multiboot && !multibootArgs) {
- /* first mb module line is the real kernel */
- while (line && line->type != LT_MBMODULE) line = line->next;
- firstElement = 2;
- } else if (useKernelArgs) {
- while (line && line->type != LT_KERNELARGS) line = line->next;
+ /* Determine where to put the args. If this config supports
+ * LT_KERNELARGS, use that. Otherwise use
+ * LT_HYPER/LT_KERNEL/LT_MBMODULE lines.
+ */
+ if (useKernelArgs) {
+ line = getLineByType(LT_KERNELARGS, entry->lines);
+ if (!line) {
+ /* no LT_KERNELARGS, need to add it */
+ line = addLine(entry, cfg->cfi, LT_KERNELARGS,
+ cfg->secondaryIndent, NULL);
+ }
firstElement = 1;
+
+ } else if (multibootArgs) {
+ line = getLineByType(LT_HYPER, entry->lines);
+ if (!line) {
+ /* a multiboot entry without LT_HYPER? */
+ continue;
+ }
+ firstElement = 2;
+
+ } else {
+ line = getLineByType2(LT_KERNEL, LT_MBMODULE, entry->lines);
+ if (!line) {
+ /* no LT_KERNEL or LT_MBMODULE in this entry? */
+ continue;
+ }
+ firstElement = 2;
}
- if (!line && useKernelArgs) {
- /* no append in there, need to add it */
- line = addLine(entry, cfg->cfi, LT_KERNELARGS, NULL, NULL);
+ /* handle the elilo case which does:
+ * append="hypervisor args -- kernel args"
+ */
+ if (entry->multiboot && cfg->cfi->mbConcatArgs) {
+ /* this is a multiboot entry, make sure there's
+ * -- on the args line
+ */
+ for (i = firstElement; i < line->numElements; i++) {
+ if (!strcmp(line->elements[i].item, "--"))
+ break;
+ }
+ if (i == line->numElements) {
+ /* assume all existing args are kernel args,
+ * prepend -- to make it official
+ */
+ insertElement(line, "--", firstElement);
+ i = firstElement;
+ }
+ if (!multibootArgs) {
+ /* kernel args start after the -- */
+ firstElement = i + 1;
+ }
+ } else if (cfg->cfi->mbConcatArgs) {
+ /* this is a non-multiboot entry, remove hyper args */
+ for (i = firstElement; i < line->numElements; i++) {
+ if (!strcmp(line->elements[i].item, "--"))
+ break;
+ }
+ if (i < line->numElements) {
+ /* remove args up to -- */
+ while (strcmp(line->elements[firstElement].item, "--"))
+ removeElement(line, firstElement);
+ /* remove -- */
+ removeElement(line, firstElement);
+ }
}
- usedElements = calloc(line->numElements, sizeof(int));
-
- k = 0;
- for (arg = newArgs; *arg; arg++) {
- if (usedArgs[k]) {
- k++;
- continue;
- }
+ usedElements = calloc(line->numElements, sizeof(*usedElements));
+
+ for (k = 0, arg = newArgs; *arg; arg++, k++) {
+ if (usedArgs[k]) continue;
+
+ doreplace = 1;
for (i = firstElement; i < line->numElements; i++) {
+ if (multibootArgs && cfg->cfi->mbConcatArgs &&
+ !strcmp(line->elements[i].item, "--"))
+ {
+ /* reached the end of hyper args, insert here */
+ doreplace = 0;
+ break;
+ }
if (usedElements[i])
continue;
if (!argMatch(line->elements[i].item, *arg)) {
@@ -1844,91 +1898,62 @@
break;
}
}
- chptr = strchr(*arg, '=');
- if (i < line->numElements) {
- /* replace */
+ if (i < line->numElements && doreplace) {
+ /* direct replacement */
free(line->elements[i].item);
line->elements[i].item = strdup(*arg);
- } else if (useRoot && !strncmp(*arg, "root=/dev/", 10) && *chptr) {
- rootLine = entry->lines;
- while (rootLine && rootLine->type != LT_ROOT)
- rootLine = rootLine->next;
- if (!rootLine) {
- rootLine = addLine(entry, cfg->cfi, LT_ROOT, NULL, NULL);
- rootLine->elements = realloc(rootLine->elements,
- 2 * sizeof(*rootLine->elements));
- rootLine->numElements++;
- rootLine->elements[1].indent = strdup("");
- rootLine->elements[1].item = strdup("");
- }
- free(rootLine->elements[1].item);
- rootLine->elements[1].item = strdup(chptr + 1);
- } else {
- /* append */
- line->elements = realloc(line->elements,
- (line->numElements + 1) * sizeof(*line->elements));
- line->elements[line->numElements].item = strdup(*arg);
- usedElements = realloc(usedElements,
- (line->numElements + 1) * sizeof(int));
- usedElements[line->numElements] = 1;
-
- if (line->numElements > 1) {
- /* add to existing list of arguments */
- line->elements[line->numElements].indent =
- line->elements[line->numElements - 1].indent;
- line->elements[line->numElements - 1].indent = strdup(" ");
+ } else if (useRoot && !strncmp(*arg, "root=/dev/", 10)) {
+ /* root= replacement */
+ rootLine = getLineByType(LT_ROOT, entry->lines);
+ if (rootLine) {
+ free(rootLine->elements[1].item);
+ rootLine->elements[1].item = strdup(*arg + 5);
} else {
- /* First thing on this line; treat a bit differently. Note
- this is only possible if we've added a LT_KERNELARGS
- entry */
- line->elements[line->numElements].indent = strdup("");
+ rootLine = addLine(entry, cfg->cfi, LT_ROOT,
+ cfg->secondaryIndent, *arg + 5);
}
+ }
- line->numElements++;
+ else {
+ /* insert/append */
+ insertElement(line, *arg, i);
+ usedElements = realloc(usedElements, line->numElements *
+ sizeof(*usedElements));
+ memmove(&usedElements[i + 1], &usedElements[i],
+ line->numElements - i - 1);
+ usedElements[i] = 1;
/* if we updated a root= here even though there is a
LT_ROOT available we need to remove the LT_ROOT entry
(this will happen if we switch from a device to a label) */
if (useRoot && !strncmp(*arg, "root=", 5)) {
- rootLine = entry->lines;
- while (rootLine && rootLine->type != LT_ROOT)
- rootLine = rootLine->next;
- if (rootLine) {
+ rootLine = getLineByType(LT_ROOT, entry->lines);
+ if (rootLine)
removeLine(entry, rootLine);
- }
}
}
- k++;
}
free(usedElements);
- /* no arguments to remove (i.e. no append line) */
- if (!line) continue;
-
- /* this won't remove an LT_ROOT item properly (but then again,
- who cares? */
for (arg = oldArgs; *arg; arg++) {
- for (i = firstElement; i < line->numElements; i++)
- if (!argMatch(line->elements[i].item, *arg))
+ for (i = firstElement; i < line->numElements; i++) {
+ if (multibootArgs && cfg->cfi->mbConcatArgs &&
+ !strcmp(line->elements[i].item, "--"))
+ /* reached the end of hyper args, stop here */
+ break;
+ if (!argMatch(line->elements[i].item, *arg)) {
+ removeElement(line, i);
break;
-
- if (i < line->numElements) {
- /* if this isn't the first argument the previous argument
- gets this arguments post-indention */
- if (i > firstElement) {
- free(line->elements[i - 1].indent);
- line->elements[i - 1].indent = line->elements[i].indent;
}
-
- free(line->elements[i].item);
-
- for (j = i + 1; j < line->numElements; j++)
- line->elements[j - 1] = line->elements[j];
-
- line->numElements--;
+ }
+ /* handle removing LT_ROOT line too */
+ if (useRoot && !strncmp(*arg, "root=", 5)) {
+ rootLine = getLineByType(LT_ROOT, entry->lines);
+ if (rootLine)
+ removeLine(entry, rootLine);
}
}
@@ -2318,54 +2343,6 @@
needs &= ~NEED_INITRD;
}
- strdup(tmplLine->elements[i].indent);
- }
-
- lastLine = tmplLine;
- if (tmplLine->type == LT_KERNEL && tmplLine->numElements >= 2) {
- char * repl;
- if (!template->multiboot) {
- needs &= ~KERNEL_KERNEL;
- repl = newKernelPath;
- } else {
- needs &= ~KERNEL_MB;
- repl = newMBKernel;
- }
- if (new->multiboot && !template->multiboot) {
- free(newLine->elements[0].item);
- newLine->elements[0].item = strdup("module");
- newLine->type = LT_MBMODULE;
- }
- free(newLine->elements[1].item);
- rootspec = getRootSpecifier(tmplLine->elements[1].item);
- if (rootspec != NULL) {
- newLine->elements[1].item = sdupprintf("%s%s",
- rootspec,
- repl +
- strlen(prefix));
- } else {
- newLine->elements[1].item = strdup(repl +
- strlen(prefix));
- }
- } else if (tmplLine->type == LT_MBMODULE &&
- tmplLine->numElements >= 2 && (needs & KERNEL_KERNEL)) {
- needs &= ~KERNEL_KERNEL;
- if (!new->multiboot && template->multiboot) {
- free(newLine->elements[0].item);
- newLine->elements[0].item = strdup("kernel");
- newLine->type = LT_KERNEL;
- }
- free(newLine->elements[1].item);
- rootspec = getRootSpecifier(tmplLine->elements[1].item);
- if (rootspec != NULL) {
- newLine->elements[1].item = sdupprintf("%s%s",
- rootspec,
- newKernelPath +
- strlen(prefix));
- } else {
- newLine->elements[1].item = strdup(newKernelPath +
- strlen(prefix));
- }
} else if (tmplLine->type == LT_INITRD &&
tmplLine->numElements >= 2 &&
(needs & NEED_INITRD)) {
More information about the Fedora-xen
mailing list