grub2/0116-Remove-nested-functions-from-device-iterators.patch
2013-06-07 14:03:56 -04:00

4099 lines
115 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 5092c4144b402744481e435bedca2bcbda3839e4 Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@ubuntu.com>
Date: Sun, 20 Jan 2013 15:52:15 +0000
Subject: [PATCH 116/471] 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.2.1