grub2/0115-Remove-nested-functions-from-device-iterators.patch

4100 lines
115 KiB
Diff
Raw Normal View History

From ba97422da261d8d41d61af28af5344c47a723cff Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@ubuntu.com>
Date: Sun, 20 Jan 2013 15:52:15 +0000
Subject: [PATCH 115/364] Remove nested functions from device iterators.
* include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type.
(grub_arc_iterate_devs): Add hook_data argument.
* include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type.
(struct grub_ata_dev.iterate): Add hook_data argument.
* include/grub/device.h (grub_device_iterate_hook_t): New type.
(grub_device_iterate): Add hook_data argument.
* include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type.
(struct grub_disk_dev.iterate): Add hook_data argument.
(grub_disk_dev_iterate): Likewise.
* include/grub/gpt_partition.h (grub_gpt_partition_map_iterate):
Likewise.
* include/grub/msdos_partition.h (grub_partition_msdos_iterate):
Likewise.
* include/grub/partition.h (grub_partition_iterate_hook_t): New
type.
(struct grub_partition_map.iterate): Add hook_data argument.
(grub_partition_iterate): Likewise.
* include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type.
(struct grub_scsi_dev.iterate): Add hook_data argument.
Update all callers.
---
ChangeLog | 26 ++
grub-core/commands/arc/lsdev.c | 18 +-
grub-core/commands/ls.c | 27 +-
grub-core/commands/search.c | 398 +++++++++++++++--------------
grub-core/commands/wildcard.c | 84 ++++---
grub-core/disk/ahci.c | 6 +-
grub-core/disk/arc/arcdisk.c | 34 ++-
grub-core/disk/ata.c | 118 +++++----
grub-core/disk/cryptodisk.c | 13 +-
grub-core/disk/diskfilter.c | 113 +++++----
grub-core/disk/efi/efidisk.c | 69 ++---
grub-core/disk/host.c | 4 +-
grub-core/disk/i386/pc/biosdisk.c | 15 +-
grub-core/disk/ieee1275/nand.c | 4 +-
grub-core/disk/ieee1275/ofdisk.c | 4 +-
grub-core/disk/ldm.c | 50 ++--
grub-core/disk/loopback.c | 6 +-
grub-core/disk/memdisk.c | 4 +-
grub-core/disk/pata.c | 5 +-
grub-core/disk/scsi.c | 81 +++---
grub-core/disk/usbms.c | 5 +-
grub-core/fs/btrfs.c | 101 ++++----
grub-core/fs/zfs/zfs.c | 72 +++---
grub-core/kern/corecmd.c | 4 +-
grub-core/kern/device.c | 145 ++++++-----
grub-core/kern/emu/hostdisk.c | 4 +-
grub-core/kern/mips/arc/init.c | 14 +-
grub-core/kern/partition.c | 156 +++++++-----
grub-core/loader/i386/pc/plan9.c | 513 ++++++++++++++++++++------------------
grub-core/normal/completion.c | 11 +-
grub-core/partmap/acorn.c | 6 +-
grub-core/partmap/amiga.c | 6 +-
grub-core/partmap/apple.c | 6 +-
grub-core/partmap/bsdlabel.c | 103 ++++----
grub-core/partmap/dvh.c | 5 +-
grub-core/partmap/gpt.c | 88 ++++---
grub-core/partmap/msdos.c | 6 +-
grub-core/partmap/plan.c | 6 +-
grub-core/partmap/sun.c | 5 +-
grub-core/partmap/sunpc.c | 6 +-
include/grub/arc/arc.h | 7 +-
include/grub/ata.h | 4 +-
include/grub/device.h | 5 +-
include/grub/disk.h | 8 +-
include/grub/gpt_partition.h | 4 +-
include/grub/msdos_partition.h | 4 +-
include/grub/partition.h | 11 +-
include/grub/scsi.h | 5 +-
util/getroot.c | 72 +++---
util/grub-setup.c | 125 ++++++----
50 files changed, 1438 insertions(+), 1148 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 1c816d6..733b212 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+ Remove nested functions from device iterators.
+
+ * include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type.
+ (grub_arc_iterate_devs): Add hook_data argument.
+ * include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type.
+ (struct grub_ata_dev.iterate): Add hook_data argument.
+ * include/grub/device.h (grub_device_iterate_hook_t): New type.
+ (grub_device_iterate): Add hook_data argument.
+ * include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type.
+ (struct grub_disk_dev.iterate): Add hook_data argument.
+ (grub_disk_dev_iterate): Likewise.
+ * include/grub/gpt_partition.h (grub_gpt_partition_map_iterate):
+ Likewise.
+ * include/grub/msdos_partition.h (grub_partition_msdos_iterate):
+ Likewise.
+ * include/grub/partition.h (grub_partition_iterate_hook_t): New
+ type.
+ (struct grub_partition_map.iterate): Add hook_data argument.
+ (grub_partition_iterate): Likewise.
+ * include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type.
+ (struct grub_scsi_dev.iterate): Add hook_data argument.
+
+ Update all callers.
+
+2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+
Fix typos for "developer" and "development".
2013-01-18 Vladimir Serbinenko <phcoder@gmail.com>
diff --git a/grub-core/commands/arc/lsdev.c b/grub-core/commands/arc/lsdev.c
index 5d4b0cd..27ed0a2 100644
--- a/grub-core/commands/arc/lsdev.c
+++ b/grub-core/commands/arc/lsdev.c
@@ -24,18 +24,22 @@
GRUB_MOD_LICENSE ("GPLv3+");
+/* Helper for grub_cmd_lsdev. */
+static int
+grub_cmd_lsdev_iter (const char *name,
+ const struct grub_arc_component *comp __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ grub_printf ("%s\n", name);
+ return 0;
+}
+
static grub_err_t
grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
- auto int hook (const char *name, const struct grub_arc_component *comp);
- int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused)))
- {
- grub_printf ("%s\n", name);
- return 0;
- }
- grub_arc_iterate_devs (hook, 0);
+ grub_arc_iterate_devs (grub_cmd_lsdev_iter, 0, 0);
return 0;
}
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
index 913bb65..7929747 100644
--- a/grub-core/commands/ls.c
+++ b/grub-core/commands/ls.c
@@ -45,21 +45,24 @@ static const struct grub_arg_option options[] =
static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
-static grub_err_t
-grub_ls_list_devices (int longlist)
+/* Helper for grub_ls_list_devices. */
+static int
+grub_ls_print_devices (const char *name, void *data)
{
- auto int grub_ls_print_devices (const char *name);
- int grub_ls_print_devices (const char *name)
- {
- if (longlist)
- grub_normal_print_device_info (name);
- else
- grub_printf ("(%s) ", name);
+ int *longlist = data;
- return 0;
- }
+ if (longlist)
+ grub_normal_print_device_info (name);
+ else
+ grub_printf ("(%s) ", name);
+
+ return 0;
+}
- grub_device_iterate (grub_ls_print_devices);
+static grub_err_t
+grub_ls_list_devices (int longlist)
+{
+ grub_device_iterate (grub_ls_print_devices, &longlist);
grub_xputs ("\n");
#if 0
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 5e9b7e3..16143a3 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -42,23 +42,29 @@ struct cache_entry
static struct cache_entry *cache;
-void
-FUNC_NAME (const char *key, const char *var, int no_floppy,
- char **hints, unsigned nhints)
+/* Context for FUNC_NAME. */
+struct search_ctx
{
- int count = 0;
- int is_cache = 0;
- grub_fs_autoload_hook_t saved_autoload;
+ const char *key;
+ const char *var;
+ int no_floppy;
+ char **hints;
+ unsigned nhints;
+ int count;
+ int is_cache;
+};
- auto int iterate_device (const char *name);
- int iterate_device (const char *name)
- {
- int found = 0;
+/* Helper for FUNC_NAME. */
+static int
+iterate_device (const char *name, void *data)
+{
+ struct search_ctx *ctx = data;
+ int found = 0;
- /* Skip floppy drives when requested. */
- if (no_floppy &&
- name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
- return 0;
+ /* Skip floppy drives when requested. */
+ if (ctx->no_floppy &&
+ name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
+ return 0;
#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
@@ -67,34 +73,34 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
#endif
#ifdef DO_SEARCH_FILE
- {
- char *buf;
- grub_file_t file;
-
- buf = grub_xasprintf ("(%s)%s", name, key);
- if (! buf)
- return 1;
-
- grub_file_filter_disable_compression ();
- file = grub_file_open (buf);
- if (file)
- {
- found = 1;
- grub_file_close (file);
- }
- grub_free (buf);
- }
+ {
+ char *buf;
+ grub_file_t file;
+
+ buf = grub_xasprintf ("(%s)%s", name, ctx->key);
+ if (! buf)
+ return 1;
+
+ grub_file_filter_disable_compression ();
+ file = grub_file_open (buf);
+ if (file)
+ {
+ found = 1;
+ grub_file_close (file);
+ }
+ grub_free (buf);
+ }
#else
- {
- /* SEARCH_FS_UUID or SEARCH_LABEL */
- grub_device_t dev;
- grub_fs_t fs;
- char *quid;
+ {
+ /* SEARCH_FS_UUID or SEARCH_LABEL */
+ grub_device_t dev;
+ grub_fs_t fs;
+ char *quid;
- dev = grub_device_open (name);
- if (dev)
- {
- fs = grub_fs_probe (dev);
+ dev = grub_device_open (name);
+ if (dev)
+ {
+ fs = grub_fs_probe (dev);
#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
@@ -102,173 +108,191 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
#define read_fn label
#endif
- if (fs && fs->read_fn)
- {
- fs->read_fn (dev, &quid);
+ if (fs && fs->read_fn)
+ {
+ fs->read_fn (dev, &quid);
- if (grub_errno == GRUB_ERR_NONE && quid)
- {
- if (compare_fn (quid, key) == 0)
- found = 1;
+ if (grub_errno == GRUB_ERR_NONE && quid)
+ {
+ if (compare_fn (quid, ctx->key) == 0)
+ found = 1;
- grub_free (quid);
- }
- }
+ grub_free (quid);
+ }
+ }
- grub_device_close (dev);
- }
- }
+ grub_device_close (dev);
+ }
+ }
#endif
- if (!is_cache && found && count == 0)
- {
- struct cache_entry *cache_ent;
- cache_ent = grub_malloc (sizeof (*cache_ent));
- if (cache_ent)
- {
- cache_ent->key = grub_strdup (key);
- cache_ent->value = grub_strdup (name);
- if (cache_ent->value && cache_ent->key)
- {
- cache_ent->next = cache;
- cache = cache_ent;
- }
- else
- {
- grub_free (cache_ent->value);
- grub_free (cache_ent->key);
- grub_free (cache_ent);
- grub_errno = GRUB_ERR_NONE;
- }
- }
- else
- grub_errno = GRUB_ERR_NONE;
- }
-
- if (found)
- {
- count++;
- if (var)
- grub_env_set (var, name);
- else
- grub_printf (" %s", name);
- }
-
- grub_errno = GRUB_ERR_NONE;
- return (found && var);
- }
-
- auto int part_hook (grub_disk_t disk, const grub_partition_t partition);
- int part_hook (grub_disk_t disk, const grub_partition_t partition)
- {
- char *partition_name, *devname;
- int ret;
-
- partition_name = grub_partition_get_name (partition);
- if (! partition_name)
- return 1;
-
- devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
- grub_free (partition_name);
- if (!devname)
- return 1;
- ret = iterate_device (devname);
- grub_free (devname);
-
- return ret;
- }
-
- auto void try (void);
- void try (void)
- {
- unsigned i;
- struct cache_entry **prev;
- struct cache_entry *cache_ent;
-
- for (prev = &cache, cache_ent = *prev; cache_ent;
- prev = &cache_ent->next, cache_ent = *prev)
- if (compare_fn (cache_ent->key, key) == 0)
- break;
- if (cache_ent)
- {
- is_cache = 1;
- if (iterate_device (cache_ent->value))
- {
- is_cache = 0;
- return;
- }
- is_cache = 0;
- /* Cache entry was outdated. Remove it. */
- if (!count)
- {
- grub_free (cache_ent->key);
- grub_free (cache_ent->value);
- grub_free (cache_ent);
- *prev = cache_ent->next;
- }
- }
-
- for (i = 0; i < nhints; i++)
- {
- char *end;
- if (!hints[i][0])
- continue;
- end = hints[i] + grub_strlen (hints[i]) - 1;
- if (*end == ',')
- *end = 0;
- if (iterate_device (hints[i]))
- {
- if (!*end)
- *end = ',';
+ if (!ctx->is_cache && found && ctx->count == 0)
+ {
+ struct cache_entry *cache_ent;
+ cache_ent = grub_malloc (sizeof (*cache_ent));
+ if (cache_ent)
+ {
+ cache_ent->key = grub_strdup (ctx->key);
+ cache_ent->value = grub_strdup (name);
+ if (cache_ent->value && cache_ent->key)
+ {
+ cache_ent->next = cache;
+ cache = cache_ent;
+ }
+ else
+ {
+ grub_free (cache_ent->value);
+ grub_free (cache_ent->key);
+ grub_free (cache_ent);
+ grub_errno = GRUB_ERR_NONE;
+ }
+ }
+ else
+ grub_errno = GRUB_ERR_NONE;
+ }
+
+ if (found)
+ {
+ ctx->count++;
+ if (ctx->var)
+ grub_env_set (ctx->var, name);
+ else
+ grub_printf (" %s", name);
+ }
+
+ grub_errno = GRUB_ERR_NONE;
+ return (found && ctx->var);
+}
+
+/* Helper for FUNC_NAME. */
+static int
+part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
+{
+ struct search_ctx *ctx = data;
+ char *partition_name, *devname;
+ int ret;
+
+ partition_name = grub_partition_get_name (partition);
+ if (! partition_name)
+ return 1;
+
+ devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
+ grub_free (partition_name);
+ if (!devname)
+ return 1;
+ ret = iterate_device (devname, ctx);
+ grub_free (devname);
+
+ return ret;
+}
+
+/* Helper for FUNC_NAME. */
+static void
+try (struct search_ctx *ctx)
+{
+ unsigned i;
+ struct cache_entry **prev;
+ struct cache_entry *cache_ent;
+
+ for (prev = &cache, cache_ent = *prev; cache_ent;
+ prev = &cache_ent->next, cache_ent = *prev)
+ if (compare_fn (cache_ent->key, ctx->key) == 0)
+ break;
+ if (cache_ent)
+ {
+ ctx->is_cache = 1;
+ if (iterate_device (cache_ent->value, ctx))
+ {
+ ctx->is_cache = 0;
+ return;
+ }
+ ctx->is_cache = 0;
+ /* Cache entry was outdated. Remove it. */
+ if (!ctx->count)
+ {
+ grub_free (cache_ent->key);
+ grub_free (cache_ent->value);
+ grub_free (cache_ent);
+ *prev = cache_ent->next;
+ }
+ }
+
+ for (i = 0; i < ctx->nhints; i++)
+ {
+ char *end;
+ if (!ctx->hints[i][0])
+ continue;
+ end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1;
+ if (*end == ',')
+ *end = 0;
+ if (iterate_device (ctx->hints[i], ctx))
+ {
+ if (!*end)
+ *end = ',';
+ return;
+ }
+ if (!*end)
+ {
+ grub_device_t dev;
+ int ret;
+ dev = grub_device_open (ctx->hints[i]);
+ if (!dev)
+ {
+ if (!*end)
+ *end = ',';
+ continue;
+ }
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ if (!*end)
+ *end = ',';
+ continue;
+ }
+ ret = grub_partition_iterate (dev->disk, part_hook, ctx);
+ if (!*end)
+ *end = ',';
+ grub_device_close (dev);
+ if (ret)
return;
- }
- if (!*end)
- {
- grub_device_t dev;
- int ret;
- dev = grub_device_open (hints[i]);
- if (!dev)
- {
- if (!*end)
- *end = ',';
- continue;
- }
- if (!dev->disk)
- {
- grub_device_close (dev);
- if (!*end)
- *end = ',';
- continue;
- }
- ret = grub_partition_iterate (dev->disk, part_hook);
- if (!*end)
- *end = ',';
- grub_device_close (dev);
- if (ret)
- return;
- }
- }
- grub_device_iterate (iterate_device);
- }
+ }
+ }
+ grub_device_iterate (iterate_device, ctx);
+}
+
+void
+FUNC_NAME (const char *key, const char *var, int no_floppy,
+ char **hints, unsigned nhints)
+{
+ struct search_ctx ctx = {
+ .key = key,
+ .var = var,
+ .no_floppy = no_floppy,
+ .hints = hints,
+ .nhints = nhints,
+ .count = 0,
+ .is_cache = 0
+ };
+ grub_fs_autoload_hook_t saved_autoload;
/* First try without autoloading if we're setting variable. */
if (var)
{
saved_autoload = grub_fs_autoload_hook;
grub_fs_autoload_hook = 0;
- try ();
+ try (&ctx);
/* Restore autoload hook. */
grub_fs_autoload_hook = saved_autoload;
/* Retry with autoload if nothing found. */
- if (grub_errno == GRUB_ERR_NONE && count == 0)
- try ();
+ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
+ try (&ctx);
}
else
- try ();
+ try (&ctx);
- if (grub_errno == GRUB_ERR_NONE && count == 0)
+ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
}
diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
index 2b73d9a..633de51 100644
--- a/grub-core/commands/wildcard.c
+++ b/grub-core/commands/wildcard.c
@@ -210,59 +210,71 @@ split_path (const char *str, const char **noregexop, const char **regexop)
*noregexop = split;
}
-static char **
-match_devices (const regex_t *regexp, int noparts)
+/* Context for match_devices. */
+struct match_devices_ctx
{
- int i;
+ const regex_t *regexp;
+ int noparts;
int ndev;
char **devs;
+};
- auto int match (const char *name);
- int match (const char *name)
- {
- char **t;
- char *buffer;
+/* Helper for match_devices. */
+static int
+match_devices_iter (const char *name, void *data)
+{
+ struct match_devices_ctx *ctx = data;
+ char **t;
+ char *buffer;
- /* skip partitions if asked to. */
- if (noparts && grub_strchr(name, ','))
- return 0;
+ /* skip partitions if asked to. */
+ if (ctx->noparts && grub_strchr (name, ','))
+ return 0;
- buffer = grub_xasprintf ("(%s)", name);
- if (! buffer)
- return 1;
+ buffer = grub_xasprintf ("(%s)", name);
+ if (! buffer)
+ return 1;
- grub_dprintf ("expand", "matching: %s\n", buffer);
- if (regexec (regexp, buffer, 0, 0, 0))
- {
- grub_dprintf ("expand", "not matched\n");
- grub_free (buffer);
- return 0;
- }
+ grub_dprintf ("expand", "matching: %s\n", buffer);
+ if (regexec (ctx->regexp, buffer, 0, 0, 0))
+ {
+ grub_dprintf ("expand", "not matched\n");
+ grub_free (buffer);
+ return 0;
+ }
- t = grub_realloc (devs, sizeof (char*) * (ndev + 2));
- if (! t)
- return 1;
+ t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
+ if (! t)
+ return 1;
- devs = t;
- devs[ndev++] = buffer;
- devs[ndev] = 0;
- return 0;
- }
+ ctx->devs = t;
+ ctx->devs[ctx->ndev++] = buffer;
+ ctx->devs[ctx->ndev] = 0;
+ return 0;
+}
- ndev = 0;
- devs = 0;
+static char **
+match_devices (const regex_t *regexp, int noparts)
+{
+ struct match_devices_ctx ctx = {
+ .regexp = regexp,
+ .noparts = noparts,
+ .ndev = 0,
+ .devs = 0
+ };
+ int i;
- if (grub_device_iterate (match))
+ if (grub_device_iterate (match_devices_iter, &ctx))
goto fail;
- return devs;
+ return ctx.devs;
fail:
- for (i = 0; devs && devs[i]; i++)
- grub_free (devs[i]);
+ for (i = 0; ctx.devs && ctx.devs[i]; i++)
+ grub_free (ctx.devs[i]);
- grub_free (devs);
+ grub_free (ctx.devs);
return 0;
}
diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c
index f229ff1..f9258fd 100644
--- a/grub-core/disk/ahci.c
+++ b/grub-core/disk/ahci.c
@@ -455,8 +455,8 @@ grub_ahci_restore_hw (void)
static int
-grub_ahci_iterate (int (*hook) (int id, int bus),
- grub_disk_pull_t pull)
+grub_ahci_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_ahci_device *dev;
@@ -464,7 +464,7 @@ grub_ahci_iterate (int (*hook) (int id, int bus),
return 0;
FOR_LIST_ELEMENTS(dev, grub_ahci_devices)
- if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num))
+ if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num, hook_data))
return 1;
return 0;
diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c
index 10cbc87..37c0ac3 100644
--- a/grub-core/disk/arc/arcdisk.c
+++ b/grub-core/disk/arc/arcdisk.c
@@ -80,23 +80,37 @@ arcdisk_hash_add (char *devpath)
}
+/* Context for grub_arcdisk_iterate. */
+struct grub_arcdisk_iterate_ctx
+{
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_arcdisk_iterate. */
+static int
+grub_arcdisk_iterate_iter (const char *name,
+ const struct grub_arc_component *comp, void *data)
+{
+ struct grub_arcdisk_iterate_ctx *ctx = data;
+
+ if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
+ || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
+ || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
+ return 0;
+ return ctx->hook (name, ctx->hook_data);
+}
+
static int
grub_arcdisk_iterate (int (*hook_in) (const char *name),
grub_disk_pull_t pull)
{
- auto int hook (const char *name, const struct grub_arc_component *comp);
- int hook (const char *name, const struct grub_arc_component *comp)
- {
- if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
- || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
- || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
- return 0;
- return hook_in (name);
- }
+ struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data };
+
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- return grub_arc_iterate_devs (hook, 1);
+ return grub_arc_iterate_devs (grub_arcdisk_iterate_iter, &ctx, 1);
}
#define RAW_SUFFIX "partition(10)"
diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c
index c0d378c..c84d316 100644
--- a/grub-core/disk/ata.c
+++ b/grub-core/disk/ata.c
@@ -392,40 +392,50 @@ grub_ata_real_open (int id, int bus)
return NULL;
}
+/* Context for grub_ata_iterate. */
+struct grub_ata_iterate_ctx
+{
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_ata_iterate. */
static int
-grub_ata_iterate (int (*hook_in) (const char *name),
- grub_disk_pull_t pull)
+grub_ata_iterate_iter (int id, int bus, void *data)
{
- auto int hook (int id, int bus);
- int hook (int id, int bus)
- {
- struct grub_ata *ata;
- int ret;
- char devname[40];
+ struct grub_ata_iterate_ctx *ctx = data;
+ struct grub_ata *ata;
+ int ret;
+ char devname[40];
- ata = grub_ata_real_open (id, bus);
+ ata = grub_ata_real_open (id, bus);
- if (!ata)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (ata->atapi)
- {
- grub_ata_real_close (ata);
- return 0;
- }
- grub_snprintf (devname, sizeof (devname),
- "%s%d", grub_scsi_names[id], bus);
- ret = hook_in (devname);
- grub_ata_real_close (ata);
- return ret;
- }
+ if (!ata)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (ata->atapi)
+ {
+ grub_ata_real_close (ata);
+ return 0;
+ }
+ grub_snprintf (devname, sizeof (devname),
+ "%s%d", grub_scsi_names[id], bus);
+ ret = ctx->hook (devname, ctx->hook_data);
+ grub_ata_real_close (ata);
+ return ret;
+}
+static int
+grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_ata_iterate_ctx ctx = { hook, hook_data };
grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next)
- if (p->iterate && p->iterate (hook, pull))
+ if (p->iterate && p->iterate (grub_ata_iterate_iter, &ctx, pull))
return 1;
return 0;
}
@@ -561,37 +571,47 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi)
return GRUB_ERR_NONE;
}
+/* Context for grub_atapi_iterate. */
+struct grub_atapi_iterate_ctx
+{
+ grub_scsi_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_atapi_iterate. */
static int
-grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns),
- grub_disk_pull_t pull)
+grub_atapi_iterate_iter (int id, int bus, void *data)
{
- auto int hook (int id, int bus);
- int hook (int id, int bus)
- {
- struct grub_ata *ata;
- int ret;
+ struct grub_atapi_iterate_ctx *ctx = data;
+ struct grub_ata *ata;
+ int ret;
- ata = grub_ata_real_open (id, bus);
+ ata = grub_ata_real_open (id, bus);
- if (!ata)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (!ata->atapi)
- {
- grub_ata_real_close (ata);
- return 0;
- }
- ret = hook_in (id, bus, 1);
- grub_ata_real_close (ata);
- return ret;
- }
+ if (!ata)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (!ata->atapi)
+ {
+ grub_ata_real_close (ata);
+ return 0;
+ }
+ ret = ctx->hook (id, bus, 1, ctx->hook_data);
+ grub_ata_real_close (ata);
+ return ret;
+}
+static int
+grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_atapi_iterate_ctx ctx = { hook, hook_data };
grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next)
- if (p->iterate && p->iterate (hook, pull))
+ if (p->iterate && p->iterate (grub_atapi_iterate_iter, &ctx, pull))
return 1;
return 0;
}
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 3de3b86..ce755c3 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -448,8 +448,8 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke
}
static int
-grub_cryptodisk_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
grub_cryptodisk_t i;
@@ -460,7 +460,7 @@ grub_cryptodisk_iterate (int (*hook) (const char *name),
{
char buf[30];
grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
@@ -866,7 +866,8 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
#endif
static int
-grub_cryptodisk_scan_device (const char *name)
+grub_cryptodisk_scan_device (const char *name,
+ void *data __attribute__ ((unused)))
{
grub_err_t err;
grub_disk_t source;
@@ -908,7 +909,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
check_boot = state[2].set;
search_uuid = args[0];
- grub_device_iterate (&grub_cryptodisk_scan_device);
+ grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL;
if (!have_it)
@@ -919,7 +920,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{
search_uuid = NULL;
check_boot = state[2].set;
- grub_device_iterate (&grub_cryptodisk_scan_device);
+ grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL;
return GRUB_ERR_NONE;
}
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index 4117b20..2ff47e9 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -120,65 +120,68 @@ is_valid_diskfilter_name (const char *name)
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
}
+/* Helper for scan_disk. */
static int
-scan_disk (const char *name, int accept_diskfilter)
+scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data)
{
- auto int hook (grub_disk_t disk, grub_partition_t p);
- int hook (grub_disk_t disk, grub_partition_t p)
- {
- struct grub_diskfilter_vg *arr;
- grub_disk_addr_t start_sector;
- struct grub_diskfilter_pv_id id;
- grub_diskfilter_t diskfilter;
-
- grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
- name);
+ const char *name = data;
+ struct grub_diskfilter_vg *arr;
+ grub_disk_addr_t start_sector;
+ struct grub_diskfilter_pv_id id;
+ grub_diskfilter_t diskfilter;
+
+ grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
+ name);
#ifdef GRUB_UTIL
- grub_util_info ("Scanning for DISKFILTER devices on disk %s", name);
+ grub_util_info ("Scanning for DISKFILTER devices on disk %s", name);
#endif
- disk->partition = p;
-
- for (arr = array_list; arr != NULL; arr = arr->next)
- {
- struct grub_diskfilter_pv *m;
- for (m = arr->pvs; m; m = m->next)
- if (m->disk && m->disk->id == disk->id
- && m->disk->dev->id == disk->dev->id
- && m->part_start == grub_partition_get_start (disk->partition)
- && m->part_size == grub_disk_get_size (disk))
- return 0;
- }
+ disk->partition = p;
+
+ for (arr = array_list; arr != NULL; arr = arr->next)
+ {
+ struct grub_diskfilter_pv *m;
+ for (m = arr->pvs; m; m = m->next)
+ if (m->disk && m->disk->id == disk->id
+ && m->disk->dev->id == disk->dev->id
+ && m->part_start == grub_partition_get_start (disk->partition)
+ && m->part_size == grub_disk_get_size (disk))
+ return 0;
+ }
- for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next)
- {
+ for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next)
+ {
#ifdef GRUB_UTIL
- grub_util_info ("Scanning for %s devices on disk %s",
- diskfilter->name, name);
+ grub_util_info ("Scanning for %s devices on disk %s",
+ diskfilter->name, name);
#endif
- id.uuid = 0;
- id.uuidlen = 0;
- arr = diskfilter->detect (disk, &id, &start_sector);
- if (arr &&
- (! insert_array (disk, &id, arr, start_sector, diskfilter)))
- {
- if (id.uuidlen)
- grub_free (id.uuid);
- return 0;
- }
- if (arr && id.uuidlen)
+ id.uuid = 0;
+ id.uuidlen = 0;
+ arr = diskfilter->detect (disk, &id, &start_sector);
+ if (arr &&
+ (! insert_array (disk, &id, arr, start_sector, diskfilter)))
+ {
+ if (id.uuidlen)
grub_free (id.uuid);
-
- /* This error usually means it's not diskfilter, no need to display
- it. */
- if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
- grub_print_error ();
-
- grub_errno = GRUB_ERR_NONE;
+ return 0;
}
+ if (arr && id.uuidlen)
+ grub_free (id.uuid);
- return 0;
+ /* This error usually means it's not diskfilter, no need to display
+ it. */
+ if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
+ grub_print_error ();
+
+ grub_errno = GRUB_ERR_NONE;
}
+
+ return 0;
+}
+
+static int
+scan_disk (const char *name, int accept_diskfilter)
+{
grub_disk_t disk;
static int scan_depth = 0;
@@ -196,12 +199,12 @@ scan_disk (const char *name, int accept_diskfilter)
scan_depth--;
return 0;
}
- if (hook (disk, 0))
+ if (scan_disk_partition_iter (disk, 0, (void *) name))
{
scan_depth--;
return 1;
}
- if (grub_partition_iterate (disk, hook))
+ if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name))
{
scan_depth--;
return 1;
@@ -212,7 +215,7 @@ scan_disk (const char *name, int accept_diskfilter)
}
static int
-scan_disk_hook (const char *name)
+scan_disk_hook (const char *name, void *data __attribute__ ((unused)))
{
return scan_disk (name, 0);
}
@@ -230,7 +233,7 @@ scan_devices (const char *arname)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
{
- if ((p->iterate) (scan_disk_hook, pull))
+ if ((p->iterate) (scan_disk_hook, NULL, pull))
return;
if (arname && is_lv_readable (find_lv (arname), 1))
return;
@@ -249,8 +252,8 @@ scan_devices (const char *arname)
}
static int
-grub_diskfilter_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_diskfilter_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_diskfilter_vg *array;
int islcnt = 0;
@@ -271,7 +274,7 @@ grub_diskfilter_iterate (int (*hook) (const char *name),
for (lv = array->lvs; lv; lv = lv->next)
if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt)
{
- if (hook (lv->fullname))
+ if (hook (lv->fullname, hook_data))
return 1;
}
}
@@ -303,7 +306,7 @@ grub_diskfilter_memberlist (grub_disk_t disk)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
{
- (p->iterate) (scan_disk_hook, pull);
+ (p->iterate) (scan_disk_hook, NULL, pull);
while (pv && pv->disk)
pv = pv->next;
}
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index d9d788c..98cd226 100644
--- a/grub-core/disk/efi/efidisk.c
+++ b/grub-core/disk/efi/efidisk.c
@@ -404,7 +404,7 @@ enumerate_disks (void)
}
static int
-grub_efidisk_iterate (int (*hook) (const char *name),
+grub_efidisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
struct grub_efidisk_data *d;
@@ -418,7 +418,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "hd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
@@ -427,7 +427,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "fd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
@@ -435,7 +435,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "cd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
@@ -736,6 +736,31 @@ get_diskname_from_path (const grub_efi_device_path_t *path,
return 0;
}
+/* Context for grub_efidisk_get_device_name. */
+struct grub_efidisk_get_device_name_ctx
+{
+ char *partition_name;
+ grub_efi_hard_drive_device_path_t hd;
+};
+
+/* Helper for grub_efidisk_get_device_name.
+ Find the identical partition. */
+static int
+grub_efidisk_get_device_name_iter (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t part, void *data)
+{
+ struct grub_efidisk_get_device_name_ctx *ctx = data;
+
+ if (grub_partition_get_start (part) == ctx->hd.partition_start
+ && grub_partition_get_len (part) == ctx->hd.partition_size)
+ {
+ ctx->partition_name = grub_partition_get_name (part);
+ return 1;
+ }
+
+ return 0;
+}
+
char *
grub_efidisk_get_device_name (grub_efi_handle_t *handle)
{
@@ -754,28 +779,11 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
{
- char *partition_name = NULL;
+ struct grub_efidisk_get_device_name_ctx ctx;
char *dev_name;
grub_efi_device_path_t *dup_dp, *dup_ldp;
- grub_efi_hard_drive_device_path_t hd;
grub_disk_t parent = 0;
- auto int find_partition (grub_disk_t disk, const grub_partition_t part);
-
- /* Find the identical partition. */
- int find_partition (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t part)
- {
- if (grub_partition_get_start (part) == hd.partition_start
- && grub_partition_get_len (part) == hd.partition_size)
- {
- partition_name = grub_partition_get_name (part);
- return 1;
- }
-
- return 0;
- }
-
/* It is necessary to duplicate the device path so that GRUB
can overwrite it. */
dup_dp = duplicate_device_path (dp);
@@ -797,24 +805,27 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
return 0;
/* Find a partition which matches the hard drive device path. */
- grub_memcpy (&hd, ldp, sizeof (hd));
- if (hd.partition_start == 0
- && hd.partition_size == grub_disk_get_size (parent))
+ ctx.partition_name = NULL;
+ grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd));
+ if (ctx.hd.partition_start == 0
+ && ctx.hd.partition_size == grub_disk_get_size (parent))
{
dev_name = grub_strdup (parent->name);
}
else
{
- grub_partition_iterate (parent, find_partition);
+ grub_partition_iterate (parent, grub_efidisk_get_device_name_iter,
+ &ctx);
- if (! partition_name)
+ if (! ctx.partition_name)
{
grub_disk_close (parent);
return 0;
}
- dev_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
- grub_free (partition_name);
+ dev_name = grub_xasprintf ("%s,%s", parent->name,
+ ctx.partition_name);
+ grub_free (ctx.partition_name);
}
grub_disk_close (parent);
diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c
index 5ee0d2e..959211b 100644
--- a/grub-core/disk/host.c
+++ b/grub-core/disk/host.c
@@ -27,13 +27,13 @@
int grub_disk_host_i_want_a_reference;
static int
-grub_host_iterate (int (*hook) (const char *name),
+grub_host_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- if (hook ("host"))
+ if (hook ("host", hook_data))
return 1;
return 0;
}
diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c
index 7ca89e3..7c8dca3 100644
--- a/grub-core/disk/i386/pc/biosdisk.c
+++ b/grub-core/disk/i386/pc/biosdisk.c
@@ -272,20 +272,21 @@ grub_biosdisk_get_drive (const char *name)
}
static int
-grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
+grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ int drive)
{
char name[10];
if (cd_drive && drive == cd_drive)
- return hook ("cd");
+ return hook ("cd", hook_data);
grub_snprintf (name, sizeof (name),
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
- return hook (name);
+ return hook (name, hook_data);
}
static int
-grub_biosdisk_iterate (int (*hook) (const char *name),
+grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull __attribute__ ((unused)))
{
int num_floppies;
@@ -304,7 +305,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
break;
}
- if (grub_biosdisk_call_hook (hook, drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, drive))
return 1;
}
return 0;
@@ -312,14 +313,14 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
case GRUB_DISK_PULL_REMOVABLE:
if (cd_drive)
{
- if (grub_biosdisk_call_hook (hook, cd_drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, cd_drive))
return 1;
}
/* For floppy disks, we can get the number safely. */
num_floppies = grub_biosdisk_get_num_floppies ();
for (drive = 0; drive < num_floppies; drive++)
- if (grub_biosdisk_call_hook (hook, drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, drive))
return 1;
return 0;
default:
diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c
index 3474b3e..b2844b1 100644
--- a/grub-core/disk/ieee1275/nand.c
+++ b/grub-core/disk/ieee1275/nand.c
@@ -33,7 +33,7 @@ struct grub_nand_data
};
static int
-grub_nand_iterate (int (*hook) (const char *name),
+grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
auto int dev_iterate (struct grub_ieee1275_devalias *alias);
@@ -41,7 +41,7 @@ grub_nand_iterate (int (*hook) (const char *name),
{
if (grub_strcmp (alias->name, "nand") == 0)
{
- hook (alias->name);
+ hook (alias->name, hook_data);
return 1;
}
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index c9535a0..644bbd2 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -218,7 +218,7 @@ scan (void)
}
static int
-grub_ofdisk_iterate (int (*hook) (const char *name),
+grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -276,7 +276,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name),
*optr++ = *iptr++;
}
*optr = 0;
- if (hook (buffer))
+ if (hook (buffer, hook_data))
return 1;
}
}
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 0e4761b..b92433d 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -105,35 +105,39 @@ read_int (grub_uint8_t *in, grub_size_t s)
static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
+/* Helper for gpt_ldm_sector. */
+static int
+gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data)
+{
+ grub_disk_addr_t *sector = data;
+ struct grub_gpt_partentry gptdata;
+ grub_partition_t p2;
+
+ p2 = disk->partition;
+ disk->partition = p->parent;
+ if (grub_disk_read (disk, p->offset, p->index,
+ sizeof (gptdata), &gptdata))
+ {
+ disk->partition = p2;
+ return 0;
+ }
+ disk->partition = p2;
+
+ if (! grub_memcmp (&gptdata.type, &ldm_type, 16))
+ {
+ *sector = p->start + p->len - 1;
+ return 1;
+ }
+ return 0;
+}
+
static grub_disk_addr_t
gpt_ldm_sector (grub_disk_t dsk)
{
grub_disk_addr_t sector = 0;
grub_err_t err;
- auto int hook (grub_disk_t disk, const grub_partition_t p);
- int hook (grub_disk_t disk, const grub_partition_t p)
- {
- struct grub_gpt_partentry gptdata;
- grub_partition_t p2;
-
- p2 = disk->partition;
- disk->partition = p->parent;
- if (grub_disk_read (disk, p->offset, p->index,
- sizeof (gptdata), &gptdata))
- {
- disk->partition = p2;
- return 0;
- }
- disk->partition = p2;
- if (! grub_memcmp (&gptdata.type, &ldm_type, 16))
- {
- sector = p->start + p->len - 1;
- return 1;
- }
- return 0;
- }
- err = grub_gpt_partition_map_iterate (dsk, hook);
+ err = grub_gpt_partition_map_iterate (dsk, gpt_ldm_sector_iter, &sector);
if (err)
{
grub_errno = GRUB_ERR_NONE;
diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c
index fffd1bb..fed88de 100644
--- a/grub-core/disk/loopback.c
+++ b/grub-core/disk/loopback.c
@@ -135,15 +135,15 @@ fail:
static int
-grub_loopback_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_loopback *d;
if (pull != GRUB_DISK_PULL_NONE)
return 0;
for (d = loopback_list; d; d = d->next)
{
- if (hook (d->devname))
+ if (hook (d->devname, hook_data))
return 1;
}
return 0;
diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c
index 4de0971..4ad1cb1 100644
--- a/grub-core/disk/memdisk.c
+++ b/grub-core/disk/memdisk.c
@@ -30,13 +30,13 @@ static char *memdisk_addr;
static grub_off_t memdisk_size = 0;
static int
-grub_memdisk_iterate (int (*hook) (const char *name),
+grub_memdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- return hook ("memdisk");
+ return hook ("memdisk", hook_data);
}
static grub_err_t
diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c
index 07c3d7f..75e5deb 100644
--- a/grub-core/disk/pata.c
+++ b/grub-core/disk/pata.c
@@ -501,7 +501,7 @@ grub_pata_open (int id, int devnum, struct grub_ata *ata)
}
static int
-grub_pata_iterate (int (*hook) (int id, int bus),
+grub_pata_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
struct grub_pata_device *dev;
@@ -510,7 +510,8 @@ grub_pata_iterate (int (*hook) (int id, int bus),
return 0;
for (dev = grub_pata_devices; dev; dev = dev->next)
- if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device))
+ if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device,
+ hook_data))
return 1;
return 0;
diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c
index 29dd0d3..90ac379 100644
--- a/grub-core/disk/scsi.c
+++ b/grub-core/disk/scsi.c
@@ -423,50 +423,59 @@ grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector,
-static int
-grub_scsi_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+/* Context for grub_scsi_iterate. */
+struct grub_scsi_iterate_ctx
{
- grub_scsi_dev_t p;
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
- auto int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns);
+/* Helper for grub_scsi_iterate. */
+static int
+scsi_iterate (int id, int bus, int luns, void *data)
+{
+ struct grub_scsi_iterate_ctx *ctx = data;
+ int i;
- int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns)
+ /* In case of a single LUN, just return `usbX'. */
+ if (luns == 1)
{
- int i;
-
- /* In case of a single LUN, just return `usbX'. */
- if (luns == 1)
- {
- char *sname;
- int ret;
- sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
- if (!sname)
- return 1;
- ret = hook (sname);
- grub_free (sname);
- return ret;
- }
+ char *sname;
+ int ret;
+ sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
+ if (!sname)
+ return 1;
+ ret = ctx->hook (sname, ctx->hook_data);
+ grub_free (sname);
+ return ret;
+ }
- /* In case of multiple LUNs, every LUN will get a prefix to
- distinguish it. */
- for (i = 0; i < luns; i++)
- {
- char *sname;
- int ret;
- sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
- if (!sname)
- return 1;
- ret = hook (sname);
- grub_free (sname);
- if (ret)
- return 1;
- }
- return 0;
+ /* In case of multiple LUNs, every LUN will get a prefix to
+ distinguish it. */
+ for (i = 0; i < luns; i++)
+ {
+ char *sname;
+ int ret;
+ sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
+ if (!sname)
+ return 1;
+ ret = ctx->hook (sname, ctx->hook_data);
+ grub_free (sname);
+ if (ret)
+ return 1;
}
+ return 0;
+}
+
+static int
+grub_scsi_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_scsi_iterate_ctx ctx = { hook, hook_data };
+ grub_scsi_dev_t p;
for (p = grub_scsi_dev_list; p; p = p->next)
- if (p->iterate && (p->iterate) (scsi_iterate, pull))
+ if (p->iterate && (p->iterate) (scsi_iterate, &ctx, pull))
return 1;
return 0;
diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
index 52cc33e..50f0caf 100644
--- a/grub-core/disk/usbms.c
+++ b/grub-core/disk/usbms.c
@@ -265,7 +265,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
static int
-grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
+grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -278,7 +278,8 @@ grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (grub_usbms_devices[i])
{
- if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns))
+ if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns,
+ hook_data))
return 1;
}
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index a993f07..bcc75ba 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -538,56 +538,71 @@ lower_bound (struct grub_btrfs_data *data,
}
}
-static grub_device_t
-find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
+/* Context for find_device. */
+struct find_device_ctx
{
- grub_device_t dev_found = NULL;
- auto int hook (const char *name);
- int hook (const char *name)
- {
- grub_device_t dev;
- grub_err_t err;
- struct grub_btrfs_superblock sb;
- dev = grub_device_open (name);
- if (!dev)
+ struct grub_btrfs_data *data;
+ grub_uint64_t id;
+ grub_device_t dev_found;
+};
+
+/* Helper for find_device. */
+static int
+find_device_iter (const char *name, void *data)
+{
+ struct find_device_ctx *ctx = data;
+ grub_device_t dev;
+ grub_err_t err;
+ struct grub_btrfs_superblock sb;
+
+ dev = grub_device_open (name);
+ if (!dev)
+ return 0;
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
return 0;
- if (!dev->disk)
- {
- grub_device_close (dev);
- return 0;
- }
- err = read_sblock (dev->disk, &sb);
- if (err == GRUB_ERR_BAD_FS)
- {
- grub_device_close (dev);
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (err)
- {
- grub_device_close (dev);
- grub_print_error ();
- return 0;
- }
- if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
- || sb.this_device.device_id != id)
- {
- grub_device_close (dev);
- return 0;
- }
+ }
+ err = read_sblock (dev->disk, &sb);
+ if (err == GRUB_ERR_BAD_FS)
+ {
+ grub_device_close (dev);
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (err)
+ {
+ grub_device_close (dev);
+ grub_print_error ();
+ return 0;
+ }
+ if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
+ || sb.this_device.device_id != ctx->id)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
- dev_found = dev;
- return 1;
- }
+ ctx->dev_found = dev;
+ return 1;
+}
+static grub_device_t
+find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
+{
+ struct find_device_ctx ctx = {
+ .data = data,
+ .id = id,
+ .dev_found = NULL
+ };
unsigned i;
for (i = 0; i < data->n_devices_attached; i++)
if (id == data->devices_attached[i].id)
return data->devices_attached[i].dev;
if (do_rescan)
- grub_device_iterate (hook);
- if (!dev_found)
+ grub_device_iterate (find_device_iter, &ctx);
+ if (!ctx.dev_found)
{
grub_error (GRUB_ERR_BAD_FS,
N_("couldn't find a necessary member device "
@@ -605,14 +620,14 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
* sizeof (data->devices_attached[0]));
if (!data->devices_attached)
{
- grub_device_close (dev_found);
+ grub_device_close (ctx.dev_found);
data->devices_attached = tmp;
return NULL;
}
}
data->devices_attached[data->n_devices_attached - 1].id = id;
- data->devices_attached[data->n_devices_attached - 1].dev = dev_found;
- return dev_found;
+ data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found;
+ return ctx.dev_found;
}
static grub_err_t
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index ba0554a..6ef6db3 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -988,43 +988,47 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data,
return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label");
}
-static grub_err_t
-scan_devices (struct grub_zfs_data *data)
+/* Helper for scan_devices. */
+static int
+scan_devices_iter (const char *name, void *hook_data)
{
- auto int hook (const char *name);
- int hook (const char *name)
- {
- grub_device_t dev;
- grub_err_t err;
- int inserted;
- dev = grub_device_open (name);
- if (!dev)
- return 0;
- if (!dev->disk)
- {
- grub_device_close (dev);
- return 0;
- }
- err = scan_disk (dev, data, 0, &inserted);
- if (err == GRUB_ERR_BAD_FS)
- {
- grub_device_close (dev);
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (err)
- {
- grub_device_close (dev);
- grub_print_error ();
- return 0;
- }
+ struct grub_zfs_data *data = hook_data;
+ grub_device_t dev;
+ grub_err_t err;
+ int inserted;
- if (!inserted)
- grub_device_close (dev);
-
+ dev = grub_device_open (name);
+ if (!dev)
return 0;
- }
- grub_device_iterate (hook);
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+ err = scan_disk (dev, data, 0, &inserted);
+ if (err == GRUB_ERR_BAD_FS)
+ {
+ grub_device_close (dev);
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (err)
+ {
+ grub_device_close (dev);
+ grub_print_error ();
+ return 0;
+ }
+
+ if (!inserted)
+ grub_device_close (dev);
+
+ return 0;
+}
+
+static grub_err_t
+scan_devices (struct grub_zfs_data *data)
+{
+ grub_device_iterate (scan_devices_iter, data);
return GRUB_ERR_NONE;
}
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
index 43240e9..3441ccb 100644
--- a/grub-core/kern/corecmd.c
+++ b/grub-core/kern/corecmd.c
@@ -96,7 +96,7 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
}
static int
-grub_mini_print_devices (const char *name)
+grub_mini_print_devices (const char *name, void *data __attribute__ ((unused)))
{
grub_printf ("(%s) ", name);
@@ -119,7 +119,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
{
if (argc < 1)
{
- grub_device_iterate (grub_mini_print_devices);
+ grub_device_iterate (grub_mini_print_devices, NULL);
grub_xputs ("\n");
grub_refresh ();
}
diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c
index 1261564..73b8ecc 100644
--- a/grub-core/kern/device.c
+++ b/grub-core/kern/device.c
@@ -85,94 +85,107 @@ grub_device_close (grub_device_t device)
return grub_errno;
}
-int
-grub_device_iterate (int (*hook) (const char *name))
+struct part_ent
{
- auto int iterate_disk (const char *disk_name);
- auto int iterate_partition (grub_disk_t disk,
- const grub_partition_t partition);
+ struct part_ent *next;
+ char *name;
+};
- struct part_ent
- {
- struct part_ent *next;
- char *name;
- } *ents;
+/* Context for grub_device_iterate. */
+struct grub_device_iterate_ctx
+{
+ grub_device_iterate_hook_t hook;
+ void *hook_data;
+ struct part_ent *ents;
+};
+
+/* Helper for grub_device_iterate. */
+static int
+iterate_partition (grub_disk_t disk, const grub_partition_t partition,
+ void *data)
+{
+ struct grub_device_iterate_ctx *ctx = data;
+ struct part_ent *p;
+ char *part_name;
- int iterate_disk (const char *disk_name)
+ p = grub_malloc (sizeof (*p));
+ if (!p)
{
- grub_device_t dev;
-
- if (hook (disk_name))
- return 1;
-
- dev = grub_device_open (disk_name);
- if (! dev)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
-
- if (dev->disk)
- {
- struct part_ent *p;
- int ret = 0;
+ return 1;
+ }
- ents = NULL;
- (void) grub_partition_iterate (dev->disk, iterate_partition);
- grub_device_close (dev);
+ part_name = grub_partition_get_name (partition);
+ if (!part_name)
+ {
+ grub_free (p);
+ return 1;
+ }
+ p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
+ grub_free (part_name);
+ if (!p->name)
+ {
+ grub_free (p);
+ return 1;
+ }
- grub_errno = GRUB_ERR_NONE;
+ p->next = ctx->ents;
+ ctx->ents = p;
- p = ents;
- while (p != NULL)
- {
- struct part_ent *next = p->next;
+ return 0;
+}
- if (!ret)
- ret = hook (p->name);
- grub_free (p->name);
- grub_free (p);
- p = next;
- }
+/* Helper for grub_device_iterate. */
+static int
+iterate_disk (const char *disk_name, void *data)
+{
+ struct grub_device_iterate_ctx *ctx = data;
+ grub_device_t dev;
- return ret;
- }
+ if (ctx->hook (disk_name, ctx->hook_data))
+ return 1;
- grub_device_close (dev);
+ dev = grub_device_open (disk_name);
+ if (! dev)
+ {
+ grub_errno = GRUB_ERR_NONE;
return 0;
}
- int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
+ if (dev->disk)
{
struct part_ent *p;
- char *part_name;
+ int ret = 0;
- p = grub_malloc (sizeof (*p));
- if (!p)
- {
- return 1;
- }
+ ctx->ents = NULL;
+ (void) grub_partition_iterate (dev->disk, iterate_partition, ctx);
+ grub_device_close (dev);
- part_name = grub_partition_get_name (partition);
- if (!part_name)
- {
- grub_free (p);
- return 1;
- }
- p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
- grub_free (part_name);
- if (!p->name)
+ grub_errno = GRUB_ERR_NONE;
+
+ p = ctx->ents;
+ while (p != NULL)
{
+ struct part_ent *next = p->next;
+
+ if (!ret)
+ ret = ctx->hook (p->name, ctx->hook_data);
+ grub_free (p->name);
grub_free (p);
- return 1;
+ p = next;
}
- p->next = ents;
- ents = p;
-
- return 0;
+ return ret;
}
+ grub_device_close (dev);
+ return 0;
+}
+
+int
+grub_device_iterate (grub_device_iterate_hook_t hook, void *hook_data)
+{
+ struct grub_device_iterate_ctx ctx = { hook, hook_data, NULL };
+
/* Only disk devices are supported at the moment. */
- return grub_disk_dev_iterate (iterate_disk);
+ return grub_disk_dev_iterate (iterate_disk, &ctx);
}
diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c
index ccd2417..92ce1d9 100644
--- a/grub-core/kern/emu/hostdisk.c
+++ b/grub-core/kern/emu/hostdisk.c
@@ -223,7 +223,7 @@ find_free_slot (void)
}
static int
-grub_util_biosdisk_iterate (int (*hook) (const char *name),
+grub_util_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -232,7 +232,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name),
return 0;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
- if (map[i].drive && hook (map[i].drive))
+ if (map[i].drive && hook (map[i].drive, hook_data))
return 1;
return 0;
diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c
index 4d680ed..f63ac6d 100644
--- a/grub-core/kern/mips/arc/init.c
+++ b/grub-core/kern/mips/arc/init.c
@@ -48,8 +48,7 @@ const char *type_names[] = {
static int
iterate_rec (const char *prefix, const struct grub_arc_component *parent,
- int (*hook) (const char *name,
- const struct grub_arc_component *comp),
+ grub_arc_iterate_devs_hook_t hook, void *hook_data,
int alt_names)
{
const struct grub_arc_component *comp;
@@ -67,12 +66,13 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent,
name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
if (!name)
return 1;
- if (hook (name, comp))
+ if (hook (name, comp, hook_data))
{
grub_free (name);
return 1;
}
- if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names))
+ if (iterate_rec ((parent ? name : prefix), comp, hook, hook_data,
+ alt_names))
{
grub_free (name);
return 1;
@@ -83,11 +83,11 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent,
}
int
-grub_arc_iterate_devs (int (*hook) (const char *name,
- const struct grub_arc_component *comp),
+grub_arc_iterate_devs (grub_arc_iterate_devs_hook_t hook, void *hook_data,
int alt_names)
{
- return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names);
+ return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, hook_data,
+ alt_names);
}
grub_err_t
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
index 82ae9c8..e499147 100644
--- a/grub-core/kern/partition.c
+++ b/grub-core/kern/partition.c
@@ -59,39 +59,50 @@ grub_partition_check_containment (const grub_disk_t disk,
return 1;
}
-static grub_partition_t
-grub_partition_map_probe (const grub_partition_map_t partmap,
- grub_disk_t disk, int partnum)
+/* Context for grub_partition_map_probe. */
+struct grub_partition_map_probe_ctx
{
- grub_partition_t p = 0;
+ int partnum;
+ grub_partition_t p;
+};
- auto int find_func (grub_disk_t d, const grub_partition_t partition);
+/* Helper for grub_partition_map_probe. */
+static int
+probe_iter (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct grub_partition_map_probe_ctx *ctx = data;
- int find_func (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- if (partnum != partition->number)
- return 0;
+ if (ctx->partnum != partition->number)
+ return 0;
- if (!(grub_partition_check_containment (dsk, partition)))
- return 0;
+ if (!(grub_partition_check_containment (dsk, partition)))
+ return 0;
- p = (grub_partition_t) grub_malloc (sizeof (*p));
- if (! p)
- return 1;
+ ctx->p = (grub_partition_t) grub_malloc (sizeof (*ctx->p));
+ if (! ctx->p)
+ return 1;
- grub_memcpy (p, partition, sizeof (*p));
- return 1;
- }
+ grub_memcpy (ctx->p, partition, sizeof (*ctx->p));
+ return 1;
+}
- partmap->iterate (disk, find_func);
+static grub_partition_t
+grub_partition_map_probe (const grub_partition_map_t partmap,
+ grub_disk_t disk, int partnum)
+{
+ struct grub_partition_map_probe_ctx ctx = {
+ .partnum = partnum,
+ .p = 0
+ };
+
+ partmap->iterate (disk, probe_iter, &ctx);
if (grub_errno)
goto fail;
- return p;
+ return ctx.p;
fail:
- grub_free (p);
+ grub_free (ctx.p);
return 0;
}
@@ -162,62 +173,71 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
return part;
}
-int
-grub_partition_iterate (struct grub_disk *disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+/* Context for grub_partition_iterate. */
+struct grub_partition_iterate_ctx
{
- int ret = 0;
-
- auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
+ int ret;
+ grub_partition_iterate_hook_t hook;
+ void *hook_data;
+};
- int part_iterate (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- struct grub_partition p = *partition;
+/* Helper for grub_partition_iterate. */
+static int
+part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct grub_partition_iterate_ctx *ctx = data;
+ struct grub_partition p = *partition;
- if (!(grub_partition_check_containment (dsk, partition)))
- return 0;
+ if (!(grub_partition_check_containment (dsk, partition)))
+ return 0;
- p.parent = dsk->partition;
- dsk->partition = 0;
- if (hook (dsk, &p))
- {
- ret = 1;
- return 1;
- }
- if (p.start != 0)
- {
- const struct grub_partition_map *partmap;
- dsk->partition = &p;
- FOR_PARTITION_MAPS(partmap)
- {
- grub_err_t err;
- err = partmap->iterate (dsk, part_iterate);
- if (err)
- grub_errno = GRUB_ERR_NONE;
- if (ret)
- break;
- }
- }
- dsk->partition = p.parent;
- return ret;
+ p.parent = dsk->partition;
+ dsk->partition = 0;
+ if (ctx->hook (dsk, &p, ctx->hook_data))
+ {
+ ctx->ret = 1;
+ return 1;
}
-
- {
- const struct grub_partition_map *partmap;
- FOR_PARTITION_MAPS(partmap)
+ if (p.start != 0)
{
- grub_err_t err;
- err = partmap->iterate (disk, part_iterate);
- if (err)
- grub_errno = GRUB_ERR_NONE;
- if (ret)
- break;
+ const struct grub_partition_map *partmap;
+ dsk->partition = &p;
+ FOR_PARTITION_MAPS(partmap)
+ {
+ grub_err_t err;
+ err = partmap->iterate (dsk, part_iterate, ctx);
+ if (err)
+ grub_errno = GRUB_ERR_NONE;
+ if (ctx->ret)
+ break;
+ }
}
+ dsk->partition = p.parent;
+ return ctx->ret;
+}
+
+int
+grub_partition_iterate (struct grub_disk *disk,
+ grub_partition_iterate_hook_t hook, void *hook_data)
+{
+ struct grub_partition_iterate_ctx ctx = {
+ .ret = 0,
+ .hook = hook,
+ .hook_data = hook_data
+ };
+ const struct grub_partition_map *partmap;
+
+ FOR_PARTITION_MAPS(partmap)
+ {
+ grub_err_t err;
+ err = partmap->iterate (disk, part_iterate, &ctx);
+ if (err)
+ grub_errno = GRUB_ERR_NONE;
+ if (ctx.ret)
+ break;
}
- return ret;
+ return ctx.ret;
}
char *
diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c
index b41dfd2..7dc12a8 100644
--- a/grub-core/loader/i386/pc/plan9.c
+++ b/grub-core/loader/i386/pc/plan9.c
@@ -102,248 +102,281 @@ grub_plan9_unload (void)
return GRUB_ERR_NONE;
}
-static grub_err_t
-grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
+/* Context for grub_cmd_plan9. */
+struct grub_cmd_plan9_ctx
{
- grub_file_t file = 0;
- void *mem;
- grub_size_t memsize, padsize;
- struct grub_plan9_header hdr;
- char *config, *configptr;
- grub_size_t configsize;
- char *pmap = NULL;
- grub_size_t pmapalloc = 256;
- grub_size_t pmapptr = 0;
- int noslash = 1;
- char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"};
+ grub_extcmd_context_t ctxt;
+ grub_file_t file;
+ char *pmap;
+ grub_size_t pmapalloc;
+ grub_size_t pmapptr;
+ int noslash;
int prefixescnt[5];
- char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL;
+ char *bootdisk, *bootpart;
+};
- auto int fill_partition (grub_disk_t disk,
- const grub_partition_t partition);
- int fill_partition (grub_disk_t disk,
- const grub_partition_t partition)
- {
- int file_disk = 0;
- int pstart, pend;
- if (!noslash)
- {
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
- return 1;
- pmap[pmapptr++] = '/';
- }
- noslash = 0;
+static const char prefixes[5][10] = {
+ "dos", "plan9", "ntfs", "linux", "linuxswap"
+};
- file_disk = file->device->disk && disk->id == file->device->disk->id
- && disk->dev->id == file->device->disk->dev->id;
+/* Helper for grub_cmd_plan9. */
+static int
+fill_partition (grub_disk_t disk, const grub_partition_t partition, void *data)
+{
+ struct grub_cmd_plan9_ctx *fill_ctx = data;
+ int file_disk = 0;
+ int pstart, pend;
- pstart = pmapptr;
- if (grub_strcmp (partition->partmap->name, "plan") == 0)
- {
- unsigned ptr = partition->index + sizeof ("part ") - 1;
- grub_err_t err;
- disk->partition = partition->parent;
- do
- {
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
- return 1;
- err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr);
- if (err)
- {
- disk->partition = 0;
- return err;
- }
- ptr++;
- pmapptr++;
- }
- while (grub_isalpha (pmap[pmapptr - 1])
- || grub_isdigit (pmap[pmapptr - 1]));
- pmapptr--;
- }
- else
- {
- char name[50];
- int c = 0;
- if (grub_strcmp (partition->partmap->name, "msdos") == 0)
- {
- switch (partition->msdostype)
- {
- case GRUB_PC_PARTITION_TYPE_PLAN9:
- c = 1;
- break;
- case GRUB_PC_PARTITION_TYPE_NTFS:
- c = 2;
- break;
- case GRUB_PC_PARTITION_TYPE_MINIX:
- case GRUB_PC_PARTITION_TYPE_LINUX_MINIX:
- case GRUB_PC_PARTITION_TYPE_EXT2FS:
- c = 3;
- break;
- case GRUB_PC_PARTITION_TYPE_LINUX_SWAP:
- c = 4;
- break;
- }
- }
+ if (!fill_ctx->noslash)
+ {
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = '/';
+ }
+ fill_ctx->noslash = 0;
- if (prefixescnt[c] == 0)
- grub_strcpy (name, prefixes[c]);
- else
- grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c],
- prefixescnt[c]);
- prefixescnt[c]++;
- if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1,
- &pmapalloc, (void **) &pmap))
- return 1;
- grub_strcpy (pmap + pmapptr, name);
- pmapptr += grub_strlen (name);
- }
- pend = pmapptr;
- if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc,
- (void **) &pmap))
- return 1;
- pmap[pmapptr++] = ' ';
- grub_snprintf (pmap + pmapptr, 25 + 5 + 25,
- "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T,
- grub_partition_get_start (partition),
- grub_partition_get_start (partition)
- + grub_partition_get_len (partition));
- if (file_disk && grub_partition_get_start (partition)
- == grub_partition_get_start (file->device->disk->partition)
- && grub_partition_get_len (partition)
- == grub_partition_get_len (file->device->disk->partition))
- {
- grub_free (bootpart);
- bootpart = grub_strndup (pmap + pstart, pend - pstart);
- }
+ file_disk = fill_ctx->file->device->disk
+ && disk->id == fill_ctx->file->device->disk->id
+ && disk->dev->id == fill_ctx->file->device->disk->dev->id;
- pmapptr += grub_strlen (pmap + pmapptr);
- return 0;
- }
+ pstart = fill_ctx->pmapptr;
+ if (grub_strcmp (partition->partmap->name, "plan") == 0)
+ {
+ unsigned ptr = partition->index + sizeof ("part ") - 1;
+ grub_err_t err;
+ disk->partition = partition->parent;
+ do
+ {
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ err = grub_disk_read (disk, 1, ptr, 1,
+ fill_ctx->pmap + fill_ctx->pmapptr);
+ if (err)
+ {
+ disk->partition = 0;
+ return err;
+ }
+ ptr++;
+ fill_ctx->pmapptr++;
+ }
+ while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1])
+ || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1]));
+ fill_ctx->pmapptr--;
+ }
+ else
+ {
+ char name[50];
+ int c = 0;
+ if (grub_strcmp (partition->partmap->name, "msdos") == 0)
+ {
+ switch (partition->msdostype)
+ {
+ case GRUB_PC_PARTITION_TYPE_PLAN9:
+ c = 1;
+ break;
+ case GRUB_PC_PARTITION_TYPE_NTFS:
+ c = 2;
+ break;
+ case GRUB_PC_PARTITION_TYPE_MINIX:
+ case GRUB_PC_PARTITION_TYPE_LINUX_MINIX:
+ case GRUB_PC_PARTITION_TYPE_EXT2FS:
+ c = 3;
+ break;
+ case GRUB_PC_PARTITION_TYPE_LINUX_SWAP:
+ c = 4;
+ break;
+ }
+ }
- auto int fill_disk (const char *name);
- int fill_disk (const char *name)
- {
- grub_device_t dev;
- char *plan9name = NULL;
- unsigned i;
- int file_disk = 0;
+ if (fill_ctx->prefixescnt[c] == 0)
+ grub_strcpy (name, prefixes[c]);
+ else
+ grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c],
+ fill_ctx->prefixescnt[c]);
+ fill_ctx->prefixescnt[c]++;
+ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1,
+ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
+ return 1;
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name);
+ fill_ctx->pmapptr += grub_strlen (name);
+ }
+ pend = fill_ctx->pmapptr;
+ if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25,
+ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = ' ';
+ grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25,
+ "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T,
+ grub_partition_get_start (partition),
+ grub_partition_get_start (partition)
+ + grub_partition_get_len (partition));
+ if (file_disk && grub_partition_get_start (partition)
+ == grub_partition_get_start (fill_ctx->file->device->disk->partition)
+ && grub_partition_get_len (partition)
+ == grub_partition_get_len (fill_ctx->file->device->disk->partition))
+ {
+ grub_free (fill_ctx->bootpart);
+ fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart,
+ pend - pstart);
+ }
- dev = grub_device_open (name);
- if (!dev)
- {
- grub_print_error ();
- return 0;
- }
- if (!dev->disk)
+ fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr);
+ return 0;
+}
+
+/* Helper for grub_cmd_plan9. */
+static int
+fill_disk (const char *name, void *data)
+{
+ struct grub_cmd_plan9_ctx *fill_ctx = data;
+ grub_device_t dev;
+ char *plan9name = NULL;
+ unsigned i;
+ int file_disk = 0;
+
+ dev = grub_device_open (name);
+ if (!dev)
+ {
+ grub_print_error ();
+ return 0;
+ }
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+ file_disk = fill_ctx->file->device->disk
+ && dev->disk->id == fill_ctx->file->device->disk->id
+ && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id;
+ for (i = 0;
+ fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]; i++)
+ if (grub_strncmp (name, fill_ctx->ctxt->state[0].args[i],
+ grub_strlen (name)) == 0
+ && fill_ctx->ctxt->state[0].args[i][grub_strlen (name)] == '=')
+ break;
+ if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i])
+ plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i]
+ + grub_strlen (name) + 1);
+ else
+ switch (dev->disk->dev->id)
{
- grub_device_close (dev);
- return 0;
- }
- file_disk = file->device->disk && dev->disk->id == file->device->disk->id
- && dev->disk->dev->id == file->device->disk->dev->id;
- for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++)
- if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0
- && ctxt->state[0].args[i][grub_strlen (name)] == '=')
+ case GRUB_DISK_DEVICE_BIOSDISK_ID:
+ if (dev->disk->id & 0x80)
+ plan9name = grub_xasprintf ("sdB%u",
+ (unsigned) (dev->disk->id & 0x7f));
+ else
+ plan9name = grub_xasprintf ("fd%u",
+ (unsigned) (dev->disk->id & 0x7f));
break;
- if (ctxt->state[0].args && ctxt->state[0].args[i])
- plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1);
- else
- switch (dev->disk->dev->id)
+ /* Shouldn't happen as Plan9 doesn't work on these platforms. */
+ case GRUB_DISK_DEVICE_OFDISK_ID:
+ case GRUB_DISK_DEVICE_EFIDISK_ID:
+
+ /* Plan9 doesn't see those. */
+ default:
+
+ /* Not sure how to handle those. */
+ case GRUB_DISK_DEVICE_NAND_ID:
+ if (!file_disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+
+ /* if it's the disk the kernel is loaded from we need to name
+ it nevertheless. */
+ plan9name = grub_strdup ("sdZ0");
+ break;
+
+ case GRUB_DISK_DEVICE_ATA_ID:
{
- case GRUB_DISK_DEVICE_BIOSDISK_ID:
- if (dev->disk->id & 0x80)
- plan9name = grub_xasprintf ("sdB%u",
- (unsigned) (dev->disk->id & 0x7f));
+ int unit;
+ if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
+ unit = 0;
else
- plan9name = grub_xasprintf ("fd%u",
- (unsigned) (dev->disk->id & 0x7f));
- break;
- /* Shouldn't happen as Plan9 doesn't work on these platforms. */
- case GRUB_DISK_DEVICE_OFDISK_ID:
- case GRUB_DISK_DEVICE_EFIDISK_ID:
-
- /* Plan9 doesn't see those. */
- default:
-
- /* Not sure how to handle those. */
- case GRUB_DISK_DEVICE_NAND_ID:
- if (!file_disk)
- {
- grub_device_close (dev);
- return 0;
- }
-
- /* if it's the disk the kernel is loaded from we need to name
- it nevertheless. */
- plan9name = grub_strdup ("sdZ0");
- break;
-
- case GRUB_DISK_DEVICE_ATA_ID:
+ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0);
+ plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
+ }
+ break;
+ case GRUB_DISK_DEVICE_SCSI_ID:
+ if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff)
+ == GRUB_SCSI_SUBSYSTEM_PATA)
{
int unit;
if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
unit = 0;
else
- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0);
+ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1,
+ 0, 0);
plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
+ break;
}
- break;
- case GRUB_DISK_DEVICE_SCSI_ID:
- if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff)
- == GRUB_SCSI_SUBSYSTEM_PATA)
- {
- int unit;
- if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
- unit = 0;
- else
- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1,
- 0, 0);
- plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
- break;
- }
-
- /* FIXME: how does Plan9 number controllers?
- We probably need save the SCSI devices and sort them */
- plan9name
- = grub_xasprintf ("sd0%u", (unsigned)
- ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT)
- & 0xf));
- break;
- }
- if (!plan9name)
- {
- grub_print_error ();
- return 0;
- }
- if (grub_extend_alloc (pmapptr + grub_strlen (plan9name)
- + sizeof ("part="), &pmapalloc,
- (void **) &pmap))
- {
- grub_free (plan9name);
- return 1;
+
+ /* FIXME: how does Plan9 number controllers?
+ We probably need save the SCSI devices and sort them */
+ plan9name
+ = grub_xasprintf ("sd0%u", (unsigned)
+ ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT)
+ & 0xf));
+ break;
}
- grub_strcpy (pmap + pmapptr, plan9name);
- pmapptr += grub_strlen (plan9name);
- if (!file_disk)
+ if (!plan9name)
+ {
+ grub_print_error ();
+ return 0;
+ }
+ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name)
+ + sizeof ("part="), &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ {
grub_free (plan9name);
- else
- {
- grub_free (bootdisk);
- bootdisk = plan9name;
- }
- grub_strcpy (pmap + pmapptr, "part=");
- pmapptr += sizeof ("part=") - 1;
-
- noslash = 1;
- grub_memset (prefixescnt, 0, sizeof (prefixescnt));
- if (grub_partition_iterate (dev->disk, fill_partition))
- return 1;
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
return 1;
- pmap[pmapptr++] = '\n';
+ }
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name);
+ fill_ctx->pmapptr += grub_strlen (plan9name);
+ if (!file_disk)
+ grub_free (plan9name);
+ else
+ {
+ grub_free (fill_ctx->bootdisk);
+ fill_ctx->bootdisk = plan9name;
+ }
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part=");
+ fill_ctx->pmapptr += sizeof ("part=") - 1;
+
+ fill_ctx->noslash = 1;
+ grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt));
+ if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx))
+ return 1;
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = '\n';
+
+ return 0;
+}
- return 0;
- }
+static grub_err_t
+grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
+{
+ struct grub_cmd_plan9_ctx fill_ctx = {
+ .ctxt = ctxt,
+ .file = 0,
+ .pmap = NULL,
+ .pmapalloc = 256,
+ .pmapptr = 0,
+ .noslash = 1,
+ .bootdisk = NULL,
+ .bootpart = NULL
+ };
+ void *mem;
+ grub_size_t memsize, padsize;
+ struct grub_plan9_header hdr;
+ char *config, *configptr;
+ grub_size_t configsize;
+ char *bootpath = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -354,21 +387,21 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (!rel)
goto fail;
- file = grub_file_open (argv[0]);
- if (! file)
+ fill_ctx.file = grub_file_open (argv[0]);
+ if (! fill_ctx.file)
goto fail;
- pmap = grub_malloc (pmapalloc);
- if (!pmap)
+ fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc);
+ if (!fill_ctx.pmap)
goto fail;
- if (grub_disk_dev_iterate (fill_disk))
+ if (grub_disk_dev_iterate (fill_disk, &fill_ctx))
goto fail;
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc,
- (void **) &pmap))
+ if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc,
+ (void **) &fill_ctx.pmap))
goto fail;
- pmap[pmapptr] = 0;
+ fill_ctx.pmap[fill_ctx.pmapptr] = 0;
{
char *file_name = grub_strchr (argv[0], ')');
@@ -379,17 +412,19 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (*file_name)
file_name++;
- if (bootpart)
- bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name);
+ if (fill_ctx.bootpart)
+ bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk,
+ fill_ctx.bootpart, file_name);
else
- bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name);
- grub_free (bootdisk);
- grub_free (bootpart);
+ bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name);
+ grub_free (fill_ctx.bootdisk);
+ grub_free (fill_ctx.bootpart);
}
if (!bootpath)
goto fail;
- if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr))
+ if (grub_file_read (fill_ctx.file, &hdr,
+ sizeof (hdr)) != (grub_ssize_t) sizeof (hdr))
{
if (!grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -420,7 +455,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
configsize += grub_strlen (argv[i]) + 1;
}
configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1;
- configsize += pmapptr;
+ configsize += fill_ctx.pmapptr;
/* Terminating \0. */
configsize++;
@@ -452,7 +487,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
*configptr++ = '\n';
}
}
- configptr = grub_stpcpy (configptr, pmap);
+ configptr = grub_stpcpy (configptr, fill_ctx.pmap);
{
grub_relocator_chunk_t ch;
@@ -471,7 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_memcpy (ptr, &hdr, sizeof (hdr));
ptr += sizeof (hdr);
- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size))
+ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.text_size))
!= (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size))
{
if (!grub_errno)
@@ -487,7 +522,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_memset (ptr, 0, padsize);
ptr += padsize;
- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size))
+ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.data_size))
!= (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size))
{
if (!grub_errno)
@@ -508,10 +543,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
return GRUB_ERR_NONE;
fail:
- grub_free (pmap);
+ grub_free (fill_ctx.pmap);
- if (file)
- grub_file_close (file);
+ if (fill_ctx.file)
+ grub_file_close (fill_ctx.file);
grub_plan9_unload ();
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
index 805f002..367a2b7 100644
--- a/grub-core/normal/completion.c
+++ b/grub-core/normal/completion.c
@@ -99,7 +99,8 @@ add_completion (const char *completion, const char *extra,
}
static int
-iterate_partition (grub_disk_t disk, const grub_partition_t p)
+iterate_partition (grub_disk_t disk, const grub_partition_t p,
+ void *data __attribute__ ((unused)))
{
const char *disk_name = disk->name;
char *name;
@@ -154,7 +155,7 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info)
}
static int
-iterate_dev (const char *devname)
+iterate_dev (const char *devname, void *data __attribute__ ((unused)))
{
grub_device_t dev;
@@ -180,7 +181,7 @@ iterate_dev (const char *devname)
}
if (dev->disk)
- if (grub_partition_iterate (dev->disk, iterate_partition))
+ if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{
grub_device_close (dev);
return 1;
@@ -213,7 +214,7 @@ complete_device (void)
if (! p)
{
/* Complete the disk part. */
- if (grub_disk_dev_iterate (iterate_dev))
+ if (grub_disk_dev_iterate (iterate_dev, NULL))
return 1;
}
else
@@ -228,7 +229,7 @@ complete_device (void)
{
if (dev->disk)
{
- if (grub_partition_iterate (dev->disk, iterate_partition))
+ if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{
grub_device_close (dev);
return 1;
diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c
index 341b8ac..4d7f500 100644
--- a/grub-core/partmap/acorn.c
+++ b/grub-core/partmap/acorn.c
@@ -101,8 +101,8 @@ fail:
static grub_err_t
acorn_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct linux_part map[LINUX_MAP_ENTRIES];
@@ -127,7 +127,7 @@ acorn_partition_map_iterate (grub_disk_t disk,
part.offset = 6;
part.number = part.index = i;
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
}
diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c
index 0b89cdc..213d707 100644
--- a/grub-core/partmap/amiga.c
+++ b/grub-core/partmap/amiga.c
@@ -87,8 +87,8 @@ amiga_partition_map_checksum (void *buf, grub_size_t sz)
static grub_err_t
amiga_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_amiga_rdsk rdsk;
@@ -145,7 +145,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
part.index = 0;
part.partmap = &grub_amiga_partition_map;
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
next = grub_be_to_cpu32 (apart.next);
diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c
index c08cae5..f4e608f 100644
--- a/grub-core/partmap/apple.c
+++ b/grub-core/partmap/apple.c
@@ -101,8 +101,8 @@ static struct grub_partition_map grub_apple_partition_map;
static grub_err_t
apple_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_apple_header aheader;
@@ -163,7 +163,7 @@ apple_partition_map_iterate (grub_disk_t disk,
grub_be_to_cpu32 (apart.first_phys_block),
grub_be_to_cpu32 (apart.blockcnt));
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
pos += grub_be_to_cpu16 (aheader.blocksize);
diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c
index c806f19..16b9c87 100644
--- a/grub-core/partmap/bsdlabel.c
+++ b/grub-core/partmap/bsdlabel.c
@@ -41,8 +41,7 @@ static struct grub_partition_map grub_openbsdlabel_partition_map;
static grub_err_t
iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
struct grub_partition_map *pmap,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition_bsd_disk_label label;
struct grub_partition p;
@@ -116,7 +115,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
p.start -= delta;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
return GRUB_ERR_NONE;
@@ -124,14 +123,14 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
static grub_err_t
bsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1,
- &grub_bsdlabel_partition_map, hook);
+ &grub_bsdlabel_partition_map, hook, hook_data);
if (disk->partition
&& (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
@@ -141,7 +140,44 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0,
- &grub_bsdlabel_partition_map, hook);
+ &grub_bsdlabel_partition_map, hook, hook_data);
+}
+
+/* Context for netopenbsdlabel_partition_map_iterate. */
+struct netopenbsdlabel_ctx
+{
+ grub_uint8_t type;
+ struct grub_partition_map *pmap;
+ grub_partition_iterate_hook_t hook;
+ void *hook_data;
+ int count;
+};
+
+/* Helper for netopenbsdlabel_partition_map_iterate. */
+static int
+check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct netopenbsdlabel_ctx *ctx = data;
+ grub_err_t err;
+
+ if (partition->msdostype != ctx->type)
+ return 0;
+
+ err = iterate_real (dsk, partition->start
+ + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap,
+ ctx->hook, ctx->hook_data);
+ if (err == GRUB_ERR_NONE)
+ {
+ ctx->count++;
+ return 1;
+ }
+ if (err == GRUB_ERR_BAD_PART_TABLE)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ grub_print_error ();
+ return 0;
}
/* This is a total breakage. Even when net-/openbsd label is inside partition
@@ -150,45 +186,26 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
static grub_err_t
netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
struct grub_partition_map *pmap,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
int count = 0;
- auto int check_msdos (grub_disk_t dsk,
- const grub_partition_t partition);
-
- int check_msdos (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- grub_err_t err;
-
- if (partition->msdostype != type)
- return 0;
-
- err = iterate_real (dsk, partition->start
- + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook);
- if (err == GRUB_ERR_NONE)
- {
- count++;
- return 1;
- }
- if (err == GRUB_ERR_BAD_PART_TABLE)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- grub_print_error ();
- return 0;
- }
-
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
{
+ struct netopenbsdlabel_ctx ctx = {
+ .type = type,
+ .pmap = pmap,
+ .hook = hook,
+ .hook_data = hook_data,
+ .count = count
+ };
grub_err_t err;
- err = grub_partition_msdos_iterate (disk, check_msdos);
+
+ err = grub_partition_msdos_iterate (disk, check_msdos, &ctx);
if (err)
return err;
@@ -200,24 +217,24 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
static grub_err_t
netbsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_NETBSD,
&grub_netbsdlabel_partition_map,
- hook);
+ hook, hook_data);
}
static grub_err_t
openbsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_OPENBSD,
&grub_openbsdlabel_partition_map,
- hook);
+ hook, hook_data);
}
diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c
index 79ec01b..5b464da 100644
--- a/grub-core/partmap/dvh.c
+++ b/grub-core/partmap/dvh.c
@@ -64,8 +64,7 @@ grub_dvh_is_valid (grub_uint32_t *label)
static grub_err_t
dvh_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition p;
union
@@ -101,7 +100,7 @@ dvh_partition_map_iterate (grub_disk_t disk,
p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start);
p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length);
p.number = p.index = partnum;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
break;
}
diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
index 17f242d..38df7b3 100644
--- a/grub-core/partmap/gpt.c
+++ b/grub-core/partmap/gpt.c
@@ -48,8 +48,8 @@ static struct grub_partition_map grub_gpt_partition_map;
grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_gpt_header gpt;
@@ -113,7 +113,7 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
(unsigned long long) part.start,
(unsigned long long) part.len);
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
}
@@ -129,71 +129,81 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
}
#ifdef GRUB_UTIL
+/* Context for gpt_partition_map_embed. */
+struct gpt_partition_map_embed_ctx
+{
+ grub_disk_addr_t start, len;
+};
+
+/* Helper for gpt_partition_map_embed. */
+static int
+find_usable_region (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t p, void *data)
+{
+ struct gpt_partition_map_embed_ctx *ctx = data;
+ struct grub_gpt_partentry gptdata;
+ grub_partition_t p2;
+
+ p2 = disk->partition;
+ disk->partition = p->parent;
+ if (grub_disk_read (disk, p->offset, p->index,
+ sizeof (gptdata), &gptdata))
+ {
+ disk->partition = p2;
+ return 0;
+ }
+ disk->partition = p2;
+
+ /* If there's an embed region, it is in a dedicated partition. */
+ if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
+ {
+ ctx->start = p->start;
+ ctx->len = p->len;
+ return 1;
+ }
+
+ return 0;
+}
+
static grub_err_t
-gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
+gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
unsigned int max_nsectors,
grub_embed_type_t embed_type,
grub_disk_addr_t **sectors)
{
- grub_disk_addr_t start = 0, len = 0;
+ struct gpt_partition_map_embed_ctx ctx = {
+ .start = 0,
+ .len = 0
+ };
unsigned i;
grub_err_t err;
- auto int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk,
- const grub_partition_t p);
- int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t p)
- {
- struct grub_gpt_partentry gptdata;
- grub_partition_t p2;
-
- p2 = disk->partition;
- disk->partition = p->parent;
- if (grub_disk_read (disk, p->offset, p->index,
- sizeof (gptdata), &gptdata))
- {
- disk->partition = p2;
- return 0;
- }
- disk->partition = p2;
-
- /* If there's an embed region, it is in a dedicated partition. */
- if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
- {
- start = p->start;
- len = p->len;
- return 1;
- }
-
- return 0;
- }
-
if (embed_type != GRUB_EMBED_PCBIOS)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"GPT currently supports only PC-BIOS embedding");
- err = grub_gpt_partition_map_iterate (disk_, find_usable_region);
+ err = grub_gpt_partition_map_iterate (disk, find_usable_region, &ctx);
if (err)
return err;
- if (len == 0)
+ if (ctx.len == 0)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
N_("this GPT partition label contains no BIOS Boot Partition;"
" embedding won't be possible"));
- if (len < *nsectors)
+ if (ctx.len < *nsectors)
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("your BIOS Boot Partition is too small;"
" embedding won't be possible"));
- *nsectors = len;
+ *nsectors = ctx.len;
if (*nsectors > max_nsectors)
*nsectors = max_nsectors;
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
if (!*sectors)
return grub_errno;
for (i = 0; i < *nsectors; i++)
- (*sectors)[i] = start + i;
+ (*sectors)[i] = ctx.start + i;
return GRUB_ERR_NONE;
}
diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
index 10ca3f0..47527c3 100644
--- a/grub-core/partmap/msdos.c
+++ b/grub-core/partmap/msdos.c
@@ -100,8 +100,8 @@ struct embed_signature embed_signatures[] =
grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition p;
struct grub_msdos_partition_mbr mbr;
@@ -186,7 +186,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
{
p.number++;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
else if (p.number < 4)
diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c
index e6e3113..83db224 100644
--- a/grub-core/partmap/plan.c
+++ b/grub-core/partmap/plan.c
@@ -31,8 +31,8 @@ static struct grub_partition_map grub_plan_partition_map;
static grub_err_t
plan_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition p;
int ptr = 0;
@@ -92,7 +92,7 @@ plan_partition_map_iterate (grub_disk_t disk,
if (c != '\n')
break;
p.len -= p.start;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
if (p.number == 0)
diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c
index dfe51f3..cff09ae 100644
--- a/grub-core/partmap/sun.c
+++ b/grub-core/partmap/sun.c
@@ -86,8 +86,7 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t
sun_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition p;
union
@@ -128,7 +127,7 @@ sun_partition_map_iterate (grub_disk_t disk,
p.number = p.index = partnum;
if (p.len)
{
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
}
}
diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c
index 1c1fdce..7034272 100644
--- a/grub-core/partmap/sunpc.c
+++ b/grub-core/partmap/sunpc.c
@@ -68,8 +68,8 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t
sun_pc_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
grub_partition_t p;
union
@@ -122,7 +122,7 @@ sun_pc_partition_map_iterate (grub_disk_t disk,
p->number = partnum;
if (p->len)
{
- if (hook (disk, p))
+ if (hook (disk, p, hook_data))
partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
}
}
diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h
index a825a98..739926f 100644
--- a/include/grub/arc/arc.h
+++ b/include/grub/arc/arc.h
@@ -255,7 +255,12 @@ struct grub_arc_system_parameter_block
#define GRUB_ARC_STDIN 0
#define GRUB_ARC_STDOUT 1
-int EXPORT_FUNC (grub_arc_iterate_devs) (int (*hook) (const char *name, const struct grub_arc_component *comp), int alt_names);
+typedef int (*grub_arc_iterate_devs_hook_t)
+ (const char *name, const struct grub_arc_component *comp, void *data);
+
+int EXPORT_FUNC (grub_arc_iterate_devs) (grub_arc_iterate_devs_hook_t hook,
+ void *hook_data,
+ int alt_names);
#define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp))
diff --git a/include/grub/ata.h b/include/grub/ata.h
index efba7b7..e8a84b8 100644
--- a/include/grub/ata.h
+++ b/include/grub/ata.h
@@ -193,10 +193,12 @@ struct grub_ata
typedef struct grub_ata *grub_ata_t;
+typedef int (*grub_ata_dev_iterate_hook_t) (int id, int bus, void *data);
+
struct grub_ata_dev
{
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int (*hook) (int id, int bus),
+ int (*iterate) (grub_ata_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */
diff --git a/include/grub/device.h b/include/grub/device.h
index f3e43bf..1d1a239 100644
--- a/include/grub/device.h
+++ b/include/grub/device.h
@@ -33,8 +33,11 @@ struct grub_device
};
typedef struct grub_device *grub_device_t;
+typedef int (*grub_device_iterate_hook_t) (const char *name, void *data);
+
grub_device_t EXPORT_FUNC(grub_device_open) (const char *name);
grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device);
-int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name));
+int EXPORT_FUNC(grub_device_iterate) (grub_device_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_DEVICE_HEADER */
diff --git a/include/grub/disk.h b/include/grub/disk.h
index 096173d..013ca1f 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -56,6 +56,8 @@ typedef enum
GRUB_DISK_PULL_MAX
} grub_disk_pull_t;
+typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data);
+
/* Disk device. */
struct grub_disk_dev
{
@@ -66,7 +68,7 @@ struct grub_disk_dev
enum grub_disk_dev_id id;
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int (*hook) (const char *name),
+ int (*iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up DISK. */
@@ -158,14 +160,14 @@ void grub_disk_cache_invalidate_all (void);
void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
static inline int
-grub_disk_dev_iterate (int (*hook) (const char *name))
+grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data)
{
grub_disk_dev_t p;
grub_disk_pull_t pull;
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
for (p = grub_disk_dev_list; p; p = p->next)
- if (p->iterate && (p->iterate) (hook, pull))
+ if (p->iterate && (p->iterate) (hook, hook_data, pull))
return 1;
return 0;
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
index 83e3b31..4aaf1c4 100644
--- a/include/grub/gpt_partition.h
+++ b/include/grub/gpt_partition.h
@@ -80,8 +80,8 @@ struct grub_gpt_partentry
grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h
index 9c8ac3e..1e9b65e 100644
--- a/include/grub/msdos_partition.h
+++ b/include/grub/msdos_partition.h
@@ -120,7 +120,7 @@ grub_msdos_partition_is_extended (int type)
grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/include/grub/partition.h b/include/grub/partition.h
index ec0a667..7adb7ec 100644
--- a/include/grub/partition.h
+++ b/include/grub/partition.h
@@ -33,6 +33,10 @@ typedef enum
} grub_embed_type_t;
#endif
+typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk,
+ const grub_partition_t partition,
+ void *data);
+
/* Partition map type. */
struct grub_partition_map
{
@@ -45,8 +49,7 @@ struct grub_partition_map
/* Call HOOK with each partition, until HOOK returns non-zero. */
grub_err_t (*iterate) (struct grub_disk *disk,
- int (*hook) (struct grub_disk *disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook, void *hook_data);
#ifdef GRUB_UTIL
/* Determine sectors available for embedding. */
grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors,
@@ -89,8 +92,8 @@ struct grub_partition
grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
const char *str);
int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
- int (*hook) (struct grub_disk *disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
diff --git a/include/grub/scsi.h b/include/grub/scsi.h
index 13300ca..a919a7c 100644
--- a/include/grub/scsi.h
+++ b/include/grub/scsi.h
@@ -49,10 +49,13 @@ grub_make_scsi_id (int subsystem, int bus, int lun)
| (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_LUN_SHIFT);
}
+typedef int (*grub_scsi_dev_iterate_hook_t) (int id, int bus, int luns,
+ void *data);
+
struct grub_scsi_dev
{
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
+ int (*iterate) (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */
diff --git a/util/getroot.c b/util/getroot.c
index 3b5b0f6..654d1e1 100644
--- a/util/getroot.c
+++ b/util/getroot.c
@@ -2198,6 +2198,36 @@ grub_util_get_os_disk (const char *os_dev)
return convert_system_partition_to_system_disk (os_dev, &st, &is_part);
}
+#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__)
+/* Context for grub_util_biosdisk_get_grub_dev. */
+struct grub_util_biosdisk_get_grub_dev_ctx
+{
+ char *partname;
+ grub_disk_addr_t start;
+};
+
+/* Helper for grub_util_biosdisk_get_grub_dev. */
+static int
+find_partition (grub_disk_t dsk __attribute__ ((unused)),
+ const grub_partition_t partition, void *data)
+{
+ struct grub_util_biosdisk_get_grub_dev_ctx *ctx = data;
+ grub_disk_addr_t part_start = 0;
+ grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T,
+ partition->number, partition->start);
+
+ part_start = grub_partition_get_start (partition);
+
+ if (ctx->start == part_start)
+ {
+ ctx->partname = grub_partition_get_name (partition);
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
char *
grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
@@ -2250,29 +2280,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
For NetBSD and FreeBSD, proceed as for Linux, except that the start
sector is obtained from the disk label. */
{
- char *name, *partname;
+ char *name;
grub_disk_t disk;
- grub_disk_addr_t start;
- auto int find_partition (grub_disk_t dsk,
- const grub_partition_t partition);
-
- int find_partition (grub_disk_t dsk __attribute__ ((unused)),
- const grub_partition_t partition)
- {
- grub_disk_addr_t part_start = 0;
- grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T,
- partition->number, partition->start);
-
- part_start = grub_partition_get_start (partition);
-
- if (start == part_start)
- {
- partname = grub_partition_get_name (partition);
- return 1;
- }
-
- return 0;
- }
+ struct grub_util_biosdisk_get_grub_dev_ctx ctx;
name = make_device_name (drive, -1, -1);
@@ -2284,16 +2294,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
* different, we know that os_dev cannot be a floppy device. */
# endif /* !defined(HAVE_DIOCGDINFO) */
- start = grub_hostdisk_find_partition_start (os_dev);
+ ctx.start = grub_hostdisk_find_partition_start (os_dev);
if (grub_errno != GRUB_ERR_NONE)
{
free (name);
return 0;
}
- grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, start);
+ grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, ctx.start);
- if (start == 0 && !is_part)
+ if (ctx.start == 0 && !is_part)
return name;
grub_util_info ("opening the device %s", name);
@@ -2325,20 +2335,20 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
- name = grub_util_get_ldm (disk, start);
+ name = grub_util_get_ldm (disk, ctx.start);
if (name)
return name;
- partname = NULL;
+ ctx.partname = NULL;
- grub_partition_iterate (disk, find_partition);
+ grub_partition_iterate (disk, find_partition, &ctx);
if (grub_errno != GRUB_ERR_NONE)
{
grub_disk_close (disk);
return 0;
}
- if (partname == NULL)
+ if (ctx.partname == NULL)
{
grub_disk_close (disk);
grub_util_info ("cannot find the partition of `%s'", os_dev);
@@ -2347,8 +2357,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
- name = grub_xasprintf ("%s,%s", disk->name, partname);
- free (partname);
+ name = grub_xasprintf ("%s,%s", disk->name, ctx.partname);
+ free (ctx.partname);
grub_disk_close (disk);
return name;
}
diff --git a/util/grub-setup.c b/util/grub-setup.c
index de0417f..187345a 100644
--- a/util/grub-setup.c
+++ b/util/grub-setup.c
@@ -138,6 +138,44 @@ write_rootdev (grub_device_t root_dev,
#define BOOT_SECTOR 0
#endif
+#ifdef GRUB_SETUP_BIOS
+/* Context for setup/identify_partmap. */
+struct identify_partmap_ctx
+{
+ grub_partition_map_t dest_partmap;
+ grub_partition_t container;
+ int multiple_partmaps;
+};
+
+/* Helper for setup/identify_partmap.
+ Unlike root_dev, with dest_dev we're interested in the partition map even
+ if dest_dev itself is a whole disk. */
+static int
+identify_partmap (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t p, void *data)
+{
+ struct identify_partmap_ctx *ctx = data;
+
+ if (p->parent != ctx->container)
+ return 0;
+ /* NetBSD and OpenBSD subpartitions have metadata inside a partition,
+ so they are safe to ignore.
+ */
+ if (grub_strcmp (p->partmap->name, "netbsd") == 0
+ || grub_strcmp (p->partmap->name, "openbsd") == 0)
+ return 0;
+ if (ctx->dest_partmap == NULL)
+ {
+ ctx->dest_partmap = p->partmap;
+ return 0;
+ }
+ if (ctx->dest_partmap == p->partmap)
+ return 0;
+ ctx->multiple_partmaps = 1;
+ return 1;
+}
+#endif
+
static void
setup (const char *dir,
const char *boot_file, const char *core_file,
@@ -337,9 +375,11 @@ setup (const char *dir,
#ifdef GRUB_SETUP_BIOS
{
- grub_partition_map_t dest_partmap = NULL;
- grub_partition_t container = dest_dev->disk->partition;
- int multiple_partmaps = 0;
+ struct identify_partmap_ctx ctx = {
+ .dest_partmap = NULL,
+ .container = dest_dev->disk->partition,
+ .multiple_partmaps = 0
+ };
int is_ldm;
grub_err_t err;
grub_disk_addr_t *sectors;
@@ -347,38 +387,13 @@ setup (const char *dir,
grub_fs_t fs;
unsigned int nsec, maxsec;
- /* Unlike root_dev, with dest_dev we're interested in the partition map even
- if dest_dev itself is a whole disk. */
- auto int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk,
- const grub_partition_t p);
- int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t p)
- {
- if (p->parent != container)
- return 0;
- /* NetBSD and OpenBSD subpartitions have metadata inside a partition,
- so they are safe to ignore.
- */
- if (grub_strcmp (p->partmap->name, "netbsd") == 0
- || grub_strcmp (p->partmap->name, "openbsd") == 0)
- return 0;
- if (dest_partmap == NULL)
- {
- dest_partmap = p->partmap;
- return 0;
- }
- if (dest_partmap == p->partmap)
- return 0;
- multiple_partmaps = 1;
- return 1;
- }
-
- grub_partition_iterate (dest_dev->disk, identify_partmap);
+ grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx);
- if (container && grub_strcmp (container->partmap->name, "msdos") == 0
- && dest_partmap
- && (container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD
- || container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD))
+ if (ctx.container
+ && grub_strcmp (ctx.container->partmap->name, "msdos") == 0
+ && ctx.dest_partmap
+ && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD
+ || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD))
{
grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet."));
goto unable_to_embed;
@@ -392,7 +407,7 @@ setup (const char *dir,
if (fs_probe)
{
- if (!fs && !dest_partmap)
+ if (!fs && !ctx.dest_partmap)
grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
dest_dev->disk->name);
if (fs && !fs->reserved_first_sector)
@@ -403,20 +418,20 @@ setup (const char *dir,
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), dest_dev->disk->name, fs->name);
- if (dest_partmap && strcmp (dest_partmap->name, "msdos") != 0
- && strcmp (dest_partmap->name, "gpt") != 0
- && strcmp (dest_partmap->name, "bsd") != 0
- && strcmp (dest_partmap->name, "netbsd") != 0
- && strcmp (dest_partmap->name, "openbsd") != 0
- && strcmp (dest_partmap->name, "sunpc") != 0)
+ if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
+ && strcmp (ctx.dest_partmap->name, "gpt") != 0
+ && strcmp (ctx.dest_partmap->name, "bsd") != 0
+ && strcmp (ctx.dest_partmap->name, "netbsd") != 0
+ && strcmp (ctx.dest_partmap->name, "openbsd") != 0
+ && strcmp (ctx.dest_partmap->name, "sunpc") != 0)
/* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */
grub_util_error (_("%s appears to contain a %s partition map which isn't known to "
"reserve space for DOS-style boot. Installing GRUB there could "
"result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
"by grub-setup (--skip-fs-probe disables this "
- "check, use at your own risk)"), dest_dev->disk->name, dest_partmap->name);
- if (is_ldm && dest_partmap && strcmp (dest_partmap->name, "msdos") != 0
- && strcmp (dest_partmap->name, "gpt") != 0)
+ "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name);
+ if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
+ && strcmp (ctx.dest_partmap->name, "gpt") != 0)
grub_util_error (_("%s appears to contain a %s partition map and "
"LDM which isn't known to be a safe combination."
" Installing GRUB there could "
@@ -424,12 +439,12 @@ setup (const char *dir,
" is overwritten "
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"),
- dest_dev->disk->name, dest_partmap->name);
+ dest_dev->disk->name, ctx.dest_partmap->name);
}
/* Copy the partition table. */
- if (dest_partmap ||
+ if (ctx.dest_partmap ||
(!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)))
memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
@@ -437,21 +452,21 @@ setup (const char *dir,
free (tmp_img);
- if (! dest_partmap && ! fs && !is_ldm)
+ if (! ctx.dest_partmap && ! fs && !is_ldm)
{
grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea."));
goto unable_to_embed;
}
- if (multiple_partmaps || (dest_partmap && fs) || (is_ldm && fs))
+ if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs))
{
grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet."));
goto unable_to_embed;
}
- if (dest_partmap && !dest_partmap->embed)
+ if (ctx.dest_partmap && !ctx.dest_partmap->embed)
{
grub_util_warn (_("Partition style `%s' doesn't support embedding"),
- dest_partmap->name);
+ ctx.dest_partmap->name);
goto unable_to_embed;
}
@@ -473,9 +488,9 @@ setup (const char *dir,
if (is_ldm)
err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
- else if (dest_partmap)
- err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
- GRUB_EMBED_PCBIOS, &sectors);
+ else if (ctx.dest_partmap)
+ err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
+ GRUB_EMBED_PCBIOS, &sectors);
else
err = fs->embed (dest_dev, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
@@ -507,12 +522,12 @@ setup (const char *dir,
grub_util_error ("%s", _("no terminator in the core image"));
}
- save_first_sector (sectors[0] + grub_partition_get_start (container),
+ save_first_sector (sectors[0] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE);
block = first_block;
for (i = 1; i < nsec; i++)
- save_blocklists (sectors[i] + grub_partition_get_start (container),
+ save_blocklists (sectors[i] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE);
/* Make sure that the last blocklist is a terminator. */
--
1.8.1.4