From e4f5bd235894c11823ac1befe8c8c43063cad026 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 14 Mar 2013 14:18:54 +0800 Subject: [PATCH] discover: Introduce a container type for boot options This change introduces a new type, struct discover_boot_option. Like struct discover_device adds discover-specific data to struct device, struct discover_boot_option allows the discover server to store more than just the boot option strings for a boot option. Signed-off-by: Jeremy Kerr --- discover/device-handler.c | 43 +++++++++++------ discover/device-handler.h | 16 ++++++- discover/discover-server.c | 9 ++-- discover/event-parser.c | 10 ++-- discover/grub2-parser.c | 43 +++++++++-------- discover/kboot-parser.c | 14 +++--- discover/yaboot-parser.c | 97 ++++++++++++++++++++------------------ test/parser/parser-test.c | 31 ++++++++---- 8 files changed, 160 insertions(+), 103 deletions(-) diff --git a/discover/device-handler.c b/discover/device-handler.c index 89aa67d..2b16b2e 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -37,8 +37,8 @@ static void context_commit(struct device_handler *handler, struct discover_context *ctx) { struct discover_device *dev = ctx->device; + struct discover_boot_option *opt, *tmp; unsigned int i, existing_device; - struct boot_option *opt, *tmp; /* do we already have this device? */ for (i = 0; i < handler->n_devices; i++) { @@ -63,14 +63,15 @@ static void context_commit(struct device_handler *handler, /* move boot options from the context to the device */ list_for_each_entry_safe(&ctx->boot_options, opt, tmp, list) { list_remove(&opt->list); - list_add(&dev->device->boot_options, &opt->list); - dev->device->n_options++; - discover_server_notify_boot_option_add(handler->server, opt); + list_add(&dev->boot_options, &opt->list); + talloc_steal(dev, opt); + discover_server_notify_boot_option_add(handler->server, + opt->option); } } void discover_context_add_boot_option(struct discover_context *ctx, - struct boot_option *boot_option) + struct discover_boot_option *boot_option) { list_add(&ctx->boot_options, &boot_option->list); talloc_steal(ctx, boot_option); @@ -118,7 +119,7 @@ int device_handler_get_device_count(const struct device_handler *handler) * device_handler_get_device - Get a handler device by index. */ -const struct device *device_handler_get_device( +const struct discover_device *device_handler_get_device( const struct device_handler *handler, unsigned int index) { if (index >= handler->n_devices) { @@ -126,7 +127,7 @@ const struct device *device_handler_get_device( return NULL; } - return handler->devices[index]->device; + return handler->devices[index]; } static void setup_device_links(struct discover_device *dev) @@ -303,7 +304,7 @@ static struct discover_device *discover_device_create( dev = talloc_zero(ctx, struct discover_device); dev->device = talloc_zero(dev, struct device); - list_init(&dev->device->boot_options); + list_init(&dev->boot_options); devname = event_get_param(ctx->event, "DEVNAME"); if (devname) @@ -316,6 +317,20 @@ static struct discover_device *discover_device_create( return dev; } +struct discover_boot_option *discover_boot_option_create( + struct discover_context *ctx, + struct discover_device *device) +{ + struct discover_boot_option *opt; + + opt = talloc_zero(ctx, struct discover_boot_option); + opt->option = talloc_zero(opt, struct boot_option); + opt->device = device; + + return opt; +} + + static int handle_add_udev_event(struct device_handler *handler, struct event *event) { @@ -551,17 +566,17 @@ struct discover_device *device_lookup_by_id( return device_lookup(device_handler, device_match_id, id); } -static struct boot_option *find_boot_option_by_id( +static struct discover_boot_option *find_boot_option_by_id( struct device_handler *handler, const char *id) { unsigned int i; for (i = 0; i < handler->n_devices; i++) { struct discover_device *dev = handler->devices[i]; - struct boot_option *opt; + struct discover_boot_option *opt; - list_for_each_entry(&dev->device->boot_options, opt, list) - if (!strcmp(opt->id, id)) + list_for_each_entry(&dev->boot_options, opt, list) + if (!strcmp(opt->option->id, id)) return opt; } @@ -571,9 +586,9 @@ static struct boot_option *find_boot_option_by_id( void device_handler_boot(struct device_handler *handler, struct boot_command *cmd) { - struct boot_option *opt; + struct discover_boot_option *opt; opt = find_boot_option_by_id(handler, cmd->option_id); - boot(handler, opt, cmd, handler->dry_run); + boot(handler, opt->option, cmd, handler->dry_run); } diff --git a/discover/device-handler.h b/discover/device-handler.h index 9a7cf6d..3c4574b 100644 --- a/discover/device-handler.h +++ b/discover/device-handler.h @@ -22,8 +22,17 @@ struct discover_device { char *mount_path; char *device_path; + + struct list boot_options; +}; + +struct discover_boot_option { + struct discover_device *device; + struct boot_option *option; + struct list_item list; }; + struct discover_context { struct event *event; struct discover_device *device; @@ -36,12 +45,15 @@ struct device_handler *device_handler_init(struct discover_server *server, void device_handler_destroy(struct device_handler *devices); int device_handler_get_device_count(const struct device_handler *handler); -const struct device *device_handler_get_device( +const struct discover_device *device_handler_get_device( const struct device_handler *handler, unsigned int index); struct device *discover_context_device(struct discover_context *ctx); +struct discover_boot_option *discover_boot_option_create( + struct discover_context *ctx, + struct discover_device *dev); void discover_context_add_boot_option(struct discover_context *ctx, - struct boot_option *opt); + struct discover_boot_option *opt); int device_handler_event(struct device_handler *handler, struct event *event); diff --git a/discover/discover-server.c b/discover/discover-server.c index 9f6e7da..1987932 100644 --- a/discover/discover-server.c +++ b/discover/discover-server.c @@ -200,14 +200,15 @@ static int discover_server_process_connection(void *arg) /* send existing devices to client */ n_devices = device_handler_get_device_count(server->device_handler); for (i = 0; i < n_devices; i++) { - const struct device *device; - struct boot_option *opt; + const struct discover_boot_option *opt; + const struct discover_device *device; device = device_handler_get_device(server->device_handler, i); - write_device_add_message(server, client, device); + write_device_add_message(server, client, device->device); list_for_each_entry(&device->boot_options, opt, list) - discover_server_notify_boot_option_add(server, opt); + discover_server_notify_boot_option_add(server, + opt->option); } diff --git a/discover/event-parser.c b/discover/event-parser.c index d7c0820..289fee9 100644 --- a/discover/event-parser.c +++ b/discover/event-parser.c @@ -16,15 +16,17 @@ int parse_user_event(struct discover_context *ctx, struct event *event) { + struct discover_boot_option *d_opt; struct boot_option *opt; struct device *dev; const char *p; dev = ctx->device->device; - opt = talloc_zero(dev, struct boot_option); + d_opt = discover_boot_option_create(ctx, ctx->device); + opt = d_opt->option; - if (!opt) + if (!d_opt) goto fail; p = event_get_param(event, "name"); @@ -56,11 +58,11 @@ int parse_user_event(struct discover_context *ctx, struct event *event) opt->description = talloc_asprintf(opt, "%s %s", opt->boot_image_file, opt->boot_args); - discover_context_add_boot_option(ctx, opt); + discover_context_add_boot_option(ctx, d_opt); return 0; fail: - talloc_free(opt); + talloc_free(d_opt); return -1; } diff --git a/discover/grub2-parser.c b/discover/grub2-parser.c index 3c756c1..8a0868a 100644 --- a/discover/grub2-parser.c +++ b/discover/grub2-parser.c @@ -33,7 +33,7 @@ #include "paths.h" struct grub2_state { - struct boot_option *opt; + struct discover_boot_option *opt; char *desc_image; char *desc_initrd; const char *const *known_names; @@ -43,6 +43,7 @@ static void grub2_finish(struct conf_context *conf) { struct device *dev = conf->dc->device->device; struct grub2_state *state = conf->parser_info; + struct boot_option *opt; if (!state->desc_image) { pb_log("%s: %s: no image found\n", __func__, dev->id); @@ -50,26 +51,30 @@ static void grub2_finish(struct conf_context *conf) } assert(state->opt); - assert(state->opt->name); - assert(state->opt->boot_args); + opt = state->opt->option; - state->opt->description = talloc_asprintf(state->opt, "%s %s %s", + assert(opt); + assert(opt->name); + assert(opt->boot_args); + + opt->description = talloc_asprintf(opt, "%s %s %s", state->desc_image, (state->desc_initrd ? state->desc_initrd : ""), - state->opt->boot_args); + opt->boot_args); talloc_free(state->desc_initrd); state->desc_initrd = NULL; - conf_strip_str(state->opt->boot_args); - conf_strip_str(state->opt->description); + conf_strip_str(opt->boot_args); + conf_strip_str(opt->description); /* opt is persistent, so must be associated with device */ discover_context_add_boot_option(conf->dc, state->opt); - state->opt = talloc_zero(conf->dc, struct boot_option); - state->opt->boot_args = talloc_strdup(state->opt, ""); + state->opt = discover_boot_option_create(conf->dc, conf->dc->device); + opt = state->opt->option; + opt->boot_args = talloc_strdup(opt, ""); talloc_free(state->desc_image); state->desc_image = NULL; @@ -80,6 +85,7 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, { struct device *dev = conf->dc->device->device; struct grub2_state *state = conf->parser_info; + struct boot_option *opt = state->opt->option; if (!name || !conf_param_in_list(state->known_names, name)) return; @@ -96,9 +102,8 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, if (sep) *sep = 0; - state->opt->id = talloc_asprintf(state->opt, "%s#%s", - dev->id, value); - state->opt->name = talloc_strdup(state->opt, value); + opt->id = talloc_asprintf(opt, "%s#%s", dev->id, value); + opt->name = talloc_strdup(opt, value); return; } @@ -111,19 +116,19 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, if (sep) *sep = 0; - state->opt->boot_image_file = resolve_path(state->opt, - value, conf->dc->device->device_path); - state->desc_image = talloc_strdup(state->opt, value); + opt->boot_image_file = resolve_path(opt, value, + conf->dc->device->device_path); + state->desc_image = talloc_strdup(opt, value); if (sep) - state->opt->boot_args = talloc_strdup(state->opt, + opt->boot_args = talloc_strdup(opt, sep + 1); return; } if (streq(name, "initrd")) { - state->opt->initrd_file = resolve_path(state->opt, + opt->initrd_file = resolve_path(opt, value, conf->dc->device->device_path); state->desc_initrd = talloc_asprintf(state, "initrd=%s", value); @@ -177,8 +182,8 @@ static int grub2_parse(struct discover_context *dc, char *buf, int len) /* opt is persistent, so must be associated with device */ - state->opt = talloc_zero(conf->dc->device, struct boot_option); - state->opt->boot_args = talloc_strdup(state->opt, ""); + state->opt = discover_boot_option_create(dc, dc->device); + state->opt->option->boot_args = talloc_strdup(state->opt->option, ""); conf_parse_buf(conf, buf, len); diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c index b28603e..cb6a248 100644 --- a/discover/kboot-parser.c +++ b/discover/kboot-parser.c @@ -15,12 +15,12 @@ static void kboot_process_pair(struct conf_context *conf, const char *name, char *value) { const char *const *ignored_names = conf->parser_info; - struct device *dev; + struct discover_boot_option *d_opt; + struct boot_option *opt; char *pos; char *args; const char *initrd; const char *root; - struct boot_option *opt; /* ignore bare values */ @@ -35,13 +35,15 @@ static void kboot_process_pair(struct conf_context *conf, const char *name, /* opt must be associated with dc */ - dev = conf->dc->device->device; - opt = talloc_zero(dev, struct boot_option); + d_opt = talloc_zero(conf->dc, struct discover_boot_option); + d_opt->device = conf->dc->device; + opt = talloc_zero(d_opt, struct boot_option); if (!opt) return; - opt->id = talloc_asprintf(opt, "%s#%s", dev->id, name); + opt->id = talloc_asprintf(opt, "%s#%s", conf->dc->device->device->id, + name); opt->name = talloc_strdup(opt, name); args = talloc_strdup(opt, ""); @@ -103,7 +105,7 @@ out_add: conf_strip_str(opt->boot_args); conf_strip_str(opt->description); - discover_context_add_boot_option(conf->dc, opt); + discover_context_add_boot_option(conf->dc, d_opt); } static struct conf_global_option kboot_global_options[] = { diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c index d7a0a9f..7fedf20 100644 --- a/discover/yaboot-parser.c +++ b/discover/yaboot-parser.c @@ -12,7 +12,7 @@ #include "paths.h" struct yaboot_state { - struct boot_option *opt; + struct discover_boot_option *opt; const char *desc_image; char *desc_initrd; int globals_done; @@ -23,6 +23,7 @@ static void yaboot_finish(struct conf_context *conf) { struct yaboot_state *state = conf->parser_info; struct device *dev = conf->dc->device->device; + struct boot_option *opt; if (!state->desc_image) { pb_log("%s: %s: no image found\n", __func__, dev->id); @@ -30,32 +31,36 @@ static void yaboot_finish(struct conf_context *conf) } assert(state->opt); - assert(state->opt->name); - assert(state->opt->boot_args); - state->opt->description = talloc_asprintf(state->opt, "%s %s %s", + opt = state->opt->option; + assert(opt); + assert(opt->name); + assert(opt->boot_args); + + opt->description = talloc_asprintf(opt, "%s %s %s", state->desc_image, (state->desc_initrd ? state->desc_initrd : ""), - state->opt->boot_args); + opt->boot_args); talloc_free(state->desc_initrd); state->desc_initrd = NULL; - conf_strip_str(state->opt->boot_args); - conf_strip_str(state->opt->description); + conf_strip_str(opt->boot_args); + conf_strip_str(opt->description); /* opt is persistent, so must be associated with device */ discover_context_add_boot_option(conf->dc, state->opt); - state->opt = talloc_zero(conf->dc, struct boot_option); - state->opt->boot_args = talloc_strdup(state->opt, ""); + state->opt = discover_boot_option_create(conf->dc, conf->dc->device); + state->opt->option->boot_args = talloc_strdup(state->opt->option, ""); } static void yaboot_process_pair(struct conf_context *conf, const char *name, char *value) { struct yaboot_state *state = conf->parser_info; + struct boot_option *opt = state->opt->option; struct fixed_pair { const char *image; const char *initrd; @@ -91,7 +96,7 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, /* First finish any previous image. */ - if (state->opt->boot_image_file) + if (opt->boot_image_file) yaboot_finish(conf); /* Then start the new image. */ @@ -100,20 +105,20 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, char* dev = talloc_asprintf(NULL, "%s%s", g_boot, g_part); - state->opt->boot_image_file = resolve_path(state->opt, + opt->boot_image_file = resolve_path(opt, value, dev); - state->desc_image = talloc_asprintf(state->opt, + state->desc_image = talloc_asprintf(opt, "%s%s", dev, value); talloc_free(dev); } else if (g_boot) { - state->opt->boot_image_file = resolve_path(state->opt, + opt->boot_image_file = resolve_path(opt, value, g_boot); - state->desc_image = talloc_asprintf(state->opt, + state->desc_image = talloc_asprintf(opt, "%s%s", g_boot, value); } else { - state->opt->boot_image_file = resolve_path(state->opt, + opt->boot_image_file = resolve_path(opt, value, conf->dc->device->device_path); - state->desc_image = talloc_strdup(state->opt, value); + state->desc_image = talloc_strdup(opt, value); } return; @@ -131,22 +136,22 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, if (suse_fp) { /* First finish any previous image. */ - if (state->opt->boot_image_file) + if (opt->boot_image_file) yaboot_finish(conf); /* Then start the new image. */ if (*value == '/') { - state->opt->boot_image_file = resolve_path(state->opt, + opt->boot_image_file = resolve_path(opt, value, conf->dc->device->device_path); - state->desc_image = talloc_strdup(state->opt, value); + state->desc_image = talloc_strdup(opt, value); } else { - state->opt->boot_image_file = resolve_path(state->opt, + opt->boot_image_file = resolve_path(opt, suse_fp->image, conf->dc->device->device_path); - state->desc_image = talloc_strdup(state->opt, + state->desc_image = talloc_strdup(opt, suse_fp->image); - state->opt->initrd_file = resolve_path(state->opt, + opt->initrd_file = resolve_path(opt, suse_fp->initrd, conf->dc->device->device_path); state->desc_initrd = talloc_asprintf(state, "initrd=%s", suse_fp->initrd); @@ -155,7 +160,7 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, return; } - if (!state->opt->boot_image_file) { + if (!opt->boot_image_file) { pb_log("%s: unknown name: %s\n", __func__, name); return; } @@ -170,18 +175,18 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, char* dev = talloc_asprintf(NULL, "%s%s", g_boot, g_part); - state->opt->initrd_file = resolve_path(state->opt, + opt->initrd_file = resolve_path(opt, value, dev); state->desc_initrd = talloc_asprintf(state, "initrd=%s%s", dev, value); talloc_free(dev); } else if (g_boot) { - state->opt->initrd_file = resolve_path(state->opt, + opt->initrd_file = resolve_path(opt, value, g_boot); state->desc_initrd = talloc_asprintf(state, "initrd=%s%s", g_boot, value); } else { - state->opt->initrd_file = resolve_path(state->opt, + opt->initrd_file = resolve_path(opt, value, conf->dc->device->device_path); state->desc_initrd = talloc_asprintf(state, "initrd=%s", value); @@ -192,57 +197,57 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, /* label */ if (streq(name, "label")) { - state->opt->id = talloc_asprintf(state->opt, "%s#%s", + opt->id = talloc_asprintf(opt, "%s#%s", conf->dc->device->device->id, value); - state->opt->name = talloc_strdup(state->opt, value); + opt->name = talloc_strdup(opt, value); return; } /* args */ if (streq(name, "append")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "%s ", value); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "%s ", value); return; } if (streq(name, "initrd-size")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "ramdisk_size=%s ", value); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "ramdisk_size=%s ", value); return; } if (streq(name, "literal")) { - if (*state->opt->boot_args) { + if (*opt->boot_args) { pb_log("%s: literal over writes '%s'\n", __func__, - state->opt->boot_args); - talloc_free(state->opt->boot_args); + opt->boot_args); + talloc_free(opt->boot_args); } - talloc_asprintf(state->opt, "%s ", value); + talloc_asprintf(opt, "%s ", value); return; } if (streq(name, "ramdisk")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "ramdisk=%s ", value); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "ramdisk=%s ", value); return; } if (streq(name, "read-only")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "ro "); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "ro "); return; } if (streq(name, "read-write")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "rw "); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "rw "); return; } if (streq(name, "root")) { - state->opt->boot_args = talloc_asprintf_append( - state->opt->boot_args, "root=%s ", value); + opt->boot_args = talloc_asprintf_append( + opt->boot_args, "root=%s ", value); return; } @@ -309,8 +314,8 @@ static int yaboot_parse(struct discover_context *dc, char *buf, int len) /* opt is persistent, so must be associated with device */ - state->opt = talloc_zero(conf->dc->device, struct boot_option); - state->opt->boot_args = talloc_strdup(state->opt, ""); + state->opt = discover_boot_option_create(conf->dc, conf->dc->device); + state->opt->option->boot_args = talloc_strdup(state->opt->option, ""); conf_parse_buf(conf, buf, len); diff --git a/test/parser/parser-test.c b/test/parser/parser-test.c index d8ec75b..cd6e62f 100644 --- a/test/parser/parser-test.c +++ b/test/parser/parser-test.c @@ -22,17 +22,32 @@ struct device *discover_context_device(struct discover_context *ctx) return ctx->device->device; } +struct discover_boot_option *discover_boot_option_create( + struct discover_context *ctx, + struct discover_device *dev) +{ + struct discover_boot_option *opt; + + opt = talloc_zero(ctx, struct discover_boot_option); + opt->option = talloc(opt, struct boot_option); + opt->device = dev; + + return opt; +} + void discover_context_add_boot_option(struct discover_context *ctx, - struct boot_option *boot_option) + struct discover_boot_option *boot_option) { + struct boot_option *opt = boot_option->option; + fprintf(testf, "%s: %s\n", __func__, ctx->device->device->id); - fprintf(testf, " id '%s'\n", boot_option->id); - fprintf(testf, " name '%s'\n", boot_option->name); - fprintf(testf, " descr '%s'\n", boot_option->description); - fprintf(testf, " icon '%s'\n", boot_option->icon_file); - fprintf(testf, " image '%s'\n", boot_option->boot_image_file); - fprintf(testf, " initrd '%s'\n", boot_option->initrd_file); - fprintf(testf, " args '%s'\n", boot_option->boot_args); + fprintf(testf, " id '%s'\n", opt->id); + fprintf(testf, " name '%s'\n", opt->name); + fprintf(testf, " descr '%s'\n", opt->description); + fprintf(testf, " icon '%s'\n", opt->icon_file); + fprintf(testf, " image '%s'\n", opt->boot_image_file); + fprintf(testf, " initrd '%s'\n", opt->initrd_file); + fprintf(testf, " args '%s'\n", opt->boot_args); fflush(testf); } -- 2.39.2