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.
This commit is contained in:
Colin Watson 2013-01-20 15:52:15 +00:00
parent 6c0314d638
commit 25239370fd
50 changed files with 1455 additions and 1165 deletions

View file

@ -1,3 +1,29 @@
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> 2013-01-20 Colin Watson <cjwatson@ubuntu.com>
Fix typos for "developer" and "development". Fix typos for "developer" and "development".

View file

@ -24,18 +24,22 @@
GRUB_MOD_LICENSE ("GPLv3+"); 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 static grub_err_t
grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)), grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)), int argc __attribute__ ((unused)),
char **args __attribute__ ((unused))) char **args __attribute__ ((unused)))
{ {
auto int hook (const char *name, const struct grub_arc_component *comp); grub_arc_iterate_devs (grub_cmd_lsdev_iter, 0, 0);
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);
return 0; return 0;
} }

View file

@ -45,21 +45,24 @@ static const struct grub_arg_option options[] =
static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'}; static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
static grub_err_t /* Helper for grub_ls_list_devices. */
grub_ls_list_devices (int longlist) static int
grub_ls_print_devices (const char *name, void *data)
{ {
auto int grub_ls_print_devices (const char *name); int *longlist = data;
int grub_ls_print_devices (const char *name)
{
if (longlist) if (longlist)
grub_normal_print_device_info (name); grub_normal_print_device_info (name);
else else
grub_printf ("(%s) ", name); grub_printf ("(%s) ", name);
return 0; 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"); grub_xputs ("\n");
#if 0 #if 0

View file

@ -42,21 +42,27 @@ struct cache_entry
static struct cache_entry *cache; static struct cache_entry *cache;
void /* Context for FUNC_NAME. */
FUNC_NAME (const char *key, const char *var, int no_floppy, struct search_ctx
char **hints, unsigned nhints)
{ {
int count = 0; const char *key;
int is_cache = 0; const char *var;
grub_fs_autoload_hook_t saved_autoload; int no_floppy;
char **hints;
unsigned nhints;
int count;
int is_cache;
};
auto int iterate_device (const char *name); /* Helper for FUNC_NAME. */
int iterate_device (const char *name) static int
{ iterate_device (const char *name, void *data)
{
struct search_ctx *ctx = data;
int found = 0; int found = 0;
/* Skip floppy drives when requested. */ /* Skip floppy drives when requested. */
if (no_floppy && if (ctx->no_floppy &&
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
return 0; return 0;
@ -71,7 +77,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
char *buf; char *buf;
grub_file_t file; grub_file_t file;
buf = grub_xasprintf ("(%s)%s", name, key); buf = grub_xasprintf ("(%s)%s", name, ctx->key);
if (! buf) if (! buf)
return 1; return 1;
@ -108,7 +114,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
if (grub_errno == GRUB_ERR_NONE && quid) if (grub_errno == GRUB_ERR_NONE && quid)
{ {
if (compare_fn (quid, key) == 0) if (compare_fn (quid, ctx->key) == 0)
found = 1; found = 1;
grub_free (quid); grub_free (quid);
@ -120,13 +126,13 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
} }
#endif #endif
if (!is_cache && found && count == 0) if (!ctx->is_cache && found && ctx->count == 0)
{ {
struct cache_entry *cache_ent; struct cache_entry *cache_ent;
cache_ent = grub_malloc (sizeof (*cache_ent)); cache_ent = grub_malloc (sizeof (*cache_ent));
if (cache_ent) if (cache_ent)
{ {
cache_ent->key = grub_strdup (key); cache_ent->key = grub_strdup (ctx->key);
cache_ent->value = grub_strdup (name); cache_ent->value = grub_strdup (name);
if (cache_ent->value && cache_ent->key) if (cache_ent->value && cache_ent->key)
{ {
@ -147,20 +153,22 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
if (found) if (found)
{ {
count++; ctx->count++;
if (var) if (ctx->var)
grub_env_set (var, name); grub_env_set (ctx->var, name);
else else
grub_printf (" %s", name); grub_printf (" %s", name);
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
return (found && var); return (found && ctx->var);
} }
auto int part_hook (grub_disk_t disk, const grub_partition_t partition); /* Helper for FUNC_NAME. */
int part_hook (grub_disk_t disk, const grub_partition_t partition) static int
{ part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
{
struct search_ctx *ctx = data;
char *partition_name, *devname; char *partition_name, *devname;
int ret; int ret;
@ -172,34 +180,35 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
grub_free (partition_name); grub_free (partition_name);
if (!devname) if (!devname)
return 1; return 1;
ret = iterate_device (devname); ret = iterate_device (devname, ctx);
grub_free (devname); grub_free (devname);
return ret; return ret;
} }
auto void try (void); /* Helper for FUNC_NAME. */
void try (void) static void
{ try (struct search_ctx *ctx)
{
unsigned i; unsigned i;
struct cache_entry **prev; struct cache_entry **prev;
struct cache_entry *cache_ent; struct cache_entry *cache_ent;
for (prev = &cache, cache_ent = *prev; cache_ent; for (prev = &cache, cache_ent = *prev; cache_ent;
prev = &cache_ent->next, cache_ent = *prev) prev = &cache_ent->next, cache_ent = *prev)
if (compare_fn (cache_ent->key, key) == 0) if (compare_fn (cache_ent->key, ctx->key) == 0)
break; break;
if (cache_ent) if (cache_ent)
{ {
is_cache = 1; ctx->is_cache = 1;
if (iterate_device (cache_ent->value)) if (iterate_device (cache_ent->value, ctx))
{ {
is_cache = 0; ctx->is_cache = 0;
return; return;
} }
is_cache = 0; ctx->is_cache = 0;
/* Cache entry was outdated. Remove it. */ /* Cache entry was outdated. Remove it. */
if (!count) if (!ctx->count)
{ {
grub_free (cache_ent->key); grub_free (cache_ent->key);
grub_free (cache_ent->value); grub_free (cache_ent->value);
@ -208,15 +217,15 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
} }
} }
for (i = 0; i < nhints; i++) for (i = 0; i < ctx->nhints; i++)
{ {
char *end; char *end;
if (!hints[i][0]) if (!ctx->hints[i][0])
continue; continue;
end = hints[i] + grub_strlen (hints[i]) - 1; end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1;
if (*end == ',') if (*end == ',')
*end = 0; *end = 0;
if (iterate_device (hints[i])) if (iterate_device (ctx->hints[i], ctx))
{ {
if (!*end) if (!*end)
*end = ','; *end = ',';
@ -226,7 +235,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
{ {
grub_device_t dev; grub_device_t dev;
int ret; int ret;
dev = grub_device_open (hints[i]); dev = grub_device_open (ctx->hints[i]);
if (!dev) if (!dev)
{ {
if (!*end) if (!*end)
@ -240,7 +249,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
*end = ','; *end = ',';
continue; continue;
} }
ret = grub_partition_iterate (dev->disk, part_hook); ret = grub_partition_iterate (dev->disk, part_hook, ctx);
if (!*end) if (!*end)
*end = ','; *end = ',';
grub_device_close (dev); grub_device_close (dev);
@ -248,27 +257,42 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
return; 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. */ /* First try without autoloading if we're setting variable. */
if (var) if (var)
{ {
saved_autoload = grub_fs_autoload_hook; saved_autoload = grub_fs_autoload_hook;
grub_fs_autoload_hook = 0; grub_fs_autoload_hook = 0;
try (); try (&ctx);
/* Restore autoload hook. */ /* Restore autoload hook. */
grub_fs_autoload_hook = saved_autoload; grub_fs_autoload_hook = saved_autoload;
/* Retry with autoload if nothing found. */ /* Retry with autoload if nothing found. */
if (grub_errno == GRUB_ERR_NONE && count == 0) if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
try (); try (&ctx);
} }
else 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); grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
} }

View file

@ -210,21 +210,25 @@ split_path (const char *str, const char **noregexop, const char **regexop)
*noregexop = split; *noregexop = split;
} }
static char ** /* Context for match_devices. */
match_devices (const regex_t *regexp, int noparts) struct match_devices_ctx
{ {
int i; const regex_t *regexp;
int noparts;
int ndev; int ndev;
char **devs; char **devs;
};
auto int match (const char *name); /* Helper for match_devices. */
int match (const char *name) static int
{ match_devices_iter (const char *name, void *data)
{
struct match_devices_ctx *ctx = data;
char **t; char **t;
char *buffer; char *buffer;
/* skip partitions if asked to. */ /* skip partitions if asked to. */
if (noparts && grub_strchr(name, ',')) if (ctx->noparts && grub_strchr (name, ','))
return 0; return 0;
buffer = grub_xasprintf ("(%s)", name); buffer = grub_xasprintf ("(%s)", name);
@ -232,37 +236,45 @@ match_devices (const regex_t *regexp, int noparts)
return 1; return 1;
grub_dprintf ("expand", "matching: %s\n", buffer); grub_dprintf ("expand", "matching: %s\n", buffer);
if (regexec (regexp, buffer, 0, 0, 0)) if (regexec (ctx->regexp, buffer, 0, 0, 0))
{ {
grub_dprintf ("expand", "not matched\n"); grub_dprintf ("expand", "not matched\n");
grub_free (buffer); grub_free (buffer);
return 0; return 0;
} }
t = grub_realloc (devs, sizeof (char*) * (ndev + 2)); t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
if (! t) if (! t)
return 1; return 1;
devs = t; ctx->devs = t;
devs[ndev++] = buffer; ctx->devs[ctx->ndev++] = buffer;
devs[ndev] = 0; ctx->devs[ctx->ndev] = 0;
return 0; return 0;
} }
ndev = 0; static char **
devs = 0; 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; goto fail;
return devs; return ctx.devs;
fail: fail:
for (i = 0; devs && devs[i]; i++) for (i = 0; ctx.devs && ctx.devs[i]; i++)
grub_free (devs[i]); grub_free (ctx.devs[i]);
grub_free (devs); grub_free (ctx.devs);
return 0; return 0;
} }

View file

@ -455,7 +455,7 @@ grub_ahci_restore_hw (void)
static int static int
grub_ahci_iterate (int (*hook) (int id, int bus), grub_ahci_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull) grub_disk_pull_t pull)
{ {
struct grub_ahci_device *dev; struct grub_ahci_device *dev;
@ -464,7 +464,7 @@ grub_ahci_iterate (int (*hook) (int id, int bus),
return 0; return 0;
FOR_LIST_ELEMENTS(dev, grub_ahci_devices) 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 1;
return 0; return 0;

View file

@ -80,23 +80,37 @@ arcdisk_hash_add (char *devpath)
} }
static int /* Context for grub_arcdisk_iterate. */
grub_arcdisk_iterate (int (*hook_in) (const char *name), struct grub_arcdisk_iterate_ctx
grub_disk_pull_t pull)
{ {
auto int hook (const char *name, const struct grub_arc_component *comp); grub_disk_dev_iterate_hook_t hook;
int hook (const char *name, const struct grub_arc_component *comp) 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 if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|| comp->type == GRUB_ARC_COMPONENT_TYPE_DISK || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|| comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
return 0; return 0;
return hook_in (name); return ctx->hook (name, ctx->hook_data);
} }
static int
grub_arcdisk_iterate (int (*hook_in) (const char *name),
grub_disk_pull_t pull)
{
struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data };
if (pull != GRUB_DISK_PULL_NONE) if (pull != GRUB_DISK_PULL_NONE)
return 0; 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)" #define RAW_SUFFIX "partition(10)"

View file

@ -392,13 +392,18 @@ grub_ata_real_open (int id, int bus)
return NULL; return NULL;
} }
static int /* Context for grub_ata_iterate. */
grub_ata_iterate (int (*hook_in) (const char *name), struct grub_ata_iterate_ctx
grub_disk_pull_t pull)
{ {
auto int hook (int id, int bus); grub_disk_dev_iterate_hook_t hook;
int hook (int id, int bus) void *hook_data;
{ };
/* Helper for grub_ata_iterate. */
static int
grub_ata_iterate_iter (int id, int bus, void *data)
{
struct grub_ata_iterate_ctx *ctx = data;
struct grub_ata *ata; struct grub_ata *ata;
int ret; int ret;
char devname[40]; char devname[40];
@ -417,15 +422,20 @@ grub_ata_iterate (int (*hook_in) (const char *name),
} }
grub_snprintf (devname, sizeof (devname), grub_snprintf (devname, sizeof (devname),
"%s%d", grub_scsi_names[id], bus); "%s%d", grub_scsi_names[id], bus);
ret = hook_in (devname); ret = ctx->hook (devname, ctx->hook_data);
grub_ata_real_close (ata); grub_ata_real_close (ata);
return ret; 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; grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next) 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 1;
return 0; return 0;
} }
@ -561,13 +571,18 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static int /* Context for grub_atapi_iterate. */
grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns), struct grub_atapi_iterate_ctx
grub_disk_pull_t pull)
{ {
auto int hook (int id, int bus); grub_scsi_dev_iterate_hook_t hook;
int hook (int id, int bus) void *hook_data;
{ };
/* Helper for grub_atapi_iterate. */
static int
grub_atapi_iterate_iter (int id, int bus, void *data)
{
struct grub_atapi_iterate_ctx *ctx = data;
struct grub_ata *ata; struct grub_ata *ata;
int ret; int ret;
@ -583,15 +598,20 @@ grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns),
grub_ata_real_close (ata); grub_ata_real_close (ata);
return 0; return 0;
} }
ret = hook_in (id, bus, 1); ret = ctx->hook (id, bus, 1, ctx->hook_data);
grub_ata_real_close (ata); grub_ata_real_close (ata);
return ret; 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; grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next) 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 1;
return 0; return 0;
} }

View file

@ -448,7 +448,7 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke
} }
static int static int
grub_cryptodisk_iterate (int (*hook) (const char *name), grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull) grub_disk_pull_t pull)
{ {
grub_cryptodisk_t i; grub_cryptodisk_t i;
@ -460,7 +460,7 @@ grub_cryptodisk_iterate (int (*hook) (const char *name),
{ {
char buf[30]; char buf[30];
grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id); grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
if (hook (buf)) if (hook (buf, hook_data))
return 1; return 1;
} }
@ -866,7 +866,8 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
#endif #endif
static int 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_err_t err;
grub_disk_t source; 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; check_boot = state[2].set;
search_uuid = args[0]; search_uuid = args[0];
grub_device_iterate (&grub_cryptodisk_scan_device); grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL; search_uuid = NULL;
if (!have_it) if (!have_it)
@ -919,7 +920,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{ {
search_uuid = NULL; search_uuid = NULL;
check_boot = state[2].set; check_boot = state[2].set;
grub_device_iterate (&grub_cryptodisk_scan_device); grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL; search_uuid = NULL;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -120,12 +120,11 @@ is_valid_diskfilter_name (const char *name)
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0); || grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
} }
/* Helper for scan_disk. */
static int 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); const char *name = data;
int hook (grub_disk_t disk, grub_partition_t p)
{
struct grub_diskfilter_vg *arr; struct grub_diskfilter_vg *arr;
grub_disk_addr_t start_sector; grub_disk_addr_t start_sector;
struct grub_diskfilter_pv_id id; struct grub_diskfilter_pv_id id;
@ -178,7 +177,11 @@ scan_disk (const char *name, int accept_diskfilter)
} }
return 0; return 0;
} }
static int
scan_disk (const char *name, int accept_diskfilter)
{
grub_disk_t disk; grub_disk_t disk;
static int scan_depth = 0; static int scan_depth = 0;
@ -196,12 +199,12 @@ scan_disk (const char *name, int accept_diskfilter)
scan_depth--; scan_depth--;
return 0; return 0;
} }
if (hook (disk, 0)) if (scan_disk_partition_iter (disk, 0, (void *) name))
{ {
scan_depth--; scan_depth--;
return 1; return 1;
} }
if (grub_partition_iterate (disk, hook)) if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name))
{ {
scan_depth--; scan_depth--;
return 1; return 1;
@ -212,7 +215,7 @@ scan_disk (const char *name, int accept_diskfilter)
} }
static int static int
scan_disk_hook (const char *name) scan_disk_hook (const char *name, void *data __attribute__ ((unused)))
{ {
return scan_disk (name, 0); return scan_disk (name, 0);
} }
@ -230,7 +233,7 @@ scan_devices (const char *arname)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate) && p->iterate)
{ {
if ((p->iterate) (scan_disk_hook, pull)) if ((p->iterate) (scan_disk_hook, NULL, pull))
return; return;
if (arname && is_lv_readable (find_lv (arname), 1)) if (arname && is_lv_readable (find_lv (arname), 1))
return; return;
@ -249,7 +252,7 @@ scan_devices (const char *arname)
} }
static int static int
grub_diskfilter_iterate (int (*hook) (const char *name), grub_diskfilter_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull) grub_disk_pull_t pull)
{ {
struct grub_diskfilter_vg *array; struct grub_diskfilter_vg *array;
@ -271,7 +274,7 @@ grub_diskfilter_iterate (int (*hook) (const char *name),
for (lv = array->lvs; lv; lv = lv->next) for (lv = array->lvs; lv; lv = lv->next)
if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt) if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt)
{ {
if (hook (lv->fullname)) if (hook (lv->fullname, hook_data))
return 1; return 1;
} }
} }
@ -303,7 +306,7 @@ grub_diskfilter_memberlist (grub_disk_t disk)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate) && p->iterate)
{ {
(p->iterate) (scan_disk_hook, pull); (p->iterate) (scan_disk_hook, NULL, pull);
while (pv && pv->disk) while (pv && pv->disk)
pv = pv->next; pv = pv->next;
} }

