[PATCH 7/7] syslinux: add syslinux parser support
Samuel Mendoza-Jonas
sam at mendozajonas.com
Thu Feb 8 15:11:37 AEDT 2018
On Thu, 2018-02-08 at 12:07 +1000, Brett Grandbois wrote:
> Signed-off-by: Brett Grandbois <brett.grandbois at opengear.com>
> ---
> discover/Makefile.am | 3 +-
> discover/syslinux-parser.c | 486 +++++++++++++++++++++++++++
> test/parser/Makefile.am | 13 +-
> test/parser/data/syslinux-include-nest-1.cfg | 7 +
> test/parser/data/syslinux-include-nest-2.cfg | 6 +
> test/parser/data/syslinux-include-root.cfg | 18 +
> test/parser/test-syslinux-explicit.c | 41 +++
> test/parser/test-syslinux-global-append.c | 56 +++
> test/parser/test-syslinux-nested-config.c | 41 +++
> test/parser/test-syslinux-single-yocto.c | 36 ++
> 10 files changed, 704 insertions(+), 3 deletions(-)
> create mode 100644 discover/syslinux-parser.c
> create mode 100644 test/parser/data/syslinux-include-nest-1.cfg
> create mode 100644 test/parser/data/syslinux-include-nest-2.cfg
> create mode 100644 test/parser/data/syslinux-include-root.cfg
> create mode 100644 test/parser/test-syslinux-explicit.c
> create mode 100644 test/parser/test-syslinux-global-append.c
> create mode 100644 test/parser/test-syslinux-nested-config.c
> create mode 100644 test/parser/test-syslinux-single-yocto.c
>
> diff --git a/discover/Makefile.am b/discover/Makefile.am
> index 4a6cbd0..ef4c602 100644
> --- a/discover/Makefile.am
> +++ b/discover/Makefile.am
> @@ -52,7 +52,8 @@ discover_pb_discover_SOURCES = \
> discover/user-event.h \
> discover/kboot-parser.c \
> discover/yaboot-parser.c \
> - discover/pxe-parser.c
> + discover/pxe-parser.c \
> + discover/syslinux-parser.c
Technically there's crossover between pxe-parser and syslinux-parser but
I'm happy to have these as separate implementations at the moment,
especially since we currently abuse the syslinux format a bit in pxe-
parser. Perhaps later on I can have a look at having a syslinux core
parser and putting the bonus bits in pxe-parser on top.
Otherwise looks good, and with tests no less! Some comments below:
>
> discover_pb_discover_LDADD = \
> discover/grub2/grub2-parser.ro \
> diff --git a/discover/syslinux-parser.c b/discover/syslinux-parser.c
> new file mode 100644
> index 0000000..7225a4f
> --- /dev/null
> +++ b/discover/syslinux-parser.c
> @@ -0,0 +1,486 @@
> +#if defined(HAVE_CONFIG_H)
> +#include "config.h"
> +#endif
> +
> +#include <assert.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <i18n/i18n.h>
> +#include <libgen.h>
> +
> +#include "log/log.h"
> +#include "list/list.h"
> +#include "file/file.h"
> +#include "talloc/talloc.h"
> +#include "types/types.h"
> +#include "parser-conf.h"
> +#include "parser-utils.h"
> +#include "resource.h"
> +#include "paths.h"
> +
> +struct syslinux_boot_option {
> + char *label;
> + char *image;
> + char *append;
> + char *initrd;
> + struct list_item list;
> +};
> +
> +/* by spec 16 is allowed */
> +#define INCLUDE_NEST_LIMIT 16
> +
> +struct syslinux_options {
> + struct list processed_options;
> + struct syslinux_boot_option *current_option;
> + int include_nest_level;
> + char *cfg_dir;
> +};
> +
> +
> +static const char *const syslinux_conf_files[] = {
> + "/boot/syslinux/syslinux.cfg",
> + "/syslinux/syslinux.cfg",
> + "/syslinux.cfg",
> + "/BOOT/SYSLINUX/SYSLINUX.CFG",
> + "/SYSLINUX/SYSLINUX.CFG",
> + "/SYSLINUX.CFG",
> + NULL
> +};
> +
> +static const char *const syslinux_kernel_unsupported_extensions[] = {
> + ".0", /* eventually support PXE here? */
> + ".bin",
> + ".bs",
> + ".bss",
> + ".c32",
> + ".cbt",
> + ".com",
> + ".img",
> + NULL
> +};
> +
> +static const char *const syslinux_ignored_names[] = {
> + "config",
> + "sysapend",
> + "localboot",
> + "ui",
> + "prompt",
> + "noescape",
> + "nocomplete",
> + "allowoptions",
> + "timeout",
> + "totaltimeout",
> + "ontimeout",
> + "onerror",
> + "serial",
> + "nohalt",
> + "console",
> + "font",
> + "kbdmap",
> + "say",
> + "display",
> + "f1",
> + "f2",
> + "f3",
> + "f4",
> + "f5"
> + "f6",
> + "f7",
> + "f8",
> + "f9",
> + "f10",
> + "f11",
> + "f12",
> + NULL
> +};
> +
> +static const char *const syslinux_unsupported_boot_names[] = {
> + "boot",
> + "bss",
> + "pxe",
> + "fdimage",
> + "comboot",
> + "com32",
> + NULL
> +};
> +
> +static struct conf_global_option syslinux_global_options[] = {
> + { .name = "default" },
> + { .name = "implicit" },
> + { .name = "append" },
> + { .name = NULL }
> +};
> +
> +
> +#define free_and_continue_on_false(X,Y) if (!(X)) { talloc_free((Y)); continue; }
> +
> +static void finish_boot_option(struct syslinux_options *state,
> + bool free_if_unused)
> +{
> + /*
> + * in the normal this function signals a new image block which means
> + * move the current block to the list of processed items
> + * the special case is a label before an image block which we need to
> + * know whether to keep it for further processing or junk it
> + */
> + if (state->current_option) {
> + if (state->current_option->image) {
> + list_add(&state->processed_options,
> + &state->current_option->list);
> + state->current_option = NULL;
> + }
> + else if (free_if_unused) {
> + talloc_free(state->current_option);
> + state->current_option = NULL;
> + }
> + }
> +}
> +
> +static bool start_new_option(struct syslinux_options *state)
> +{
> + bool ret = false;
> +
> + finish_boot_option(state, false);
> + if (!state->current_option)
> + state->current_option = talloc_zero(state, struct syslinux_boot_option);
> +
> + if (state->current_option)
> + ret = true;
> +
> + return ret;
> +}
> +
> +static void syslinux_process_pair(struct conf_context *conf, const char *name, char *value)
> +{
> + struct syslinux_options *state = conf->parser_info;
> + int len, rc;
> + char *buf;
> + char *pos;
> + char *path;
Fine to just have
char *buf, *pos, *path;
> +
> + do {
We return right after the do { } while(false), would it be neater to just
return instead of breaking to save ourselves a level of indent? It would
also help keep a few of these longer lines under 80 characters.
> + /* ignore bare values */
> + if (!name)
> + break;
> +
> + if (conf_param_in_list(syslinux_ignored_names, name))
> + break;
> +
> + /* a new boot entry needs to terminate any prior one */
> + if (conf_param_in_list(syslinux_unsupported_boot_names, name)) {
> + finish_boot_option(state, true);
> + break;
> + }
> +
> + if (streq(name, "label")) {
> + finish_boot_option(state, true);
> + state->current_option = talloc_zero(state,
> + struct syslinux_boot_option);
> + if (state->current_option)
> + state->current_option->label = talloc_strdup(state, value);
> + break;
> + }
> +
> + if (streq(name, "linux")) {
> +
> + if (start_new_option(state)) {
> + state->current_option->image = talloc_strdup(state, value);
> + if (!state->current_option->image) {
> + talloc_free(state->current_option);
> + state->current_option = NULL;
> + }
> + }
> +
> + break;
> + }
> +
> + if (streq(name, "kernel")) {
> +
> + if (start_new_option(state)) {
> + /*
> + * by spec a linux image can not have any of these
> + * extensions, it can have no extension or anything not
> + * in this list
> + */
> + pos = strrchr(value, '.');
> + if (!pos ||
> + !conf_param_in_list(syslinux_kernel_unsupported_extensions, pos)) {
> + state->current_option->image = talloc_strdup(state, value);
> + if (!state->current_option->image) {
> + talloc_free(state->current_option);
> + state->current_option = NULL;
> + }
> + }
> + else /* clean up any possible trailing label */
> + finish_boot_option(state, true);
> + }
> + break;
> + }
> +
> +
> +
> + /* APPEND can be global and/or local so need special handling */
> + if (streq(name, "append")) {
> + if (state->current_option) {
> + /* by spec only take last if multiple APPENDs */
> + if (state->current_option->append)
> + talloc_free(state->current_option->append);
> + state->current_option->append = talloc_strdup(state, value);
> + if (!state->current_option->append) {
> + talloc_free(state->current_option);
> + state->current_option = NULL;
> + }
> + }
> + else {
> + finish_boot_option(state, true);
> + conf_set_global_option(conf, name, value);
> + }
> + break;
> + }
> +
> + /* now the general globals */
> + if (conf_set_global_option(conf, name, value)) {
> + finish_boot_option(state, true);
> + break;
> + }
> +
> + if (streq(name, "initrd")) {
> + if (state->current_option) {
> + state->current_option->initrd = talloc_strdup(state, value);
> + if (!state->current_option->initrd) {
> + talloc_free(state->current_option);
> + state->current_option = NULL;
> + }
> + }
> + break;
> + }
> +
> + if (streq(name, "include")) {
> + if (state->include_nest_level < INCLUDE_NEST_LIMIT) {
> + state->include_nest_level++;
> +
> + /* if absolute in as-is */
> + if (value[0] == '/')
> + path = talloc_strdup(state, value);
> + else /* otherwise relative to the root config file */
> + path = join_paths(state, state->cfg_dir, value);
> +
> + rc = parser_request_file(conf->dc, conf->dc->device, path, &buf, &len);
> + if (!rc) {
> + conf_parse_buf(conf, buf, len);
> +
> + device_handler_status_dev_info(conf->dc->handler, conf->dc->device,
> + _("Parsed nested syslinux configuration from %s"), value);
> + talloc_free(buf);
> + }
> + else {
> + device_handler_status_dev_info(conf->dc->handler, conf->dc->device,
> + _("Failed to parse nested syslinux configuration from %s"), value);
> + }
> +
> + talloc_free(path);
> +
> + state->include_nest_level--;
> + }
> + else {
> + device_handler_status_dev_err(conf->dc->handler, conf->dc->device,
> + _("Nested syslinux INCLUDE exceeds limit...ignored"));
> + }
> + break;
> + }
> +
> + pb_debug("%s: unknown name: %s\n", __func__, name);
> + } while(false);
> +}
> +
> +static void syslinux_finalize(struct conf_context *conf)
> +{
> + struct syslinux_options *state = conf->parser_info;
> + const char *global_append;
> + const char *global_default;
> + struct syslinux_boot_option *syslinux_opt;
> + const char *image;
> + const char *label;
> + bool implicit_image = true;
> + struct discover_context *dc = conf->dc;
> + struct discover_boot_option *d_opt;
> + struct boot_option *opt;
> + char *args_sigfile_default;
> +
> + /* clean up any lingering boot entries */
> + finish_boot_option(state, true);
> +
> + global_append = conf_get_global_option(conf, "append");
> + global_default = conf_get_global_option(conf, "default");
> +
> + /*
> + * by spec '0' means disable
> + * note we set the default to '1' (which is by spec) in syslinux_parse
> + */
> + if (conf_get_global_option(conf, "implicit"), "0")
> + implicit_image = false;
> +
> + list_for_each_entry(&state->processed_options, syslinux_opt, list) {
> + /* need a valid image */
> + if (!syslinux_opt->image)
> + continue;
> +
> + image = syslinux_opt->image;
> + label = syslinux_opt->label;
> +
> + /* if implicit is disabled we must have a label */
> + if (!label && !implicit_image)
> + continue;
> +
> + d_opt = discover_boot_option_create(dc, dc->device);
> + if (!d_opt) continue;
Indent this
> + free_and_continue_on_false(d_opt->option, d_opt);
Despite the big hint in the name this macro still throws me off a little
due to the 'hidden' continue in it. I think I'd be happier trading a
bigger line count to have something like
static inline bool free_if_null(foo, bar)
{
if (!foo)
talloc_free(bar);
return !foo;
}
...
if (free_if_null(d_opt->option, d_opt))
continue;
Or in this particular case since 'bar' is always d_opt,
if (!d_opt->option)
goto fail;
...
fail:
talloc_free(d_opt)
} /* loop */
Thoughts?
> +
> + opt = d_opt->option;
> +
> + if (syslinux_opt->append) {
> + /* '-' can signal do not use global APPEND */
> + if (!strcmp(syslinux_opt->append, "-"))
> + opt->boot_args = talloc_strdup(opt, "");
> + else
> + opt->boot_args = talloc_asprintf(opt, "%s %s",
> + global_append,
> + syslinux_opt->append);
> + }
> + else
} else
> + opt->boot_args = talloc_strdup(opt, global_append);
> +
> + free_and_continue_on_false(opt->boot_args, d_opt);
> +
> + opt->id = talloc_asprintf(opt, "%s#%s", dc->device->device->id, image);
> +
> + free_and_continue_on_false(opt->id, d_opt);
> +
> + if (label) {
> + opt->name = talloc_strdup(opt, label);
> + if (!strcmp(label, global_default))
> + opt->is_default = true;
> +
> + opt->description = talloc_asprintf(opt, "(%s) %s", label, image);
> + }
> + else {
> + opt->name = talloc_strdup(opt, image);
> + opt->description = talloc_strdup(opt, image);
> + }
> +
> + free_and_continue_on_false(opt->name, d_opt);
> +
> + d_opt->boot_image = create_devpath_resource(d_opt, dc->device, image);
> +
> + free_and_continue_on_false(d_opt->boot_image, d_opt);
> +
> + if (syslinux_opt->initrd) {
> + d_opt->initrd = create_devpath_resource(d_opt, dc->device,
> + syslinux_opt->initrd);
> + opt->description = talloc_asprintf_append(opt->description,
> + " initrd=%s",
> + syslinux_opt->initrd);
> +
> + free_and_continue_on_false(d_opt->initrd, d_opt);
> + }
> +
> + opt->description = talloc_asprintf_append(opt->description,
> + " args=%s",
> + opt->boot_args);
> +
> + free_and_continue_on_false(opt->description, d_opt);
> +
> + args_sigfile_default = talloc_asprintf(d_opt, "%s.cmdline.sig",
> + image);
> + free_and_continue_on_false(args_sigfile_default, d_opt);
> +
> + d_opt->args_sig_file = create_devpath_resource(d_opt, dc->device,
> + args_sigfile_default);
> + free_and_continue_on_false(d_opt->args_sig_file, d_opt);
> +
> + talloc_free(args_sigfile_default);
> +
> + conf_strip_str(opt->boot_args);
> + conf_strip_str(opt->description);
> +
> + discover_context_add_boot_option(dc, d_opt);
> + }
> +}
> +
> +
> +
Super nit-picky but extra space :)
> +static int syslinux_parse(struct discover_context *dc)
> +{
> + struct conf_context *conf;
> + const char * const *filename;
> + char *cfg_dir;
> + struct syslinux_options *state;
> + char *buf;
> + int len, rc;
And we tend to order declarations in descending length, eg:
struct syslinux_options *state;
const char * const *filename;
struct conf_context *conf;
char *cfg_dir, *buf;
int len, rc;
> +
> + /* Support block device boot only at present */
> + if (dc->event)
> + return -1;
> +
> + conf = talloc_zero(dc, struct conf_context);
> +
> + if (!conf)
> + return -1;
> +
> + conf->dc = dc;
> + conf->global_options = syslinux_global_options,
> + conf_init_global_options(conf);
> + conf->get_pair = conf_get_pair_space;
> + conf->process_pair = syslinux_process_pair;
> +
> + conf->parser_info = state = talloc_zero(conf, struct syslinux_options);
> + list_init(&state->processed_options);
> +
> + /*
> + * set the global defaults
> + * by spec 'default' defaults to 'linux' and
> + * 'implicit' defaults to '1', we also just set
> + * and empty string in 'append' to make it easier
> + * in syslinux_finish
> + */
> + conf_set_global_option(conf, "default", "linux");
> + conf_set_global_option(conf, "implicit", "1");
> + conf_set_global_option(conf, "append", "");
> +
> + for (filename = syslinux_conf_files; *filename; filename++) {
> + rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
> + if (rc)
> + continue;
> +
> + /*
> + * save location of root config file for possible
> + * INCLUDE directives later
> + *
> + * dirname can overwrite so need local copy to work on
> + */
> + cfg_dir = talloc_strdup(conf, *filename);
> + state->cfg_dir = talloc_strdup(state, dirname(cfg_dir));
> + talloc_free(cfg_dir);
> +
> + conf_parse_buf(conf, buf, len);
> + device_handler_status_dev_info(dc->handler, dc->device,
> + _("Parsed syslinux configuration from %s"),
> + *filename);
> + talloc_free(buf);
> +
> + syslinux_finalize(conf);
> + }
> +
> + talloc_free(conf);
> + return 0;
> +}
> +
> +
> +
> +static struct parser syslinux_parser = {
> + .name = "syslinux",
> + .parse = syslinux_parse,
> + .resolve_resource = resolve_devpath_resource,
> +};
> +
> +register_parser(syslinux_parser);
> diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am
> index 31300f0..a0795db 100644
> --- a/test/parser/Makefile.am
> +++ b/test/parser/Makefile.am
> @@ -73,7 +73,12 @@ parser_TESTS = \
> test/parser/test-pxe-discover-bootfile-relative-conffile \
> test/parser/test-pxe-discover-bootfile-absolute-conffile \
> test/parser/test-pxe-discover-bootfile-async-file \
> - test/parser/test-unresolved-remove
> + test/parser/test-unresolved-remove \
> + test/parser/test-syslinux-single-yocto \
> + test/parser/test-syslinux-global-append \
> + test/parser/test-syslinux-explicit \
> + test/parser/test-syslinux-nested-config
> +
>
> TESTS += $(parser_TESTS)
> check_PROGRAMS += $(parser_TESTS) test/parser/libtest.ro
> @@ -82,7 +87,10 @@ check_DATA += \
> test/parser/data/grub2-f18-ppc64.conf \
> test/parser/data/grub2-f20-ppc.conf \
> test/parser/data/grub2-ubuntu-13_04-x86.conf \
> - test/parser/data/yaboot-rh8-ppc64.conf
> + test/parser/data/yaboot-rh8-ppc64.conf \
> + test/parser/data/syslinux-include-root.cfg \
> + test/parser/data/syslinux-include-nest-1.cfg \
> + test/parser/data/syslinux-include-nest-2.cfg
>
> $(parser_TESTS): AM_CPPFLAGS += \
> -I$(top_srcdir)/discover \
> @@ -107,6 +115,7 @@ test_parser_libtest_ro_SOURCES = \
> discover/yaboot-parser.c \
> discover/kboot-parser.c \
> discover/pxe-parser.c \
> + discover/syslinux-parser.c \
> discover/platform.c \
> discover/resource.c \
> discover/paths.c \
> diff --git a/test/parser/data/syslinux-include-nest-1.cfg b/test/parser/data/syslinux-include-nest-1.cfg
> new file mode 100644
> index 0000000..65e680e
> --- /dev/null
> +++ b/test/parser/data/syslinux-include-nest-1.cfg
> @@ -0,0 +1,7 @@
> +LABEL com32
> +COM32 /boot/com32.c32
> +
> +INCLUDE syslinux-include-nest-2.cfg
> +
> +LABEL bss
> +KERNEL /boot/test.bss
> diff --git a/test/parser/data/syslinux-include-nest-2.cfg b/test/parser/data/syslinux-include-nest-2.cfg
> new file mode 100644
> index 0000000..26d7cff
> --- /dev/null
> +++ b/test/parser/data/syslinux-include-nest-2.cfg
> @@ -0,0 +1,6 @@
> +LABEL boot
> +KERNEL /bzImage-boot
> +INITRD /initrd-boot
> +APPEND root=/dev/sda
> +
> +DEFAULT boot
> diff --git a/test/parser/data/syslinux-include-root.cfg b/test/parser/data/syslinux-include-root.cfg
> new file mode 100644
> index 0000000..834360c
> --- /dev/null
> +++ b/test/parser/data/syslinux-include-root.cfg
> @@ -0,0 +1,18 @@
> +APPEND console=ttyS0
> +
> +LABEL floppy
> +FDIMAGE /boot/floppy.img
> +
> +LABEL backup
> +KERNEL /backup/vmlinuz
> +APPEND root=/dev/sdb
> +INITRD /boot/initrd
> +
> +LABEL comboot
> +KERNEL /boot/comboot.com
> +
> +INCLUDE /syslinux-include-nest-1.cfg
> +
> +LABEL linux
> +LINUX /boot/bzImage
> +APPEND root=/dev/sdc
> diff --git a/test/parser/test-syslinux-explicit.c b/test/parser/test-syslinux-explicit.c
> new file mode 100644
> index 0000000..5d23f50
> --- /dev/null
> +++ b/test/parser/test-syslinux-explicit.c
> @@ -0,0 +1,41 @@
> +/* test a standard yocto syslinux wic cfg */
> +
> +#include "parser-test.h"
> +
> +#if 0 /* PARSER_EMBEDDED_CONFIG */
> +
> +
> +DEFAULT boot
> +
> +KERNEL /vmlinuz
> +APPEND console=tty0
> +
> +LABEL backup
> +KERNEL /backup/vmlinuz
> +APPEND root=/dev/sdb
> +INITRD /boot/initrd
> +
> +IMPLICIT 0
> +
> +#endif
> +
> +void run_test(struct parser_test *test)
> +{
> + struct discover_boot_option *opt;
> + struct discover_context *ctx;
> +
> + test_read_conf_embedded(test, "/boot/syslinux/syslinux.cfg");
> +
> + test_run_parser(test, "syslinux");
> +
> + ctx = test->ctx;
> +
> + check_boot_option_count(ctx, 1);
> +
> + opt = get_boot_option(ctx, 0);
> +
> + check_name(opt, "backup");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/backup/vmlinuz");
> + check_args(opt, " root=/dev/sdb");
> + check_resolved_local_resource(opt->initrd, ctx->device, "/boot/initrd");
> +}
> diff --git a/test/parser/test-syslinux-global-append.c b/test/parser/test-syslinux-global-append.c
> new file mode 100644
> index 0000000..18af99a
> --- /dev/null
> +++ b/test/parser/test-syslinux-global-append.c
> @@ -0,0 +1,56 @@
> +
> +#include "parser-test.h"
> +
> +#if 0 /* PARSER_EMBEDDED_CONFIG */
> +
> +APPEND console=ttyS0
> +
> +LABEL linux
> +LINUX /vmlinuz
> +APPEND console=tty0
> +
> +LABEL backup
> +KERNEL /backup/vmlinuz
> +APPEND root=/dev/sdb
> +INITRD /boot/initrd
> +
> +LABEL hyphen
> +KERNEL /test/vmlinuz
> +APPEND -
> +
> +#endif
> +
> +void run_test(struct parser_test *test)
> +{
> + struct discover_boot_option *opt;
> + struct discover_context *ctx;
> +
> + test_read_conf_embedded(test, "/syslinux/syslinux.cfg");
> +
> + test_run_parser(test, "syslinux");
> +
> + ctx = test->ctx;
> +
> + check_boot_option_count(ctx, 3);
> + opt = get_boot_option(ctx, 2);
> +
> + check_name(opt, "linux");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/vmlinuz");
> + check_is_default(opt);
> + check_args(opt, "console=ttyS0 console=tty0");
> + check_not_present_resource(opt->initrd);
> +
> + opt = get_boot_option(ctx, 1);
> +
> + check_name(opt, "backup");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/backup/vmlinuz");
> + check_args(opt, "console=ttyS0 root=/dev/sdb");
> + check_resolved_local_resource(opt->initrd, ctx->device, "/boot/initrd");
> +
> + opt = get_boot_option(ctx, 0);
> +
> + check_name(opt, "hyphen");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/test/vmlinuz");
> + check_args(opt, "");
> + check_not_present_resource(opt->initrd);
> +}
> diff --git a/test/parser/test-syslinux-nested-config.c b/test/parser/test-syslinux-nested-config.c
> new file mode 100644
> index 0000000..73c4774
> --- /dev/null
> +++ b/test/parser/test-syslinux-nested-config.c
> @@ -0,0 +1,41 @@
> +
> +#include "parser-test.h"
> +
> +
> +void run_test(struct parser_test *test)
> +{
> + struct discover_boot_option *opt;
> + struct discover_context *ctx;
> +
> + test_read_conf_file(test, "syslinux-include-root.cfg", "/boot/syslinux/syslinux.cfg");
> + test_read_conf_file(test, "syslinux-include-nest-1.cfg", "/syslinux-include-nest-1.cfg");
> + test_read_conf_file(test, "syslinux-include-nest-2.cfg", "/boot/syslinux/syslinux-include-nest-2.cfg");
> +
> + test_run_parser(test, "syslinux");
> +
> + ctx = test->ctx;
> +
> + check_boot_option_count(ctx, 3);
> +
> + opt = get_boot_option(ctx, 1);
> +
> + check_name(opt, "boot");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/bzImage-boot");
> + check_is_default(opt);
> + check_args(opt, "console=ttyS0 root=/dev/sda");
> + check_resolved_local_resource(opt->initrd, ctx->device, "/initrd-boot");
> +
> + opt = get_boot_option(ctx, 2);
> +
> + check_name(opt, "backup");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/backup/vmlinuz");
> + check_args(opt, "console=ttyS0 root=/dev/sdb");
> + check_resolved_local_resource(opt->initrd, ctx->device, "/boot/initrd");
> +
> + opt = get_boot_option(ctx, 0);
> +
> + check_name(opt, "linux");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/boot/bzImage");
> + check_args(opt, "console=ttyS0 root=/dev/sdc");
> + check_not_present_resource(opt->initrd);
> +}
> diff --git a/test/parser/test-syslinux-single-yocto.c b/test/parser/test-syslinux-single-yocto.c
> new file mode 100644
> index 0000000..e5e084d
> --- /dev/null
> +++ b/test/parser/test-syslinux-single-yocto.c
> @@ -0,0 +1,36 @@
> +/* test a standard yocto syslinux wic cfg */
> +
> +#include "parser-test.h"
> +
> +#if 0 /* PARSER_EMBEDDED_CONFIG */
> +PROMPT 0
> +TIMEOUT 0
> +
> +ALLOWOPTIONS 1
> +SERIAL 0 115200
> +
> +DEFAULT boot
> +LABEL boot
> +KERNEL /vmlinuz
> +APPEND console=ttyS0,115200n8 console=tty0
> +#endif
> +
> +void run_test(struct parser_test *test)
> +{
> + struct discover_boot_option *opt;
> + struct discover_context *ctx;
> +
> + test_read_conf_embedded(test, "/syslinux.cfg");
> +
> + test_run_parser(test, "syslinux");
> +
> + ctx = test->ctx;
> +
> + check_boot_option_count(ctx, 1);
> + opt = get_boot_option(ctx, 0);
> +
> + check_name(opt, "boot");
> + check_resolved_local_resource(opt->boot_image, ctx->device, "/vmlinuz");
> + check_is_default(opt);
> + check_args(opt, " console=ttyS0,115200n8 console=tty0");
> +}
More information about the Petitboot
mailing list