8 #include "talloc/talloc.h"
9 #include "types/types.h"
10 #include "parser-conf.h"
11 #include "parser-utils.h"
15 struct boot_option *opt;
16 const char *desc_image;
19 const char *const *known_names;
22 static void yaboot_finish(struct conf_context *conf)
24 struct yaboot_state *state = conf->parser_info;
25 struct device *dev = conf->dc->device->device;
27 if (!state->desc_image) {
28 pb_log("%s: %s: no image found\n", __func__, dev->id);
33 assert(state->opt->name);
34 assert(state->opt->boot_args);
36 state->opt->description = talloc_asprintf(state->opt, "%s %s %s",
38 (state->desc_initrd ? state->desc_initrd : ""),
39 state->opt->boot_args);
41 talloc_free(state->desc_initrd);
42 state->desc_initrd = NULL;
44 conf_strip_str(state->opt->boot_args);
45 conf_strip_str(state->opt->description);
47 /* opt is persistent, so must be associated with device */
49 discover_context_add_boot_option(conf->dc, state->opt);
51 state->opt = talloc_zero(conf->dc, struct boot_option);
52 state->opt->boot_args = talloc_strdup(state->opt, "");
55 static void yaboot_process_pair(struct conf_context *conf, const char *name,
58 struct yaboot_state *state = conf->parser_info;
63 static const struct fixed_pair suse_fp32 = {
64 .image = "/suseboot/vmlinux32",
65 .initrd = "/suseboot/initrd32",
67 static const struct fixed_pair suse_fp64 = {
68 .image = "/suseboot/vmlinux64",
69 .initrd = "/suseboot/initrd64",
71 const struct fixed_pair *suse_fp;
73 /* fixup for bare values */
78 if (!state->globals_done && conf_set_global_option(conf, name, value))
81 if (!conf_param_in_list(state->known_names, name))
84 state->globals_done = 1;
88 if (streq(name, "image")) {
89 const char *g_boot = conf_get_global_option(conf, "boot");
90 const char *g_part = conf_get_global_option(conf, "partition");
92 /* First finish any previous image. */
94 if (state->opt->boot_image_file)
97 /* Then start the new image. */
99 if (g_boot && g_part) {
100 char* dev = talloc_asprintf(NULL, "%s%s", g_boot,
103 state->opt->boot_image_file = resolve_path(state->opt,
105 state->desc_image = talloc_asprintf(state->opt,
109 state->opt->boot_image_file = resolve_path(state->opt,
111 state->desc_image = talloc_asprintf(state->opt,
112 "%s%s", g_boot, value);
114 state->opt->boot_image_file = resolve_path(state->opt,
115 value, conf->dc->device->device_path);
116 state->desc_image = talloc_strdup(state->opt, value);
122 /* Special processing for SUSE install CD. */
124 if (streq(name, "image[32bit]"))
125 suse_fp = &suse_fp32;
126 else if (streq(name, "image[64bit]"))
127 suse_fp = &suse_fp64;
132 /* First finish any previous image. */
134 if (state->opt->boot_image_file)
137 /* Then start the new image. */
140 state->opt->boot_image_file = resolve_path(state->opt,
141 value, conf->dc->device->device_path);
142 state->desc_image = talloc_strdup(state->opt, value);
144 state->opt->boot_image_file = resolve_path(state->opt,
145 suse_fp->image, conf->dc->device->device_path);
146 state->desc_image = talloc_strdup(state->opt,
149 state->opt->initrd_file = resolve_path(state->opt,
150 suse_fp->initrd, conf->dc->device->device_path);
151 state->desc_initrd = talloc_asprintf(state, "initrd=%s",
158 if (!state->opt->boot_image_file) {
159 pb_log("%s: unknown name: %s\n", __func__, name);
165 if (streq(name, "initrd")) {
166 const char *g_boot = conf_get_global_option(conf, "boot");
167 const char *g_part = conf_get_global_option(conf, "partition");
169 if (g_boot && g_part) {
170 char* dev = talloc_asprintf(NULL, "%s%s", g_boot,
173 state->opt->initrd_file = resolve_path(state->opt,
175 state->desc_initrd = talloc_asprintf(state,
176 "initrd=%s%s", dev, value);
179 state->opt->initrd_file = resolve_path(state->opt,
181 state->desc_initrd = talloc_asprintf(state,
182 "initrd=%s%s", g_boot, value);
184 state->opt->initrd_file = resolve_path(state->opt,
185 value, conf->dc->device->device_path);
186 state->desc_initrd = talloc_asprintf(state, "initrd=%s",
194 if (streq(name, "label")) {
195 state->opt->id = talloc_asprintf(state->opt, "%s#%s",
196 conf->dc->device->device->id, value);
197 state->opt->name = talloc_strdup(state->opt, value);
203 if (streq(name, "append")) {
204 state->opt->boot_args = talloc_asprintf_append(
205 state->opt->boot_args, "%s ", value);
209 if (streq(name, "initrd-size")) {
210 state->opt->boot_args = talloc_asprintf_append(
211 state->opt->boot_args, "ramdisk_size=%s ", value);
215 if (streq(name, "literal")) {
216 if (*state->opt->boot_args) {
217 pb_log("%s: literal over writes '%s'\n", __func__,
218 state->opt->boot_args);
219 talloc_free(state->opt->boot_args);
221 talloc_asprintf(state->opt, "%s ", value);
225 if (streq(name, "ramdisk")) {
226 state->opt->boot_args = talloc_asprintf_append(
227 state->opt->boot_args, "ramdisk=%s ", value);
231 if (streq(name, "read-only")) {
232 state->opt->boot_args = talloc_asprintf_append(
233 state->opt->boot_args, "ro ");
237 if (streq(name, "read-write")) {
238 state->opt->boot_args = talloc_asprintf_append(
239 state->opt->boot_args, "rw ");
243 if (streq(name, "root")) {
244 state->opt->boot_args = talloc_asprintf_append(
245 state->opt->boot_args, "root=%s ", value);
249 pb_log("%s: unknown name: %s\n", __func__, name);
252 static struct conf_global_option yaboot_global_options[] = {
254 { .name = "initrd" },
255 { .name = "partition" },
260 static const char *const yaboot_conf_files[] = {
265 "/suseboot/yaboot.cnf",
270 "/SUSEBOOT/YABOOT.CNF",
274 static const char *yaboot_known_names[] = {
277 "image[64bit]", /* SUSE extension */
278 "image[32bit]", /* SUSE extension */
290 static int yaboot_parse(struct discover_context *dc, char *buf, int len)
292 struct conf_context *conf;
293 struct yaboot_state *state;
295 conf = talloc_zero(dc, struct conf_context);
301 conf->global_options = yaboot_global_options,
302 conf_init_global_options(conf);
303 conf->get_pair = conf_get_pair_equal;
304 conf->process_pair = yaboot_process_pair;
305 conf->finish = yaboot_finish;
306 conf->parser_info = state = talloc_zero(conf, struct yaboot_state);
308 state->known_names = yaboot_known_names;
310 /* opt is persistent, so must be associated with device */
312 state->opt = talloc_zero(conf->dc->device, struct boot_option);
313 state->opt->boot_args = talloc_strdup(state->opt, "");
315 conf_parse_buf(conf, buf, len);
321 struct parser __yaboot_parser = {
323 .parse = yaboot_parse,
324 .filenames = yaboot_conf_files,