X-Git-Url: https://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=devices%2Fkboot-parser.c;h=df2e7620e13ad8ea40a735aaa04da60881f43de1;hp=ba4fbf5f26bad3b6b43e49f8229aa3d18e967400;hb=a57e4ef92b8e590643a325d309511306c5b941a9;hpb=bdb389592338a2f69af98d763a39c617374c1233;ds=sidebyside diff --git a/devices/kboot-parser.c b/devices/kboot-parser.c index ba4fbf5..df2e762 100644 --- a/devices/kboot-parser.c +++ b/devices/kboot-parser.c @@ -15,7 +15,7 @@ #define buf_size 1024 -static const char *mountpoint; +static const char *devpath; static int param_is_ignored(const char *param) { @@ -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; +}; + + +static 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,15 +138,16 @@ 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, devpath); opt->description = strdup(config); return 1; } *pos = 0; - opt->boot_image_file = join_paths(mountpoint, config); + opt->boot_image_file = resolve_path(config, devpath); cmdline = malloc(buf_size); + *cmdline = 0; for (pos++; pos;) { pos = get_param_pair(pos, &name, &value, ' '); @@ -127,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, devpath); } if (root) { @@ -140,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; } @@ -170,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); @@ -182,16 +236,16 @@ static void parse_buf(struct device *dev, char *buf) } } -static int parse(const char *devicepath, const char *_mountpoint) +static int parse(const char *device) { char *filepath, *buf; int fd, len, rc = 0; struct stat stat; struct device *dev; - mountpoint = _mountpoint; + devpath = device; - filepath = join_paths(mountpoint, "/etc/kboot.conf"); + filepath = resolve_path("/etc/kboot.conf", devpath); fd = open(filepath, O_RDONLY); if (fd < 0) @@ -211,7 +265,7 @@ static int parse(const char *devicepath, const char *_mountpoint) dev = malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); - dev->id = strdup(devicepath); + dev->id = strdup(device); dev->icon_file = strdup(generic_icon_file(guess_device_type())); parse_buf(dev, buf);