Magellan Linux

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

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

trunk/mkinitrd-magellan/grubby/grubby.c revision 914 by niro, Wed Oct 28 00:16:16 2009 UTC trunk/grubby/grubby.c revision 1692 by niro, Fri Feb 17 23:14:54 2012 UTC
# Line 139  struct keywordTypes grubKeywords[] = { Line 139  struct keywordTypes grubKeywords[] = {
139  };  };
140    
141  struct configFileInfo grubConfigType = {  struct configFileInfo grubConfigType = {
142      "/etc/grub.conf",    /* defaultConfig */      .defaultConfig = "/boot/grub/grub.conf",
143      grubKeywords,    /* keywords */      .keywords = grubKeywords,
144      1,    /* defaultIsIndex */      .defaultIsIndex = 1,
145      1,    /* defaultSupportSaved */      .defaultSupportSaved = 1,
146      LT_TITLE,    /* entrySeparator */      .entrySeparator = LT_TITLE,
147      1,    /* needsBootPrefix */      .needsBootPrefix = 1,
148      0,    /* argsInQuotes */      .mbHyperFirst = 1,
149      0,    /* maxTitleLength */      .mbInitRdIsModule = 1,
150      0,                                      /* titleBracketed */      .mbAllowExtraInitRds = 1,
     1,                                      /* mbHyperFirst */  
     1,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     1,                                      /* mbAllowExtraInitRds */  
151  };  };
152    
153  struct keywordTypes yabootKeywords[] = {  struct keywordTypes yabootKeywords[] = {
# Line 249  struct keywordTypes extlinuxKeywords[] = Line 245  struct keywordTypes extlinuxKeywords[] =
245  };  };
246  int useextlinuxmenu;  int useextlinuxmenu;
247  struct configFileInfo eliloConfigType = {  struct configFileInfo eliloConfigType = {
248      "/boot/efi/EFI/redhat/elilo.conf",    /* defaultConfig */      .defaultConfig = "/boot/efi/EFI/redhat/elilo.conf",
249      eliloKeywords,    /* keywords */      .keywords = eliloKeywords,
250      0,    /* defaultIsIndex */      .entrySeparator = LT_KERNEL,
251      0,    /* defaultSupportSaved */      .needsBootPrefix = 1,
252      LT_KERNEL,    /* entrySeparator */      .argsInQuotes = 1,
253      1,                    /* needsBootPrefix */      .mbConcatArgs = 1,
     1,    /* argsInQuotes */  
     0,    /* maxTitleLength */  
     0,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     1,                                      /* mbConcatArgs */  
     0,                                      /* mbAllowExtraInitRds */  
254  };  };
255    
256  struct configFileInfo liloConfigType = {  struct configFileInfo liloConfigType = {
257      "/etc/lilo.conf",    /* defaultConfig */      .defaultConfig = "/etc/lilo.conf",
258      liloKeywords,    /* keywords */      .keywords = liloKeywords,
259      0,    /* defaultIsIndex */      .entrySeparator = LT_KERNEL,
260      0,    /* defaultSupportSaved */      .argsInQuotes = 1,
261      LT_KERNEL,    /* entrySeparator */      .maxTitleLength = 15,
     0,    /* needsBootPrefix */  
     1,    /* argsInQuotes */  
     15,    /* maxTitleLength */  
     0,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     0,                                      /* mbAllowExtraInitRds */  
262  };  };
263    
264  struct configFileInfo yabootConfigType = {  struct configFileInfo yabootConfigType = {
265      "/etc/yaboot.conf",    /* defaultConfig */      .defaultConfig = "/etc/yaboot.conf",
266      yabootKeywords,    /* keywords */      .keywords = yabootKeywords,
267      0,    /* defaultIsIndex */      .entrySeparator = LT_KERNEL,
268      0,    /* defaultSupportSaved */      .needsBootPrefix = 1,
269      LT_KERNEL,    /* entrySeparator */      .argsInQuotes = 1,
270      1,    /* needsBootPrefix */      .maxTitleLength = 15,
271      1,    /* argsInQuotes */      .mbAllowExtraInitRds = 1,
     15,    /* maxTitleLength */  
     0,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     1,                                      /* mbAllowExtraInitRds */  
272  };  };
273    
274  struct configFileInfo siloConfigType = {  struct configFileInfo siloConfigType = {
275      "/etc/silo.conf",    /* defaultConfig */      .defaultConfig = "/etc/silo.conf",
276      siloKeywords,    /* keywords */      .keywords = siloKeywords,
277      0,    /* defaultIsIndex */      .entrySeparator = LT_KERNEL,
278      0,    /* defaultSupportSaved */      .needsBootPrefix = 1,
279      LT_KERNEL,    /* entrySeparator */      .argsInQuotes = 1,
280      1,    /* needsBootPrefix */      .maxTitleLength = 15,
     1,    /* argsInQuotes */  
     15,    /* maxTitleLength */  
     0,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     0,                                      /* mbAllowExtraInitRds */  
281  };  };
282    
283  struct configFileInfo ziplConfigType = {  struct configFileInfo ziplConfigType = {
284      "/etc/zipl.conf",    /* defaultConfig */      .defaultConfig = "/etc/zipl.conf",
285      ziplKeywords,    /* keywords */      .keywords = ziplKeywords,
286      0,    /* defaultIsIndex */      .entrySeparator = LT_TITLE,
287      0,    /* defaultSupportSaved */      .argsInQuotes = 1,
288      LT_TITLE,    /* entrySeparator */      .titleBracketed = 1,
     0,    /* needsBootPrefix */  
     1,    /* argsInQuotes */  
     0,    /* maxTitleLength */  
     1,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     0,                                      /* mbAllowExtraInitRds */  
289  };  };
290    
291  struct configFileInfo extlinuxConfigType = {  struct configFileInfo extlinuxConfigType = {
292      "/boot/extlinux/extlinux.conf",         /* defaultConfig */      .defaultConfig = "/boot/extlinux/extlinux.conf",
293      extlinuxKeywords,                       /* keywords */      .keywords = extlinuxKeywords,
294      0,                                      /* defaultIsIndex */      .entrySeparator = LT_TITLE,
295      0,                                      /* defaultSupportSaved */      .needsBootPrefix = 1,
296      LT_TITLE,                               /* entrySeparator */      .maxTitleLength = 255,
297      1,                                      /* needsBootPrefix */      .mbAllowExtraInitRds = 1,
     0,                                      /* argsInQuotes */  
     255,                                    /* maxTitleLength */  
     0,                                      /* titleBracketed */  
     0,                                      /* mbHyperFirst */  
     0,                                      /* mbInitRdIsModule */  
     0,                                      /* mbConcatArgs */  
     1,                                      /* mbAllowExtraInitRds */  
298  };  };
299    
300  struct grubConfig {  struct grubConfig {
# Line 356  struct grubConfig { Line 309  struct grubConfig {
309      struct configFileInfo * cfi;      struct configFileInfo * cfi;
310  };  };
311    
312    blkid_cache blkid;
313    
314  struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index);  struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index);
315  struct singleEntry * findEntryByPath(struct grubConfig * cfg,  struct singleEntry * findEntryByPath(struct grubConfig * cfg,
316       const char * path, const char * prefix,       const char * path, const char * prefix,
# Line 434  static struct keywordTypes * getKeywordB Line 389  static struct keywordTypes * getKeywordB
389  }  }
390    
391  static char * getpathbyspec(char *device) {  static char * getpathbyspec(char *device) {
     static blkid_cache blkid;  
   
392      if (!blkid)      if (!blkid)
393          blkid_get_cache(&blkid, NULL);          blkid_get_cache(&blkid, NULL);
394    
395      return blkid_get_devname(blkid, device, NULL);      return blkid_get_devname(blkid, device, NULL);
396  }  }
397    
398    static char * getuuidbydev(char *device) {
399        if (!blkid)
400     blkid_get_cache(&blkid, NULL);
401    
402        return blkid_get_tag_value(blkid, "UUID", device);
403    }
404    
405  static enum lineType_e getTypeByKeyword(char * keyword,  static enum lineType_e getTypeByKeyword(char * keyword,
406   struct configFileInfo * cfi) {   struct configFileInfo * cfi) {
407      struct keywordTypes * kw;      struct keywordTypes * kw;
# Line 1155  static int numEntries(struct grubConfig Line 1115  static int numEntries(struct grubConfig
1115      return i;      return i;
1116  }  }
1117    
1118    static char *findDiskForRoot()
1119    {
1120        int fd;
1121        char buf[65536];
1122        char *devname;
1123        char *chptr;
1124        int rc;
1125    
1126        if ((fd = open(_PATH_MOUNTED, O_RDONLY)) < 0) {
1127            fprintf(stderr, "grubby: failed to open %s: %s\n",
1128                    _PATH_MOUNTED, strerror(errno));
1129            return NULL;
1130        }
1131    
1132        rc = read(fd, buf, sizeof(buf) - 1);
1133        if (rc <= 0) {
1134            fprintf(stderr, "grubby: failed to read %s: %s\n",
1135                    _PATH_MOUNTED, strerror(errno));
1136            close(fd);
1137            return NULL;
1138        }
1139        close(fd);
1140        buf[rc] = '\0';
1141        chptr = buf;
1142    
1143        while (chptr && chptr != buf+rc) {
1144            devname = chptr;
1145    
1146            /*
1147             * The first column of a mtab entry is the device, but if the entry is a
1148             * special device it won't start with /, so move on to the next line.
1149             */
1150            if (*devname != '/') {
1151                chptr = strchr(chptr, '\n');
1152                if (chptr)
1153                    chptr++;
1154                continue;
1155            }
1156    
1157            /* Seek to the next space */
1158            chptr = strchr(chptr, ' ');
1159            if (!chptr) {
1160                fprintf(stderr, "grubby: error parsing %s: %s\n",
1161                        _PATH_MOUNTED, strerror(errno));
1162                return NULL;
1163            }
1164    
1165            /*
1166             * The second column of a mtab entry is the mount point, we are looking
1167             * for '/' obviously.
1168             */
1169            if (*(++chptr) == '/' && *(++chptr) == ' ') {
1170                /*
1171                 * Move back 2, which is the first space after the device name, set
1172                 * it to \0 so strdup will just get the devicename.
1173                 */
1174                chptr -= 2;
1175                *chptr = '\0';
1176                return strdup(devname);
1177            }
1178    
1179            /* Next line */
1180            chptr = strchr(chptr, '\n');
1181            if (chptr)
1182                chptr++;
1183        }
1184    
1185        return NULL;
1186    }
1187    
1188  int suitableImage(struct singleEntry * entry, const char * bootPrefix,  int suitableImage(struct singleEntry * entry, const char * bootPrefix,
1189    int skipRemoved, int flags) {    int skipRemoved, int flags) {
1190      struct singleLine * line;      struct singleLine * line;
1191      char * fullName;      char * fullName;
1192      int i;      int i;
     struct stat sb, sb2;  
1193      char * dev;      char * dev;
1194      char * rootspec;      char * rootspec;
1195        char * rootdev;
1196    
1197      if (skipRemoved && entry->skip) return 0;      if (skipRemoved && entry->skip) return 0;
1198    
# Line 1212  int suitableImage(struct singleEntry * e Line 1242  int suitableImage(struct singleEntry * e
1242      if (!dev)      if (!dev)
1243          return 0;          return 0;
1244    
1245      i = stat(dev, &sb);      rootdev = findDiskForRoot();
1246      if (i)      if (!rootdev)
1247   return 0;   return 0;
1248    
1249      stat("/", &sb2);      if (!getuuidbydev(rootdev) || !getuuidbydev(dev)) {
1250            free(rootdev);
1251            return 0;
1252        }
1253    
1254      if (sb.st_rdev != sb2.st_dev)      if (strcmp(getuuidbydev(rootdev), getuuidbydev(dev))) {
1255     free(rootdev);
1256          return 0;          return 0;
1257        }
1258    
1259        free(rootdev);
1260    
1261      return 1;      return 1;
1262  }  }
# Line 1582  int parseSysconfigGrub(int * lbaPtr, cha Line 1619  int parseSysconfigGrub(int * lbaPtr, cha
1619      char * start;      char * start;
1620      char * param;      char * param;
1621    
1622      in = fopen("/etc/sysconfig/grub", "r");      in = fopen("/etc/conf.d/grub", "r");
1623      if (!in) return 1;      if (!in) return 1;
1624    
1625      if (lbaPtr) *lbaPtr = 0;      if (lbaPtr) *lbaPtr = 0;
# Line 1644  int displayInfo(struct grubConfig * conf Line 1681  int displayInfo(struct grubConfig * conf
1681   return 1;   return 1;
1682      }      }
1683    
1684      /* this is a horrible hack to support /etc/sysconfig/grub; there must      /* this is a horrible hack to support /etc/conf.d/grub; there must
1685         be a better way */         be a better way */
1686      if (config->cfi == &grubConfigType) {      if (config->cfi == &grubConfigType) {
1687   dumpSysconfigGrub();   dumpSysconfigGrub();
# Line 1895  int updateActualImage(struct grubConfig Line 1932  int updateActualImage(struct grubConfig
1932      const char ** arg;      const char ** arg;
1933      int useKernelArgs, useRoot;      int useKernelArgs, useRoot;
1934      int firstElement;      int firstElement;
1935      int *usedElements, *usedArgs;      int *usedElements;
1936      int doreplace;      int doreplace;
1937    
1938      if (!image) return 0;      if (!image) return 0;
# Line 1930  int updateActualImage(struct grubConfig Line 1967  int updateActualImage(struct grubConfig
1967      useRoot = (getKeywordByType(LT_ROOT, cfg->cfi)      useRoot = (getKeywordByType(LT_ROOT, cfg->cfi)
1968         && !multibootArgs);         && !multibootArgs);
1969    
     for (k = 0, arg = newArgs; *arg; arg++, k++) ;  
     usedArgs = calloc(k, sizeof(*usedArgs));  
   
1970      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
1971    
1972   if (multibootArgs && !entry->multiboot)   if (multibootArgs && !entry->multiboot)
# Line 2008  int updateActualImage(struct grubConfig Line 2042  int updateActualImage(struct grubConfig
2042          usedElements = calloc(line->numElements, sizeof(*usedElements));          usedElements = calloc(line->numElements, sizeof(*usedElements));
2043    
2044   for (k = 0, arg = newArgs; *arg; arg++, k++) {   for (k = 0, arg = newArgs; *arg; arg++, k++) {
             if (usedArgs[k]) continue;  
2045    
2046      doreplace = 1;      doreplace = 1;
2047      for (i = firstElement; i < line->numElements; i++) {      for (i = firstElement; i < line->numElements; i++) {
# Line 2023  int updateActualImage(struct grubConfig Line 2056  int updateActualImage(struct grubConfig
2056                      continue;                      continue;
2057   if (!argMatch(line->elements[i].item, *arg)) {   if (!argMatch(line->elements[i].item, *arg)) {
2058                      usedElements[i]=1;                      usedElements[i]=1;
                     usedArgs[k]=1;  
2059      break;      break;
2060                  }                  }
2061              }              }
# Line 2093  int updateActualImage(struct grubConfig Line 2125  int updateActualImage(struct grubConfig
2125   }   }
2126      }      }
2127    
     free(usedArgs);  
