summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-03-14 14:18:54 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-04-29 14:31:20 +1000
commite4f5bd235894c11823ac1befe8c8c43063cad026 (patch)
treec5787f3434f43d331edfb55dc64d1d4dfe1cb807
parent397dc244bfdc2a57fc3e8fd191b0ef60c8a4b66b (diff)
downloadtalos-petitboot-e4f5bd235894c11823ac1befe8c8c43063cad026.tar.gz
talos-petitboot-e4f5bd235894c11823ac1befe8c8c43063cad026.zip
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 <jk@ozlabs.org>
-rw-r--r--discover/device-handler.c43
-rw-r--r--discover/device-handler.h16
-rw-r--r--discover/discover-server.c9
-rw-r--r--discover/event-parser.c10
-rw-r--r--discover/grub2-parser.c43
-rw-r--r--discover/kboot-parser.c14
-rw-r--r--discover/yaboot-parser.c97
-rw-r--r--test/parser/parser-test.c31
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);
}
OpenPOWER on IntegriCloud