--- trunk/grubby/grubby.c 2017/06/27 14:14:00 3003 +++ trunk/grubby/grubby.c 2017/06/27 14:38:16 3019 @@ -132,6 +132,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 @@ -677,6 +681,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; @@ -1296,6 +1302,7 @@ cfg->theLines = NULL; cfg->entries = NULL; cfg->fallbackImage = 0; + cfg->isModified = 0; /* copy everything we have */ while (*head) { @@ -1615,7 +1622,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 +1635,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 +1645,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 +1673,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 +1690,7 @@ cfg->defaultImage = index; } } else { - cfg->defaultImage = 0; + cfg->defaultImage = FIRST_ENTRY_INDEX; } return cfg; @@ -1703,7 +1710,7 @@ 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); line = getLineByType(LT_MENUENTRY, entry->lines); @@ -1716,7 +1723,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, @@ -2420,7 +2427,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) @@ -2494,28 +2501,28 @@ entry->skip = 1; } -void setDefaultImage(struct grubConfig *config, int hasNew, - const char *defaultKernelPath, int newIsDefault, - const char *prefix, int flags, int index) +void setDefaultImage(struct grubConfig *config, int isUserSpecifiedKernelPath, + const char *defaultKernelPath, int newBootEntryIsDefault, + const char *prefix, int flags, int newDefaultBootEntryIndex) { struct singleEntry *entry, *entry2, *newDefault; int i, j; - if (newIsDefault) { - config->defaultImage = 0; + if (newBootEntryIsDefault) { + config->defaultImage = FIRST_ENTRY_INDEX; return; - } else if ((index >= 0) && config->cfi->defaultIsIndex) { - if (findEntryByIndex(config, index)) - config->defaultImage = index; + } else if ((newDefaultBootEntryIndex >= 0) && config->cfi->defaultIsIndex) { + if (findEntryByIndex(config, newDefaultBootEntryIndex)) + config->defaultImage = newDefaultBootEntryIndex; else - config->defaultImage = -1; + config->defaultImage = NO_DEFAULT_ENTRY; return; } else if (defaultKernelPath) { i = 0; if (findEntryByPath(config, defaultKernelPath, prefix, &i)) { config->defaultImage = i; } else { - config->defaultImage = -1; + config->defaultImage = NO_DEFAULT_ENTRY; return; } } @@ -2527,14 +2534,14 @@ /* default is set to saved, we don't want to change it */ return; - if (config->defaultImage > -1) + if (config->defaultImage >= FIRST_ENTRY_INDEX) entry = findEntryByIndex(config, config->defaultImage); else entry = NULL; if (entry && !entry->skip) { /* we can preserve the default */ - if (hasNew) + if (isUserSpecifiedKernelPath) config->defaultImage++; /* count the number of entries erased before this one */ @@ -2543,8 +2550,8 @@ if (entry2->skip) config->defaultImage--; } - } else if (hasNew) { - config->defaultImage = 0; + } else if (isUserSpecifiedKernelPath) { + config->defaultImage = FIRST_ENTRY_INDEX; } 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 @@ -2553,7 +2560,7 @@ findTemplate(config, prefix, &config->defaultImage, 1, flags); if (!newDefault) - config->defaultImage = -1; + config->defaultImage = NO_DEFAULT_ENTRY; } } @@ -4210,16 +4217,22 @@ const char *newKernelArgs, const char *newKernelInitrd, const char **extraInitrds, int extraInitrdCount, const char *newMBKernel, const char *newMBKernelArgs, - const char *newDevTreePath) + const char *newDevTreePath, int newIndex) { - struct singleEntry *new; + struct singleEntry *new, *entry, *prev = NULL; struct singleLine *newLine = NULL, *tmplLine = NULL, *masterLine = NULL; int needs; + char *indexs; char *chptr; + int rc; if (!newKernelPath) return 0; + rc = asprintf(&indexs, "%d", newIndex); + if (rc < 0) + return 1; + /* if the newKernelTitle is too long silently munge it into something * we can live with. truncating is first check, then we'll just mess with * it until it looks better */ @@ -4242,9 +4255,20 @@ new = malloc(sizeof(*new)); new->skip = 0; new->multiboot = 0; - new->next = config->entries; new->lines = NULL; - config->entries = new; + entry = config->entries; + for (unsigned int i = 0; i < newIndex; i++) { + if (!entry) + break; + prev = entry; + entry = entry->next; + } + new->next = entry; + + if (prev) + prev->next = new; + else + config->entries = new; /* copy/update from the template */ needs = NEED_KERNEL | NEED_TITLE; @@ -4707,9 +4731,11 @@ abort(); } - if (updateImage(config, "0", prefix, newKernelArgs, NULL, - newMBKernelArgs, NULL)) + if (updateImage(config, indexs, prefix, newKernelArgs, NULL, + newMBKernelArgs, NULL)) { + config->isModified = 1; return 1; + } return 0; } @@ -4737,6 +4763,7 @@ char *newDevTreePath = NULL; char *newMBKernel = NULL; char *newMBKernelArgs = NULL; + int newIndex = 0; char *removeMBKernelArgs = NULL; char *removeMBKernel = NULL; char *bootPrefix = NULL; @@ -4771,7 +4798,7 @@ NULL}, {"boot-filesystem", 0, POPT_ARG_STRING, &bootPrefix, 0, _ - ("filestystem which contains /boot directory (for testing only)"), + ("filesystem which contains /boot directory (for testing only)"), _("bootfs")}, #if defined(__i386__) || defined(__x86_64__) || defined (__powerpc64__) || defined (__ia64__) {"bootloader-probe", 0, POPT_ARG_NONE, &bootloaderProbe, 0, @@ -4843,6 +4870,9 @@ {"set-default-index", 0, POPT_ARG_INT, &defaultIndex, 0, _("make the given entry index the default entry"), _("entry-index")}, + {"set-index", 0, POPT_ARG_INT, &newIndex, 0, + _("use the given index when creating a new entry"), + _("entry-index")}, {"silo", 0, POPT_ARG_NONE, &configureSilo, 0, _("configure silo bootloader")}, {"title", 0, POPT_ARG_STRING, &newKernelTitle, 0, @@ -5157,11 +5187,11 @@ struct singleEntry *entry; char *rootspec; - 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; @@ -5184,11 +5214,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; @@ -5218,11 +5248,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; @@ -5258,7 +5288,8 @@ if (addNewKernel(config, template, bootPrefix, newKernelPath, newKernelTitle, newKernelArgs, newKernelInitrd, (const char **)extraInitrds, extraInitrdCount, - newMBKernel, newMBKernelArgs, newDevTreePath)) + newMBKernel, newMBKernelArgs, newDevTreePath, + newIndex)) return 1; if (numEntries(config) == 0) {