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