summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-04-16 16:58:18 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-04-29 14:41:04 +1000
commit5be946cda7b8e2271ade6188ca3f5dc068826619 (patch)
treea62a64792bb61aa57c5d8dac36c7df9756d01ef8
parent4e8b779626da98e2896efbb2df99b64f76e878f6 (diff)
downloadtalos-petitboot-5be946cda7b8e2271ade6188ca3f5dc068826619.tar.gz
talos-petitboot-5be946cda7b8e2271ade6188ca3f5dc068826619.zip
discover: Change parsers to emit resources rather than filenames
This change switches the parsers over to populate the resources in discover_boot_option, rather than the string parameters in boot_option. To do this, we need a few things: * Add struct resources to discover_boot_option for the boot_image, initrd and icon data. * Have the parsers populate the resources, rather than the strings. Currently, parsers can all use the devpath resource type. * Add a resolve_resource callback to parsers; this is how the device handler will attempt to resolve resources. * Change load_file to load_url, as we should be only accessing (resolved) resources by URLs. This then allows us to remove the mount map, and associated lookup code, as well as the UUID and label links to devices. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
-rw-r--r--discover/Makefile.am4
-rw-r--r--discover/boot.c28
-rw-r--r--discover/boot.h2
-rw-r--r--discover/device-handler.c71
-rw-r--r--discover/device-handler.h4
-rw-r--r--discover/grub2-parser.c20
-rw-r--r--discover/kboot-parser.c17
-rw-r--r--discover/parser.c21
-rw-r--r--discover/parser.h23
-rw-r--r--discover/paths.c131
-rw-r--r--discover/paths.h39
-rw-r--r--discover/yaboot-parser.c154
-rw-r--r--test/parser/parser-test.c24
13 files changed, 177 insertions, 361 deletions
diff --git a/discover/Makefile.am b/discover/Makefile.am
index a8d07b2..a3087ef 100644
--- a/discover/Makefile.am
+++ b/discover/Makefile.am
@@ -30,6 +30,8 @@ libparser_la_SOURCES = \
parser-utils.h \
paths.c \
paths.h \
+ resource.c \
+ resource.h \
kboot-parser.c \
grub2-parser.c \
yaboot-parser.c
@@ -54,8 +56,6 @@ pb_discover_SOURCES = \
params.h \
pb-discover.c \
pb-discover.h \
- resource.c \
- resource.h \
udev.c \
udev.h \
user-event.c \
diff --git a/discover/boot.c b/discover/boot.c
index e67ed00..804425c 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -5,9 +5,12 @@
#include <pb-protocol/pb-protocol.h>
#include <system/system.h>
#include <talloc/talloc.h>
+#include <url/url.h>
+#include "device-handler.h"
#include "boot.h"
#include "paths.h"
+#include "resource.h"
/**
* kexec_load - kexec load helper.
@@ -94,13 +97,14 @@ static int kexec_reboot(int dry_run)
return result;
}
-int boot(void *ctx, struct boot_option *opt, struct boot_command *cmd,
+int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd,
int dry_run)
{
char *local_image, *local_initrd;
unsigned int clean_image = 0;
unsigned int clean_initrd = 0;
- char *image, *initrd, *args;
+ struct pb_url *image, *initrd;
+ char *args;
int result;
local_initrd = NULL;
@@ -109,34 +113,34 @@ int boot(void *ctx, struct boot_option *opt, struct boot_command *cmd,
args = NULL;
if (cmd->boot_image_file) {
- image = talloc_strdup(ctx, cmd->boot_image_file);
- } else if (opt && opt->boot_image_file) {
- image = talloc_strdup(ctx, opt->boot_image_file);
+ image = pb_url_parse(opt, cmd->boot_image_file);
+ } else if (opt && opt->boot_image) {
+ image = opt->boot_image->url;
} else {
pb_log("%s: no image specified", __func__);
return -1;
}
if (cmd->initrd_file) {
- initrd = talloc_strdup(ctx, cmd->initrd_file);
- } else if (opt && opt->initrd_file) {
- initrd = talloc_strdup(ctx, opt->initrd_file);
+ initrd = pb_url_parse(opt, cmd->initrd_file);
+ } else if (opt && opt->initrd) {
+ initrd = opt->initrd->url;
}
if (cmd->boot_args) {
args = talloc_strdup(ctx, cmd->boot_args);
- } else if (opt && opt->boot_args) {
- args = talloc_strdup(ctx, opt->boot_args);
+ } else if (opt && opt->option->boot_args) {
+ args = talloc_strdup(ctx, opt->option->boot_args);
}
result = -1;
- local_image = load_file(NULL, image, &clean_image);
+ local_image = load_url(NULL, image, &clean_image);
if (!local_image)
goto no_load;
if (initrd) {
- local_initrd = load_file(NULL, initrd, &clean_initrd);
+ local_initrd = load_url(NULL, initrd, &clean_initrd);
if (!local_initrd)
goto no_load;
}
diff --git a/discover/boot.h b/discover/boot.h
index be2ca57..1dc5767 100644
--- a/discover/boot.h
+++ b/discover/boot.h
@@ -4,7 +4,7 @@
struct boot_option;
struct boot_command;
-int boot(void *ctx, struct boot_option *opt, struct boot_command *cmd,
+int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd,
int dry_run);
#endif /* _BOOT_H */
diff --git a/discover/device-handler.c b/discover/device-handler.c
index 2b16b2e..950e730 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -130,73 +130,13 @@ const struct discover_device *device_handler_get_device(
return handler->devices[index];
}
-static void setup_device_links(struct discover_device *dev)
-{
- struct link {
- const char *dir, *val;
- } *link, links[] = {
- {
- .dir = "disk/by-uuid",
- .val = dev->uuid,
- },
- {
- .dir = "disk/by-label",
- .val = dev->label,
- },
- {
- .dir = NULL
- }
- };
-
- for (link = links; link->dir; link++) {
- char *enc, *dir, *path;
-
- if (!link->val || !*link->val)
- continue;
-
- enc = encode_label(dev, link->val);
- dir = join_paths(dev, mount_base(), link->dir);
- path = join_paths(dev, dir, enc);
-
- if (!pb_mkdir_recursive(dir)) {
- unlink(path);
- if (symlink(dev->mount_path, path)) {
- pb_log("symlink(%s,%s): %s\n",
- dev->mount_path, path,
- strerror(errno));
- talloc_free(path);
- } else {
- int i = dev->n_links++;
- dev->links = talloc_realloc(dev,
- dev->links, char *,
- dev->n_links);
- dev->links[i] = path;
- }
-
- }
-
- talloc_free(dir);
- talloc_free(enc);
- }
-}
-
-static void remove_device_links(struct discover_device *dev)
-{
- int i;
-
- for (i = 0; i < dev->n_links; i++)
- unlink(dev->links[i]);
-}
-
static int mount_device(struct discover_device *dev)
{
- const char *mountpoint;
const char *argv[6];
- if (!dev->mount_path) {
- mountpoint = mountpoint_for_device(dev->device_path);
- dev->mount_path = talloc_strdup(dev, mountpoint);
- }
+ if (!dev->mount_path)
+ dev->mount_path = join_paths(dev, mount_base(),
+ dev->device_path);
if (pb_mkdir_recursive(dev->mount_path))
pb_log("couldn't create mount directory %s: %s\n",
@@ -222,7 +162,6 @@ static int mount_device(struct discover_device *dev)
goto out_rmdir;
}
- setup_device_links(dev);
return 0;
out_rmdir:
@@ -235,8 +174,6 @@ static int umount_device(struct discover_device *dev)
int status;
pid_t pid;
- remove_device_links(dev);
-
if (!dev->mount_path)
return 0;
@@ -590,5 +527,5 @@ void device_handler_boot(struct device_handler *handler,
opt = find_boot_option_by_id(handler, cmd->option_id);
- boot(handler, opt->option, cmd, handler->dry_run);
+ boot(handler, opt, cmd, handler->dry_run);
}
diff --git a/discover/device-handler.h b/discover/device-handler.h
index 3c4574b..5dead24 100644
--- a/discover/device-handler.h
+++ b/discover/device-handler.h
@@ -30,6 +30,10 @@ struct discover_boot_option {
struct discover_device *device;
struct boot_option *option;
struct list_item list;
+
+ struct resource *boot_image;
+ struct resource *initrd;
+ struct resource *icon;
};
diff --git a/discover/grub2-parser.c b/discover/grub2-parser.c
index 8a0868a..eaf3cd3 100644
--- a/discover/grub2-parser.c
+++ b/discover/grub2-parser.c
@@ -30,7 +30,7 @@
#include "types/types.h"
#include "parser-conf.h"
#include "parser-utils.h"
-#include "paths.h"
+#include "resource.h"
struct grub2_state {
struct discover_boot_option *opt;
@@ -85,7 +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;
+ struct discover_boot_option *opt = state->opt;
if (!name || !conf_param_in_list(state->known_names, name))
return;
@@ -102,8 +102,9 @@ static void grub2_process_pair(struct conf_context *conf, const char *name,
if (sep)
*sep = 0;
- opt->id = talloc_asprintf(opt, "%s#%s", dev->id, value);
- opt->name = talloc_strdup(opt, value);
+ opt->option->id = talloc_asprintf(opt->option,
+ "%s#%s", dev->id, value);
+ opt->option->name = talloc_strdup(opt->option, value);
return;
}
@@ -116,20 +117,19 @@ static void grub2_process_pair(struct conf_context *conf, const char *name,
if (sep)
*sep = 0;
- opt->boot_image_file = resolve_path(opt, value,
- conf->dc->device->device_path);
+ opt->boot_image = create_devpath_resource(opt,
+ conf->dc->device, value);
state->desc_image = talloc_strdup(opt, value);
if (sep)
- opt->boot_args = talloc_strdup(opt,
- sep + 1);
+ opt->option->boot_args = talloc_strdup(opt, sep + 1);
return;
}
if (streq(name, "initrd")) {
- opt->initrd_file = resolve_path(opt,
- value, conf->dc->device->device_path);
+ opt->initrd = create_devpath_resource(opt,
+ conf->dc->device, value);
state->desc_initrd = talloc_asprintf(state, "initrd=%s",
value);
return;
diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c
index cb6a248..e602dc4 100644
--- a/discover/kboot-parser.c
+++ b/discover/kboot-parser.c
@@ -9,7 +9,7 @@
#include "types/types.h"
#include "parser-conf.h"
#include "parser-utils.h"
-#include "paths.h"
+#include "resource.h"
static void kboot_process_pair(struct conf_context *conf, const char *name,
char *value)
@@ -83,8 +83,8 @@ static void kboot_process_pair(struct conf_context *conf, const char *name,
}
out_add:
- opt->boot_image_file = resolve_path(opt, value,
- conf->dc->device->device_path);
+ d_opt->boot_image = create_devpath_resource(opt,
+ conf->dc->device, value);
if (root) {
opt->boot_args = talloc_asprintf(opt, "root=%s %s", root, args);
@@ -93,8 +93,8 @@ out_add:
opt->boot_args = args;
if (initrd) {
- opt->initrd_file = resolve_path(opt, initrd,
- conf->dc->device->device_path);
+ d_opt->initrd = create_devpath_resource(opt,
+ conf->dc->device, initrd);
opt->description = talloc_asprintf(opt, "%s initrd=%s %s",
value, initrd, opt->boot_args);
@@ -158,7 +158,8 @@ static int kboot_parse(struct discover_context *dc, char *buf, int len)
}
struct parser __kboot_parser = {
- .name = "kboot",
- .parse = kboot_parse,
- .filenames = kboot_conf_files,
+ .name = "kboot",
+ .parse = kboot_parse,
+ .filenames = kboot_conf_files,
+ .resolve_resource = resolve_devpath_resource,
};
diff --git a/discover/parser.c b/discover/parser.c
index 1f3674d..462d614 100644
--- a/discover/parser.c
+++ b/discover/parser.c
@@ -77,12 +77,17 @@ err_close:
return -1;
}
+static char *local_path(struct discover_context *ctx,
+ const char *filename)
+{
+ return join_paths(ctx, ctx->device->mount_path, filename);
+}
+
static void iterate_parser_files(struct discover_context *ctx,
const struct parser *parser)
{
const char * const *filename;
- const char *path, *url;
- unsigned int tempfile;
+ const char *path;
if (!parser->filenames)
return;
@@ -91,12 +96,7 @@ static void iterate_parser_files(struct discover_context *ctx,
int rc, len;
char *buf;
- url = resolve_path(ctx, *filename, ctx->device->device_path);
- if (!url)
- continue;
-
- path = load_file(ctx, url, &tempfile);
-
+ path = local_path(ctx, *filename);
if (!path)
continue;
@@ -105,12 +105,7 @@ static void iterate_parser_files(struct discover_context *ctx,
parser->parse(ctx, buf, len);
talloc_free(buf);
}
-
- if (tempfile)
- unlink(path);
-
}
-
}
void iterate_parsers(struct discover_context *ctx)
diff --git a/discover/parser.h b/discover/parser.h
index 18c9963..03ba8d4 100644
--- a/discover/parser.h
+++ b/discover/parser.h
@@ -1,13 +1,36 @@
#ifndef _PARSER_H
#define _PARSER_H
+#include <stdbool.h>
+
struct discover_context;
+struct device_handler;
+struct resource;
+/**
+ * Our config parser.
+ *
+ * Each parser is responsible for creating discover_boot_options from config
+ * files found on new devices. The boot items discovered during parse will have
+ * 'resources' attached (see @discover_boot_option), which may already be
+ * resolved (in the case of a device-local filename, or a URL), or unresolved
+ * (in the case of a filename on another device).
+ *
+ * If the boot option contains references to unresolved resources, the
+ * device handler will not inform clients about the boot options, as
+ * they're not properly "available" at this stage. The handler will attempt to
+ * resolve them whenever new devices are discovered, by calling the parser's
+ * resolve_resource function. Once a boot option's resources are full resolved,
+ * the option can be sent to clients.
+ */
struct parser {
char *name;
const char * const *filenames;
int (*parse)(struct discover_context *ctx,
char *buf, int len);
+ bool (*resolve_resource)(
+ struct device_handler *handler,
+ struct resource *res);
};
enum generic_icon_type {
diff --git a/discover/paths.c b/discover/paths.c
index ef8a45f..d95e359 100644
--- a/discover/paths.c
+++ b/discover/paths.c
@@ -13,135 +13,11 @@
#define DEVICE_MOUNT_BASE (LOCAL_STATE_DIR "/petitboot/mnt")
-struct mount_map {
- char *dev, *mnt;
-};
-
-static struct mount_map *mount_map;
-static int mount_map_size;
-
-static int is_prefix(const char *str, const char *prefix)
-{
- return !strncmp(str, prefix, strlen(prefix));
-}
-
-static int is_prefix_ignorecase(const char *str, const char *prefix)
-{
- return !strncasecmp(str, prefix, strlen(prefix));
-}
-
const char *mount_base(void)
{
return DEVICE_MOUNT_BASE;
}
-char *encode_label(void *alloc_ctx, const char *label)
-{
- char *str, *c;
- unsigned int i;
-
- /* the label can be expanded by up to four times */
- str = talloc_size(alloc_ctx, strlen(label) * 4 + 1);
- c = str;
-
- for (i = 0; i < strlen(label); i++) {
-
- if (label[i] == '/' || label[i] == '\\') {
- sprintf(c, "\\x%02x", label[i]);
- c += 4;
- continue;
- }
-
- *(c++) = label[i];
- }
-
- *c = '\0';
-
- return str;
-}
-
-char *parse_device_path(void *alloc_ctx,
- const char *dev_str, const char __attribute__((unused)) *cur_dev)
-{
- char *dev, *enc;
-
- if (is_prefix_ignorecase(dev_str, "uuid=")) {
- dev = talloc_asprintf(alloc_ctx, "/dev/disk/by-uuid/%s",
- dev_str + strlen("uuid="));
- return dev;
- }
-
- if (is_prefix_ignorecase(dev_str, "label=")) {
- enc = encode_label(NULL, dev_str + strlen("label="));
- dev = talloc_asprintf(alloc_ctx, "/dev/disk/by-label/%s", enc);
- talloc_free(enc);
- return dev;
- }
-
- /* normalise '/dev/foo' to 'foo' for easy comparisons, we'll expand
- * back before returning.
- */
- if (is_prefix(dev_str, "/dev/"))
- dev_str += strlen("/dev/");
-
- return join_paths(alloc_ctx, "/dev", dev_str);
-}
-
-const char *mountpoint_for_device(const char *dev)
-{
- int i;
-
- if (is_prefix(dev, "/dev/"))
- dev += strlen("/dev/");
-
- /* check existing entries in the map */
- for (i = 0; i < mount_map_size; i++)
- if (!strcmp(mount_map[i].dev, dev))
- return mount_map[i].mnt;
-
- /* no existing entry, create a new one */
- i = mount_map_size++;
- mount_map = talloc_realloc(NULL, mount_map,
- struct mount_map, mount_map_size);
-
- mount_map[i].dev = talloc_strdup(mount_map, dev);
- mount_map[i].mnt = join_paths(mount_map, DEVICE_MOUNT_BASE, dev);
- return mount_map[i].mnt;
-}
-
-char *resolve_path(void *alloc_ctx, const char *path, const char *current_dev)
-{
- static const char s_file[] = "file://";
- char *ret;
- const char *devpath, *sep;
-
- /* test for urls */
-
- if (!strncasecmp(path, s_file, sizeof(s_file) - 1))
- path += sizeof(s_file) - 1;
- else if (strstr(path, "://"))
- return talloc_strdup(alloc_ctx, path);
-
- sep = strchr(path, ':');
- if (!sep) {
- devpath = mountpoint_for_device(current_dev);
- ret = join_paths(alloc_ctx, devpath, path);
- } else {
- /* parse just the device name into dev */
- char *tmp, *dev;
- tmp = talloc_strndup(NULL, path, sep - path);
- dev = parse_device_path(NULL, tmp, current_dev);
-
- devpath = mountpoint_for_device(dev);
- ret = join_paths(alloc_ctx, devpath, sep + 1);
-
- talloc_free(dev);
- talloc_free(tmp);
- }
-
- return ret;
-}
-
char *join_paths(void *alloc_ctx, const char *a, const char *b)
{
char *full_path;
@@ -376,10 +252,10 @@ fail:
}
/**
- * pb_load_file - Loads a (possibly) remote file and returns the local file
+ * load_url - Loads a (possibly) remote URL and returns the local file
* path.
* @ctx: The talloc context to associate with the returned string.
- * @remote: The remote file URL.
+ * @URL: The remote file URL.
* @tempfile: An optional variable pointer to be set when a temporary local
* file is created.
*
@@ -387,9 +263,8 @@ fail:
* or NULL on error.
*/
-char *load_file(void *ctx, const char *remote, unsigned int *tempfile)
+char *load_url(void *ctx, struct pb_url *url, unsigned int *tempfile)
{
- struct pb_url *url = pb_url_parse(ctx, remote);
char *local;
int tmp = 0;
diff --git a/discover/paths.h b/discover/paths.h
index 34de79a..20a2249 100644
--- a/discover/paths.h
+++ b/discover/paths.h
@@ -1,37 +1,7 @@
#ifndef PATHS_H
#define PATHS_H
-/**
- * Given a string (eg /dev/sda1, sda1 or UUID=B8E53381CA9EA0E3), parse the
- * device path (eg /dev/sda1). Any device descriptions read from config files
- * should be parsed into the path first.
- *
- * The cur_dev is provided for some remapping situations. If NULL is provided,
- * no remapping will be done.
- *
- * Returns a newly-allocated string.
- */
-char *parse_device_path(void *alloc_ctx,
- const char *dev_str, const char *current_device);
-
-/**
- * Get the mountpoint for a device.
- */
-const char *mountpoint_for_device(const char *dev);
-
-/**
- * Resolve a path given in a config file, to a path in the local filesystem.
- * Paths may be of the form:
- * device:path (eg /dev/sda:/boot/vmlinux)
- *
- * or just a path:
- * /boot/vmlinux
- * - in this case, the current mountpoint is used.
- *
- * Returns a newly-allocated string containing a full path to the file in path
- */
-char *resolve_path(void *alloc_ctx,
- const char *path, const char *current_device);
+#include <url/url.h>
/**
* Utility function for joining two paths. Adds a / between a and b if
@@ -42,16 +12,11 @@ char *resolve_path(void *alloc_ctx,
char *join_paths(void *alloc_ctx, const char *a, const char *b);
/**
- * encode a disk label (or uuid) for use in a symlink.
- */
-char *encode_label(void *alloc_ctx, const char *label);
-
-/**
* Returns the base path for mount points
*/
const char *mount_base(void);
/* Load a (potentially remote) file, and return a guaranteed-local name */
-char *load_file(void *ctx, const char *remote, unsigned int *tempfile);
+char *load_url(void *ctx, struct pb_url *url, unsigned int *tempfile);
#endif /* PATHS_H */
diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c
index 7fedf20..0a66e8d 100644
--- a/discover/yaboot-parser.c
+++ b/discover/yaboot-parser.c
@@ -9,11 +9,11 @@
#include "types/types.h"
#include "parser-conf.h"
#include "parser-utils.h"
-#include "paths.h"
+#include "resource.h"
struct yaboot_state {
struct discover_boot_option *opt;
- const char *desc_image;
+ char *desc_image;
char *desc_initrd;
int globals_done;
const char *const *known_names;
@@ -56,11 +56,40 @@ static void yaboot_finish(struct conf_context *conf)
state->opt->option->boot_args = talloc_strdup(state->opt->option, "");
}
+static struct resource *create_yaboot_devpath_resource(
+ struct conf_context *conf,
+ const char *path, char **desc_str)
+{
+ const char *g_boot = conf_get_global_option(conf, "boot");
+ const char *g_part = conf_get_global_option(conf, "partition");
+ struct resource *res;
+ char *devpath;
+
+ if (g_boot && g_part) {
+ devpath = talloc_asprintf(conf,
+ "%s%s:%s", g_boot, g_part, path);
+ } else if (g_boot) {
+ devpath = talloc_asprintf(conf, "%s:%s", g_boot, path);
+ } else {
+ devpath = talloc_strdup(conf, path);
+ }
+
+ res = create_devpath_resource(conf->dc, conf->dc->device, devpath);
+
+ if (desc_str)
+ *desc_str = devpath;
+ else
+ talloc_free(devpath);
+
+ return res;
+}
+
+
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 discover_boot_option *opt = state->opt;
struct fixed_pair {
const char *image;
const char *initrd;
@@ -91,35 +120,14 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name,
/* image */
if (streq(name, "image")) {
- const char *g_boot = conf_get_global_option(conf, "boot");
- const char *g_part = conf_get_global_option(conf, "partition");
/* First finish any previous image. */
-
- if (opt->boot_image_file)
+ if (opt->boot_image)
yaboot_finish(conf);
/* Then start the new image. */
-
- if (g_boot && g_part) {
- char* dev = talloc_asprintf(NULL, "%s%s", g_boot,
- g_part);
-
- opt->boot_image_file = resolve_path(opt,
- value, dev);
- state->desc_image = talloc_asprintf(opt,
- "%s%s", dev, value);
- talloc_free(dev);
- } else if (g_boot) {
- opt->boot_image_file = resolve_path(opt,
- value, g_boot);
- state->desc_image = talloc_asprintf(opt,
- "%s%s", g_boot, value);
- } else {
- opt->boot_image_file = resolve_path(opt,
- value, conf->dc->device->device_path);
- state->desc_image = talloc_strdup(opt, value);
- }
+ opt->boot_image = create_yaboot_devpath_resource(conf,
+ value, &state->desc_image);
return;
}
@@ -136,31 +144,33 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name,
if (suse_fp) {
/* First finish any previous image. */
- if (opt->boot_image_file)
+ if (opt->boot_image)
yaboot_finish(conf);
/* Then start the new image. */
if (*value == '/') {
- opt->boot_image_file = resolve_path(opt,
- value, conf->dc->device->device_path);
- state->desc_image = talloc_strdup(opt, value);
+ opt->boot_image = create_yaboot_devpath_resource(
+ conf, value, &state->desc_image);
} else {
- opt->boot_image_file = resolve_path(opt,
- suse_fp->image, conf->dc->device->device_path);
- state->desc_image = talloc_strdup(opt,
- suse_fp->image);
-
- 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);
+ char *tmp;
+
+ opt->boot_image = create_yaboot_devpath_resource(
+ conf, suse_fp->image,
+ &state->desc_image);
+
+ opt->initrd = create_yaboot_devpath_resource(
+ conf, suse_fp->initrd, &tmp);
+
+ state->desc_initrd = talloc_asprintf(opt,
+ "initrd=%s", tmp);
+ talloc_free(tmp);
}
return;
}
- if (!opt->boot_image_file) {
+ if (!opt->boot_image) {
pb_log("%s: unknown name: %s\n", __func__, name);
return;
}
@@ -168,86 +178,66 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name,
/* initrd */
if (streq(name, "initrd")) {
- const char *g_boot = conf_get_global_option(conf, "boot");
- const char *g_part = conf_get_global_option(conf, "partition");
-
- if (g_boot && g_part) {
- char* dev = talloc_asprintf(NULL, "%s%s", g_boot,
- g_part);
-
- 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) {
- opt->initrd_file = resolve_path(opt,
- value, g_boot);
- state->desc_initrd = talloc_asprintf(state,
- "initrd=%s%s", g_boot, value);
- } else {
- opt->initrd_file = resolve_path(opt,
- value, conf->dc->device->device_path);
- state->desc_initrd = talloc_asprintf(state, "initrd=%s",
- value);
- }
+ opt->initrd = create_yaboot_devpath_resource(conf,
+ value, &state->desc_image);
+
return;
}
/* label */
if (streq(name, "label")) {
- opt->id = talloc_asprintf(opt, "%s#%s",
+ opt->option->id = talloc_asprintf(opt->option, "%s#%s",
conf->dc->device->device->id, value);
- opt->name = talloc_strdup(opt, value);
+ opt->option->name = talloc_strdup(opt->option, value);
return;
}
/* args */
if (streq(name, "append")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "%s ", value);
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "%s ", value);
return;
}
if (streq(name, "initrd-size")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "ramdisk_size=%s ", value);
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "ramdisk_size=%s ", value);
return;
}
if (streq(name, "literal")) {
- if (*opt->boot_args) {
+ if (*opt->option->boot_args) {
pb_log("%s: literal over writes '%s'\n", __func__,
- opt->boot_args);
- talloc_free(opt->boot_args);
+ opt->option->boot_args);
+ talloc_free(opt->option->boot_args);
}
- talloc_asprintf(opt, "%s ", value);
+ talloc_asprintf(opt->option, "%s ", value);
return;
}
if (streq(name, "ramdisk")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "ramdisk=%s ", value);
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "ramdisk=%s ", value);
return;
}
if (streq(name, "read-only")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "ro ");
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "ro ");
return;
}
if (streq(name, "read-write")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "rw ");
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "rw ");
return;
}
if (streq(name, "root")) {
- opt->boot_args = talloc_asprintf_append(
- opt->boot_args, "root=%s ", value);
+ opt->option->boot_args = talloc_asprintf_append(
+ opt->option->boot_args, "root=%s ", value);
return;
}
diff --git a/test/parser/parser-test.c b/test/parser/parser-test.c
index cd6e62f..33b411b 100644
--- a/test/parser/parser-test.c
+++ b/test/parser/parser-test.c
@@ -35,6 +35,28 @@ struct discover_boot_option *discover_boot_option_create(
return opt;
}
+struct discover_device *device_lookup_by_name(
+ struct device_handler *handler __attribute__((unused)),
+ const char *name __attribute__((unused)))
+{
+ return NULL;
+}
+
+struct discover_device *device_lookup_by_label(
+ struct device_handler *handler __attribute__((unused)),
+ const char *label __attribute__((unused)))
+{
+ return NULL;
+}
+
+struct discover_device *device_lookup_by_uuid(
+ struct device_handler *handler __attribute__((unused)),
+ const char *uuid __attribute__((unused)))
+{
+ return NULL;
+}
+
+
void discover_context_add_boot_option(struct discover_context *ctx,
struct discover_boot_option *boot_option)
{
@@ -84,7 +106,7 @@ int main(int argc, char **argv)
ctx->device = talloc_zero(ctx, struct discover_device);
ctx->device->device = talloc_zero(ctx->device, struct device);
- ctx->device->device_path = talloc_asprintf(ctx, "%s/%s",
+ ctx->device->mount_path = talloc_asprintf(ctx, "%s/%s",
argv[1], argv[2]);
ctx->device->device->id = talloc_strdup(ctx->device->device, argv[2]);
OpenPOWER on IntegriCloud