Magellan Linux

Diff of /trunk/grubby/grubby.c

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

revision 3138 by niro, Tue Jul 7 11:11:04 2020 UTC revision 3139 by niro, Tue Jul 7 11:12:00 2020 UTC
# Line 68  int isEfi = 0; Line 68  int isEfi = 0;
68    
69  char *saved_command_line = NULL;  char *saved_command_line = NULL;
70    
71    const char *mounts = "/proc/mounts";
72    
73  /* comments get lumped in with indention */  /* comments get lumped in with indention */
74  struct lineElement {  struct lineElement {
75   char *item;   char *item;
# Line 2118  static int endswith(const char *s, char Line 2120  static int endswith(const char *s, char
2120   return s[slen] == c;   return s[slen] == c;
2121  }  }
2122    
2123    typedef struct {
2124     const char *start;
2125     size_t      chars;
2126    } field;
2127    
2128    static int iscomma(int c)
2129    {
2130     return c == ',';
2131    }
2132    
2133    static int isequal(int c)
2134    {
2135     return c == '=';
2136    }
2137    
2138    static field findField(const field *in, typeof(isspace) *isdelim, field *out)
2139    {
2140     field nxt = {};
2141     size_t off = 0;
2142    
2143     while (off < in->chars && isdelim(in->start[off]))
2144     off++;
2145    
2146     if (off == in->chars)
2147     return nxt;
2148    
2149     out->start = &in->start[off];
2150     out->chars = 0;
2151    
2152     while (off + out->chars < in->chars && !isdelim(out->start[out->chars]))
2153     out->chars++;
2154    
2155     nxt.start = out->start + out->chars;
2156     nxt.chars = in->chars - off - out->chars;
2157     return nxt;
2158    }
2159    
2160    static int fieldEquals(const field *in, const char *str)
2161    {
2162     return in->chars == strlen(str) &&
2163     strncmp(in->start, str, in->chars) == 0;
2164    }
2165    
2166    /* Parse /proc/mounts to determine the subvolume prefix. */
2167    static size_t subvolPrefix(const char *str)
2168    {
2169     FILE *file = NULL;
2170     char *line = NULL;
2171     size_t prfx = 0;
2172     size_t size = 0;
2173    
2174     file = fopen(mounts, "r");
2175     if (!file)
2176     return 0;
2177    
2178     for (ssize_t s; (s = getline(&line, &size, file)) >= 0; ) {
2179     field nxt = { line, s };
2180     field dev = {};
2181     field path = {};
2182     field type = {};
2183     field opts = {};
2184     field opt = {};
2185    
2186     nxt = findField(&nxt, isspace, &dev);
2187     if (!nxt.start)
2188     continue;
2189    
2190     nxt = findField(&nxt, isspace, &path);
2191     if (!nxt.start)
2192     continue;
2193    
2194     nxt = findField(&nxt, isspace, &type);
2195     if (!nxt.start)
2196     continue;
2197    
2198     nxt = findField(&nxt, isspace, &opts);
2199     if (!nxt.start)
2200     continue;
2201    
2202     if (!fieldEquals(&type, "btrfs"))
2203     continue;
2204    
2205     /* We have found a btrfs mount point. */
2206    
2207     nxt = opts;
2208     while ((nxt = findField(&nxt, iscomma, &opt)).start) {
2209     field key = {};
2210     field val = {};
2211    
2212     opt = findField(&opt, isequal, &key);
2213     if (!opt.start)
2214     continue;
2215    
2216     opt = findField(&opt, isequal, &val);
2217     if (!opt.start)
2218     continue;
2219    
2220     if (!fieldEquals(&key, "subvol"))
2221     continue;
2222    
2223     /* We have found a btrfs subvolume mount point. */
2224    
2225     if (strncmp(val.start, str, val.chars))
2226     continue;
2227    
2228     if (val.start[val.chars - 1] != '/' &&
2229     str[val.chars] != '/')
2230     continue;
2231    
2232     /* The subvolume mount point matches our input. */
2233    
2234     if (prfx < val.chars)
2235     prfx = val.chars;
2236     }
2237     }
2238    
2239     dbgPrintf("%s(): str: '%s', prfx: '%s'\n", __FUNCTION__, str, prfx);
2240    
2241     fclose(file);
2242     free(line);
2243     return prfx;
2244    }
2245    
2246  int suitableImage(struct singleEntry *entry, const char *bootPrefix,  int suitableImage(struct singleEntry *entry, const char *bootPrefix,
2247    int skipRemoved, int flags)    int skipRemoved, int flags)
2248  {  {
# Line 3265  struct singleLine *addLineTmpl(struct si Line 3390  struct singleLine *addLineTmpl(struct si
3390      type & (LT_HYPER | LT_KERNEL | LT_MBMODULE | LT_INITRD |      type & (LT_HYPER | LT_KERNEL | LT_MBMODULE | LT_INITRD |
3391      LT_KERNEL_EFI | LT_INITRD_EFI | LT_KERNEL_16 |      LT_KERNEL_EFI | LT_INITRD_EFI | LT_KERNEL_16 |
3392      LT_INITRD_16)) {      LT_INITRD_16)) {
3393   size_t rs = getRootSpecifier(tmplLine->elements[1].item);   const char *prfx = tmplLine->elements[1].item;
3394     size_t rs = getRootSpecifier(prfx);
3395     if (isinitrd(tmplLine->type)) {
3396     for (struct singleLine *l = entry->lines;
3397         rs == 0 && l; l = l->next) {
3398     if (iskernel(l->type)) {
3399     prfx = l->elements[1].item;
3400     rs = getRootSpecifier(prfx);
3401     break;
3402     }
3403     }
3404     }
3405   if (rs > 0) {   if (rs > 0) {
3406   free(newLine->elements[1].item);   free(newLine->elements[1].item);
3407   newLine->elements[1].item = sdupprintf(   newLine->elements[1].item = sdupprintf(
3408   "%.*s%s", (int) rs,   "%.*s%s", (int) rs, prfx, val);
  tmplLine->elements[1].item, val);  
3409   }   }
3410   }   }
3411   }   }
# Line 4334  static size_t getRootSpecifier(const cha Line 4469  static size_t getRootSpecifier(const cha
4469   rs++;   rs++;
4470   }   }
4471    
4472   return rs;   return rs + subvolPrefix(str + rs);
4473  }  }
4474    
4475  static char *getInitrdVal(struct grubConfig *config,  static char *getInitrdVal(struct grubConfig *config,
# Line 4966  int main(int argc, const char **argv) Line 5101  int main(int argc, const char **argv)
5101   {"mbargs", 0, POPT_ARG_STRING, &newMBKernelArgs, 0,   {"mbargs", 0, POPT_ARG_STRING, &newMBKernelArgs, 0,
5102   _("default arguments for the new multiboot kernel or "   _("default arguments for the new multiboot kernel or "
5103     "new arguments for multiboot kernel being updated"), NULL},     "new arguments for multiboot kernel being updated"), NULL},
5104     {"mounts", 0, POPT_ARG_STRING, &mounts, 0,
5105     _("path to fake /proc/mounts file (for testing only)"),
5106     _("mounts")},
5107   {"bad-image-okay", 0, 0, &badImageOkay, 0,   {"bad-image-okay", 0, 0, &badImageOkay, 0,
5108   _   _
5109   ("don't sanity check images in boot entries (for testing only)"),   ("don't sanity check images in boot entries (for testing only)"),

Legend:
Removed from v.3138  
changed lines
  Added in v.3139