Magellan Linux

Diff of /tags/grubby-8_40_20170706/grubby.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3007 by niro, Tue Jun 27 14:28:28 2017 UTC revision 3021 by niro, Tue Jun 27 14:39:37 2017 UTC
# Line 132  struct singleEntry { Line 132  struct singleEntry {
132  #define NEED_DEVTREE (1 << 6)  #define NEED_DEVTREE (1 << 6)
133    
134  #define MAIN_DEFAULT    (1 << 0)  #define MAIN_DEFAULT    (1 << 0)
135    #define FIRST_ENTRY_INDEX    0 /* boot entry index value begin and increment
136       from this initial value */
137    #define NO_DEFAULT_ENTRY    -1 /* indicates that no specific default boot
138       entry was set or currently exists */
139  #define DEFAULT_SAVED       -2  #define DEFAULT_SAVED       -2
140  #define DEFAULT_SAVED_GRUB2 -3  #define DEFAULT_SAVED_GRUB2 -3
141    
# Line 677  struct grubConfig { Line 681  struct grubConfig {
681   int fallbackImage; /* just like defaultImage */   int fallbackImage; /* just like defaultImage */
682   int flags;   int flags;
683   struct configFileInfo *cfi;   struct configFileInfo *cfi;
684     int isModified; /* assumes only one entry added
685       per invocation of grubby */
686  };  };
687    
688  blkid_cache blkid;  blkid_cache blkid;
# Line 1296  static struct grubConfig *readConfig(con Line 1302  static struct grubConfig *readConfig(con
1302   cfg->theLines = NULL;   cfg->theLines = NULL;
1303   cfg->entries = NULL;   cfg->entries = NULL;
1304   cfg->fallbackImage = 0;   cfg->fallbackImage = 0;
1305     cfg->isModified = 0;
1306    
1307   /* copy everything we have */   /* copy everything we have */
1308   while (*head) {   while (*head) {
# Line 1615  static struct grubConfig *readConfig(con Line 1622  static struct grubConfig *readConfig(con
1622   *end == ' ' || *end == '\t'))   *end == ' ' || *end == '\t'))
1623   end++;   end++;
1624   if (*end)   if (*end)
1625   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1626   } else if (defaultLine->numElements == 3) {   } else if (defaultLine->numElements == 3) {
1627   char *value = defaultLine->elements[2].item;   char *value = defaultLine->elements[2].item;
1628   while (*value && (*value == '"' ||   while (*value && (*value == '"' ||
# Line 1628  static struct grubConfig *readConfig(con Line 1635  static struct grubConfig *readConfig(con
1635   *end == ' ' || *end == '\t'))   *end == ' ' || *end == '\t'))
1636   end++;   end++;
1637   if (*end)   if (*end)
1638   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1639   }   }
1640   } else if (cfi->defaultSupportSaved &&   } else if (cfi->defaultSupportSaved &&
1641     !strncmp(defaultLine->elements[1].item, "saved",     !strncmp(defaultLine->elements[1].item, "saved",
# Line 1638  static struct grubConfig *readConfig(con Line 1645  static struct grubConfig *readConfig(con
1645   cfg->defaultImage =   cfg->defaultImage =
1646      strtol(defaultLine->elements[1].item, &end, 10);      strtol(defaultLine->elements[1].item, &end, 10);
1647   if (*end)   if (*end)
1648   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1649   } else if (defaultLine->numElements >= 2) {   } else if (defaultLine->numElements >= 2) {
1650   int i = 0;   int i = 0;
1651   while ((entry = findEntryByIndex(cfg, i))) {   while ((entry = findEntryByIndex(cfg, i))) {
# Line 1666  static struct grubConfig *readConfig(con Line 1673  static struct grubConfig *readConfig(con
1673   if (entry) {   if (entry) {
1674   cfg->defaultImage = i;   cfg->defaultImage = i;
1675   } else {   } else {
1676   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1677   }   }
1678   }   }
1679   } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) {   } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) {
# Line 1683  static struct grubConfig *readConfig(con Line 1690  static struct grubConfig *readConfig(con
1690   cfg->defaultImage = index;   cfg->defaultImage = index;
1691   }   }
1692   } else {   } else {
1693   cfg->defaultImage = 0;   cfg->defaultImage = FIRST_ENTRY_INDEX;
1694   }   }
1695    
1696   return cfg;   return cfg;
# Line 1703  static void writeDefault(FILE * out, cha Line 1710  static void writeDefault(FILE * out, cha
1710   fprintf(out, "%sdefault%ssaved\n", indent, separator);   fprintf(out, "%sdefault%ssaved\n", indent, separator);
1711   else if (cfg->cfi->defaultIsSaved) {   else if (cfg->cfi->defaultIsSaved) {
1712   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);
1713   if (cfg->defaultImage >= 0 && cfg->cfi->setEnv) {   if (cfg->defaultImage >= FIRST_ENTRY_INDEX && cfg->cfi->setEnv) {
1714   char *title;   char *title;
1715   entry = findEntryByIndex(cfg, cfg->defaultImage);   entry = findEntryByIndex(cfg, cfg->defaultImage);
1716   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
# Line 1716  static void writeDefault(FILE * out, cha Line 1723  static void writeDefault(FILE * out, cha
1723   "saved_entry", title);   "saved_entry", title);
1724   }   }
1725   }   }
1726   } else if (cfg->defaultImage > -1) {   } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) {
1727   if (cfg->cfi->defaultIsIndex) {   if (cfg->cfi->defaultIsIndex) {
1728   if (cfg->cfi->defaultIsVariable) {   if (cfg->cfi->defaultIsVariable) {
1729   fprintf(out, "%sset default=\"%d\"\n", indent,   fprintf(out, "%sset default=\"%d\"\n", indent,
# Line 2420  struct singleEntry *findTemplate(struct Line 2427  struct singleEntry *findTemplate(struct
2427   }   }
2428   }   }
2429   }   }
2430   } else if (cfg->defaultImage > -1) {   } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) {
2431   entry = findEntryByIndex(cfg, cfg->defaultImage);   entry = findEntryByIndex(cfg, cfg->defaultImage);
2432   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2433   if (indexPtr)   if (indexPtr)
# Line 2494  void markRemovedImage(struct grubConfig Line 2501  void markRemovedImage(struct grubConfig
2501   entry->skip = 1;   entry->skip = 1;
2502  }  }
2503    
2504  void setDefaultImage(struct grubConfig *config, int hasNew,  void setDefaultImage(struct grubConfig *config, int isAddingBootEntry,
2505       const char *defaultKernelPath, int newIsDefault,       const char *defaultKernelPath, int newBootEntryIsDefault,
2506       const char *prefix, int flags, int index)       const char *prefix, int flags,
2507  {       int newDefaultBootEntryIndex, int newBootEntryIndex)
2508   struct singleEntry *entry, *entry2, *newDefault;  {
2509   int i, j;   struct singleEntry *bootEntry, *newDefault;
2510     int indexToVerify, firstKernelEntryIndex, currentLookupIndex;
2511   if (newIsDefault) {  
2512   config->defaultImage = 0;   /* handle the two cases where the user explictly picks the default
2513   return;   * boot entry index as it would exist post-modification */
2514   } else if ((index >= 0) && config->cfi->defaultIsIndex) {  
2515   if (findEntryByIndex(config, index))   /* Case 1: user chose to make the latest boot entry the default */
2516   config->defaultImage = index;   if (newBootEntryIsDefault) {
2517   else   config->defaultImage = newBootEntryIndex;
  config->defaultImage = -1;  
2518   return;   return;
2519   } else if (defaultKernelPath) {   }
2520   i = 0;  
2521   if (findEntryByPath(config, defaultKernelPath, prefix, &i)) {   /* Case 2: user picked an arbitrary index as the default boot entry */
2522   config->defaultImage = i;   if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX
2523   } else {      && config->cfi->defaultIsIndex) {
2524   config->defaultImage = -1;   indexToVerify = newDefaultBootEntryIndex;
2525    
2526     /* user chose to make latest boot entry the default */
2527     if (newDefaultBootEntryIndex == newBootEntryIndex) {
2528     config->defaultImage = newBootEntryIndex;
2529   return;   return;
2530   }   }
  }  
2531    
2532   /* defaultImage now points to what we'd like to use, but before any   /* the user picks the default index based on the
2533   * order changes */   * order of the bootloader configuration after
2534   if ((config->defaultImage == DEFAULT_SAVED) ||   * modification; ensure we are checking for the
2535      (config->defaultImage == DEFAULT_SAVED_GRUB2))   * existence of the correct entry */
2536   /* default is set to saved, we don't want to change it */   if (newBootEntryIndex < newDefaultBootEntryIndex) {
2537     if (!config->isModified)
2538     indexToVerify--;
2539     }
2540    
2541     /* verify the user selected index will exist */
2542     if (findEntryByIndex(config, indexToVerify)) {
2543     config->defaultImage = newDefaultBootEntryIndex;
2544     } else {
2545     config->defaultImage = NO_DEFAULT_ENTRY;
2546     }
2547    
2548   return;   return;
2549     }
2550    
2551   if (config->defaultImage > -1)   /* handle cases where the index value may shift */
  entry = findEntryByIndex(config, config->defaultImage);  
  else  
  entry = NULL;  
2552    
2553   if (entry && !entry->skip) {   /* check validity of existing default or first-entry-found
2554   /* we can preserve the default */     selection */
2555   if (hasNew)   if (defaultKernelPath) {
2556   config->defaultImage++;   /* user requested first-entry-found */
2557     if (!findEntryByPath(config, defaultKernelPath,
2558         prefix, &firstKernelEntryIndex)) {
2559     /* don't change default if can't find match */
2560     config->defaultImage = NO_DEFAULT_ENTRY;
2561     return;
2562     }
2563    
2564     config->defaultImage = firstKernelEntryIndex;
2565    
2566   /* count the number of entries erased before this one */   /* this is where we start looking for decrement later */
2567   for (j = 0; j < config->defaultImage; j++) {   currentLookupIndex = config->defaultImage;
2568   entry2 = findEntryByIndex(config, j);  
2569   if (entry2->skip)   if (isAddingBootEntry && !config->isModified &&
2570   config->defaultImage--;      (newBootEntryIndex < config->defaultImage)) {
2571     /* increment because new entry added before default */
2572     config->defaultImage++;
2573   }   }
  } else if (hasNew) {  
  config->defaultImage = 0;  
2574   } else {   } else {
2575   /* Either we just erased the default (or the default line was   /* use pre-existing default entry */
2576   * bad to begin with) and didn't put a new one in. We'll use   currentLookupIndex = config->defaultImage;
2577   * the first valid image. */  
2578     if (isAddingBootEntry
2579        && (newBootEntryIndex <= config->defaultImage)) {
2580     config->defaultImage++;
2581    
2582     if (config->isModified) {
2583     currentLookupIndex++;
2584     }
2585     }
2586     }
2587    
2588     /* sanity check - is this entry index valid? */
2589     bootEntry = findEntryByIndex(config, currentLookupIndex);
2590    
2591     if ((bootEntry && bootEntry->skip) || !bootEntry) {
2592     /* entry is to be skipped or is invalid */
2593     if (isAddingBootEntry) {
2594     config->defaultImage = newBootEntryIndex;
2595     return;
2596     }
2597   newDefault =   newDefault =
2598      findTemplate(config, prefix, &config->defaultImage, 1,      findTemplate(config, prefix, &config->defaultImage, 1,
2599   flags);   flags);
2600   if (!newDefault)   if (!newDefault) {
2601   config->defaultImage = -1;   config->defaultImage = NO_DEFAULT_ENTRY;
2602     }
2603    
2604     return;
2605     }
2606    
2607     currentLookupIndex--;
2608    
2609     /* decrement index by the total number of entries deleted */
2610    
2611     for (indexToVerify = currentLookupIndex;
2612         indexToVerify >= FIRST_ENTRY_INDEX; indexToVerify--) {
2613    
2614     bootEntry = findEntryByIndex(config, indexToVerify);
2615    
2616     if (bootEntry && bootEntry->skip) {
2617     config->defaultImage--;
2618     }
2619   }   }
2620  }  }
2621    
# Line 4215  int addNewKernel(struct grubConfig *conf Line 4277  int addNewKernel(struct grubConfig *conf
4277   struct singleEntry *new, *entry, *prev = NULL;   struct singleEntry *new, *entry, *prev = NULL;
4278   struct singleLine *newLine = NULL, *tmplLine = NULL, *masterLine = NULL;   struct singleLine *newLine = NULL, *tmplLine = NULL, *masterLine = NULL;
4279   int needs;   int needs;
4280     char *indexs;
4281   char *chptr;   char *chptr;
4282     int rc;
4283    
4284   if (!newKernelPath)   if (!newKernelPath)
4285   return 0;   return 0;
4286    
4287     rc = asprintf(&indexs, "%d", newIndex);
4288     if (rc < 0)
4289     return 1;
4290    
4291   /* if the newKernelTitle is too long silently munge it into something   /* if the newKernelTitle is too long silently munge it into something
4292   * we can live with. truncating is first check, then we'll just mess with   * we can live with. truncating is first check, then we'll just mess with
4293   * it until it looks better */   * it until it looks better */
# Line 4718  int addNewKernel(struct grubConfig *conf Line 4786  int addNewKernel(struct grubConfig *conf
4786   abort();   abort();
4787   }   }
4788    
4789   if (updateImage(config, "0", prefix, newKernelArgs, NULL,   if (updateImage(config, indexs, prefix, newKernelArgs, NULL,
4790   newMBKernelArgs, NULL))   newMBKernelArgs, NULL)) {
4791     config->isModified = 1;
4792   return 1;   return 1;
4793     }
4794    
4795   return 0;   return 0;
4796  }  }
# Line 4783  int main(int argc, const char **argv) Line 4853  int main(int argc, const char **argv)
4853   NULL},   NULL},
4854   {"boot-filesystem", 0, POPT_ARG_STRING, &bootPrefix, 0,   {"boot-filesystem", 0, POPT_ARG_STRING, &bootPrefix, 0,
4855   _   _
4856   ("filestystem which contains /boot directory (for testing only)"),   ("filesystem which contains /boot directory (for testing only)"),
4857   _("bootfs")},   _("bootfs")},
4858  #if defined(__i386__) || defined(__x86_64__) || defined (__powerpc64__) || defined (__ia64__)  #if defined(__i386__) || defined(__x86_64__) || defined (__powerpc64__) || defined (__ia64__)
4859   {"bootloader-probe", 0, POPT_ARG_NONE, &bootloaderProbe, 0,   {"bootloader-probe", 0, POPT_ARG_NONE, &bootloaderProbe, 0,
# Line 5172  int main(int argc, const char **argv) Line 5242  int main(int argc, const char **argv)
5242   struct singleEntry *entry;   struct singleEntry *entry;
5243   char *rootspec;   char *rootspec;
5244    
5245   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5246   return 0;   return 0;
5247   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5248      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5249   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5250   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
5251   if (!entry)   if (!entry)
5252   return 0;   return 0;
# Line 5199  int main(int argc, const char **argv) Line 5269  int main(int argc, const char **argv)
5269   struct singleLine *line;   struct singleLine *line;
5270   struct singleEntry *entry;   struct singleEntry *entry;
5271    
5272   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5273   return 0;   return 0;
5274   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5275      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5276   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5277   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
5278   if (!entry)   if (!entry)
5279   return 0;   return 0;
# Line 5233  int main(int argc, const char **argv) Line 5303  int main(int argc, const char **argv)
5303   return 0;   return 0;
5304    
5305   } else if (displayDefaultIndex) {   } else if (displayDefaultIndex) {
5306   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5307   return 0;   return 0;
5308   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5309      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5310   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5311   printf("%i\n", config->defaultImage);   printf("%i\n", config->defaultImage);
5312   return 0;   return 0;
5313    
# Line 5253  int main(int argc, const char **argv) Line 5323  int main(int argc, const char **argv)
5323   markRemovedImage(config, removeKernelPath, bootPrefix);   markRemovedImage(config, removeKernelPath, bootPrefix);
5324   markRemovedImage(config, removeMBKernel, bootPrefix);   markRemovedImage(config, removeMBKernel, bootPrefix);
5325   setDefaultImage(config, newKernelPath != NULL, defaultKernel,   setDefaultImage(config, newKernelPath != NULL, defaultKernel,
5326   makeDefault, bootPrefix, flags, defaultIndex);   makeDefault, bootPrefix, flags, defaultIndex,
5327     newIndex);
5328   setFallbackImage(config, newKernelPath != NULL);   setFallbackImage(config, newKernelPath != NULL);
5329   if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,   if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
5330   removeArgs, newMBKernelArgs, removeMBKernelArgs))   removeArgs, newMBKernelArgs, removeMBKernelArgs))

Legend:
Removed from v.3007  
changed lines
  Added in v.3021