View file

@ -404,7 +404,7 @@ enumerate_disks (void)
} }
static int 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) grub_disk_pull_t pull)
{ {
struct grub_efidisk_data *d; 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_snprintf (buf, sizeof (buf), "hd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf); grub_dprintf ("efidisk", "iterating %s\n", buf);
if (hook (buf)) if (hook (buf, hook_data))
return 1; return 1;
} }
break; break;
@ -427,7 +427,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{ {
grub_snprintf (buf, sizeof (buf), "fd%d", count); grub_snprintf (buf, sizeof (buf), "fd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf); grub_dprintf ("efidisk", "iterating %s\n", buf);
if (hook (buf)) if (hook (buf, hook_data))
return 1; return 1;
} }
@ -435,7 +435,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{ {
grub_snprintf (buf, sizeof (buf), "cd%d", count); grub_snprintf (buf, sizeof (buf), "cd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf); grub_dprintf ("efidisk", "iterating %s\n", buf);
if (hook (buf)) if (hook (buf, hook_data))
return 1; return 1;
} }
break; break;
@ -736,6 +736,31 @@ get_diskname_from_path (const grub_efi_device_path_t *path,
return 0; 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 * char *
grub_efidisk_get_device_name (grub_efi_handle_t *handle) 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_DEVICE_PATH_SUBTYPE (ldp)
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
{ {
char *partition_name = NULL; struct grub_efidisk_get_device_name_ctx ctx;
char *dev_name; char *dev_name;
grub_efi_device_path_t *dup_dp, *dup_ldp; grub_efi_device_path_t *dup_dp, *dup_ldp;
grub_efi_hard_drive_device_path_t hd;
grub_disk_t parent = 0; 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 /* It is necessary to duplicate the device path so that GRUB
can overwrite it. */ can overwrite it. */
dup_dp = duplicate_device_path (dp); dup_dp = duplicate_device_path (dp);
@ -797,24 +805,27 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
return 0; return 0;
/* Find a partition which matches the hard drive device path. */ /* Find a partition which matches the hard drive device path. */
grub_memcpy (&hd, ldp, sizeof (hd)); ctx.partition_name = NULL;
if (hd.partition_start == 0 grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd));
&& hd.partition_size == grub_disk_get_size (parent)) if (ctx.hd.partition_start == 0
&& ctx.hd.partition_size == grub_disk_get_size (parent))
{ {
dev_name = grub_strdup (parent->name); dev_name = grub_strdup (parent->name);
} }
else 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); grub_disk_close (parent);
return 0; return 0;
} }
dev_name = grub_xasprintf ("%s,%s", parent->name, partition_name); dev_name = grub_xasprintf ("%s,%s", parent->name,
grub_free (partition_name); ctx.partition_name);
grub_free (ctx.partition_name);
} }
grub_disk_close (parent); grub_disk_close (parent);

