summaryrefslogtreecommitdiffstats
path: root/discover/kboot-parser.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2009-01-02 16:34:18 +0900
committerJeremy Kerr <jk@ozlabs.org>2009-01-02 16:34:18 +0900
commitce5eab024583af5a4725503bad6ed2aee452b1aa (patch)
tree534753bfa7fd65f6c173f62e75995adc6376ff9f /discover/kboot-parser.c
parentb118597194815910897ccf86d77b8b5a066adf5a (diff)
downloadtalos-petitboot-ce5eab024583af5a4725503bad6ed2aee452b1aa.tar.gz
talos-petitboot-ce5eab024583af5a4725503bad6ed2aee452b1aa.zip
Hook up parsers to device discovery
Iterate the parsers from the device handler on an add event. Initial change to just the kboot parser. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/kboot-parser.c')
-rw-r--r--discover/kboot-parser.c155
1 files changed, 82 insertions, 73 deletions
diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c
index df2e762..f227ee3 100644
--- a/discover/kboot-parser.c
+++ b/discover/kboot-parser.c
@@ -10,12 +10,28 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include "parser.h"
+#include <talloc/talloc.h>
+
+#include "log.h"
+#include "pb-protocol/pb-protocol.h"
+#include "paths.h"
#include "params.h"
+#include "parser-utils.h"
+#include "device-handler.h"
#define buf_size 1024
-static const char *devpath;
+struct kboot_context {
+ struct discover_context *discover;
+
+ char *buf;
+
+ struct global_option {
+ char *name;
+ char *value;
+ } *global_options;
+ int n_global_options;
+};
static int param_is_ignored(const char *param)
{
@@ -76,12 +92,6 @@ 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" },
@@ -93,20 +103,21 @@ static struct global_option global_options[] = {
* 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)
+static int check_for_global_option(struct kboot_context *ctx,
+ const char *name, const char *value)
{
int i;
- for (i = 0; global_options[i].name ;i++) {
- if (!strcmp(name, global_options[i].name)) {
+ for (i = 0; i < ctx->n_global_options; i++) {
+ if (!strcmp(name, ctx->global_options[i].name)) {
global_options[i].value = strdup(value);
- return 1;
+ break;
}
}
return 0;
}
-static char *get_global_option(const char *name)
+static char *get_global_option(struct kboot_context *ctx, const char *name)
{
int i;
@@ -117,9 +128,11 @@ static char *get_global_option(const char *name)
return NULL;
}
-static int parse_option(struct boot_option *opt, char *config)
+static int parse_option(struct kboot_context *kboot_ctx, char *opt_name,
+ char *config)
{
char *pos, *name, *value, *root, *initrd, *cmdline, *tmp;
+ struct boot_option *opt;
root = initrd = cmdline = NULL;
@@ -136,17 +149,24 @@ static int parse_option(struct boot_option *opt, char *config)
pos = strchr(config, ' ');
+ opt = talloc_zero(kboot_ctx, struct boot_option);
+ opt->id = talloc_asprintf(opt, "%s#%s",
+ kboot_ctx->discover->device->id, opt_name);
+ opt->name = talloc_strdup(opt, opt_name);
+
/* if there's no space, it's only a kernel image with no params */
if (!pos) {
- opt->boot_image_file = resolve_path(config, devpath);
- opt->description = strdup(config);
- return 1;
+ opt->boot_image_file = resolve_path(opt, config,
+ kboot_ctx->discover->device_path);
+ opt->description = talloc_strdup(opt, config);
+ goto out_add;
}
*pos = 0;
- opt->boot_image_file = resolve_path(config, devpath);
+ opt->boot_image_file = resolve_path(opt, config,
+ kboot_ctx->discover->device_path);
- cmdline = malloc(buf_size);
+ cmdline = talloc_array(opt, char, buf_size);
*cmdline = 0;
for (pos++; pos;) {
@@ -170,119 +190,108 @@ static int parse_option(struct boot_option *opt, char *config)
}
if (!root)
- root = get_global_option("root");
+ root = get_global_option(kboot_ctx, "root");
if (!initrd)
- initrd = get_global_option("initrd");
+ initrd = get_global_option(kboot_ctx, "initrd");
if (initrd) {
- asprintf(&tmp, "initrd=%s %s", initrd, cmdline);
- free(cmdline);
+ tmp = talloc_asprintf(opt, "initrd=%s %s", initrd, cmdline);
+ talloc_free(cmdline);
cmdline = tmp;
- opt->initrd_file = resolve_path(initrd, devpath);
+ opt->initrd_file = resolve_path(opt, initrd,
+ kboot_ctx->discover->device_path);
}
if (root) {
- asprintf(&tmp, "root=%s %s", root, cmdline);
- free(cmdline);
+ tmp = talloc_asprintf(opt, "root=%s %s", root, cmdline);
+ talloc_free(cmdline);
cmdline = tmp;
} else if (initrd) {
/* if there's an initrd but no root, fake up /dev/ram0 */
- asprintf(&tmp, "root=/dev/ram0 %s", cmdline);
- free(cmdline);
+ tmp = talloc_asprintf(opt, "root=/dev/ram0 %s", cmdline);
+ talloc_free(cmdline);
cmdline = tmp;
}
- pb_log("kboot cmdline: %s\n", cmdline);
opt->boot_args = cmdline;
- asprintf(&opt->description, "%s %s",
+ opt->description = talloc_asprintf(opt, "%s %s",
config, opt->boot_args);
+out_add:
+ device_add_boot_option(kboot_ctx->discover->device, opt);
return 1;
}
-static void parse_buf(struct device *dev, char *buf)
+static void parse_buf(struct kboot_context *kboot_ctx)
{
char *pos, *name, *value;
- int sent_device = 0;
-
- for (pos = buf; pos;) {
- struct boot_option opt;
+ for (pos = kboot_ctx->buf; pos;) {
pos = get_param_pair(pos, &name, &value, '\n');
- pb_log("kboot param: '%s' = '%s'\n", name, value);
-
if (name == NULL || param_is_ignored(name))
continue;
if (*name == '#')
continue;
- if (check_for_global_option(name, value))
+ if (check_for_global_option(kboot_ctx, name, value))
continue;
- memset(&opt, 0, sizeof(opt));
- opt.name = strdup(name);
-
- if (parse_option(&opt, value))
- if (!sent_device++)
- add_device(dev);
- add_boot_option(&opt);
-
- free(opt.name);
+ parse_option(kboot_ctx, name, value);
}
}
-static int parse(const char *device)
+
+static int parse(struct discover_context *ctx)
{
- char *filepath, *buf;
- int fd, len, rc = 0;
+ struct kboot_context *kboot_ctx;
+ char *filepath;
+ int fd, len, rc;
struct stat stat;
- struct device *dev;
- devpath = device;
+ rc = 0;
+ fd = -1;
+
+ kboot_ctx = talloc_zero(ctx, struct kboot_context);
+ kboot_ctx->discover = ctx;
- filepath = resolve_path("/etc/kboot.conf", devpath);
+ filepath = resolve_path(kboot_ctx, "/etc/kboot.conf", ctx->device_path);
fd = open(filepath, O_RDONLY);
if (fd < 0)
- goto out_free_path;
+ goto out;
if (fstat(fd, &stat))
- goto out_close;
+ goto out;
- buf = malloc(stat.st_size + 1);
- if (!buf)
- goto out_close;;
+ kboot_ctx->buf = talloc_array(kboot_ctx, char, stat.st_size + 1);
- len = read(fd, buf, stat.st_size);
+ len = read(fd, kboot_ctx->buf, stat.st_size);
if (len < 0)
- goto out_free_buf;
- buf[len] = 0;
+ goto out;
+ kboot_ctx->buf[len] = 0;
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->id = strdup(device);
- dev->icon_file = strdup(generic_icon_file(guess_device_type()));
+ if (!ctx->device->icon_file)
+ ctx->device->icon_file = talloc_strdup(ctx,
+ generic_icon_file(guess_device_type(ctx)));
- parse_buf(dev, buf);
+ parse_buf(kboot_ctx);
rc = 1;
-out_free_buf:
- free(buf);
-out_close:
- close(fd);
-out_free_path:
- free(filepath);
+out:
+ if (fd >= 0)
+ close(fd);
+ talloc_free(kboot_ctx);
return rc;
}
struct parser kboot_parser = {
- .name = "kboot.conf parser",
+ .name = "kboot.conf parser",
.priority = 98,
.parse = parse
};
OpenPOWER on IntegriCloud