--- trunk/grubby/grubby.c 2017/06/27 14:34:11 3014 +++ trunk/grubby/grubby.c 2020/07/07 11:23:41 3149 @@ -68,6 +68,8 @@ char *saved_command_line = NULL; +const char *mounts = "/proc/mounts"; + /* comments get lumped in with indention */ struct lineElement { char *item; @@ -132,6 +134,10 @@ #define NEED_DEVTREE (1 << 6) #define MAIN_DEFAULT (1 << 0) +#define FIRST_ENTRY_INDEX 0 /* boot entry index value begin and increment + from this initial value */ +#define NO_DEFAULT_ENTRY -1 /* indicates that no specific default boot + entry was set or currently exists */ #define DEFAULT_SAVED -2 #define DEFAULT_SAVED_GRUB2 -3 @@ -476,20 +482,28 @@ snprintf(result, resultMaxSize, "%s", ++current); i++; + int result_len = 0; for (; i < line->numElements; ++i) { current = line->elements[i].item; current_len = strlen(current); current_indent = line->elements[i].indent; current_indent_len = strlen(current_indent); - strncat(result, current_indent, current_indent_len); + memcpy(result + result_len, current_indent, current_indent_len); + result_len += current_indent_len; + if (current[current_len - 1] != quote_char) { - strncat(result, current, current_len); + memcpy(result + result_len, current_indent, + current_indent_len); + result_len += current_len; } else { - strncat(result, current, current_len - 1); + memcpy(result + result_len, current_indent, + current_indent_len); + result_len += (current_len - 1); break; } } + result[result_len] = '\0'; return result; } @@ -677,6 +691,8 @@ int fallbackImage; /* just like defaultImage */ int flags; struct configFileInfo *cfi; + int isModified; /* assumes only one entry added + per invocation of grubby */ }; blkid_cache blkid; @@ -695,7 +711,7 @@ struct configFileInfo *cfi); static int getNextLine(char **bufPtr, struct singleLine *line, struct configFileInfo *cfi); -static char *getRootSpecifier(char *str); +static size_t getRootSpecifier(const char *str); static void requote(struct singleLine *line, struct configFileInfo *cfi); static void insertElement(struct singleLine *line, const char *item, int insertHere, @@ -1296,6 +1312,7 @@ cfg->theLines = NULL; cfg->entries = NULL; cfg->fallbackImage = 0; + cfg->isModified = 0; /* copy everything we have */ while (*head) { @@ -1431,6 +1448,7 @@ extras = malloc(len + 1); *extras = '\0'; + int buf_len = 0; /* get title. */ for (int i = 0; i < line->numElements; i++) { if (!strcmp @@ -1447,13 +1465,18 @@ len = strlen(title); if (title[len - 1] == quote_char) { - strncat(buf, title, len - 1); + memcpy(buf + buf_len, title, len - 1); + buf_len += (len - 1); break; } else { - strcat(buf, title); - strcat(buf, line->elements[i].indent); + memcpy(buf + buf_len, title, len); + buf_len += len; + len = strlen(line->elements[i].indent); + memcpy(buf + buf_len, line->elements[i].indent, len); + buf_len += len; } } + buf[buf_len] = '\0'; /* get extras */ int count = 0; @@ -1615,7 +1638,7 @@ *end == ' ' || *end == '\t')) end++; if (*end) - cfg->defaultImage = -1; + cfg->defaultImage = NO_DEFAULT_ENTRY; } else if (defaultLine->numElements == 3) { char *value = defaultLine->elements[2].item; while (*value && (*value == '"' || @@ -1628,7 +1651,7 @@ *end == ' ' || *end == '\t')) end++; if (*end) - cfg->defaultImage = -1; + cfg->defaultImage = NO_DEFAULT_ENTRY; } } else if (cfi->defaultSupportSaved && !strncmp(defaultLine->elements[1].item, "saved", @@ -1638,7 +1661,7 @@ cfg->defaultImage = strtol(defaultLine->elements[1].item, &end, 10); if (*end) - cfg->defaultImage = -1; + cfg->defaultImage = NO_DEFAULT_ENTRY; } else if (defaultLine->numElements >= 2) { int i = 0; while ((entry = findEntryByIndex(cfg, i))) { @@ -1666,7 +1689,7 @@ if (entry) { cfg->defaultImage = i; } else { - cfg->defaultImage = -1; + cfg->defaultImage = NO_DEFAULT_ENTRY; } } } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) { @@ -1683,7 +1706,7 @@ cfg->defaultImage = index; } } else { - cfg->defaultImage = 0; + cfg->defaultImage = FIRST_ENTRY_INDEX; } return cfg; @@ -1703,9 +1726,22 @@ fprintf(out, "%sdefault%ssaved\n", indent, separator); else if (cfg->cfi->defaultIsSaved) { fprintf(out, "%sset default=\"${saved_entry}\"\n", indent); - if (cfg->defaultImage >= 0 && cfg->cfi->setEnv) { + if (cfg->defaultImage >= FIRST_ENTRY_INDEX && cfg->cfi->setEnv) { char *title; - entry = findEntryByIndex(cfg, cfg->defaultImage); + int trueIndex, currentIndex; + + trueIndex = 0; + currentIndex = 0; + + while ((entry = findEntryByIndex(cfg, currentIndex))) { + if (!entry->skip) { + if (trueIndex == cfg->defaultImage) { + break; + } + trueIndex++; + } + currentIndex++; + } line = getLineByType(LT_MENUENTRY, entry->lines); if (!line) line = getLineByType(LT_TITLE, entry->lines); @@ -1716,7 +1752,7 @@ "saved_entry", title); } } - } else if (cfg->defaultImage > -1) { + } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) { if (cfg->cfi->defaultIsIndex) { if (cfg->cfi->defaultIsVariable) { fprintf(out, "%sset default=\"%d\"\n", indent, @@ -1772,6 +1808,7 @@ int needs = MAIN_DEFAULT; struct stat sb; int i; + int rc = 0; if (!strcmp(outName, "-")) { out = stdout; @@ -1886,16 +1923,42 @@ } if (tmpOutName) { - if (rename(tmpOutName, outName)) { - fprintf(stderr, - _("grubby: error moving %s to %s: %s\n"), - tmpOutName, outName, strerror(errno)); - unlink(outName); - return 1; + /* write userspace buffers */ + if (fflush(out)) + rc = 1; + + /* purge the write-back cache with fsync() */ + if (fsync(fileno(out))) + rc = 1; + + if (fclose(out)) + rc = 1; + + if (rc == 0 && rename(tmpOutName, outName)) { + unlink(tmpOutName); + rc = 1; + } + + /* fsync() the destination directory after rename */ + if (rc == 0) { + int dirfd; + + dirfd = open(dirname(strdupa(outName)), O_RDONLY); + if (dirfd < 0) + rc = 1; + else if (fsync(dirfd)) + rc = 1; + + if (dirfd >= 0) + close(dirfd); } + + if (rc == 1) + fprintf(stderr, + _("grubby: error flushing data: %m\n")); } - return 0; + return rc; } static int numEntries(struct grubConfig *cfg) @@ -2071,6 +2134,129 @@ return s[slen] == c; } +typedef struct { + const char *start; + size_t chars; +} field; + +static int iscomma(int c) +{ + return c == ','; +} + +static int isequal(int c) +{ + return c == '='; +} + +static field findField(const field *in, typeof(isspace) *isdelim, field *out) +{ + field nxt = {}; + size_t off = 0; + + while (off < in->chars && isdelim(in->start[off])) + off++; + + if (off == in->chars) + return nxt; + + out->start = &in->start[off]; + out->chars = 0; + + while (off + out->chars < in->chars && !isdelim(out->start[out->chars])) + out->chars++; + + nxt.start = out->start + out->chars; + nxt.chars = in->chars - off - out->chars; + return nxt; +} + +static int fieldEquals(const field *in, const char *str) +{ + return in->chars == strlen(str) && + strncmp(in->start, str, in->chars) == 0; +} + +/* Parse /proc/mounts to determine the subvolume prefix. */ +static size_t subvolPrefix(const char *str) +{ + FILE *file = NULL; + char *line = NULL; + size_t prfx = 0; + size_t size = 0; + + file = fopen(mounts, "r"); + if (!file) + return 0; + + for (ssize_t s; (s = getline(&line, &size, file)) >= 0; ) { + field nxt = { line, s }; + field dev = {}; + field path = {}; + field type = {}; + field opts = {}; + field opt = {}; + + nxt = findField(&nxt, isspace, &dev); + if (!nxt.start) + continue; + + nxt = findField(&nxt, isspace, &path); + if (!nxt.start) + continue; + + nxt = findField(&nxt, isspace, &type); + if (!nxt.start) + continue; + + nxt = findField(&nxt, isspace, &opts); + if (!nxt.start) + continue; + + if (!fieldEquals(&type, "btrfs")) + continue; + + /* We have found a btrfs mount point. */ + + nxt = opts; + while ((nxt = findField(&nxt, iscomma, &opt)).start) { + field key = {}; + field val = {}; + + opt = findField(&opt, isequal, &key); + if (!opt.start) + continue; + + opt = findField(&opt, isequal, &val); + if (!opt.start) + continue; + + if (!fieldEquals(&key, "subvol")) + continue; + + /* We have found a btrfs subvolume mount point. */ + + if (strncmp(val.start, str, val.chars)) + continue; + + if (val.start[val.chars - 1] != '/' && + str[val.chars] != '/') + continue; + + /* The subvolume mount point matches our input. */ + + if (prfx < val.chars) + prfx = val.chars; + } + } + + dbgPrintf("%s(): str: '%s', prfx: '%s'\n", __FUNCTION__, str, prfx); + + fclose(file); + free(line); + return prfx; +} + int suitableImage(struct singleEntry *entry, const char *bootPrefix, int skipRemoved, int flags) { @@ -2078,7 +2264,7 @@ char *fullName; int i; char *dev; - char *rootspec; + size_t rs; char *rootdev; if (skipRemoved && entry->skip) { @@ -2106,12 +2292,11 @@ fullName = alloca(strlen(bootPrefix) + strlen(line->elements[1].item) + 1); - rootspec = getRootSpecifier(line->elements[1].item); - int rootspec_offset = rootspec ? strlen(rootspec) : 0; + rs = getRootSpecifier(line->elements[1].item); int hasslash = endswith(bootPrefix, '/') || - beginswith(line->elements[1].item + rootspec_offset, '/'); + beginswith(line->elements[1].item + rs, '/'); sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/", - line->elements[1].item + rootspec_offset); + line->elements[1].item + rs); if (access(fullName, R_OK)) { notSuitablePrintf(entry, 0, "access to %s failed\n", fullName); return 0; @@ -2203,7 +2388,6 @@ struct singleLine *line; int i; char *chptr; - char *rootspec = NULL; enum lineType_e checkType = LT_KERNEL; if (isdigit(*kernel)) { @@ -2308,14 +2492,10 @@ if (line && line->type != LT_MENUENTRY && line->numElements >= 2) { - rootspec = - getRootSpecifier(line->elements[1]. - item); - if (!strcmp - (line->elements[1].item + - ((rootspec != - NULL) ? strlen(rootspec) : 0), - kernel + strlen(prefix))) + if (!strcmp(line->elements[1].item + + getRootSpecifier( + line->elements[1].item), + kernel + strlen(prefix))) break; } if (line->type == LT_MENUENTRY && @@ -2420,7 +2600,7 @@ } } } - } else if (cfg->defaultImage > -1) { + } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) { entry = findEntryByIndex(cfg, cfg->defaultImage); if (entry && suitableImage(entry, prefix, skipRemoved, flags)) { if (indexPtr) @@ -2432,8 +2612,11 @@ index = 0; while ((entry = findEntryByIndex(cfg, index))) { if (suitableImage(entry, prefix, skipRemoved, flags)) { - int j; - for (j = 0; j < index; j++) { + int j, unmodifiedIndex; + + unmodifiedIndex = index; + + for (j = 0; j < unmodifiedIndex; j++) { entry2 = findEntryByIndex(cfg, j); if (entry2->skip) index--; @@ -2494,66 +2677,147 @@ entry->skip = 1; } -void setDefaultImage(struct grubConfig *config, int hasNew, - const char *defaultKernelPath, int newIsDefault, - const char *prefix, int flags, int index) -{ - struct singleEntry *entry, *entry2, *newDefault; - int i, j; - - if (newIsDefault) { - config->defaultImage = 0; +void setDefaultImage(struct grubConfig *config, int isAddingBootEntry, + const char *defaultKernelPath, int newBootEntryIsDefault, + const char *prefix, int flags, + int newDefaultBootEntryIndex, int newBootEntryIndex) +{ + struct singleEntry *bootEntry, *newDefault; + int indexToVerify, firstKernelEntryIndex, currentLookupIndex; + + /* initialize */ + currentLookupIndex = FIRST_ENTRY_INDEX; + + /* handle the two cases where the user explictly picks the default + * boot entry index as it would exist post-modification */ + + /* Case 1: user chose to make the latest boot entry the default */ + if (newBootEntryIsDefault) { + config->defaultImage = newBootEntryIndex; return; - } else if ((index >= 0) && config->cfi->defaultIsIndex) { - if (findEntryByIndex(config, index)) - config->defaultImage = index; - else - config->defaultImage = -1; - return; - } else if (defaultKernelPath) { - i = 0; - if (findEntryByPath(config, defaultKernelPath, prefix, &i)) { - config->defaultImage = i; - } else { - config->defaultImage = -1; + } + + /* Case 2: user picked an arbitrary index as the default boot entry */ + if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX) { + indexToVerify = newDefaultBootEntryIndex; + + /* user chose to make latest boot entry the default */ + if (newDefaultBootEntryIndex == newBootEntryIndex) { + config->defaultImage = newBootEntryIndex; return; } - } - /* defaultImage now points to what we'd like to use, but before any - * order changes */ - if ((config->defaultImage == DEFAULT_SAVED) || - (config->defaultImage == DEFAULT_SAVED_GRUB2)) - /* default is set to saved, we don't want to change it */ + /* the user picks the default index based on the + * order of the bootloader configuration after + * modification; ensure we are checking for the + * existence of the correct entry */ + if (newBootEntryIndex < newDefaultBootEntryIndex) { + if (!config->isModified) + indexToVerify--; + } + + /* verify the user selected index will exist */ + if (findEntryByIndex(config, indexToVerify)) { + config->defaultImage = newDefaultBootEntryIndex; + } else { + config->defaultImage = NO_DEFAULT_ENTRY; + } + return; + } - if (config->defaultImage > -1) - entry = findEntryByIndex(config, config->defaultImage); - else - entry = NULL; + /* handle cases where the index value may shift */ - if (entry && !entry->skip) { - /* we can preserve the default */ - if (hasNew) - config->defaultImage++; + /* check validity of existing default or first-entry-found + selection */ + if (defaultKernelPath) { + /* we must initialize this */ + firstKernelEntryIndex = 0; + /* user requested first-entry-found */ + if (!findEntryByPath(config, defaultKernelPath, + prefix, &firstKernelEntryIndex)) { + /* don't change default if can't find match */ + config->defaultImage = NO_DEFAULT_ENTRY; + return; + } - /* count the number of entries erased before this one */ - for (j = 0; j < config->defaultImage; j++) { - entry2 = findEntryByIndex(config, j); - if (entry2->skip) - config->defaultImage--; + config->defaultImage = firstKernelEntryIndex; + + /* this is where we start looking for decrement later */ + currentLookupIndex = config->defaultImage; + + if (isAddingBootEntry && !config->isModified && + (newBootEntryIndex < config->defaultImage)) { + /* increment because new entry added before default */ + config->defaultImage++; } - } else if (hasNew) { - config->defaultImage = 0; } else { - /* Either we just erased the default (or the default line was - * bad to begin with) and didn't put a new one in. We'll use - * the first valid image. */ + /* check to see if the default is stored in the environment */ + if (config->defaultImage < FIRST_ENTRY_INDEX) { + if (config->defaultImage == DEFAULT_SAVED || config->defaultImage == DEFAULT_SAVED_GRUB2) + { + if (config->cfi->defaultIsSaved) { + if (config->cfi->getEnv) { + char *defaultTitle = config->cfi->getEnv(config->cfi, "saved_entry"); + + if (defaultTitle) { + if (isnumber(defaultTitle)) { + currentLookupIndex = atoi(defaultTitle); + } else { + findEntryByTitle(config, defaultTitle, ¤tLookupIndex); + } + /* set the default Image to an actual index */ + config->defaultImage = currentLookupIndex; + } + } + } + } + } else { + /* use pre-existing default entry from the file*/ + currentLookupIndex = config->defaultImage; + } + + if (isAddingBootEntry + && (newBootEntryIndex <= config->defaultImage)) { + config->defaultImage++; + + if (config->isModified) { + currentLookupIndex++; + } + } + } + + /* sanity check - is this entry index valid? */ + bootEntry = findEntryByIndex(config, currentLookupIndex); + + if ((bootEntry && bootEntry->skip) || !bootEntry) { + /* entry is to be skipped or is invalid */ + if (isAddingBootEntry) { + config->defaultImage = newBootEntryIndex; + return; + } newDefault = findTemplate(config, prefix, &config->defaultImage, 1, flags); - if (!newDefault) - config->defaultImage = -1; + if (!newDefault) { + config->defaultImage = NO_DEFAULT_ENTRY; + } + + return; + } + + currentLookupIndex--; + + /* decrement index by the total number of entries deleted */ + + for (indexToVerify = currentLookupIndex; + indexToVerify >= FIRST_ENTRY_INDEX; indexToVerify--) { + + bootEntry = findEntryByIndex(config, indexToVerify); + + if (bootEntry && bootEntry->skip) { + config->defaultImage--; + } } } @@ -2582,7 +2846,7 @@ } } -void displayEntry(struct singleEntry *entry, const char *prefix, int index) +void displayEntry(struct grubConfig *config, struct singleEntry *entry, const char *prefix, int index) { struct singleLine *line; char *root = NULL; @@ -2678,7 +2942,14 @@ line = getLineByType(LT_TITLE, entry->lines); if (line) { - printf("title=%s\n", line->elements[1].item); + char *entryTitle; + /* if we can extractTitle, then it's a zipl config and + * if not then we go ahead with what's existed prior */ + entryTitle = extractTitle(config, line); + if (!entryTitle) { + entryTitle=line->elements[1].item; + } + printf("title=%s\n", entryTitle); } else { char *title; line = getLineByType(LT_MENUENTRY, entry->lines); @@ -3094,11 +3365,11 @@ printf("lba\n"); } - displayEntry(entry, prefix, i); + displayEntry(config, entry, prefix, i); i++; while ((entry = findEntryByPath(config, kernel, prefix, &i))) { - displayEntry(entry, prefix, i); + displayEntry(config, entry, prefix, i); i++; } @@ -3133,12 +3404,22 @@ type & (LT_HYPER | LT_KERNEL | LT_MBMODULE | LT_INITRD | LT_KERNEL_EFI | LT_INITRD_EFI | LT_KERNEL_16 | LT_INITRD_16)) { - char *rootspec = - getRootSpecifier(tmplLine->elements[1].item); - if (rootspec != NULL) { + const char *prfx = tmplLine->elements[1].item; + size_t rs = getRootSpecifier(prfx); + if (isinitrd(tmplLine->type)) { + for (struct singleLine *l = entry->lines; + rs == 0 && l; l = l->next) { + if (iskernel(l->type)) { + prfx = l->elements[1].item; + rs = getRootSpecifier(prfx); + break; + } + } + } + if (rs > 0) { free(newLine->elements[1].item); - newLine->elements[1].item = - sdupprintf("%s%s", rootspec, val); + newLine->elements[1].item = sdupprintf( + "%.*s%s", (int) rs, prfx, val); } } } @@ -3428,23 +3709,67 @@ line->numElements--; } -int argMatch(const char *one, const char *two) +static int argNameMatch(const char *one, const char *two) { char *first, *second; - char *chptr; + char *chptra, *chptrb; + int rc; first = strcpy(alloca(strlen(one) + 1), one); second = strcpy(alloca(strlen(two) + 1), two); - chptr = strchr(first, '='); - if (chptr) - *chptr = '\0'; + chptra = strchr(first, '='); + if (chptra) + *chptra = '\0'; + + chptrb = strchr(second, '='); + if (chptrb) + *chptrb = '\0'; + + rc = strcmp(first, second); + + if (chptra) + *chptra = '='; + if (chptrb) + *chptrb = '='; + + return rc; +} + +static int argHasValue(const char *arg) +{ + char *chptr; - chptr = strchr(second, '='); + chptr = strchr(arg, '='); if (chptr) - *chptr = '\0'; + return 1; + return 0; +} + +static int argValueMatch(const char *one, const char *two) +{ + char *first, *second; + char *chptra, *chptrb; + + first = strcpy(alloca(strlen(one) + 1), one); + second = strcpy(alloca(strlen(two) + 1), two); + + chptra = strchr(first, '='); + if (chptra) + chptra += 1; + + chptrb = strchr(second, '='); + if (chptrb) + chptrb += 1; - return strcmp(first, second); + if (!chptra && !chptrb) + return 0; + else if (!chptra) + return *chptrb - 0; + else if (!chptrb) + return 0 - *chptra; + else + return strcmp(chptra, chptrb); } int updateActualImage(struct grubConfig *cfg, const char *image, @@ -3588,7 +3913,7 @@ } if (usedElements[i]) continue; - if (!argMatch(line->elements[i].item, *arg)) { + if (!argNameMatch(line->elements[i].item, *arg)) { usedElements[i] = 1; break; } @@ -3647,9 +3972,12 @@ !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 (!argNameMatch(line->elements[i].item, *arg)) { + if (!argHasValue(*arg) || + !argValueMatch(line->elements[i].item, *arg)) { + removeElement(line, i); + break; + } } } /* handle removing LT_ROOT line too */ @@ -4143,17 +4471,19 @@ return 1; } -static char *getRootSpecifier(char *str) +static size_t getRootSpecifier(const char *str) { - char *idx, *rootspec = NULL; + size_t rs = 0; if (*str == '(') { - idx = rootspec = strdup(str); - while (*idx && (*idx != ')') && (!isspace(*idx))) - idx++; - *(++idx) = '\0'; + for (; str[rs] != ')' && !isspace(str[rs]); rs++) { + if (!str[rs]) + return rs; + } + rs++; } - return rootspec; + + return rs + subvolPrefix(str + rs); } static char *getInitrdVal(struct grubConfig *config, @@ -4725,8 +5055,10 @@ } if (updateImage(config, indexs, prefix, newKernelArgs, NULL, - newMBKernelArgs, NULL)) + newMBKernelArgs, NULL)) { + config->isModified = 1; return 1; + } return 0; } @@ -4783,6 +5115,9 @@ {"mbargs", 0, POPT_ARG_STRING, &newMBKernelArgs, 0, _("default arguments for the new multiboot kernel or " "new arguments for multiboot kernel being updated"), NULL}, + {"mounts", 0, POPT_ARG_STRING, &mounts, 0, + _("path to fake /proc/mounts file (for testing only)"), + _("mounts")}, {"bad-image-okay", 0, 0, &badImageOkay, 0, _ ("don't sanity check images in boot entries (for testing only)"), @@ -4891,10 +5226,18 @@ exit(1); } saved_command_line[0] = '\0'; + int cmdline_len = 0, arg_len; for (int j = 1; j < argc; j++) { - strcat(saved_command_line, argv[j]); - strncat(saved_command_line, j == argc - 1 ? "" : " ", 1); + arg_len = strlen(argv[j]); + memcpy(saved_command_line + cmdline_len, argv[j], arg_len); + cmdline_len += arg_len; + if (j != argc - 1) { + memcpy(saved_command_line + cmdline_len, " ", 1); + cmdline_len++; + } + } + saved_command_line[cmdline_len] = '\0'; optCon = poptGetContext("grubby", argc, argv, options, 0); poptReadDefaultConfig(optCon, 1); @@ -4967,22 +5310,27 @@ if (!cfi) { if (grub2FindConfig(&grub2ConfigType)) { cfi = &grub2ConfigType; + configureGrub2 = 1; if (envPath) cfi->envFile = envPath; - } else + } else { #ifdef __ia64__ cfi = &eliloConfigType; -#elif __powerpc__ + configureLilo = 1; +#elif defined(__powerpc__) cfi = &yabootConfigType; -#elif __sparc__ + configureYaboot = 1; +#elif defined(__sparc__) cfi = &siloConfigType; -#elif __s390__ + configureSilo = 1; +#elif defined(__s390__) || defined(__s390x__) cfi = &ziplConfigType; -#elif __s390x__ - cfi = &ziplConfigtype; + configureZipl = 1; #else cfi = &grubConfigType; + configureGrub = 1; #endif + } } if (!grubConfig) { @@ -5176,13 +5524,13 @@ if (displayDefault) { struct singleLine *line; struct singleEntry *entry; - char *rootspec; + size_t rs; - if (config->defaultImage == -1) + if (config->defaultImage == NO_DEFAULT_ENTRY) return 0; if (config->defaultImage == DEFAULT_SAVED_GRUB2 && cfi->defaultIsSaved) - config->defaultImage = 0; + config->defaultImage = FIRST_ENTRY_INDEX; entry = findEntryByIndex(config, config->defaultImage); if (!entry) return 0; @@ -5195,9 +5543,8 @@ if (!line) return 0; - rootspec = getRootSpecifier(line->elements[1].item); - printf("%s%s\n", bootPrefix, line->elements[1].item + - ((rootspec != NULL) ? strlen(rootspec) : 0)); + rs = getRootSpecifier(line->elements[1].item); + printf("%s%s\n", bootPrefix, line->elements[1].item + rs); return 0; @@ -5205,11 +5552,11 @@ struct singleLine *line; struct singleEntry *entry; - if (config->defaultImage == -1) + if (config->defaultImage == NO_DEFAULT_ENTRY) return 0; if (config->defaultImage == DEFAULT_SAVED_GRUB2 && cfi->defaultIsSaved) - config->defaultImage = 0; + config->defaultImage = FIRST_ENTRY_INDEX; entry = findEntryByIndex(config, config->defaultImage); if (!entry) return 0; @@ -5239,11 +5586,11 @@ return 0; } else if (displayDefaultIndex) { - if (config->defaultImage == -1) + if (config->defaultImage == NO_DEFAULT_ENTRY) return 0; if (config->defaultImage == DEFAULT_SAVED_GRUB2 && cfi->defaultIsSaved) - config->defaultImage = 0; + config->defaultImage = FIRST_ENTRY_INDEX; printf("%i\n", config->defaultImage); return 0; @@ -5259,7 +5606,8 @@ markRemovedImage(config, removeKernelPath, bootPrefix); markRemovedImage(config, removeMBKernel, bootPrefix); setDefaultImage(config, newKernelPath != NULL, defaultKernel, - makeDefault, bootPrefix, flags, defaultIndex); + makeDefault, bootPrefix, flags, defaultIndex, + newIndex); setFallbackImage(config, newKernelPath != NULL); if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs, removeArgs, newMBKernelArgs, removeMBKernelArgs))