View file

@ -27,13 +27,13 @@
int grub_disk_host_i_want_a_reference; int grub_disk_host_i_want_a_reference;
static int 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) grub_disk_pull_t pull)
{ {
if (pull != GRUB_DISK_PULL_NONE) if (pull != GRUB_DISK_PULL_NONE)
return 0; return 0;
if (hook ("host")) if (hook ("host", hook_data))
return 1; return 1;
return 0; return 0;
} }

View file

@ -272,20 +272,21 @@ grub_biosdisk_get_drive (const char *name)
} }
static int 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]; char name[10];
if (cd_drive && drive == cd_drive) if (cd_drive && drive == cd_drive)
return hook ("cd"); return hook ("cd", hook_data);
grub_snprintf (name, sizeof (name), grub_snprintf (name, sizeof (name),
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
return hook (name); return hook (name, hook_data);
} }
static int 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))) grub_disk_pull_t pull __attribute__ ((unused)))
{ {
int num_floppies; int num_floppies;
@ -304,7 +305,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
break; break;
} }
if (grub_biosdisk_call_hook (hook, drive)) if (grub_biosdisk_call_hook (hook, hook_data, drive))
return 1; return 1;
} }
return 0; return 0;
@ -312,14 +313,14 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
case GRUB_DISK_PULL_REMOVABLE: case GRUB_DISK_PULL_REMOVABLE:
if (cd_drive) if (cd_drive)
{ {
if (grub_biosdisk_call_hook (hook, cd_drive)) if (grub_biosdisk_call_hook (hook, hook_data, cd_drive))
return 1; return 1;
} }
/* For floppy disks, we can get the number safely. */ /* For floppy disks, we can get the number safely. */
num_floppies = grub_biosdisk_get_num_floppies (); num_floppies = grub_biosdisk_get_num_floppies ();
for (drive = 0; drive < num_floppies; drive++) 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 1;
return 0; return 0;
default: default:

View file

@ -33,7 +33,7 @@ struct grub_nand_data
}; };
static int 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) grub_disk_pull_t pull)
{ {
auto int dev_iterate (struct grub_ieee1275_devalias *alias); 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) if (grub_strcmp (alias->name, "nand") == 0)
{ {
hook (alias->name); hook (alias->name, hook_data);
return 1; return 1;
} }

View file

@ -218,7 +218,7 @@ scan (void)
} }
static int 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) grub_disk_pull_t pull)
{ {
unsigned i; unsigned i;
@ -276,7 +276,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name),
*optr++ = *iptr++; *optr++ = *iptr++;
} }
*optr = 0; *optr = 0;
if (hook (buffer)) if (hook (buffer, hook_data))
return 1; return 1;
} }
} }

View file

@ -105,14 +105,11 @@ read_int (grub_uint8_t *in, grub_size_t s)
static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
static grub_disk_addr_t /* Helper for gpt_ldm_sector. */
gpt_ldm_sector (grub_disk_t dsk) static int
gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data)
{ {
grub_disk_addr_t sector = 0; grub_disk_addr_t *sector = data;
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; struct grub_gpt_partentry gptdata;
grub_partition_t p2; grub_partition_t p2;
@ -128,12 +125,19 @@ gpt_ldm_sector (grub_disk_t dsk)
if (! grub_memcmp (&gptdata.type, &ldm_type, 16)) if (! grub_memcmp (&gptdata.type, &ldm_type, 16))
{ {
sector = p->start + p->len - 1; *sector = p->start + p->len - 1;
return 1; return 1;
} }
return 0; return 0;
} }
err = grub_gpt_partition_map_iterate (dsk, hook);
static grub_disk_addr_t
gpt_ldm_sector (grub_disk_t dsk)
{
grub_disk_addr_t sector = 0;
grub_err_t err;
err = grub_gpt_partition_map_iterate (dsk, gpt_ldm_sector_iter, &sector);
if (err) if (err)
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;

View file

@ -135,7 +135,7 @@ fail:
static int static int
grub_loopback_iterate (int (*hook) (const char *name), grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull) grub_disk_pull_t pull)
{ {
struct grub_loopback *d; struct grub_loopback *d;
@ -143,7 +143,7 @@ grub_loopback_iterate (int (*hook) (const char *name),
return 0; return 0;
for (d = loopback_list; d; d = d->next) for (d = loopback_list; d; d = d->next)
{ {
if (hook (d->devname)) if (hook (d->devname, hook_data))
return 1; return 1;
} }
return 0; return 0;

View file

@ -30,13 +30,13 @@ static char *memdisk_addr;
static grub_off_t memdisk_size = 0; static grub_off_t memdisk_size = 0;
static int 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) grub_disk_pull_t pull)
{ {
if (pull != GRUB_DISK_PULL_NONE) if (pull != GRUB_DISK_PULL_NONE)
return 0; return 0;
return hook ("memdisk"); return hook ("memdisk", hook_data);
} }
static grub_err_t static grub_err_t

View file

@ -501,7 +501,7 @@ grub_pata_open (int id, int devnum, struct grub_ata *ata)
} }
static int 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) grub_disk_pull_t pull)
{ {
struct grub_pata_device *dev; struct grub_pata_device *dev;
@ -510,7 +510,8 @@ grub_pata_iterate (int (*hook) (int id, int bus),
return 0; return 0;
for (dev = grub_pata_devices; dev; dev = dev->next) 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 1;
return 0; return 0;

View file

@ -423,16 +423,18 @@ grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector,
static int /* Context for grub_scsi_iterate. */
grub_scsi_iterate (int (*hook) (const char *name), struct grub_scsi_iterate_ctx
grub_disk_pull_t pull)
{ {
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
int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns) scsi_iterate (int id, int bus, int luns, void *data)
{ {
struct grub_scsi_iterate_ctx *ctx = data;
int i; int i;
/* In case of a single LUN, just return `usbX'. */ /* In case of a single LUN, just return `usbX'. */
@ -443,7 +445,7 @@ grub_scsi_iterate (int (*hook) (const char *name),
sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus); sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
if (!sname) if (!sname)
return 1; return 1;
ret = hook (sname); ret = ctx->hook (sname, ctx->hook_data);
grub_free (sname); grub_free (sname);
return ret; return ret;
} }
@ -457,16 +459,23 @@ grub_scsi_iterate (int (*hook) (const char *name),
sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i); sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
if (!sname) if (!sname)
return 1; return 1;
ret = hook (sname); ret = ctx->hook (sname, ctx->hook_data);
grub_free (sname); grub_free (sname);
if (ret) if (ret)
return 1; return 1;
} }
return 0; 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) 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 1;
return 0; return 0;

View file

@ -265,7 +265,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
static int 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) grub_disk_pull_t pull)
{ {
unsigned i; 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++) for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (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; return 1;
} }

