]> git.ozlabs.org Git - petitboot/blobdiff - devices/kboot-parser.c
Resolve device paths in kernel and initrd locations.
[petitboot] / devices / kboot-parser.c
index b845d8498779184a5bbe576f9c7c45161838fab0..b70d5fca82b1290efba3f44550dc95d0ace1c582 100644 (file)
@@ -76,6 +76,47 @@ static char *get_param_pair(char *str, char **name_out, char **value_out,
        return tmp ? tmp + 1 : NULL;
 }
 
+struct global_option {
+       char *name;
+       char *value;
+};
+
+
+struct global_option global_options[] = {
+       { .name = "root" },
+       { .name = "initrd" },
+       { .name = "video" },
+       { .name = NULL }
+};
+
+/*
+ * Check if an option (name=value) is a global option. If so, store it in
+ * the global options table, and return 1. Otherwise, return 0.
+ */
+static int check_for_global_option(const char *name, const char *value)
+{
+       int i;
+
+       for (i = 0; global_options[i].name ;i++) {
+               if (!strcmp(name, global_options[i].name)) {
+                       global_options[i].value = strdup(value);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static char *get_global_option(const char *name)
+{
+       int i;
+
+       for (i = 0; global_options[i].name ;i++)
+               if (!strcmp(name, global_options[i].name))
+                       return global_options[i].value;
+
+       return NULL;
+}
+
 static int parse_option(struct boot_option *opt, char *config)
 {
        char *pos, *name, *value, *root, *initrd, *cmdline, *tmp;
@@ -97,13 +138,13 @@ static int parse_option(struct boot_option *opt, char *config)
 
        /* if there's no space, it's only a kernel image with no params */
        if (!pos) {
-               opt->boot_image_file = join_paths(mountpoint, config);
+               opt->boot_image_file = resolve_path(config, mountpoint);
                opt->description = strdup(config);
                return 1;
        }
 
        *pos = 0;
-       opt->boot_image_file = join_paths(mountpoint, config);
+       opt->boot_image_file = resolve_path(config, mountpoint);
 
        cmdline = malloc(buf_size);
        *cmdline = 0;
@@ -128,12 +169,17 @@ static int parse_option(struct boot_option *opt, char *config)
                }
        }
 
+       if (!root)
+               root = get_global_option("root");
+       if (!initrd)
+               initrd = get_global_option("initrd");
+
        if (initrd) {
                asprintf(&tmp, "initrd=%s %s", initrd, cmdline);
                free(cmdline);
                cmdline = tmp;
 
-               opt->initrd_file = join_paths(mountpoint, initrd);
+               opt->initrd_file = resolve_path(initrd, mountpoint);
        }
 
        if (root) {
@@ -141,17 +187,18 @@ static int parse_option(struct boot_option *opt, char *config)
                free(cmdline);
                cmdline = tmp;
 
-       } else if (!initrd) {
+       } else if (initrd) {
                /* if there's an initrd but no root, fake up /dev/ram0 */
                asprintf(&tmp, "root=/dev/ram0 %s", cmdline);
                free(cmdline);
                cmdline = tmp;
        }
 
-       pb_log("kboot cmdline: %s", cmdline);
+       pb_log("kboot cmdline: %s\n", cmdline);
        opt->boot_args = cmdline;
 
-       asprintf(&opt->description, "%s %s", config, cmdline);
+       asprintf(&opt->description, "%s %s",
+                       config, opt->boot_args);
 
        return 1;
 }
@@ -171,6 +218,12 @@ static void parse_buf(struct device *dev, char *buf)
                if (name == NULL || param_is_ignored(name))
                        continue;
 
+               if (*name == '#')
+                       continue;
+
+               if (check_for_global_option(name, value))
+                       continue;
+
                memset(&opt, 0, sizeof(opt));
                opt.name = strdup(name);