discover: Change parsers to emit resources rather than filenames
authorJeremy Kerr <jk@ozlabs.org>
Tue, 16 Apr 2013 08:58:18 +0000 (16:58 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Mon, 29 Apr 2013 04:41:04 +0000 (14:41 +1000)
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>
13 files changed:
discover/Makefile.am
discover/boot.c
discover/boot.h
discover/device-handler.c
discover/device-handler.h
discover/grub2-parser.c
discover/kboot-parser.c
discover/parser.c
discover/parser.h
discover/paths.c
discover/paths.h
discover/yaboot-parser.c
test/parser/parser-test.c

index a8d07b21fab1c8f08614531da4fe45d447d32876..a3087ef8fefe223796427b65998f45b4a1fcc7cf 100644 (file)
@@ -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 \
index e67ed00eec6b05de9845490c1b53241184675988..804425c65878a832ee320cf6e8b39635b4986c1b 100644 (file)
@@ -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;
        }
index be2ca5752e9e1eeca5c8471fba6651ec09949f5d..1dc5767b083d50a03fa899fe1a8cf56ddb24e473 100644 (file)
@@ -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 */
index 2b16b2ea2f7a9c937b864b66d28996cca9bae0cf..950e730b995b89af52073b0ba8eaf0906d4147a9 100644 (file)
@@ -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);
 }
index 3c4574b1403d367381f3ff76b391697a11ef27c7..5dead2459d0217c08361a41c9f2ebc1fb43ac3ef 100644 (file)
@@ -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;
 };
 
 
index 8a0868a7a72bdba905cf0d379c1c0e08ac3c65b7..eaf3cd3c64d5adcc5ac34e7601998ff4d0415799 100644 (file)
@@ -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;
index cb6a2483bc3092756e2d488a9b3e0b6588114745..e602dc4142582b31db7ad2ac25d96481bc895554 100644 (file)
@@ -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,
 };
index 1f3674d3ee461cc24fac0f9ca5a8fc11d765fb1c..462d614a5c1abeae1866a79f3748428fc956e9ec 100644 (file)
@@ -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)
index 18c9963e863021b642f7adbd840278a99fbfe53f..03ba8d4d704134b3a9a239c9da9f6657ff449505 100644 (file)
@@ -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 {
index ef8a45f924c8fa658fd4c39330f40eaf485761b4..d95e359e9f170b6a69e925a9002bdbe512818ec3 100644 (file)
 
 #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;
 
index 34de79a1649fd34e7ed4b8f22aa1ef582a7a5cba..20a22495042b7780820ea3f12678108218d26a11 100644 (file)
@@ -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
@@ -41,17 +11,12 @@ 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 */
index 7fedf20f13963434abe1729f118aabc262244fbf..0a66e8d588241d69b66a9fc3d1119edce7f3c38a 100644 (file)
@@ -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;
        }
 
index cd6e62f54c065f1d47cc3eb96c70edc0663ed52e..33b411b2e4dbe1e29f055526e66d3ad9ee8f8a15 100644 (file)
@@ -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]);