View file

@ -538,16 +538,23 @@ lower_bound (struct grub_btrfs_data *data,
} }
} }
static grub_device_t /* Context for find_device. */
find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) struct find_device_ctx
{ {
grub_device_t dev_found = NULL; struct grub_btrfs_data *data;
auto int hook (const char *name); grub_uint64_t id;
int hook (const char *name) 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_device_t dev;
grub_err_t err; grub_err_t err;
struct grub_btrfs_superblock sb; struct grub_btrfs_superblock sb;
dev = grub_device_open (name); dev = grub_device_open (name);
if (!dev) if (!dev)
return 0; return 0;
@ -569,25 +576,33 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
grub_print_error (); grub_print_error ();
return 0; return 0;
} }
if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
|| sb.this_device.device_id != id) || sb.this_device.device_id != ctx->id)
{ {
grub_device_close (dev); grub_device_close (dev);
return 0; return 0;
} }
dev_found = dev; ctx->dev_found = dev;
return 1; 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; unsigned i;
for (i = 0; i < data->n_devices_attached; i++) for (i = 0; i < data->n_devices_attached; i++)
if (id == data->devices_attached[i].id) if (id == data->devices_attached[i].id)
return data->devices_attached[i].dev; return data->devices_attached[i].dev;
if (do_rescan) if (do_rescan)
grub_device_iterate (hook); grub_device_iterate (find_device_iter, &ctx);
if (!dev_found) if (!ctx.dev_found)
{ {
grub_error (GRUB_ERR_BAD_FS, grub_error (GRUB_ERR_BAD_FS,
N_("couldn't find a necessary member device " 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])); * sizeof (data->devices_attached[0]));
if (!data->devices_attached) if (!data->devices_attached)
{ {
grub_device_close (dev_found); grub_device_close (ctx.dev_found);
data->devices_attached = tmp; data->devices_attached = tmp;
return NULL; return NULL;
} }
} }
data->devices_attached[data->n_devices_attached - 1].id = id; data->devices_attached[data->n_devices_attached - 1].id = id;
data->devices_attached[data->n_devices_attached - 1].dev = dev_found; data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found;
return dev_found; return ctx.dev_found;
} }
static grub_err_t static grub_err_t

View file

@ -988,15 +988,15 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data,
return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label");
} }
static grub_err_t /* Helper for scan_devices. */
scan_devices (struct grub_zfs_data *data) static int
scan_devices_iter (const char *name, void *hook_data)
{ {
auto int hook (const char *name); struct grub_zfs_data *data = hook_data;
int hook (const char *name)
{
grub_device_t dev; grub_device_t dev;
grub_err_t err; grub_err_t err;
int inserted; int inserted;
dev = grub_device_open (name); dev = grub_device_open (name);
if (!dev) if (!dev)
return 0; return 0;
@ -1023,8 +1023,12 @@ scan_devices (struct grub_zfs_data *data)
grub_device_close (dev); grub_device_close (dev);
return 0; return 0;
} }
grub_device_iterate (hook);
static grub_err_t
scan_devices (struct grub_zfs_data *data)
{
grub_device_iterate (scan_devices_iter, data);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -96,7 +96,7 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
} }
static int static int
grub_mini_print_devices (const char *name) grub_mini_print_devices (const char *name, void *data __attribute__ ((unused)))
{ {
grub_printf ("(%s) ", name); grub_printf ("(%s) ", name);
@ -119,7 +119,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
{ {
if (argc < 1) if (argc < 1)
{ {
grub_device_iterate (grub_mini_print_devices); grub_device_iterate (grub_mini_print_devices, NULL);
grub_xputs ("\n"); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
} }

View file

@ -85,65 +85,26 @@ grub_device_close (grub_device_t device)
return grub_errno; return grub_errno;
} }
int struct part_ent
grub_device_iterate (int (*hook) (const char *name))
{ {
auto int iterate_disk (const char *disk_name);
auto int iterate_partition (grub_disk_t disk,
const grub_partition_t partition);
struct part_ent
{
struct part_ent *next; struct part_ent *next;
char *name; char *name;
} *ents; };
int iterate_disk (const char *disk_name) /* Context for grub_device_iterate. */
{ struct grub_device_iterate_ctx
grub_device_t dev; {
grub_device_iterate_hook_t hook;
void *hook_data;
struct part_ent *ents;
};
if (hook (disk_name)) /* Helper for grub_device_iterate. */
return 1; static int
iterate_partition (grub_disk_t disk, const grub_partition_t partition,
dev = grub_device_open (disk_name); void *data)
if (! dev) {
{ struct grub_device_iterate_ctx *ctx = data;
grub_errno = GRUB_ERR_NONE;
return 0;
}
if (dev->disk)
{
struct part_ent *p;
int ret = 0;
ents = NULL;
(void) grub_partition_iterate (dev->disk, iterate_partition);
grub_device_close (dev);
grub_errno = GRUB_ERR_NONE;
p = ents;
while (p != NULL)
{
struct part_ent *next = p->next;
if (!ret)
ret = hook (p->name);
grub_free (p->name);
grub_free (p);
p = next;
}
return ret;
}
grub_device_close (dev);
return 0;
}
int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
{
struct part_ent *p; struct part_ent *p;
char *part_name; char *part_name;
@ -167,12 +128,64 @@ grub_device_iterate (int (*hook) (const char *name))
return 1; return 1;
} }
p->next = ents; p->next = ctx->ents;
ents = p; ctx->ents = p;
return 0;
}
/* 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;
if (ctx->hook (disk_name, ctx->hook_data))
return 1;
dev = grub_device_open (disk_name);
if (! dev)
{
grub_errno = GRUB_ERR_NONE;
return 0; return 0;
} }
/* Only disk devices are supported at the moment. */ if (dev->disk)
return grub_disk_dev_iterate (iterate_disk); {
struct part_ent *p;
int ret = 0;
ctx->ents = NULL;
(void) grub_partition_iterate (dev->disk, iterate_partition, ctx);
grub_device_close (dev);
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);
p = next;
}
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, &ctx);
} }

View file

@ -223,7 +223,7 @@ find_free_slot (void)
} }
static int 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) grub_disk_pull_t pull)
{ {
unsigned i; unsigned i;
@ -232,7 +232,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name),
return 0; return 0;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) 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 1;
return 0; return 0;

View file

