discover/grub2: Implement 'linux' & 'initrd' commands
authorJeremy Kerr <jk@ozlabs.org>
Mon, 16 Sep 2013 08:47:17 +0000 (16:47 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 24 Sep 2013 05:14:59 +0000 (13:14 +0800)
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/grub2/builtins.c
discover/grub2/grub2.c
discover/grub2/grub2.h

index 55597c18467d4cd3f697816a804543fcf45366df..cd56dcc033f8eb67d414e68d241fd5e53b315edb 100644 (file)
@@ -2,6 +2,8 @@
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
 
+#include <log/log.h>
+#include <types/types.h>
 #include <talloc/talloc.h>
 #include <array-size/array-size.h>
 
 #include <talloc/talloc.h>
 #include <array-size/array-size.h>
 
@@ -33,14 +35,84 @@ static int builtin_set(struct grub2_script *script,
        return 0;
 }
 
        return 0;
 }
 
+static int builtin_linux(struct grub2_script *script,
+               void *data __attribute__((unused)),
+               int argc, char *argv[])
+{
+       struct discover_boot_option *opt = script->opt;
+       const char *root;
+       int i;
+
+       if (!opt) {
+               pb_log("grub2 syntax error: 'linux' statement outside "
+                               "a menuentry.\n");
+               return -1;
+       }
+
+       if (argc < 2) {
+               pb_log("grub2 syntax error: no filename provided to "
+                               "linux statement\n");
+               return -1;
+       }
+
+       root = script_env_get(script, "root");
+
+       opt->boot_image = create_grub2_resource(opt, script->ctx->device,
+                                               root, argv[1]);
+       opt->option->boot_args = NULL;
+
+       if (argc > 2)
+               opt->option->boot_args = talloc_strdup(opt, argv[2]);
+
+       for (i = 3; i < argc; i++)
+               opt->option->boot_args = talloc_asprintf_append(
+                                               opt->option->boot_args,
+                                               " %s", argv[i]);
+       return 0;
+}
+
+static int builtin_initrd(struct grub2_script *script,
+               void *data __attribute__((unused)),
+               int argc, char *argv[])
+{
+       struct discover_boot_option *opt = script->opt;
+       const char *root;
+
+       if (!opt) {
+               pb_log("grub2 syntax error: 'initrd' statement outside "
+                               "a menuentry.\n");
+               return -1;
+       }
+
+       if (argc < 2) {
+               pb_log("grub2 syntax error: no filename provided to "
+                               "initrd statement\n");
+               return -1;
+       }
+
+       root = script_env_get(script, "root");
+       opt->initrd = create_grub2_resource(opt, script->ctx->device,
+                                               root, argv[1]);
+
+       return 0;
+}
+
 static struct {
        const char *name;
        grub2_function fn;
 } builtins[] = {
        {
                .name = "set",
 static struct {
        const char *name;
        grub2_function fn;
 } builtins[] = {
        {
                .name = "set",
-               .fn = builtin_set
+               .fn = builtin_set,
        },
        },
+       {
+               .name = "linux",
+               .fn = builtin_linux,
+       },
+       {
+               .name = "initrd",
+               .fn = builtin_initrd,
+       }
 };
 
 void register_builtins(struct grub2_script *script)
 };
 
 void register_builtins(struct grub2_script *script)
index ebc6ac7b6d72383d24efc29a1c08bf11cf2b8d6f..fb3d8668a99bdfa5334ff8f62e6b4e98904e4af3 100644 (file)
@@ -31,14 +31,14 @@ static const char *const grub2_conf_files[] = {
 };
 
 struct grub2_resource_info {
 };
 
 struct grub2_resource_info {
-       struct grub2_root *root;
+       char *root;
        char *path;
 };
 
 /* we use slightly different resources for grub2 */
 struct resource *create_grub2_resource(void *ctx,
                struct discover_device *orig_device,
        char *path;
 };
 
 /* we use slightly different resources for grub2 */
 struct resource *create_grub2_resource(void *ctx,
                struct discover_device *orig_device,
-               struct grub2_root *root, const char *path)
+               const char *root, const char *path)
 {
        struct grub2_resource_info *info;
        struct resource *res;
 {
        struct grub2_resource_info *info;
        struct resource *res;
@@ -47,8 +47,8 @@ struct resource *create_grub2_resource(void *ctx,
 
        if (root) {
                info = talloc(res, struct grub2_resource_info);
 
        if (root) {
                info = talloc(res, struct grub2_resource_info);
-               info->root = root;
                talloc_reference(info, root);
                talloc_reference(info, root);
+               info->root = talloc_strdup(info, root);
                info->path = talloc_strdup(info, path);
 
                res->resolved = false;
                info->path = talloc_strdup(info, path);
 
                res->resolved = false;
@@ -68,7 +68,7 @@ bool resolve_grub2_resource(struct device_handler *handler,
 
        assert(!res->resolved);
 
 
        assert(!res->resolved);
 
-       dev = device_lookup_by_uuid(handler, info->root->uuid);
+       dev = device_lookup_by_uuid(handler, info->root);
 
        if (!dev)
                return false;
 
        if (!dev)
                return false;
index 2de77a280b96ce97f2bbcefaa680ade0fc676221..4949f3c031a9027f4aa5e42c9c92626ff5258535 100644 (file)
@@ -85,10 +85,6 @@ struct grub2_parser {
        struct grub2_script     *script;
 };
 
        struct grub2_script     *script;
 };
 
-struct grub2_root {
-       char *uuid;
-};
-
 /* type for builtin functions */
 typedef int (*grub2_function)(struct grub2_script *script, void *data,
                                int argc, char *argv[]);
 /* type for builtin functions */
 typedef int (*grub2_function)(struct grub2_script *script, void *data,
                                int argc, char *argv[]);
@@ -150,7 +146,7 @@ void register_builtins(struct grub2_script *script);
 /* resources */
 struct resource *create_grub2_resource(void *ctx,
                struct discover_device *orig_device,
 /* resources */
 struct resource *create_grub2_resource(void *ctx,
                struct discover_device *orig_device,
-               struct grub2_root *root, const char *path);
+               const char *root, const char *path);
 
 bool resolve_grub2_resource(struct device_handler *handler,
                struct resource *res);
 
 bool resolve_grub2_resource(struct device_handler *handler,
                struct resource *res);