2128      free(newArgs);      free(newArgs);
2129      free(oldArgs);      free(oldArgs);
2130    
# Line 2119  int updateImage(struct grubConfig * cfg, Line 2150  int updateImage(struct grubConfig * cfg,
2150      return rc;      return rc;
2151  }  }
2152    
2153    int updateInitrd(struct grubConfig * cfg, const char * image,
2154                     const char * prefix, const char * initrd) {
2155        struct singleEntry * entry;
2156        struct singleLine * line, * kernelLine;
2157        int index = 0;
2158    
2159        if (!image) return 0;
2160    
2161        for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
2162            kernelLine = getLineByType(LT_KERNEL, entry->lines);
2163            if (!kernelLine) continue;
2164    
2165            line = getLineByType(LT_INITRD, entry->lines);
2166            if (line)
2167                removeLine(entry, line);
2168            if (prefix) {
2169                int prefixLen = strlen(prefix);
2170                if (!strncmp(initrd, prefix, prefixLen))
2171                    initrd += prefixLen;
2172            }
2173            line = addLine(entry, cfg->cfi, LT_INITRD, kernelLine->indent, initrd);
2174            if (!line) return 1;
2175            break;
2176        }
2177    
2178        return 0;
2179    }
2180    
2181  int checkDeviceBootloader(const char * device, const unsigned char * boot) {  int checkDeviceBootloader(const char * device, const unsigned char * boot) {
2182      int fd;      int fd;
2183      unsigned char bootSect[512];      unsigned char bootSect[512];
# Line 2948  int main(int argc, const char ** argv) { Line 3007  int main(int argc, const char ** argv) {
3007      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
3008   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
3009   return 1;   return 1;
3010      } else if (!newKernelPath && (newKernelTitle  || newKernelInitrd ||      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||
3011    newKernelInitrd || copyDefault     ||    (newKernelInitrd && !updateKernelPath)||
3012    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
3013   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
3014   return 1;   return 1;
# Line 3082  int main(int argc, const char ** argv) { Line 3141  int main(int argc, const char ** argv) {
3141      setFallbackImage(config, newKernelPath != NULL);      setFallbackImage(config, newKernelPath != NULL);
3142      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
3143                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;
3144        if (updateKernelPath && newKernelInitrd) {
3145                if (updateInitrd(config, updateKernelPath, bootPrefix,
3146                                 newKernelInitrd)) return 1;
3147        }
3148      if (addNewKernel(config, template, bootPrefix, newKernelPath,      if (addNewKernel(config, template, bootPrefix, newKernelPath,
3149                       newKernelTitle, newKernelArgs, newKernelInitrd,                       newKernelTitle, newKernelArgs, newKernelInitrd,
3150                       extraInitrds, extraInitrdCount,                       extraInitrds, extraInitrdCount,

Legend:
Removed from v.914  
changed lines
  Added in v.1692