@ -48,8 +48,7 @@ const char *type_names[] = {
static int static int
iterate_rec (const char *prefix, const struct grub_arc_component *parent, iterate_rec (const char *prefix, const struct grub_arc_component *parent,
int (*hook) (const char *name, grub_arc_iterate_devs_hook_t hook, void *hook_data,
const struct grub_arc_component *comp),
int alt_names) int alt_names)
{ {
const struct grub_arc_component *comp; 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); name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
if (!name) if (!name)
return 1; return 1;
if (hook (name, comp)) if (hook (name, comp, hook_data))
{ {
grub_free (name); grub_free (name);
return 1; 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); grub_free (name);
return 1; return 1;
@ -83,11 +83,11 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent,
} }
int int
grub_arc_iterate_devs (int (*hook) (const char *name, grub_arc_iterate_devs (grub_arc_iterate_devs_hook_t hook, void *hook_data,
const struct grub_arc_component *comp),
int alt_names) 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 grub_err_t

View file

@ -59,39 +59,50 @@ grub_partition_check_containment (const grub_disk_t disk,
return 1; return 1;
} }
static grub_partition_t /* Context for grub_partition_map_probe. */
grub_partition_map_probe (const grub_partition_map_t partmap, struct grub_partition_map_probe_ctx
grub_disk_t disk, int partnum)
{ {
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, if (ctx->partnum != partition->number)
const grub_partition_t partition)
{
if (partnum != partition->number)
return 0; return 0;
if (!(grub_partition_check_containment (dsk, partition))) if (!(grub_partition_check_containment (dsk, partition)))
return 0; return 0;
p = (grub_partition_t) grub_malloc (sizeof (*p)); ctx->p = (grub_partition_t) grub_malloc (sizeof (*ctx->p));
if (! p) if (! ctx->p)
return 1; return 1;
grub_memcpy (p, partition, sizeof (*p)); grub_memcpy (ctx->p, partition, sizeof (*ctx->p));
return 1; 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) if (grub_errno)
goto fail; goto fail;
return p; return ctx.p;
fail: fail:
grub_free (p); grub_free (ctx.p);
return 0; return 0;
} }
@ -162,18 +173,19 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
return part; return part;
} }
int /* Context for grub_partition_iterate. */
grub_partition_iterate (struct grub_disk *disk, struct grub_partition_iterate_ctx
int (*hook) (grub_disk_t disk,
const grub_partition_t partition))
{ {
int ret = 0; int ret;
grub_partition_iterate_hook_t hook;
void *hook_data;
};
auto int part_iterate (grub_disk_t dsk, const grub_partition_t p); /* Helper for grub_partition_iterate. */
static int
int part_iterate (grub_disk_t dsk, part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data)
const grub_partition_t partition) {
{ struct grub_partition_iterate_ctx *ctx = data;
struct grub_partition p = *partition; struct grub_partition p = *partition;
if (!(grub_partition_check_containment (dsk, partition))) if (!(grub_partition_check_containment (dsk, partition)))
@ -181,9 +193,9 @@ grub_partition_iterate (struct grub_disk *disk,
p.parent = dsk->partition; p.parent = dsk->partition;
dsk->partition = 0; dsk->partition = 0;
if (hook (dsk, &p)) if (ctx->hook (dsk, &p, ctx->hook_data))
{ {
ret = 1; ctx->ret = 1;
return 1; return 1;
} }
if (p.start != 0) if (p.start != 0)
@ -193,31 +205,39 @@ grub_partition_iterate (struct grub_disk *disk,
FOR_PARTITION_MAPS(partmap) FOR_PARTITION_MAPS(partmap)
{ {
grub_err_t err; grub_err_t err;
err = partmap->iterate (dsk, part_iterate); err = partmap->iterate (dsk, part_iterate, ctx);
if (err) if (err)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
if (ret) if (ctx->ret)
break; break;
} }
} }
dsk->partition = p.parent; dsk->partition = p.parent;
return ret; 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; const struct grub_partition_map *partmap;
FOR_PARTITION_MAPS(partmap) FOR_PARTITION_MAPS(partmap)
{ {
grub_err_t err; grub_err_t err;
err = partmap->iterate (disk, part_iterate); err = partmap->iterate (disk, part_iterate, &ctx);
if (err) if (err)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
if (ret) if (ctx.ret)
break; break;
} }
}
return ret; return ctx.ret;
} }
char * char *

View file

