Magellan Linux

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

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

revision 2258 by niro, Mon Oct 21 14:02:25 2013 UTC revision 2972 by niro, Thu Jun 30 10:17:00 2016 UTC
# Line 60  int debug = 0; /* Currently just for tem Line 60  int debug = 0; /* Currently just for tem
60    
61  int isEfi = 0;  int isEfi = 0;
62    
63    #if defined(__aarch64__)
64    #define isEfiOnly 1
65    #else
66    #define isEfiOnly 0
67    #endif
68    
69  char *saved_command_line = NULL;  char *saved_command_line = NULL;
70    
71  /* comments get lumped in with indention */  /* comments get lumped in with indention */
# Line 90  enum lineType_e { Line 96  enum lineType_e {
96      LT_SET_VARIABLE = 1 << 19,      LT_SET_VARIABLE = 1 << 19,
97      LT_KERNEL_EFI   = 1 << 20,      LT_KERNEL_EFI   = 1 << 20,
98      LT_INITRD_EFI   = 1 << 21,      LT_INITRD_EFI   = 1 << 21,
99      LT_UNKNOWN      = 1 << 22,      LT_KERNEL_16    = 1 << 22,
100        LT_INITRD_16    = 1 << 23,
101        LT_DEVTREE      = 1 << 24,
102        LT_UNKNOWN      = 1 << 25,
103  };  };
104    
105  struct singleLine {  struct singleLine {
# Line 119  struct singleEntry { Line 128  struct singleEntry {
128  #define NEED_ARGS    (1 << 3)  #define NEED_ARGS    (1 << 3)
129  #define NEED_MB      (1 << 4)  #define NEED_MB      (1 << 4)
130  #define NEED_END     (1 << 5)  #define NEED_END     (1 << 5)
131    #define NEED_DEVTREE (1 << 6)
132    
133  #define MAIN_DEFAULT    (1 << 0)  #define MAIN_DEFAULT    (1 << 0)
134  #define DEFAULT_SAVED       -2  #define DEFAULT_SAVED       -2
# Line 151  struct configFileInfo { Line 161  struct configFileInfo {
161      int defaultIsVariable;      int defaultIsVariable;
162      int defaultSupportSaved;      int defaultSupportSaved;
163      int defaultIsSaved;      int defaultIsSaved;
164        int defaultIsUnquoted;
165      enum lineType_e entryStart;      enum lineType_e entryStart;
166      enum lineType_e entryEnd;      enum lineType_e entryEnd;
167      int needsBootPrefix;      int needsBootPrefix;
# Line 182  const char *grubFindConfig(struct config Line 193  const char *grubFindConfig(struct config
193   "/boot/grub/grub.conf",   "/boot/grub/grub.conf",
194   "/boot/grub/menu.lst",   "/boot/grub/menu.lst",
195   "/etc/grub.conf",   "/etc/grub.conf",
196     "/boot/grub2/grub.cfg",
197     "/boot/grub2-efi/grub.cfg",
198   NULL   NULL
199      };      };
200      static int i = -1;      static int i = -1;
# Line 221  struct keywordTypes grub2Keywords[] = { Line 234  struct keywordTypes grub2Keywords[] = {
234      { "fallback",   LT_FALLBACK,    ' ' },      { "fallback",   LT_FALLBACK,    ' ' },
235      { "linux",      LT_KERNEL,      ' ' },      { "linux",      LT_KERNEL,      ' ' },
236      { "linuxefi",   LT_KERNEL_EFI,  ' ' },      { "linuxefi",   LT_KERNEL_EFI,  ' ' },
237        { "linux16",    LT_KERNEL_16,   ' ' },
238      { "initrd",     LT_INITRD,      ' ', ' ' },      { "initrd",     LT_INITRD,      ' ', ' ' },
239      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },
240        { "initrd16",   LT_INITRD_16,   ' ', ' ' },
241      { "module",     LT_MBMODULE,    ' ' },      { "module",     LT_MBMODULE,    ' ' },
242      { "kernel",     LT_HYPER,       ' ' },      { "kernel",     LT_HYPER,       ' ' },
243        { "devicetree", LT_DEVTREE,  ' ' },
244      { NULL, 0, 0 },      { NULL, 0, 0 },
245  };  };
246    
# Line 273  static char *grub2GetEnv(struct configFi Line 289  static char *grub2GetEnv(struct configFi
289      static char buf[1025];      static char buf[1025];
290      char *s = NULL;      char *s = NULL;
291      char *ret = NULL;      char *ret = NULL;
292      char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv";      char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
293      int rc = asprintf(&s, "grub2-editenv %s list | grep '^%s='", envFile, name);      int rc = asprintf(&s, "grub-editenv %s list | grep '^%s='", envFile, name);
294    
295      if (rc < 0)      if (rc < 0)
296   return NULL;   return NULL;
# Line 338  static int grub2SetEnv(struct configFile Line 354  static int grub2SetEnv(struct configFile
354  {  {
355      char *s = NULL;      char *s = NULL;
356      int rc = 0;      int rc = 0;
357      char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv";      char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
358    
359      unquote(value);      unquote(value);
360      value = shellEscape(value);      value = shellEscape(value);
361      if (!value)      if (!value)
362      return -1;      return -1;
363    
364      rc = asprintf(&s, "grub2-editenv %s set '%s=%s'", envFile, name, value);      rc = asprintf(&s, "grub-editenv %s set '%s=%s'", envFile, name, value);
365      free(value);      free(value);
366      if (rc <0)      if (rc <0)
367   return -1;   return -1;
# Line 396  static int isquote(char q) Line 412  static int isquote(char q)
412  }  }
413    
414  static int iskernel(enum lineType_e type) {  static int iskernel(enum lineType_e type) {
415      return (type == LT_KERNEL || type == LT_KERNEL_EFI);      return (type == LT_KERNEL || type == LT_KERNEL_EFI || type == LT_KERNEL_16);
416  }  }
417    
418  static int isinitrd(enum lineType_e type) {  static int isinitrd(enum lineType_e type) {
419      return (type == LT_INITRD || type == LT_INITRD_EFI);      return (type == LT_INITRD || type == LT_INITRD_EFI || type == LT_INITRD_16);
420  }  }
421    
422  char *grub2ExtractTitle(struct singleLine * line) {  char *grub2ExtractTitle(struct singleLine * line) {
# Line 566  struct keywordTypes extlinuxKeywords[] = Line 582  struct keywordTypes extlinuxKeywords[] =
582      { "initrd",    LT_INITRD,      ' ', ',' },      { "initrd",    LT_INITRD,      ' ', ',' },
583      { "append",    LT_KERNELARGS,  ' ' },      { "append",    LT_KERNELARGS,  ' ' },
584      { "prompt",     LT_UNKNOWN,     ' ' },      { "prompt",     LT_UNKNOWN,     ' ' },
585        { "fdt",        LT_DEVTREE,     ' ' },
586        { "fdtdir",     LT_DEVTREE,     ' ' },
587      { NULL,    0, 0 },      { NULL,    0, 0 },
588  };  };
589  int useextlinuxmenu;  int useextlinuxmenu;
# Line 621  struct configFileInfo extlinuxConfigType Line 639  struct configFileInfo extlinuxConfigType
639      .needsBootPrefix = 1,      .needsBootPrefix = 1,
640      .maxTitleLength = 255,      .maxTitleLength = 255,
641      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
642        .defaultIsUnquoted = 1,
643  };  };
644    
645  struct grubConfig {  struct grubConfig {
# Line 712  static enum lineType_e preferredLineType Line 731  static enum lineType_e preferredLineType
731      if (isEfi && cfi == &grub2ConfigType) {      if (isEfi && cfi == &grub2ConfigType) {
732   switch (type) {   switch (type) {
733   case LT_KERNEL:   case LT_KERNEL:
734      return LT_KERNEL_EFI;      return isEfiOnly ? LT_KERNEL : LT_KERNEL_EFI;
735     case LT_INITRD:
736        return isEfiOnly ? LT_INITRD : LT_INITRD_EFI;
737     default:
738        return type;
739     }
740    #if defined(__i386__) || defined(__x86_64__)
741        } else if (cfi == &grub2ConfigType) {
742     switch (type) {
743     case LT_KERNEL:
744        return LT_KERNEL_16;
745   case LT_INITRD:   case LT_INITRD:
746      return LT_INITRD_EFI;      return LT_INITRD_16;
747   default:   default:
748      return type;      return type;
749   }   }
750    #endif
751      }      }
752      return type;      return type;
753  }  }
# Line 1165  static struct grubConfig * readConfig(co Line 1195  static struct grubConfig * readConfig(co
1195   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1196   defaultLine = line;   defaultLine = line;
1197      }      }
  } else if (line->type == LT_DEFAULT && line->numElements == 2) {  
     cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;  
     defaultLine = line;  
1198    
1199          } else if (iskernel(line->type)) {          } else if (iskernel(line->type)) {
1200      /* if by some freak chance this is multiboot and the "module"      /* if by some freak chance this is multiboot and the "module"
1201       * lines came earlier in the template, make sure to use LT_HYPER       * lines came earlier in the template, make sure to use LT_HYPER
1202       * instead of LT_KERNEL now       * instead of LT_KERNEL now
1203       */       */
1204      if (entry->multiboot)      if (entry && entry->multiboot)
1205   line->type = LT_HYPER;   line->type = LT_HYPER;
1206    
1207          } else if (line->type == LT_MBMODULE) {          } else if (line->type == LT_MBMODULE) {
# Line 1200  static struct grubConfig * readConfig(co Line 1227  static struct grubConfig * readConfig(co
1227      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);
1228      if (*end) cfg->fallbackImage = -1;      if (*end) cfg->fallbackImage = -1;
1229    
1230   } else if (line->type == LT_TITLE && line->numElements > 1) {   } else if ((line->type == LT_DEFAULT && cfi->defaultIsUnquoted) ||
1231      /* make the title a single argument (undoing our parsing) */                  (line->type == LT_TITLE && line->numElements > 1)) {
1232        /* make the title/default a single argument (undoing our parsing) */
1233      len = 0;      len = 0;
1234      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1235   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1308  static struct grubConfig * readConfig(co Line 1336  static struct grubConfig * readConfig(co
1336      }      }
1337   }   }
1338    
1339     if (line->type == LT_DEFAULT && line->numElements == 2) {
1340        cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1341        defaultLine = line;
1342     }
1343    
1344   /* If we find a generic config option which should live at the   /* If we find a generic config option which should live at the
1345     top of the file, move it there. Old versions of grubby were     top of the file, move it there. Old versions of grubby were
1346     probably responsible for putting new images in the wrong     probably responsible for putting new images in the wrong
# Line 1805  int suitableImage(struct singleEntry * e Line 1838  int suitableImage(struct singleEntry * e
1838   return 0;   return 0;
1839      }      }
1840    
1841      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
1842      if (!line) {      if (!line) {
1843   notSuitablePrintf(entry, 0, "no line found\n");   notSuitablePrintf(entry, 0, "no line found\n");
1844   return 0;   return 0;
# Line 1929  struct singleEntry * findEntryByPath(str Line 1962  struct singleEntry * findEntryByPath(str
1962   }   }
1963    
1964   indexVars[i + 1] = -1;   indexVars[i + 1] = -1;
1965    
1966   i = 0;   i = 0;
1967   if (index) {   if (index) {
1968      while (i < *index) i++;      while (i < *index) {
1969      if (indexVars[i] == -1) return NULL;   i++;
1970     if (indexVars[i] == -1) return NULL;
1971        }
1972   }   }
1973    
1974   entry = findEntryByIndex(config, indexVars[i]);   entry = findEntryByIndex(config, indexVars[i]);
1975   if (!entry) return NULL;   if (!entry) return NULL;
1976    
1977   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
1978   if (!line) return NULL;   if (!line) return NULL;
1979    
1980   if (index) *index = indexVars[i];   if (index) *index = indexVars[i];
# Line 1990  struct singleEntry * findEntryByPath(str Line 2025  struct singleEntry * findEntryByPath(str
2025      for (line = entry->lines; line; line = line->next) {      for (line = entry->lines; line; line = line->next) {
2026   enum lineType_e ct = checkType;   enum lineType_e ct = checkType;
2027   if (entry->multiboot && checkType == LT_KERNEL)   if (entry->multiboot && checkType == LT_KERNEL)
2028      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER;      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER|LT_KERNEL_16;
2029   else if (checkType & LT_KERNEL)   else if (checkType & LT_KERNEL)
2030      ct = checkType | LT_KERNEL_EFI;      ct = checkType | LT_KERNEL_EFI | LT_KERNEL_16;
2031   line = getLineByType(ct, line);   line = getLineByType(ct, line);
2032   if (!line)   if (!line)
2033      break;  /* not found in this entry */      break;  /* not found in this entry */
# Line 2014  struct singleEntry * findEntryByPath(str Line 2049  struct singleEntry * findEntryByPath(str
2049       * non-Linux boot entries (could find netbsd etc, though, which is       * non-Linux boot entries (could find netbsd etc, though, which is
2050       * unfortunate)       * unfortunate)
2051       */       */
2052      if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines))      if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines))
2053   break; /* found 'im! */   break; /* found 'im! */
2054   }   }
2055    
# Line 2087  struct singleEntry * findTemplate(struct Line 2122  struct singleEntry * findTemplate(struct
2122   } else {   } else {
2123      entry = findEntryByTitle(cfg, defTitle, &index);      entry = findEntryByTitle(cfg, defTitle, &index);
2124   }   }
2125   if (entry)   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2126      cfg->defaultImage = index;      cfg->defaultImage = index;
2127        if (indexPtr)
2128     *indexPtr = index;
2129        return entry;
2130     }
2131      }      }
2132   }   }
2133      } else if (cfg->defaultImage > -1) {      } else if (cfg->defaultImage > -1) {
# Line 2245  void displayEntry(struct singleEntry * e Line 2284  void displayEntry(struct singleEntry * e
2284      struct singleLine * line;      struct singleLine * line;
2285      char * root = NULL;      char * root = NULL;
2286      int i;      int i;
2287        int j;
2288    
2289      printf("index=%d\n", index);      printf("index=%d\n", index);
2290    
2291      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
2292      if (!line) {      if (!line) {
2293          printf("non linux entry\n");          printf("non linux entry\n");
2294          return;          return;
# Line 2313  void displayEntry(struct singleEntry * e Line 2353  void displayEntry(struct singleEntry * e
2353   printf("root=%s\n", s);   printf("root=%s\n", s);
2354      }      }
2355    
2356      line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);      line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
2357    
2358      if (line && line->numElements >= 2) {      if (line && line->numElements >= 2) {
2359   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
# Line 2332  void displayEntry(struct singleEntry * e Line 2372  void displayEntry(struct singleEntry * e
2372      } else {      } else {
2373   char * title;   char * title;
2374   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
2375   title = grub2ExtractTitle(line);   if (line) {
2376   if (title)      title = grub2ExtractTitle(line);
2377      printf("title=%s\n", title);      if (title)
2378     printf("title=%s\n", title);
2379     }
2380        }
2381    
2382        for (j = 0, line = entry->lines; line; line = line->next) {
2383     if ((line->type & LT_MBMODULE) && line->numElements >= 2) {
2384        if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
2385     printf("mbmodule%d=", j);
2386        else
2387     printf("mbmodule%d=%s", j, prefix);
2388    
2389        for (i = 1; i < line->numElements; i++)
2390     printf("%s%s", line->elements[i].item, line->elements[i].indent);
2391        printf("\n");
2392        j++;
2393     }
2394      }      }
2395  }  }
2396    
# Line 2730  struct singleLine * addLineTmpl(struct s Line 2786  struct singleLine * addLineTmpl(struct s
2786   insertElement(newLine, val, 1, cfi);   insertElement(newLine, val, 1, cfi);
2787    
2788   /* but try to keep the rootspec from the template... sigh */   /* but try to keep the rootspec from the template... sigh */
2789   if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI)) {   if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI|LT_KERNEL_16|LT_INITRD_16)) {
2790      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);
2791      if (rootspec != NULL) {      if (rootspec != NULL) {
2792   free(newLine->elements[1].item);   free(newLine->elements[1].item);
# Line 3100  int updateActualImage(struct grubConfig Line 3156  int updateActualImage(struct grubConfig
3156      firstElement = 2;      firstElement = 2;
3157    
3158   } else {   } else {
3159      line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3160      if (!line) {      if (!line) {
3161   /* no LT_KERNEL or LT_MBMODULE in this entry? */   /* no LT_KERNEL or LT_MBMODULE in this entry? */
3162   continue;   continue;
# Line 3256  int updateImage(struct grubConfig * cfg, Line 3312  int updateImage(struct grubConfig * cfg,
3312      return rc;      return rc;
3313  }  }
3314    
3315    int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,
3316     const char * image, const char * prefix, const char * initrd,
3317     const char * title) {
3318        struct singleEntry * entry;
3319        struct singleLine * line, * kernelLine, *endLine = NULL;
3320        int index = 0;
3321    
3322        if (!image) return 0;
3323    
3324        for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3325            kernelLine = getLineByType(LT_MBMODULE, entry->lines);
3326            if (!kernelLine) continue;
3327    
3328     /* if title is supplied, the entry's title must match it. */
3329     if (title) {
3330        char *linetitle;
3331    
3332        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3333        if (!line)
3334     continue;
3335    
3336        linetitle = extractTitle(line);
3337        if (!linetitle)
3338     continue;
3339        if (strcmp(title, linetitle)) {
3340     free(linetitle);
3341     continue;
3342        }
3343        free(linetitle);
3344     }
3345    
3346            if (prefix) {
3347                int prefixLen = strlen(prefix);
3348                if (!strncmp(initrd, prefix, prefixLen))
3349                    initrd += prefixLen;
3350            }
3351     endLine = getLineByType(LT_ENTRY_END, entry->lines);
3352     if (endLine)
3353        removeLine(entry, endLine);
3354            line = addLine(entry, cfg->cfi, preferredLineType(LT_MBMODULE,cfg->cfi),
3355     kernelLine->indent, initrd);
3356            if (!line)
3357        return 1;
3358     if (endLine) {
3359        line = addLine(entry, cfg->cfi, LT_ENTRY_END, "", NULL);
3360                if (!line)
3361     return 1;
3362     }
3363    
3364            break;
3365        }
3366    
3367        return 0;
3368    }
3369    
3370  int updateInitrd(struct grubConfig * cfg, const char * image,  int updateInitrd(struct grubConfig * cfg, const char * image,
3371                   const char * prefix, const char * initrd) {                   const char * prefix, const char * initrd, const char * title) {
3372      struct singleEntry * entry;      struct singleEntry * entry;
3373      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3374      int index = 0;      int index = 0;
# Line 3265  int updateInitrd(struct grubConfig * cfg Line 3376  int updateInitrd(struct grubConfig * cfg
3376      if (!image) return 0;      if (!image) return 0;
3377    
3378      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3379          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI, entry->lines);          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3380          if (!kernelLine) continue;          if (!kernelLine) continue;
3381    
3382          line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);   /* if title is supplied, the entry's title must match it. */
3383     if (title) {
3384        char *linetitle;
3385    
3386        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3387        if (!line)
3388     continue;
3389    
3390        linetitle = extractTitle(line);
3391        if (!linetitle)
3392     continue;
3393        if (strcmp(title, linetitle)) {
3394     free(linetitle);
3395     continue;
3396        }
3397        free(linetitle);
3398     }
3399    
3400            line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
3401          if (line)          if (line)
3402              removeLine(entry, line);              removeLine(entry, line);
3403          if (prefix) {          if (prefix) {
# Line 3279  int updateInitrd(struct grubConfig * cfg Line 3408  int updateInitrd(struct grubConfig * cfg
3408   endLine = getLineByType(LT_ENTRY_END, entry->lines);   endLine = getLineByType(LT_ENTRY_END, entry->lines);
3409   if (endLine)   if (endLine)
3410      removeLine(entry, endLine);      removeLine(entry, endLine);
3411          line = addLine(entry, cfg->cfi, preferredLineType(LT_INITRD, cfg->cfi),   enum lineType_e lt;
3412   kernelLine->indent, initrd);   switch(kernelLine->type) {
3413        case LT_KERNEL:
3414            lt = LT_INITRD;
3415     break;
3416        case LT_KERNEL_EFI:
3417            lt = LT_INITRD_EFI;
3418     break;
3419        case LT_KERNEL_16:
3420            lt = LT_INITRD_16;
3421     break;
3422        default:
3423            lt = preferredLineType(LT_INITRD, cfg->cfi);
3424     }
3425            line = addLine(entry, cfg->cfi, lt, kernelLine->indent, initrd);
3426          if (!line)          if (!line)
3427      return 1;      return 1;
3428   if (endLine) {   if (endLine) {
# Line 3639  int addNewKernel(struct grubConfig * con Line 3781  int addNewKernel(struct grubConfig * con
3781   const char * newKernelPath, const char * newKernelTitle,   const char * newKernelPath, const char * newKernelTitle,
3782   const char * newKernelArgs, const char * newKernelInitrd,   const char * newKernelArgs, const char * newKernelInitrd,
3783   const char ** extraInitrds, int extraInitrdCount,   const char ** extraInitrds, int extraInitrdCount,
3784                   const char * newMBKernel, const char * newMBKernelArgs) {                   const char * newMBKernel, const char * newMBKernelArgs,
3785     const char * newDevTreePath) {
3786      struct singleEntry * new;      struct singleEntry * new;
3787      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;
3788      int needs;      int needs;
# Line 3680  int addNewKernel(struct grubConfig * con Line 3823  int addNewKernel(struct grubConfig * con
3823          needs |= NEED_MB;          needs |= NEED_MB;
3824          new->multiboot = 1;          new->multiboot = 1;
3825      }      }
3826        if (newDevTreePath && getKeywordByType(LT_DEVTREE, config->cfi))
3827     needs |= NEED_DEVTREE;
3828    
3829      if (template) {      if (template) {
3830   for (masterLine = template->lines;   for (masterLine = template->lines;
# Line 3865  int addNewKernel(struct grubConfig * con Line 4010  int addNewKernel(struct grubConfig * con
4010   newLine = addLineTmpl(new, tmplLine, newLine, NULL,   newLine = addLineTmpl(new, tmplLine, newLine, NULL,
4011   config->cfi);   config->cfi);
4012      }      }
4013        } else if (tmplLine->type == LT_DEVTREE &&
4014           tmplLine->numElements == 2 && newDevTreePath) {
4015            newLine = addLineTmpl(new, tmplLine, newLine,
4016          newDevTreePath + strlen(prefix),
4017          config->cfi);
4018     needs &= ~NEED_DEVTREE;
4019        } else if (tmplLine->type == LT_ENTRY_END && needs & NEED_DEVTREE) {
4020     const char *ndtp = newDevTreePath;
4021     if (!strncmp(newDevTreePath, prefix, strlen(prefix)))
4022        ndtp += strlen(prefix);
4023     newLine = addLine(new, config->cfi, LT_DEVTREE,
4024      config->secondaryIndent,
4025      ndtp);
4026     needs &= ~NEED_DEVTREE;
4027     newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
4028      } else {      } else {
4029   /* pass through other lines from the template */   /* pass through other lines from the template */
4030   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
# Line 3878  int addNewKernel(struct grubConfig * con Line 4038  int addNewKernel(struct grubConfig * con
4038   switch (config->cfi->entryStart) {   switch (config->cfi->entryStart) {
4039      case LT_KERNEL:      case LT_KERNEL:
4040      case LT_KERNEL_EFI:      case LT_KERNEL_EFI:
4041        case LT_KERNEL_16:
4042   if (new->multiboot && config->cfi->mbHyperFirst) {   if (new->multiboot && config->cfi->mbHyperFirst) {
4043      /* fall through to LT_HYPER */      /* fall through to LT_HYPER */
4044   } else {   } else {
# Line 3939  int addNewKernel(struct grubConfig * con Line 4100  int addNewKernel(struct grubConfig * con
4100   }   }
4101      }      }
4102    
4103        struct singleLine *endLine = NULL;
4104        endLine = getLineByType(LT_ENTRY_END, new->lines);
4105        if (endLine) {
4106        removeLine(new, endLine);
4107        needs |= NEED_END;
4108        }
4109    
4110      /* add the remainder of the lines, i.e. those that either      /* add the remainder of the lines, i.e. those that either
4111       * weren't present in the template, or in the case of no template,       * weren't present in the template, or in the case of no template,
4112       * all the lines following the entryStart.       * all the lines following the entryStart.
# Line 3984  int addNewKernel(struct grubConfig * con Line 4152  int addNewKernel(struct grubConfig * con
4152   free(initrdVal);   free(initrdVal);
4153   needs &= ~NEED_INITRD;   needs &= ~NEED_INITRD;
4154      }      }
4155        if (needs & NEED_DEVTREE) {
4156     newLine = addLine(new, config->cfi, LT_DEVTREE,
4157      config->secondaryIndent,
4158      newDevTreePath);
4159     needs &= ~NEED_DEVTREE;
4160        }
4161    
4162        /* NEEDS_END must be last on bootloaders that need it... */
4163      if (needs & NEED_END) {      if (needs & NEED_END) {
4164   newLine = addLine(new, config->cfi, LT_ENTRY_END,   newLine = addLine(new, config->cfi, LT_ENTRY_END,
4165   config->secondaryIndent, NULL);   config->secondaryIndent, NULL);
# Line 4035  int main(int argc, const char ** argv) { Line 4211  int main(int argc, const char ** argv) {
4211      char * newKernelArgs = NULL;      char * newKernelArgs = NULL;
4212      char * newKernelInitrd = NULL;      char * newKernelInitrd = NULL;
4213      char * newKernelTitle = NULL;      char * newKernelTitle = NULL;
4214      char * newKernelVersion = NULL;      char * newDevTreePath = NULL;
4215      char * newMBKernel = NULL;      char * newMBKernel = NULL;
4216      char * newMBKernelArgs = NULL;      char * newMBKernelArgs = NULL;
4217      char * removeMBKernelArgs = NULL;      char * removeMBKernelArgs = NULL;
# Line 4093  int main(int argc, const char ** argv) { Line 4269  int main(int argc, const char ** argv) {
4269      _("display the index of the default kernel") },      _("display the index of the default kernel") },
4270   { "default-title", 0, 0, &displayDefaultTitle, 0,   { "default-title", 0, 0, &displayDefaultTitle, 0,
4271      _("display the title of the default kernel") },      _("display the title of the default kernel") },
4272     { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4273        _("device tree file for new stanza"), _("dtb-path") },
4274     { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4275        _("device tree directory for new stanza"), _("dtb-path") },
4276   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,
4277      _("configure elilo bootloader") },      _("configure elilo bootloader") },
4278   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,
# Line 4258  int main(int argc, const char ** argv) { Line 4438  int main(int argc, const char ** argv) {
4438      grubConfig = cfi->defaultConfig;      grubConfig = cfi->defaultConfig;
4439      }      }
4440    
4441      if (bootloaderProbe && (displayDefault || kernelInfo || newKernelVersion ||      if (bootloaderProbe && (displayDefault || kernelInfo ||
4442      newKernelPath || removeKernelPath || makeDefault ||      newKernelPath || removeKernelPath || makeDefault ||
4443      defaultKernel || displayDefaultIndex || displayDefaultTitle ||      defaultKernel || displayDefaultIndex || displayDefaultTitle ||
4444      (defaultIndex >= 0))) {      (defaultIndex >= 0))) {
# Line 4267  int main(int argc, const char ** argv) { Line 4447  int main(int argc, const char ** argv) {
4447   return 1;   return 1;
4448      }      }
4449    
4450      if ((displayDefault || kernelInfo) && (newKernelVersion || newKernelPath ||      if ((displayDefault || kernelInfo) && (newKernelPath ||
4451     removeKernelPath)) {     removeKernelPath)) {
4452   fprintf(stderr, _("grubby: --default-kernel and --info may not "   fprintf(stderr, _("grubby: --default-kernel and --info may not "
4453    "be used when adding or removing kernels\n"));    "be used when adding or removing kernels\n"));
# Line 4277  int main(int argc, const char ** argv) { Line 4457  int main(int argc, const char ** argv) {
4457      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
4458   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
4459   return 1;   return 1;
4460      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||      } else if (!newKernelPath && (copyDefault ||
4461    (newKernelInitrd && !updateKernelPath)||    (newKernelInitrd && !updateKernelPath)||
4462    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
4463   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
# Line 4436  int main(int argc, const char ** argv) { Line 4616  int main(int argc, const char ** argv) {
4616   if (!entry) return 0;   if (!entry) return 0;
4617   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;
4618    
4619   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
4620   if (!line) return 0;   if (!line) return 0;
4621    
4622          rootspec = getRootSpecifier(line->elements[1].item);          rootspec = getRootSpecifier(line->elements[1].item);
# Line 4497  int main(int argc, const char ** argv) { Line 4677  int main(int argc, const char ** argv) {
4677      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
4678                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;
4679      if (updateKernelPath && newKernelInitrd) {      if (updateKernelPath && newKernelInitrd) {
4680              if (updateInitrd(config, updateKernelPath, bootPrefix,      if (newMBKernel) {
4681                               newKernelInitrd)) return 1;      if (addMBInitrd(config, newMBKernel, updateKernelPath,
4682     bootPrefix, newKernelInitrd,
4683     newKernelTitle))
4684        return 1;
4685        } else {
4686        if (updateInitrd(config, updateKernelPath, bootPrefix,
4687     newKernelInitrd, newKernelTitle))
4688     return 1;
4689        }
4690      }      }
4691      if (addNewKernel(config, template, bootPrefix, newKernelPath,      if (addNewKernel(config, template, bootPrefix, newKernelPath,
4692                       newKernelTitle, newKernelArgs, newKernelInitrd,                       newKernelTitle, newKernelArgs, newKernelInitrd,
4693                       (const char **)extraInitrds, extraInitrdCount,                       (const char **)extraInitrds, extraInitrdCount,
4694                       newMBKernel, newMBKernelArgs)) return 1;                       newMBKernel, newMBKernelArgs, newDevTreePath)) return 1;
4695            
4696    
4697      if (numEntries(config) == 0) {      if (numEntries(config) == 0) {

Legend:
Removed from v.2258  
changed lines
  Added in v.2972