-#define _GNU_SOURCE
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "log/log.h"
#include "talloc/talloc.h"
struct yaboot_state {
int globals_done;
- const char *const *known_names;
/* current option data */
struct discover_boot_option *opt;
const char *path)
{
struct discover_boot_option *opt = state->opt;
- const char *dev, *part;
+ const char *dev, *part, *devpos;
struct resource *res;
- char *devpath;
+ char *devpath, *devstr;
dev = state->device;
part = state->partition;
devpath = talloc_strdup(conf, path);
} else if (dev && part) {
- devpath = talloc_asprintf(conf,
- "%s%s:%s", dev, part, path);
+ devpos = &dev[strlen(dev) - 1];
+ if (isdigit(*devpos)) {
+ while (isdigit(*devpos))
+ devpos--;
+
+ devstr = talloc_strndup(conf, dev, devpos - dev + 1);
+ devpath = talloc_asprintf(conf, "%s%s:%s", devstr,
+ part, path);
+ talloc_free(devstr);
+ } else {
+ devpath = talloc_asprintf(conf,
+ "%s%s:%s", dev, part, path);
+ }
} else if (dev) {
devpath = talloc_asprintf(conf, "%s:%s", dev, path);
} else {
static void yaboot_finish(struct conf_context *conf)
{
struct yaboot_state *state = conf->parser_info;
+ const char *default_label;
struct boot_option *opt;
- assert(state->opt);
+ if (!state->opt)
+ return;
opt = state->opt->option;
assert(opt);
conf_strip_str(opt->boot_args);
conf_strip_str(opt->description);
+ default_label = conf_get_global_option(conf, "default");
+ if (default_label &&
+ !strcasecmp(state->opt->option->name, default_label))
+ state->opt->option->is_default = true;
+
discover_context_add_boot_option(conf->dc, state->opt);
}
if (!state->globals_done && conf_set_global_option(conf, name, value))
return;
- if (!conf_param_in_list(state->known_names, name))
- return;
-
- state->globals_done = 1;
-
/* image */
-
if (streq(name, "image")) {
+ /* an image section finishes our global defintions */
+ state->globals_done = 1;
/* First finish any previous image. */
if (opt)
/* all other processing requires an image */
if (!opt) {
- pb_log("%s: unknown name: %s\n", __func__, name);
+ pb_debug("%s: unknown name: %s\n", __func__, name);
return;
}
return;
}
- pb_log("%s: unknown name: %s\n", __func__, name);
+ pb_debug("%s: unknown name: %s\n", __func__, name);
}
static struct conf_global_option yaboot_global_options[] = {
{ .name = "video" },
{ .name = "literal" },
{ .name = "ramdisk" },
+ { .name = "default" },
{ .name = NULL },
};
NULL
};
-static const char *yaboot_known_names[] = {
- "append",
- "image",
- "image[64bit]", /* SUSE extension */
- "image[32bit]", /* SUSE extension */
- "initrd",
- "initrd-size",
- "label",
- "literal",
- "ramdisk",
- "read-only",
- "read-write",
- "root",
- "device",
- "partition",
- NULL
-};
-
-static int yaboot_parse(struct discover_context *dc, char *buf, int len)
+static int yaboot_parse(struct discover_context *dc)
{
- struct conf_context *conf;
+ const char * const *filename;
struct yaboot_state *state;
+ struct conf_context *conf;
+ int len, rc;
+ char *buf;
+
+ /* Support block device boot only at present */
+ if (dc->event)
+ return -1;
conf = talloc_zero(dc, struct conf_context);
if (!conf)
- return 0;
+ return -1;
conf->dc = dc;
conf->global_options = yaboot_global_options,
conf->finish = yaboot_finish;
conf->parser_info = state = talloc_zero(conf, struct yaboot_state);
- state->known_names = yaboot_known_names;
-
state->opt = NULL;
- conf_parse_buf(conf, buf, len);
+ for (filename = yaboot_conf_files; *filename; filename++) {
+ rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
+ if (rc)
+ continue;
+
+ conf_parse_buf(conf, buf, len);
+ talloc_free(buf);
+ }
talloc_free(conf);
- return 1;
+ return 0;
}
static struct parser yaboot_parser = {
.name = "yaboot",
- .method = CONF_METHOD_LOCAL_FILE,
.parse = yaboot_parse,
- .filenames = yaboot_conf_files,
.resolve_resource = resolve_devpath_resource,
};