@ -102,42 +102,45 @@ grub_plan9_unload (void)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static grub_err_t /* Context for grub_cmd_plan9. */
grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) struct grub_cmd_plan9_ctx
{ {
grub_file_t file = 0; grub_extcmd_context_t ctxt;
void *mem; grub_file_t file;
grub_size_t memsize, padsize; char *pmap;
struct grub_plan9_header hdr; grub_size_t pmapalloc;
char *config, *configptr; grub_size_t pmapptr;
grub_size_t configsize; int noslash;
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"};
int prefixescnt[5]; int prefixescnt[5];
char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL; char *bootdisk, *bootpart;
};
auto int fill_partition (grub_disk_t disk, static const char prefixes[5][10] = {
const grub_partition_t partition); "dos", "plan9", "ntfs", "linux", "linuxswap"
int fill_partition (grub_disk_t disk, };
const grub_partition_t partition)
{ /* 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 file_disk = 0;
int pstart, pend; int pstart, pend;
if (!noslash)
if (!fill_ctx->noslash)
{ {
if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
(void **) &fill_ctx->pmap))
return 1; return 1;
pmap[pmapptr++] = '/'; fill_ctx->pmap[fill_ctx->pmapptr++] = '/';
} }
noslash = 0; fill_ctx->noslash = 0;
file_disk = file->device->disk && disk->id == file->device->disk->id file_disk = fill_ctx->file->device->disk
&& disk->dev->id == file->device->disk->dev->id; && disk->id == fill_ctx->file->device->disk->id
&& disk->dev->id == fill_ctx->file->device->disk->dev->id;
pstart = pmapptr; pstart = fill_ctx->pmapptr;
if (grub_strcmp (partition->partmap->name, "plan") == 0) if (grub_strcmp (partition->partmap->name, "plan") == 0)
{ {
unsigned ptr = partition->index + sizeof ("part ") - 1; unsigned ptr = partition->index + sizeof ("part ") - 1;
@ -145,20 +148,22 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
disk->partition = partition->parent; disk->partition = partition->parent;
do do
{ {
if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
(void **) &fill_ctx->pmap))
return 1; return 1;
err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr); err = grub_disk_read (disk, 1, ptr, 1,
fill_ctx->pmap + fill_ctx->pmapptr);
if (err) if (err)
{ {
disk->partition = 0; disk->partition = 0;
return err; return err;
} }
ptr++; ptr++;
pmapptr++; fill_ctx->pmapptr++;
} }
while (grub_isalpha (pmap[pmapptr - 1]) while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1])
|| grub_isdigit (pmap[pmapptr - 1])); || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1]));
pmapptr--; fill_ctx->pmapptr--;
} }
else else
{ {
@ -185,44 +190,47 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
} }
} }
if (prefixescnt[c] == 0) if (fill_ctx->prefixescnt[c] == 0)
grub_strcpy (name, prefixes[c]); grub_strcpy (name, prefixes[c]);
else else
grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c],
prefixescnt[c]); fill_ctx->prefixescnt[c]);
prefixescnt[c]++; fill_ctx->prefixescnt[c]++;
if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1, if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1,
&pmapalloc, (void **) &pmap)) &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
return 1; return 1;
grub_strcpy (pmap + pmapptr, name); grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name);
pmapptr += grub_strlen (name); fill_ctx->pmapptr += grub_strlen (name);
} }
pend = pmapptr; pend = fill_ctx->pmapptr;
if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25,
(void **) &pmap)) &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
return 1; return 1;
pmap[pmapptr++] = ' '; fill_ctx->pmap[fill_ctx->pmapptr++] = ' ';
grub_snprintf (pmap + pmapptr, 25 + 5 + 25, grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25,
"%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T,
grub_partition_get_start (partition), grub_partition_get_start (partition),
grub_partition_get_start (partition) grub_partition_get_start (partition)
+ grub_partition_get_len (partition)); + grub_partition_get_len (partition));
if (file_disk && grub_partition_get_start (partition) if (file_disk && grub_partition_get_start (partition)
== grub_partition_get_start (file->device->disk->partition) == grub_partition_get_start (fill_ctx->file->device->disk->partition)
&& grub_partition_get_len (partition) && grub_partition_get_len (partition)
== grub_partition_get_len (file->device->disk->partition)) == grub_partition_get_len (fill_ctx->file->device->disk->partition))
{ {
grub_free (bootpart); grub_free (fill_ctx->bootpart);
bootpart = grub_strndup (pmap + pstart, pend - pstart); fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart,
pend - pstart);
} }
pmapptr += grub_strlen (pmap + pmapptr); fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr);
return 0; return 0;
} }
auto int fill_disk (const char *name); /* Helper for grub_cmd_plan9. */
int fill_disk (const char *name) static int
{ fill_disk (const char *name, void *data)
{
struct grub_cmd_plan9_ctx *fill_ctx = data;
grub_device_t dev; grub_device_t dev;
char *plan9name = NULL; char *plan9name = NULL;
unsigned i; unsigned i;
@ -239,14 +247,18 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_device_close (dev); grub_device_close (dev);
return 0; return 0;
} }
file_disk = file->device->disk && dev->disk->id == file->device->disk->id file_disk = fill_ctx->file->device->disk
&& dev->disk->dev->id == file->device->disk->dev->id; && dev->disk->id == fill_ctx->file->device->disk->id
for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++) && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id;
if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0 for (i = 0;
&& ctxt->state[0].args[i][grub_strlen (name)] == '=') 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; break;
if (ctxt->state[0].args && ctxt->state[0].args[i]) if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i])
plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1); plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i]
+ grub_strlen (name) + 1);
else else
switch (dev->disk->dev->id) switch (dev->disk->dev->id)
{ {
@ -315,35 +327,56 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_print_error (); grub_print_error ();
return 0; return 0;
} }
if (grub_extend_alloc (pmapptr + grub_strlen (plan9name) if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name)
+ sizeof ("part="), &pmapalloc, + sizeof ("part="), &fill_ctx->pmapalloc,
(void **) &pmap)) (void **) &fill_ctx->pmap))
{ {
grub_free (plan9name); grub_free (plan9name);
return 1; return 1;
} }
grub_strcpy (pmap + pmapptr, plan9name); grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name);
pmapptr += grub_strlen (plan9name); fill_ctx->pmapptr += grub_strlen (plan9name);
if (!file_disk) if (!file_disk)
grub_free (plan9name); grub_free (plan9name);
else else
{ {
grub_free (bootdisk); grub_free (fill_ctx->bootdisk);
bootdisk = plan9name; fill_ctx->bootdisk = plan9name;
} }
grub_strcpy (pmap + pmapptr, "part="); grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part=");
pmapptr += sizeof ("part=") - 1; fill_ctx->pmapptr += sizeof ("part=") - 1;
noslash = 1; fill_ctx->noslash = 1;
grub_memset (prefixescnt, 0, sizeof (prefixescnt)); grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt));
if (grub_partition_iterate (dev->disk, fill_partition)) if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx))
return 1; return 1;
if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
(void **) &fill_ctx->pmap))
return 1; return 1;
pmap[pmapptr++] = '\n'; 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) if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); 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) if (!rel)
goto fail; goto fail;
file = grub_file_open (argv[0]); fill_ctx.file = grub_file_open (argv[0]);
if (! file) if (! fill_ctx.file)
goto fail; goto fail;
pmap = grub_malloc (pmapalloc); fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc);
if (!pmap) if (!fill_ctx.pmap)
goto fail; goto fail;
if (grub_disk_dev_iterate (fill_disk)) if (grub_disk_dev_iterate (fill_disk, &fill_ctx))
goto fail; goto fail;
if (grub_extend_alloc (pmapptr + 1, &pmapalloc, if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc,
(void **) &pmap)) (void **) &fill_ctx.pmap))
goto fail; goto fail;
pmap[pmapptr] = 0; fill_ctx.pmap[fill_ctx.pmapptr] = 0;
{ {
char *file_name = grub_strchr (argv[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) if (*file_name)
file_name++; file_name++;
if (bootpart) if (fill_ctx.bootpart)
bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name); bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk,
fill_ctx.bootpart, file_name);
else else
bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name); bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name);
grub_free (bootdisk); grub_free (fill_ctx.bootdisk);
grub_free (bootpart); grub_free (fill_ctx.bootpart);
} }
if (!bootpath) if (!bootpath)
goto fail; 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) if (!grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), 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 += grub_strlen (argv[i]) + 1;
} }
configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1;
configsize += pmapptr; configsize += fill_ctx.pmapptr;
/* Terminating \0. */ /* Terminating \0. */
configsize++; configsize++;
@ -452,7 +487,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
*configptr++ = '\n'; *configptr++ = '\n';
} }
} }
configptr = grub_stpcpy (configptr, pmap); configptr = grub_stpcpy (configptr, fill_ctx.pmap);
{ {
grub_relocator_chunk_t ch; 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)); grub_memcpy (ptr, &hdr, sizeof (hdr));
ptr += 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)) != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size))
{ {
if (!grub_errno) if (!grub_errno)
@ -487,7 +522,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_memset (ptr, 0, padsize); grub_memset (ptr, 0, padsize);
ptr += 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)) != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size))
{ {
if (!grub_errno) if (!grub_errno)
@ -508,10 +543,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
fail: fail:
grub_free (pmap); grub_free (fill_ctx.pmap);
if (file) if (fill_ctx.file)
grub_file_close (file); grub_file_close (fill_ctx.file);
grub_plan9_unload (); grub_plan9_unload ();

View file

@ -99,7 +99,8 @@ add_completion (const char *completion, const char *extra,
} }
static int 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; const char *disk_name = disk->name;
char *name; char *name;
@ -154,7 +155,7 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info)
} }
static int static int
iterate_dev (const char *devname) iterate_dev (const char *devname, void *data __attribute__ ((unused)))
{ {
grub_device_t dev; grub_device_t dev;
@ -180,7 +181,7 @@ iterate_dev (const char *devname)
} }
if (dev->disk) if (dev->disk)
if (grub_partition_iterate (dev->disk, iterate_partition)) if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{ {
grub_device_close (dev); grub_device_close (dev);
return 1; return 1;
@ -213,7 +214,7 @@ complete_device (void)
if (! p) if (! p)
{ {
/* Complete the disk part. */ /* Complete the disk part. */
if (grub_disk_dev_iterate (iterate_dev)) if (grub_disk_dev_iterate (iterate_dev, NULL))
return 1; return 1;
} }
else else
@ -228,7 +229,7 @@ complete_device (void)
{ {
if (dev->disk) if (dev->disk)
{ {
if (grub_partition_iterate (dev->disk, iterate_partition)) if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{ {
grub_device_close (dev); grub_device_close (dev);
return 1; return 1;

View file

@ -101,8 +101,8 @@ fail:
static grub_err_t static grub_err_t
acorn_partition_map_iterate (grub_disk_t disk, acorn_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition part; struct grub_partition part;
struct linux_part map[LINUX_MAP_ENTRIES]; struct linux_part map[LINUX_MAP_ENTRIES];
@ -127,7 +127,7 @@ acorn_partition_map_iterate (grub_disk_t disk,
part.offset = 6; part.offset = 6;
part.number = part.index = i; part.number = part.index = i;
if (hook (disk, &part)) if (hook (disk, &part, hook_data))
return grub_errno; return grub_errno;
} }

View file

@ -87,8 +87,8 @@ amiga_partition_map_checksum (void *buf, grub_size_t sz)
static grub_err_t static grub_err_t
amiga_partition_map_iterate (grub_disk_t disk, amiga_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition part; struct grub_partition part;
struct grub_amiga_rdsk rdsk; struct grub_amiga_rdsk rdsk;
@ -145,7 +145,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
part.index = 0; part.index = 0;
part.partmap = &grub_amiga_partition_map; part.partmap = &grub_amiga_partition_map;
if (hook (disk, &part)) if (hook (disk, &part, hook_data))
return grub_errno; return grub_errno;
next = grub_be_to_cpu32 (apart.next); next = grub_be_to_cpu32 (apart.next);

View file

@ -101,8 +101,8 @@ static struct grub_partition_map grub_apple_partition_map;
static grub_err_t static grub_err_t
apple_partition_map_iterate (grub_disk_t disk, apple_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition part; struct grub_partition part;
struct grub_apple_header aheader; 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.first_phys_block),
grub_be_to_cpu32 (apart.blockcnt)); grub_be_to_cpu32 (apart.blockcnt));
if (hook (disk, &part)) if (hook (disk, &part, hook_data))
return grub_errno; return grub_errno;
pos += grub_be_to_cpu16 (aheader.blocksize); pos += grub_be_to_cpu16 (aheader.blocksize);

View file

@ -41,8 +41,7 @@ static struct grub_partition_map grub_openbsdlabel_partition_map;
static grub_err_t static grub_err_t
iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
struct grub_partition_map *pmap, struct grub_partition_map *pmap,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook, void *hook_data)
const grub_partition_t partition))
{ {
struct grub_partition_bsd_disk_label label; struct grub_partition_bsd_disk_label label;
struct grub_partition p; struct grub_partition p;
@ -116,7 +115,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
p.start -= delta; p.start -= delta;
if (hook (disk, &p)) if (hook (disk, &p, hook_data))
return grub_errno; return grub_errno;
} }
return GRUB_ERR_NONE; 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 static grub_err_t
bsdlabel_partition_map_iterate (grub_disk_t disk, bsdlabel_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD) == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, 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 if (disk->partition
&& (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
@ -141,36 +140,35 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0,
&grub_bsdlabel_partition_map, hook); &grub_bsdlabel_partition_map, hook, hook_data);
} }
/* This is a total breakage. Even when net-/openbsd label is inside partition /* Context for netopenbsdlabel_partition_map_iterate. */
it actually describes the whole disk. struct netopenbsdlabel_ctx
*/
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))
{ {
int count = 0; grub_uint8_t type;
struct grub_partition_map *pmap;
grub_partition_iterate_hook_t hook;
void *hook_data;
int count;
};
auto int check_msdos (grub_disk_t dsk, /* Helper for netopenbsdlabel_partition_map_iterate. */
const grub_partition_t partition); static int
check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data)
int check_msdos (grub_disk_t dsk, {
const grub_partition_t partition) struct netopenbsdlabel_ctx *ctx = data;
{
grub_err_t err; grub_err_t err;
if (partition->msdostype != type) if (partition->msdostype != ctx->type)
return 0; return 0;
err = iterate_real (dsk, partition->start err = iterate_real (dsk, partition->start
+ GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook); + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap,
ctx->hook, ctx->hook_data);
if (err == GRUB_ERR_NONE) if (err == GRUB_ERR_NONE)
{ {
count++; ctx->count++;
return 1; return 1;
} }
if (err == GRUB_ERR_BAD_PART_TABLE) if (err == GRUB_ERR_BAD_PART_TABLE)
@ -180,15 +178,34 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
} }
grub_print_error (); grub_print_error ();
return 0; return 0;
} }
/* This is a total breakage. Even when net-/openbsd label is inside partition
it actually describes the whole disk.
*/
static grub_err_t
netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
struct grub_partition_map *pmap,
grub_partition_iterate_hook_t hook,
void *hook_data)
{
int count = 0;
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0) == 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); 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; grub_err_t err;
err = grub_partition_msdos_iterate (disk, check_msdos);
err = grub_partition_msdos_iterate (disk, check_msdos, &ctx);
if (err) if (err)
return err; return err;
@ -200,24 +217,24 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
static grub_err_t static grub_err_t
netbsdlabel_partition_map_iterate (grub_disk_t disk, netbsdlabel_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
return netopenbsdlabel_partition_map_iterate (disk, return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_NETBSD, GRUB_PC_PARTITION_TYPE_NETBSD,
&grub_netbsdlabel_partition_map, &grub_netbsdlabel_partition_map,
hook); hook, hook_data);
} }
static grub_err_t static grub_err_t
openbsdlabel_partition_map_iterate (grub_disk_t disk, openbsdlabel_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
return netopenbsdlabel_partition_map_iterate (disk, return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_OPENBSD, GRUB_PC_PARTITION_TYPE_OPENBSD,
&grub_openbsdlabel_partition_map, &grub_openbsdlabel_partition_map,
hook); hook, hook_data);
} }

View file

@ -64,8 +64,7 @@ grub_dvh_is_valid (grub_uint32_t *label)
static grub_err_t static grub_err_t
dvh_partition_map_iterate (grub_disk_t disk, dvh_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook, void *hook_data)
const grub_partition_t partition))
{ {
struct grub_partition p; struct grub_partition p;
union 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.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start);
p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length); p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length);
p.number = p.index = partnum; p.number = p.index = partnum;
if (hook (disk, &p)) if (hook (disk, &p, hook_data))
break; break;
} }

View file

@ -48,8 +48,8 @@ static struct grub_partition_map grub_gpt_partition_map;
grub_err_t grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk, grub_gpt_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition part; struct grub_partition part;
struct grub_gpt_header gpt; 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.start,
(unsigned long long) part.len); (unsigned long long) part.len);
if (hook (disk, &part)) if (hook (disk, &part, hook_data))
return grub_errno; return grub_errno;
} }
@ -129,21 +129,18 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
} }
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
static grub_err_t /* Context for gpt_partition_map_embed. */
gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors, struct gpt_partition_map_embed_ctx
unsigned int max_nsectors,
grub_embed_type_t embed_type,
grub_disk_addr_t **sectors)
{ {
grub_disk_addr_t start = 0, len = 0; grub_disk_addr_t start, len;
unsigned i; };
grub_err_t err;
auto int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk, /* Helper for gpt_partition_map_embed. */
const grub_partition_t p); static int
int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk __attribute__ ((unused)), find_usable_region (grub_disk_t disk __attribute__ ((unused)),
const grub_partition_t p) const grub_partition_t p, void *data)
{ {
struct gpt_partition_map_embed_ctx *ctx = data;
struct grub_gpt_partentry gptdata; struct grub_gpt_partentry gptdata;
grub_partition_t p2; grub_partition_t p2;
@ -160,40 +157,53 @@ gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
/* If there's an embed region, it is in a dedicated partition. */ /* If there's an embed region, it is in a dedicated partition. */
if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
{ {
start = p->start; ctx->start = p->start;
len = p->len; ctx->len = p->len;
return 1; return 1;
} }
return 0; return 0;
} }
static grub_err_t
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)
{
struct gpt_partition_map_embed_ctx ctx = {
.start = 0,
.len = 0
};
unsigned i;
grub_err_t err;
if (embed_type != GRUB_EMBED_PCBIOS) if (embed_type != GRUB_EMBED_PCBIOS)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"GPT currently supports only PC-BIOS embedding"); "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) if (err)
return err; return err;
if (len == 0) if (ctx.len == 0)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, return grub_error (GRUB_ERR_FILE_NOT_FOUND,
N_("this GPT partition label contains no BIOS Boot Partition;" N_("this GPT partition label contains no BIOS Boot Partition;"
" embedding won't be possible")); " embedding won't be possible"));
if (len < *nsectors) if (ctx.len < *nsectors)
return grub_error (GRUB_ERR_OUT_OF_RANGE, return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("your BIOS Boot Partition is too small;" N_("your BIOS Boot Partition is too small;"
" embedding won't be possible")); " embedding won't be possible"));
*nsectors = len; *nsectors = ctx.len;
if (*nsectors > max_nsectors) if (*nsectors > max_nsectors)
*nsectors = max_nsectors; *nsectors = max_nsectors;
*sectors = grub_malloc (*nsectors * sizeof (**sectors)); *sectors = grub_malloc (*nsectors * sizeof (**sectors));
if (!*sectors) if (!*sectors)
return grub_errno; return grub_errno;
for (i = 0; i < *nsectors; i++) for (i = 0; i < *nsectors; i++)
(*sectors)[i] = start + i; (*sectors)[i] = ctx.start + i;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -100,8 +100,8 @@ struct embed_signature embed_signatures[] =
grub_err_t grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk, grub_partition_msdos_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition p; struct grub_partition p;
struct grub_msdos_partition_mbr mbr; struct grub_msdos_partition_mbr mbr;
@ -186,7 +186,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
{ {
p.number++; p.number++;
if (hook (disk, &p)) if (hook (disk, &p, hook_data))
return grub_errno; return grub_errno;
} }
else if (p.number < 4) else if (p.number < 4)

View file

@ -31,8 +31,8 @@ static struct grub_partition_map grub_plan_partition_map;
static grub_err_t static grub_err_t
plan_partition_map_iterate (grub_disk_t disk, plan_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
struct grub_partition p; struct grub_partition p;
int ptr = 0; int ptr = 0;
@ -92,7 +92,7 @@ plan_partition_map_iterate (grub_disk_t disk,
if (c != '\n') if (c != '\n')
break; break;
p.len -= p.start; p.len -= p.start;
if (hook (disk, &p)) if (hook (disk, &p, hook_data))
return grub_errno; return grub_errno;
} }
if (p.number == 0) if (p.number == 0)

View file

@ -86,8 +86,7 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t static grub_err_t
sun_partition_map_iterate (grub_disk_t disk, sun_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook, void *hook_data)
const grub_partition_t partition))
{ {
struct grub_partition p; struct grub_partition p;
union union
@ -128,7 +127,7 @@ sun_partition_map_iterate (grub_disk_t disk,
p.number = p.index = partnum; p.number = p.index = partnum;
if (p.len) if (p.len)
{ {
if (hook (disk, &p)) if (hook (disk, &p, hook_data))
partnum = GRUB_PARTMAP_SUN_MAX_PARTS; partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
} }
} }

View file

@ -68,8 +68,8 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t static grub_err_t
sun_pc_partition_map_iterate (grub_disk_t disk, sun_pc_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)) void *hook_data)
{ {
grub_partition_t p; grub_partition_t p;
union union
@ -122,7 +122,7 @@ sun_pc_partition_map_iterate (grub_disk_t disk,
p->number = partnum; p->number = partnum;
if (p->len) if (p->len)
{ {
if (hook (disk, p)) if (hook (disk, p, hook_data))
partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS; partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
} }
} }

View file

@ -255,7 +255,12 @@ struct grub_arc_system_parameter_block
#define GRUB_ARC_STDIN 0 #define GRUB_ARC_STDIN 0
#define GRUB_ARC_STDOUT 1 #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)) #define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp))

View file

@ -193,10 +193,12 @@ struct grub_ata
typedef struct grub_ata *grub_ata_t; 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 struct grub_ata_dev
{ {
/* Call HOOK with each device name, until HOOK returns non-zero. */ /* 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); grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */ /* Open the device named NAME, and set up SCSI. */

View file

@ -33,8 +33,11 @@ struct grub_device
}; };
typedef struct grub_device *grub_device_t; 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_device_t EXPORT_FUNC(grub_device_open) (const char *name);
grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device); 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 */ #endif /* ! GRUB_DEVICE_HEADER */

View file

@ -56,6 +56,8 @@ typedef enum
GRUB_DISK_PULL_MAX GRUB_DISK_PULL_MAX
} grub_disk_pull_t; } grub_disk_pull_t;
typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data);
/* Disk device. */ /* Disk device. */
struct grub_disk_dev struct grub_disk_dev
{ {
@ -66,7 +68,7 @@ struct grub_disk_dev
enum grub_disk_dev_id id; enum grub_disk_dev_id id;
/* Call HOOK with each device name, until HOOK returns non-zero. */ /* 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); grub_disk_pull_t pull);
/* Open the device named NAME, and set up DISK. */ /* 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_register) (grub_disk_dev_t dev);
void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev); void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
static inline int 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_dev_t p;
grub_disk_pull_t pull; grub_disk_pull_t pull;
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
for (p = grub_disk_dev_list; p; p = p->next) 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 1;
return 0; return 0;

View file

@ -80,8 +80,8 @@ struct grub_gpt_partentry
grub_err_t grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk, grub_gpt_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)); void *hook_data);
#endif /* ! GRUB_GPT_PARTITION_HEADER */ #endif /* ! GRUB_GPT_PARTITION_HEADER */

View file

@ -120,7 +120,7 @@ grub_msdos_partition_is_extended (int type)
grub_err_t grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk, grub_partition_msdos_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)); void *hook_data);
#endif /* ! GRUB_PC_PARTITION_HEADER */ #endif /* ! GRUB_PC_PARTITION_HEADER */

View file

@ -33,6 +33,10 @@ typedef enum
} grub_embed_type_t; } grub_embed_type_t;
#endif #endif
typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk,
const grub_partition_t partition,
void *data);
/* Partition map type. */ /* Partition map type. */
struct grub_partition_map struct grub_partition_map
{ {
@ -45,8 +49,7 @@ struct grub_partition_map
/* Call HOOK with each partition, until HOOK returns non-zero. */ /* Call HOOK with each partition, until HOOK returns non-zero. */
grub_err_t (*iterate) (struct grub_disk *disk, grub_err_t (*iterate) (struct grub_disk *disk,
int (*hook) (struct grub_disk *disk, grub_partition_iterate_hook_t hook, void *hook_data);
const grub_partition_t partition));
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
/* Determine sectors available for embedding. */ /* Determine sectors available for embedding. */
grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, 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, grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
const char *str); const char *str);
int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
int (*hook) (struct grub_disk *disk, grub_partition_iterate_hook_t hook,
const grub_partition_t partition)); void *hook_data);
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);

View file

@ -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); | (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 struct grub_scsi_dev
{ {
/* Call HOOK with each device name, until HOOK returns non-zero. */ /* 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); grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */ /* Open the device named NAME, and set up SCSI. */

View file

@ -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); 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 * char *
grub_util_biosdisk_get_grub_dev (const char *os_dev) 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 For NetBSD and FreeBSD, proceed as for Linux, except that the start
sector is obtained from the disk label. */ sector is obtained from the disk label. */
{ {
char *name, *partname; char *name;
grub_disk_t disk; grub_disk_t disk;
grub_disk_addr_t start; struct grub_util_biosdisk_get_grub_dev_ctx ctx;
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;
}
name = make_device_name (drive, -1, -1); 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. */ * different, we know that os_dev cannot be a floppy device. */
# endif /* !defined(HAVE_DIOCGDINFO) */ # 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) if (grub_errno != GRUB_ERR_NONE)
{ {
free (name); free (name);
return 0; 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; return name;
grub_util_info ("opening the device %s", 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; return 0;
} }
name = grub_util_get_ldm (disk, start); name = grub_util_get_ldm (disk, ctx.start);
if (name) if (name)
return 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) if (grub_errno != GRUB_ERR_NONE)
{ {
grub_disk_close (disk); grub_disk_close (disk);
return 0; return 0;
} }
if (partname == NULL) if (ctx.partname == NULL)
{ {
grub_disk_close (disk); grub_disk_close (disk);
grub_util_info ("cannot find the partition of `%s'", os_dev); 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; return 0;
} }
name = grub_xasprintf ("%s,%s", disk->name, partname); name = grub_xasprintf ("%s,%s", disk->name, ctx.partname);
free (partname); free (ctx.partname);
grub_disk_close (disk); grub_disk_close (disk);
return name; return name;
} }

View file

@ -138,6 +138,44 @@ write_rootdev (grub_device_t root_dev,
#define BOOT_SECTOR 0 #define BOOT_SECTOR 0
#endif #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 static void
setup (const char *dir, setup (const char *dir,
const char *boot_file, const char *core_file, const char *boot_file, const char *core_file,
@ -337,9 +375,11 @@ setup (const char *dir,
#ifdef GRUB_SETUP_BIOS #ifdef GRUB_SETUP_BIOS
{ {
grub_partition_map_t dest_partmap = NULL; struct identify_partmap_ctx ctx = {
grub_partition_t container = dest_dev->disk->partition; .dest_partmap = NULL,
int multiple_partmaps = 0; .container = dest_dev->disk->partition,
.multiple_partmaps = 0
};
int is_ldm; int is_ldm;
grub_err_t err; grub_err_t err;
grub_disk_addr_t *sectors; grub_disk_addr_t *sectors;
@ -347,38 +387,13 @@ setup (const char *dir,
grub_fs_t fs; grub_fs_t fs;
unsigned int nsec, maxsec; unsigned int nsec, maxsec;
/* Unlike root_dev, with dest_dev we're interested in the partition map even grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx);
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); if (ctx.container
&& grub_strcmp (ctx.container->partmap->name, "msdos") == 0
if (container && grub_strcmp (container->partmap->name, "msdos") == 0 && ctx.dest_partmap
&& dest_partmap && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD
&& (container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD))
|| 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.")); 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; goto unable_to_embed;
@ -392,7 +407,7 @@ setup (const char *dir,
if (fs_probe) 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"), grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
dest_dev->disk->name); dest_dev->disk->name);
if (fs && !fs->reserved_first_sector) if (fs && !fs->reserved_first_sector)
@ -403,20 +418,20 @@ setup (const char *dir,
"by grub-setup (--skip-fs-probe disables this " "by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), dest_dev->disk->name, fs->name); "check, use at your own risk)"), dest_dev->disk->name, fs->name);
if (dest_partmap && strcmp (dest_partmap->name, "msdos") != 0 if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
&& strcmp (dest_partmap->name, "gpt") != 0 && strcmp (ctx.dest_partmap->name, "gpt") != 0
&& strcmp (dest_partmap->name, "bsd") != 0 && strcmp (ctx.dest_partmap->name, "bsd") != 0
&& strcmp (dest_partmap->name, "netbsd") != 0 && strcmp (ctx.dest_partmap->name, "netbsd") != 0
&& strcmp (dest_partmap->name, "openbsd") != 0 && strcmp (ctx.dest_partmap->name, "openbsd") != 0
&& strcmp (dest_partmap->name, "sunpc") != 0) && strcmp (ctx.dest_partmap->name, "sunpc") != 0)
/* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */ /* 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 " 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 " "reserve space for DOS-style boot. Installing GRUB there could "
"result in FILESYSTEM DESTRUCTION if valuable data is overwritten " "result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
"by grub-setup (--skip-fs-probe disables this " "by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), dest_dev->disk->name, dest_partmap->name); "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name);
if (is_ldm && dest_partmap && strcmp (dest_partmap->name, "msdos") != 0 if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
&& strcmp (dest_partmap->name, "gpt") != 0) && strcmp (ctx.dest_partmap->name, "gpt") != 0)
grub_util_error (_("%s appears to contain a %s partition map and " grub_util_error (_("%s appears to contain a %s partition map and "
"LDM which isn't known to be a safe combination." "LDM which isn't known to be a safe combination."
" Installing GRUB there could " " Installing GRUB there could "
@ -424,12 +439,12 @@ setup (const char *dir,
" is overwritten " " is overwritten "
"by grub-setup (--skip-fs-probe disables this " "by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), "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. */ /* Copy the partition table. */
if (dest_partmap || if (ctx.dest_partmap ||
(!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)))
memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
tmp_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); 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.")); 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; 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.")); grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet."));
goto unable_to_embed; 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"), grub_util_warn (_("Partition style `%s' doesn't support embedding"),
dest_partmap->name); ctx.dest_partmap->name);
goto unable_to_embed; goto unable_to_embed;
} }
@ -473,8 +488,8 @@ setup (const char *dir,
if (is_ldm) if (is_ldm)
err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors); GRUB_EMBED_PCBIOS, &sectors);
else if (dest_partmap) else if (ctx.dest_partmap)
err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec, err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors); GRUB_EMBED_PCBIOS, &sectors);
else else
err = fs->embed (dest_dev, &nsec, maxsec, err = fs->embed (dest_dev, &nsec, maxsec,
@ -507,12 +522,12 @@ setup (const char *dir,
grub_util_error ("%s", _("no terminator in the core image")); 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); 0, GRUB_DISK_SECTOR_SIZE);
block = first_block; block = first_block;
for (i = 1; i < nsec; i++) 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); 0, GRUB_DISK_SECTOR_SIZE);
/* Make sure that the last blocklist is a terminator. */ /* Make sure that the last blocklist is a terminator. */