From 24b905a11c90e47cb271397bd507e0496fe130e7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 00:09:07 +0200 Subject: [PATCH 1/7] Lazy LVM and RAID assembly --- grub-core/disk/ata.c | 9 +- grub-core/disk/host.c | 9 +- grub-core/disk/i386/pc/biosdisk.c | 56 ++++++---- grub-core/disk/loopback.c | 8 +- grub-core/disk/lvm.c | 139 ++++++++++++++++++++--- grub-core/disk/memdisk.c | 9 +- grub-core/disk/raid.c | 178 ++++++++++++++++++++++-------- grub-core/disk/scsi.c | 9 +- grub-core/fs/i386/pc/pxe.c | 9 +- grub-core/kern/disk.c | 31 ++++-- grub-core/kern/emu/hostdisk.c | 6 +- include/grub/disk.h | 15 ++- include/grub/raid.h | 1 + 13 files changed, 365 insertions(+), 114 deletions(-) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 7f261560d..3a43a8cae 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -666,10 +666,14 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, static int -grub_ata_iterate (int (*hook) (const char *name)) +grub_ata_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_ata_device *dev; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; @@ -696,7 +700,8 @@ grub_ata_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_ata_open (const char *name, grub_disk_t disk) +grub_ata_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_ata_device *dev; grub_err_t err; diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c index c51966293..5376cc6ce 100644 --- a/grub-core/disk/host.c +++ b/grub-core/disk/host.c @@ -27,15 +27,20 @@ int grub_disk_host_i_want_a_reference; static int -grub_host_iterate (int (*hook) (const char *name)) +grub_host_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + if (hook ("host")) return 1; return 0; } static grub_err_t -grub_host_open (const char *name, grub_disk_t disk) +grub_host_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { if (grub_strcmp (name, "host")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 1d47dc727..e75ab184b 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -284,42 +284,52 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) } static int -grub_biosdisk_iterate (int (*hook) (const char *name)) +grub_biosdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull __attribute__ ((unused))) { - int drive; int num_floppies; + int drive; /* For hard disks, attempt to read the MBR. */ - for (drive = 0x80; drive < 0x90; drive++) + switch (pull) { - if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, - GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + case GRUB_DISK_PULL_NONE: + for (drive = 0x80; drive < 0x90; drive++) { - grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); - break; + if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, + GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + { + grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); + break; + } + + if (grub_biosdisk_call_hook (hook, drive)) + return 1; + } + return 0; + + case GRUB_DISK_PULL_REMOVABLE: + if (cd_drive) + { + if (grub_biosdisk_call_hook (hook, cd_drive)) + return 1; } - if (grub_biosdisk_call_hook (hook, 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)) + return 1; + return 0; + default: + return 0; } - - if (cd_drive) - { - if (grub_biosdisk_call_hook (hook, 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)) - return 1; - return 0; } static grub_err_t -grub_biosdisk_open (const char *name, grub_disk_t disk) +grub_biosdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { grub_uint64_t total_sectors = 0; int drive; diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index d50f353b1..21345af57 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -133,9 +133,12 @@ fail: static int -grub_loopback_iterate (int (*hook) (const char *name)) +grub_loopback_iterate (int (*hook) (const char *name), + 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)) @@ -145,7 +148,8 @@ grub_loopback_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_loopback_open (const char *name, grub_disk_t disk) +grub_loopback_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_loopback *dev; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 206e3e220..72f493540 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -32,7 +32,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_lvm_vg *vg_list; static int lv_count; +static int scan_depth = 0; +static int is_lv_readable (struct grub_lvm_lv *lv); + +static int +grub_lvm_scan_device (const char *name); /* Go the string STR and return the number after STR. *P will point at the number. In case STR is not found, *P will be NULL and the @@ -96,16 +101,39 @@ grub_lvm_check_flag (char *p, char *str, char *flag) } static int -grub_lvm_iterate (int (*hook) (const char *name)) +grub_lvm_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_lvm_vg *vg; + unsigned old_count = 0; + if (pull == GRUB_DISK_PULL_RESCAN && scan_depth) + return 0; + + if (pull == GRUB_DISK_PULL_RESCAN) + { + old_count = lv_count; + if (!scan_depth) + { + scan_depth++; + grub_device_iterate (&grub_lvm_scan_device); + scan_depth--; + } + } + if (pull != GRUB_DISK_PULL_RESCAN && pull != GRUB_DISK_PULL_NONE) + return GRUB_ERR_NONE; for (vg = vg_list; vg; vg = vg->next) { struct grub_lvm_lv *lv; if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (lv->visible && hook (lv->name)) - return 1; + if (lv->visible && lv->number >= old_count) + { + char lvname[sizeof ("lvm/") + grub_strlen (lv->name)]; + grub_memcpy (lvname, "lvm/", sizeof ("lvm/") - 1); + grub_strcpy (lvname + sizeof ("lvm/") - 1, lv->name); + if (hook (lvname)) + return 1; + } } return 0; @@ -135,8 +163,8 @@ grub_lvm_memberlist (grub_disk_t disk) } #endif -static grub_err_t -grub_lvm_open (const char *name, grub_disk_t disk) +static struct grub_lvm_lv * +find_lv (const char *name) { struct grub_lvm_vg *vg; struct grub_lvm_lv *lv = NULL; @@ -144,11 +172,43 @@ grub_lvm_open (const char *name, grub_disk_t disk) { if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (! grub_strcmp (lv->name, name)) - break; + if (! grub_strcmp (lv->name, name) && is_lv_readable (lv)) + return lv; + } + return NULL; +} - if (lv) - break; +static const char *scan_for = NULL; + +static grub_err_t +grub_lvm_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull) +{ + struct grub_lvm_lv *lv = NULL; + int explicit = 0; + + if (grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0) + { + name += sizeof ("lvm/") - 1; + explicit = 1; + } + + lv = find_lv (name); + + if (! lv && !scan_depth && + pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) + { + scan_for = name; + scan_depth++; + grub_device_iterate (&grub_lvm_scan_device); + scan_depth--; + scan_for = NULL; + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + lv = find_lv (name); } if (! lv) @@ -285,6 +345,49 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, return grub_error (GRUB_ERR_IO, "unknown LVM segment"); } +static grub_err_t +is_node_readable (const struct grub_lvm_node *node) +{ + /* Check whether we actually know the physical volume we want to + read from. */ + if (node->pv) + return !!(node->pv->disk); + if (node->lv) + return is_lv_readable (node->lv); + return 0; +} + +static int +is_lv_readable (struct grub_lvm_lv *lv) +{ + unsigned int i, j; + + if (!lv) + return 0; + + /* Find the right segment. */ + for (i = 0; i < lv->segment_count; i++) + switch (lv->segments[i].type) + { + case GRUB_LVM_STRIPED: + for (j = 0; j < lv->segments[i].node_count; j++) + if (!is_node_readable (lv->segments[i].nodes + j)) + return 0; + break; + case GRUB_LVM_MIRROR: + for (j = 0; j < lv->segments[i].node_count; j++) + if (is_node_readable (lv->segments[i].nodes + j)) + break; + if (j == lv->segments[i].node_count) + return 0; + default: + return 0; + } + + return 1; +} + + static grub_err_t grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) @@ -332,6 +435,15 @@ grub_lvm_scan_device (const char *name) return 0; } + for (vg = vg_list; vg; vg = vg->next) + for (pv = vg->pvs; pv; pv = pv->next) + if (pv->disk && pv->disk->id == disk->id + && pv->disk->dev->id == disk->dev->id) + { + grub_disk_close (disk); + return 0; + } + /* Search for label. */ for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++) { @@ -857,6 +969,8 @@ grub_lvm_scan_device (const char *name) if (grub_errno == GRUB_ERR_OUT_OF_RANGE) grub_errno = GRUB_ERR_NONE; grub_print_error (); + if (scan_for && find_lv (scan_for)) + return 1; return 0; } @@ -878,13 +992,6 @@ static struct grub_disk_dev grub_lvm_dev = GRUB_MOD_INIT(lvm) { - grub_device_iterate (&grub_lvm_scan_device); - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - grub_disk_dev_register (&grub_lvm_dev); } diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index 114ac0d9e..775234055 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -30,13 +30,18 @@ static char *memdisk_addr; static grub_off_t memdisk_size = 0; static int -grub_memdisk_iterate (int (*hook) (const char *name)) +grub_memdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + return hook ("memdisk"); } static grub_err_t -grub_memdisk_open (const char *name, grub_disk_t disk) +grub_memdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { if (grub_strcmp (name, "memdisk")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 946e6d2c2..78453ac88 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -33,6 +33,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_raid_array *array_list; grub_raid5_recover_func_t grub_raid5_recover_func; grub_raid6_recover_func_t grub_raid6_recover_func; +static grub_raid_t grub_raid_list; +static int inscnt = 0; + +static struct grub_raid_array * +find_array (const char *name); static char @@ -78,14 +83,98 @@ grub_is_array_readable (struct grub_raid_array *array) return 0; } +static grub_err_t +insert_array (grub_disk_t disk, struct grub_raid_array *new_array, + grub_disk_addr_t start_sector, const char *scanner_name, + grub_raid_t raid __attribute__ ((unused))); + +static int scan_depth = 0; + +static void +scan_devices (const char *arname) +{ + grub_raid_t raid; + + auto int hook (const char *name); + int hook (const char *name) + { + grub_disk_t disk; + struct grub_raid_array array; + struct grub_raid_array *arr; + grub_disk_addr_t start_sector; + + grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", + raid->name, name); +#ifdef GRUB_UTIL + grub_util_info ("Scanning for %s RAID devices on disk %s", + raid->name, name); +#endif + + disk = grub_disk_open (name); + if (!disk) + return 0; + + for (arr = array_list; arr != NULL; arr = arr->next) + { + struct grub_raid_member *m; + for (m = arr->members; m < arr->members + arr->nr_devs; m++) + if (m->device && m->device->id == disk->id + && m->device->dev->id == m->device->dev->id) + { + grub_disk_close (disk); + return 0; + } + } + + if ((disk->total_sectors != GRUB_ULONG_MAX) && + (! raid->detect (disk, &array, &start_sector)) && + (! insert_array (disk, &array, start_sector, raid->name, + raid))) + return 0; + + /* This error usually means it's not raid, no need to display + it. */ + if (grub_errno != GRUB_ERR_OUT_OF_RANGE) + grub_print_error (); + + grub_errno = GRUB_ERR_NONE; + + grub_disk_close (disk); + + if (arname && find_array (arname)) + return 1; + + return 0; + } + + if (scan_depth) + return; + + scan_depth++; + for (raid = grub_raid_list; raid; raid = raid->next) + grub_device_iterate (&hook); + scan_depth--; +} + static int -grub_raid_iterate (int (*hook) (const char *name)) +grub_raid_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_raid_array *array; + int islcnt = 0; + + if (pull == GRUB_DISK_PULL_RESCAN) + { + islcnt = inscnt; + scan_devices (NULL); + } + + if (pull != GRUB_DISK_PULL_NONE && pull != GRUB_DISK_PULL_RESCAN) + return 0; for (array = array_list; array != NULL; array = array->next) { - if (grub_is_array_readable (array)) + if (grub_is_array_readable (array) && array->became_readable_at >= islcnt) if (hook (array->name)) return 1; } @@ -134,11 +223,10 @@ ascii2hex (char c) return 0; } -static grub_err_t -grub_raid_open (const char *name, grub_disk_t disk) +static struct grub_raid_array * +find_array (const char *name) { struct grub_raid_array *array; - unsigned n; if (grub_memcmp (name, "mduuid/", sizeof ("mduuid/") - 1) == 0) { @@ -155,7 +243,7 @@ grub_raid_open (const char *name, grub_disk_t disk) if (uuid_len == (unsigned) array->uuid_len && grub_memcmp (uuidbin, array->uuid, uuid_len) == 0) if (grub_is_array_readable (array)) - break; + return array; } } else @@ -163,8 +251,33 @@ grub_raid_open (const char *name, grub_disk_t disk) { if (!grub_strcmp (array->name, name)) if (grub_is_array_readable (array)) - break; + return array; } + return NULL; +} + +static grub_err_t +grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) +{ + struct grub_raid_array *array; + unsigned n; + + if (grub_memcmp (name, "md", sizeof ("md") - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", + name); + + array = find_array (name); + + if (! array && pull == GRUB_DISK_PULL_RESCAN) + { + scan_devices (name); + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + array = find_array (name); + } if (!array) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", @@ -690,15 +803,19 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } /* Add the device to the array. */ - array->members[new_array->index].device = disk; - array->members[new_array->index].start_sector = start_sector; - array->nr_devs++; + { + int was_readable = grub_is_array_readable (array); + + array->members[new_array->index].device = disk; + array->members[new_array->index].start_sector = start_sector; + array->nr_devs++; + if (!was_readable && grub_is_array_readable (array)) + array->became_readable_at = inscnt++; + } return 0; } -static grub_raid_t grub_raid_list; - static void free_array (void) { @@ -729,45 +846,8 @@ free_array (void) void grub_raid_register (grub_raid_t raid) { - auto int hook (const char *name); - int hook (const char *name) - { - grub_disk_t disk; - struct grub_raid_array array; - grub_disk_addr_t start_sector; - - grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", - grub_raid_list->name, name); -#ifdef GRUB_UTIL - grub_util_info ("Scanning for %s RAID devices on disk %s", - grub_raid_list->name, name); -#endif - - disk = grub_disk_open (name); - if (!disk) - return 0; - - if ((disk->total_sectors != GRUB_ULONG_MAX) && - (! grub_raid_list->detect (disk, &array, &start_sector)) && - (! insert_array (disk, &array, start_sector, grub_raid_list->name, - grub_raid_list))) - return 0; - - /* This error usually means it's not raid, no need to display - it. */ - if (grub_errno != GRUB_ERR_OUT_OF_RANGE) - grub_print_error (); - - grub_errno = GRUB_ERR_NONE; - - grub_disk_close (disk); - - return 0; - } - raid->next = grub_raid_list; grub_raid_list = raid; - grub_device_iterate (&hook); } void diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 25f0e3aea..e85036860 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -316,7 +316,8 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, static int -grub_scsi_iterate (int (*hook) (const char *name)) +grub_scsi_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { grub_scsi_dev_t p; @@ -356,6 +357,9 @@ grub_scsi_iterate (int (*hook) (const char *name)) return 0; } + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (p = grub_scsi_dev_list; p; p = p->next) if (p->iterate && (p->iterate) (scsi_iterate)) return 1; @@ -364,7 +368,8 @@ grub_scsi_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_scsi_open (const char *name, grub_disk_t disk) +grub_scsi_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { grub_scsi_dev_t p; grub_scsi_t scsi; diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index d6dc2c22d..929f44587 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -104,8 +104,12 @@ grub_pxe_scan (void) } static int -grub_pxe_iterate (int (*hook) (const char *name)) +grub_pxe_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + if (hook ("pxe")) return 1; return 0; @@ -139,7 +143,8 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) } static grub_err_t -grub_pxe_open (const char *name, grub_disk_t disk) +grub_pxe_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_pxe_disk_data *data; diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 807ee4277..9c2c70b80 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -207,10 +207,16 @@ int grub_disk_dev_iterate (int (*hook) (const char *name)) { grub_disk_dev_t p; + grub_disk_pull_t pull; - for (p = grub_disk_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (hook)) - return 1; + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + { + if (pull == GRUB_DISK_PULL_RESCAN_UNTYPED) + continue; + for (p = grub_disk_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (hook, pull)) + return 1; + } return 0; } @@ -241,6 +247,7 @@ grub_disk_open (const char *name) grub_disk_dev_t dev; char *raw = (char *) name; grub_uint64_t current_time; + grub_disk_pull_t pull; grub_dprintf ("disk", "Opening `%s'...\n", name); @@ -266,15 +273,19 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - - for (dev = grub_disk_dev_list; dev; dev = dev->next) + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) { - if ((dev->open) (raw, disk) == GRUB_ERR_NONE) + for (dev = grub_disk_dev_list; dev; dev = dev->next) + { + if ((dev->open) (raw, disk, pull) == GRUB_ERR_NONE) + break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; + } + if (dev) break; - else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - else - goto fail; } if (! dev) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 63bca37ee..3ee6174d0 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -212,7 +212,8 @@ find_free_slot (void) } static int -grub_util_biosdisk_iterate (int (*hook) (const char *name)) +grub_util_biosdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { unsigned i; @@ -224,7 +225,8 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_util_biosdisk_open (const char *name, grub_disk_t disk) +grub_util_biosdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { int drive; struct stat st; diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..2678ad5eb 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -50,6 +50,15 @@ struct grub_disk; struct grub_disk_memberlist; #endif +typedef enum + { + GRUB_DISK_PULL_NONE, + GRUB_DISK_PULL_REMOVABLE, + GRUB_DISK_PULL_RESCAN, + GRUB_DISK_PULL_RESCAN_UNTYPED, + GRUB_DISK_PULL_MAX + } grub_disk_pull_t; + /* Disk device. */ struct grub_disk_dev { @@ -60,10 +69,12 @@ 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) (int (*hook) (const char *name), + grub_disk_pull_t pull); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*open) (const char *name, struct grub_disk *disk); + grub_err_t (*open) (const char *name, struct grub_disk *disk, + grub_disk_pull_t pull); /* Close the disk DISK. */ void (*close) (struct grub_disk *disk); diff --git a/include/grub/raid.h b/include/grub/raid.h index d5853639d..1eb43721a 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -42,6 +42,7 @@ struct grub_raid_array int number; /* The device number, taken from md_minor so we are consistent with the device name in Linux. */ + int became_readable_at; int level; /* RAID levels, only 0, 1 or 5 at the moment. */ int layout; /* Layout for RAID 5/6. */ unsigned int total_devs; /* Total number of devices in the array. */ From 5dad99b7304b4b2bb0daaa0c379420b4dd1955d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 01:10:24 +0200 Subject: [PATCH 2/7] more linux-like name for LVM volumes --- grub-core/disk/lvm.c | 42 +++++++++++++++++++++++++++--------- grub-core/kern/emu/getroot.c | 10 +++------ include/grub/lvm.h | 2 ++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 72f493540..c430f596d 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -172,7 +172,9 @@ find_lv (const char *name) { if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (! grub_strcmp (lv->name, name) && is_lv_readable (lv)) + if ((grub_strcmp (lv->fullname, name) == 0 + || grub_strcmp (lv->compatname, name) == 0) + && is_lv_readable (lv)) return lv; } return NULL; @@ -188,10 +190,7 @@ grub_lvm_open (const char *name, grub_disk_t disk, int explicit = 0; if (grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0) - { - name += sizeof ("lvm/") - 1; - explicit = 1; - } + explicit = 1; lv = find_lv (name); @@ -685,11 +684,34 @@ grub_lvm_scan_device (const char *name) q++; s = q - p; - lv->name = grub_malloc (vgname_len + 1 + s + 1); - grub_memcpy (lv->name, vgname, vgname_len); - lv->name[vgname_len] = '-'; - grub_memcpy (lv->name + vgname_len + 1, p, s); - lv->name[vgname_len + 1 + s] = '\0'; + lv->name = grub_strndup (p, s); + lv->compatname = grub_malloc (vgname_len + 1 + s + 1); + grub_memcpy (lv->compatname, vgname, vgname_len); + lv->compatname[vgname_len] = '-'; + grub_memcpy (lv->compatname + vgname_len + 1, p, s); + lv->compatname[vgname_len + 1 + s] = '\0'; + + { + const char *iptr; + char *optr; + lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len + + 1 + 2 * s + 1); + optr = lv->fullname; + for (iptr = vgname; iptr < vgname + vgname_len; iptr++) + { + *optr++ = *iptr; + if (*iptr == '-') + *optr++ = '-'; + } + *optr++ = '-'; + for (iptr = p; iptr < p + s; iptr++) + { + *optr++ = *iptr; + if (*iptr == '-') + *optr++ = '-'; + } + *optr++ = 0; + } lv->size = 0; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f836a6625..c780fd94d 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -783,14 +783,10 @@ grub_util_get_grub_dev (const char *os_dev) grub_size_t offset = sizeof ("/dev/mapper/") - 1; len = strlen (os_dev) - offset + 1; - grub_dev = xmalloc (len); + grub_dev = xmalloc (len + sizeof ("lvm/")); - for (i = 0; i < len; i++, offset++) - { - grub_dev[i] = os_dev[offset]; - if (os_dev[offset] == '-' && os_dev[offset + 1] == '-') - offset++; - } + grub_memcpy (grub_dev, "lvm/", sizeof ("lvm/") - 1); + grub_memcpy (grub_dev + sizeof ("lvm/") - 1, os_dev + offset, len); } break; diff --git a/include/grub/lvm.h b/include/grub/lvm.h index b962dfd6c..b5352c75c 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -44,6 +44,8 @@ struct grub_lvm_pv { struct grub_lvm_lv { char *name; + char *fullname; + char *compatname; unsigned int number; unsigned int segment_count; grub_uint64_t size; From 65b4742cd70d15d41483582b454f21144b9ba60e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 02:46:36 +0200 Subject: [PATCH 3/7] Add lost lvm/ prefix. Autoadd lvm subdevices. --- grub-core/disk/lvm.c | 20 ++++++ grub-core/kern/emu/getroot.c | 120 ++++++++++++++++++++++++++--------- include/grub/emu/hostdisk.h | 1 + 3 files changed, 111 insertions(+), 30 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index c430f596d..d104be750 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -26,6 +26,7 @@ #ifdef GRUB_UTIL #include +#include #endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -197,6 +198,16 @@ grub_lvm_open (const char *name, grub_disk_t disk, if (! lv && !scan_depth && pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) { +#ifdef GRUB_UTIL + if (explicit) + { + char buf[grub_strlen (name) + sizeof ("/dev/mapper/")]; + grub_memcpy (buf, "/dev/mapper/", sizeof ("/dev/mapper/")); + grub_strcpy (buf + sizeof ("/dev/mapper/") - 1, + name + sizeof ("lvm/") - 1); + grub_util_pull_device (buf); + } +#endif scan_for = name; scan_depth++; grub_device_iterate (&grub_lvm_scan_device); @@ -685,7 +696,11 @@ grub_lvm_scan_device (const char *name) s = q - p; lv->name = grub_strndup (p, s); + if (!lv->name) + goto lvs_fail; lv->compatname = grub_malloc (vgname_len + 1 + s + 1); + if (!lv->compatname) + goto lvs_fail; grub_memcpy (lv->compatname, vgname, vgname_len); lv->compatname[vgname_len] = '-'; grub_memcpy (lv->compatname + vgname_len + 1, p, s); @@ -696,7 +711,12 @@ grub_lvm_scan_device (const char *name) char *optr; lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len + 1 + 2 * s + 1); + if (!lv->fullname) + goto lvs_fail; + optr = lv->fullname; + grub_memcpy (optr, "lvm/", sizeof ("lvm/") - 1); + optr += sizeof ("lvm/") - 1; for (iptr = vgname; iptr < vgname + vgname_len; iptr++) { *optr++ = *iptr; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index dd277d705..474bb42bc 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -640,6 +640,56 @@ grub_guess_root_device (const char *dir) return os_dev; } +#ifdef HAVE_DEVICE_MAPPER + +static int +grub_util_open_dm (const char *os_dev, struct dm_tree **tree, + struct dm_tree_node **node) +{ + uint32_t maj, min; + struct stat st; + + *node = NULL; + *tree = NULL; + + if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) + return 0; + + if (stat (os_dev, &st) < 0) + return 0; + + *tree = dm_tree_create (); + if (! *tree) + { + grub_printf ("Failed to create tree\n"); + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return 0; + } + + maj = major (st.st_rdev); + min = minor (st.st_rdev); + + if (! dm_tree_add_dev (*tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + dm_tree_free (*tree); + *tree = NULL; + return 0; + } + + *node = dm_tree_find_node (*tree, maj, min); + if (! *node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + dm_tree_free (*tree); + *tree = NULL; + return 0; + } + return 1; +} + +#endif + static int grub_util_is_lvm (const char *os_dev) { @@ -648,40 +698,13 @@ grub_util_is_lvm (const char *os_dev) #ifdef HAVE_DEVICE_MAPPER { - struct dm_tree *tree; - uint32_t maj, min; - struct dm_tree_node *node = NULL; const char *node_uuid; - struct stat st; + struct dm_tree *tree; + struct dm_tree_node *node; - if (stat (os_dev, &st) < 0) + if (!grub_util_open_dm (os_dev, &tree, &node)) return 0; - tree = dm_tree_create (); - if (! tree) - { - grub_printf ("Failed to create tree\n"); - grub_dprintf ("hostdisk", "dm_tree_create failed\n"); - return 0; - } - - maj = major (st.st_rdev); - min = minor (st.st_rdev); - - if (! dm_tree_add_dev (tree, maj, min)) - { - grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); - dm_tree_free (tree); - return 0; - } - - node = dm_tree_find_node (tree, maj, min); - if (! node) - { - grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); - dm_tree_free (tree); - return 0; - } node_uuid = dm_tree_node_get_uuid (node); if (! node_uuid) { @@ -804,6 +827,43 @@ out: } #endif /* __linux__ */ +void +grub_util_pull_device (const char *os_dev) +{ + switch (grub_util_get_dev_abstraction (os_dev)) + { + case GRUB_DEV_ABSTRACTION_LVM: +#ifdef HAVE_DEVICE_MAPPER + { + struct dm_tree *tree; + struct dm_tree_node *node; + struct dm_tree_node *child; + void *handle = NULL; + + if (!grub_util_open_dm (os_dev, &tree, &node)) + return; + + while ((child = dm_tree_next_child (&handle, node, 0))) + { + const struct dm_info *dm = dm_tree_node_get_info (child); + char *subdev; + if (!dm) + continue; + subdev = grub_find_device ("/dev", makedev (dm->major, dm->minor)); + if (subdev) + grub_util_pull_device (subdev); + } + dm_tree_free (tree); + return; + } +#endif + + default: /* GRUB_DEV_ABSTRACTION_NONE */ + grub_util_biosdisk_get_grub_dev (os_dev); + return; + } +} + char * grub_util_get_grub_dev (const char *os_dev) { diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 842dff496..803c0f755 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -29,5 +29,6 @@ const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); +void grub_util_pull_device (const char *osname); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ From 4defebbec8eeae0909c6912d757e2a2f510dae78 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 13:55:30 +0200 Subject: [PATCH 4/7] automatic raid members addition --- Makefile.util.def | 2 +- grub-core/Makefile.core.def | 1 + grub-core/disk/lvm.c | 10 ---------- grub-core/kern/emu/getroot.c | 15 ++++++++++++++- {util => grub-core/kern/emu}/raid.c | 12 +++++++++--- include/grub/emu/getroot.h | 3 +++ include/grub/util/raid.h | 27 --------------------------- util/grub-setup.c | 5 ++--- 8 files changed, 30 insertions(+), 45 deletions(-) rename {util => grub-core/kern/emu}/raid.c (84%) delete mode 100644 include/grub/util/raid.h diff --git a/Makefile.util.def b/Makefile.util.def index 058572f06..40c67c233 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -10,6 +10,7 @@ library = { common = grub-core/kern/device.c; common = grub-core/kern/disk.c; common = grub-core/kern/emu/getroot.c; + common = grub-core/kern/emu/raid.c; common = grub-core/kern/emu/hostdisk.c; common = grub-core/kern/emu/misc.c; common = grub-core/kern/emu/mm.c; @@ -265,7 +266,6 @@ program = { installdir = sbin; mansection = 8; common = util/grub-setup.c; - common = util/raid.c; common = util/lvm.c; common = grub-core/lib/reed_solomon.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f4d38149d..4146e3841 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -165,6 +165,7 @@ kernel = { emu = kern/emu/cache.S; emu = kern/emu/console.c; emu = kern/emu/getroot.c; + emu = kern/emu/raid.c; emu = kern/emu/hostdisk.c; emu = kern/emu/hostfs.c; emu = kern/emu/main.c; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index d104be750..b86cd8023 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -198,16 +198,6 @@ grub_lvm_open (const char *name, grub_disk_t disk, if (! lv && !scan_depth && pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) { -#ifdef GRUB_UTIL - if (explicit) - { - char buf[grub_strlen (name) + sizeof ("/dev/mapper/")]; - grub_memcpy (buf, "/dev/mapper/", sizeof ("/dev/mapper/")); - grub_strcpy (buf + sizeof ("/dev/mapper/") - 1, - name + sizeof ("lvm/") - 1); - grub_util_pull_device (buf); - } -#endif scan_for = name; scan_depth++; grub_device_iterate (&grub_lvm_scan_device); diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 474bb42bc..d9c1c9e08 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -854,9 +854,20 @@ grub_util_pull_device (const char *os_dev) grub_util_pull_device (subdev); } dm_tree_free (tree); - return; } #endif + return; + case GRUB_DEV_ABSTRACTION_RAID: +#ifdef __linux__ + { + char **devicelist = grub_util_raid_getmembers (os_dev, 0); + int i; + for (i = 0; devicelist[i];i++) + grub_util_pull_device (devicelist[i]); + free (devicelist); + } +#endif + return; default: /* GRUB_DEV_ABSTRACTION_NONE */ grub_util_biosdisk_get_grub_dev (os_dev); @@ -869,6 +880,8 @@ grub_util_get_grub_dev (const char *os_dev) { char *grub_dev = NULL; + grub_util_pull_device (os_dev); + switch (grub_util_get_dev_abstraction (os_dev)) { case GRUB_DEV_ABSTRACTION_LVM: diff --git a/util/raid.c b/grub-core/kern/emu/raid.c similarity index 84% rename from util/raid.c rename to grub-core/kern/emu/raid.c index a6aa5f95e..1371117da 100644 --- a/util/raid.c +++ b/grub-core/kern/emu/raid.c @@ -21,7 +21,6 @@ #ifdef __linux__ #include #include -#include #include #include @@ -36,7 +35,7 @@ #include char ** -grub_util_raid_getmembers (const char *name) +grub_util_raid_getmembers (const char *name, int bootable) { int fd, ret, i, j; char **devicelist; @@ -53,7 +52,14 @@ grub_util_raid_getmembers (const char *name) if (ret != 0) grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno)); - if (version.major != 0 || version.minor != 90) + if ((version.major != 0 || version.minor != 90) + && (version.major != 1 || version.minor != 0) + && (version.major != 1 || version.minor != 1) + && (version.major != 1 || version.minor != 2)) + grub_util_error ("unsupported RAID version: %d.%d", + version.major, version.minor); + + if (bootable && (version.major != 0 || version.minor != 90)) grub_util_error ("unsupported RAID version: %d.%d", version.major, version.minor); diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 581ea8056..702903ee6 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -34,5 +34,8 @@ char *grub_util_get_grub_dev (const char *os_dev); char *grub_make_system_path_relative_to_its_root (const char *path); const char *grub_util_check_block_device (const char *blk_dev); const char *grub_util_check_char_device (const char *blk_dev); +#ifdef __linux__ +char **grub_util_raid_getmembers (const char *name, int bootable); +#endif #endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h deleted file mode 100644 index 4da5eaaa8..000000000 --- a/include/grub/util/raid.h +++ /dev/null @@ -1,27 +0,0 @@ -/* raid.h - RAID support for GRUB utils. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_RAID_UTIL_HEADER -#define GRUB_RAID_UTIL_HEADER 1 - -#ifdef __linux__ -char** grub_util_raid_getmembers (const char *name); -#endif - -#endif /* ! GRUB_RAID_UTIL_HEADER */ diff --git a/util/grub-setup.c b/util/grub-setup.c index 7d47fa654..8482e11c9 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef GRUB_MACHINE_IEEE1275 #include @@ -972,12 +971,12 @@ main (int argc, char *argv[]) int i; if (arguments.device[0] == '/') - devicelist = grub_util_raid_getmembers (arguments.device); + devicelist = grub_util_raid_getmembers (arguments.device, 1); else { char *devname; devname = xasprintf ("/dev/%s", dest_dev); - devicelist = grub_util_raid_getmembers (dest_dev); + devicelist = grub_util_raid_getmembers (dest_dev, 1); free (devname); } From 716aa45e40c96ddbe01403faa42355b22a4d4b96 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 14:58:12 +0200 Subject: [PATCH 5/7] Fix LVM listing --- grub-core/disk/lvm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index b86cd8023..ec1780e32 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -129,10 +129,7 @@ grub_lvm_iterate (int (*hook) (const char *name), for (lv = vg->lvs; lv; lv = lv->next) if (lv->visible && lv->number >= old_count) { - char lvname[sizeof ("lvm/") + grub_strlen (lv->name)]; - grub_memcpy (lvname, "lvm/", sizeof ("lvm/") - 1); - grub_strcpy (lvname + sizeof ("lvm/") - 1, lv->name); - if (hook (lvname)) + if (hook (lv->fullname)) return 1; } } From b094f07c2364b616452639db9184d9411f376f38 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:39:21 +0200 Subject: [PATCH 6/7] Don't set was_readable for new array --- grub-core/disk/raid.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 78453ac88..27a57d7fc 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -637,6 +637,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_raid_t raid __attribute__ ((unused))) { struct grub_raid_array *array = 0, *p; + int was_readable = 0; /* See whether the device is part of an array we have already seen a device from. */ @@ -647,6 +648,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_free (new_array->uuid); array = p; + was_readable = grub_is_array_readable (array); + /* Do some checks before adding the device to the array. */ if (new_array->index >= array->allocated_devs) @@ -803,15 +806,11 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } /* Add the device to the array. */ - { - int was_readable = grub_is_array_readable (array); - - array->members[new_array->index].device = disk; - array->members[new_array->index].start_sector = start_sector; - array->nr_devs++; - if (!was_readable && grub_is_array_readable (array)) - array->became_readable_at = inscnt++; - } + array->members[new_array->index].device = disk; + array->members[new_array->index].start_sector = start_sector; + array->nr_devs++; + if (!was_readable && grub_is_array_readable (array)) + array->became_readable_at = inscnt++; return 0; } From 0044d1db2e43943112aac3f3482e97d66584e645 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 7 Jul 2011 21:46:25 +0200 Subject: [PATCH 7/7] Simplify disk opening --- grub-core/disk/arc/arcdisk.c | 6 +++++- grub-core/disk/ata.c | 3 +-- grub-core/disk/efi/efidisk.c | 3 +-- grub-core/disk/host.c | 3 +-- grub-core/disk/i386/pc/biosdisk.c | 3 +-- grub-core/disk/ieee1275/nand.c | 3 +-- grub-core/disk/ieee1275/ofdisk.c | 3 +-- grub-core/disk/loopback.c | 3 +-- grub-core/disk/lvm.c | 6 ++---- grub-core/disk/memdisk.c | 3 +-- grub-core/disk/raid.c | 4 ++-- grub-core/disk/scsi.c | 3 +-- grub-core/kern/disk.c | 28 +++++++++------------------- grub-core/kern/emu/hostdisk.c | 3 +-- include/grub/disk.h | 4 +--- 15 files changed, 29 insertions(+), 49 deletions(-) diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index 7dff30931..170bf521d 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -79,7 +79,8 @@ arcdisk_hash_add (char *devpath) static int -grub_arcdisk_iterate (int (*hook_in) (const char *name)) +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) @@ -90,6 +91,9 @@ grub_arcdisk_iterate (int (*hook_in) (const char *name)) return 0; return hook_in (name); } + if (pull != GRUB_DISK_PULL_NONE) + return 0; + return grub_arc_iterate_devs (hook, 1); } diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 9a09ee158..8add7f4de 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -412,8 +412,7 @@ grub_ata_iterate (int (*hook_in) (const char *name), } static grub_err_t -grub_ata_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_ata_open (const char *name, grub_disk_t disk) { unsigned id, bus; struct grub_ata *ata; diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 4ae1d7bb9..85969cc1d 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -454,8 +454,7 @@ get_device (struct grub_efidisk_data *devices, int num) } static grub_err_t -grub_efidisk_open (const char *name, struct grub_disk *disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_efidisk_open (const char *name, struct grub_disk *disk) { int num; struct grub_efidisk_data *d = 0; diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c index 5376cc6ce..5ee0d2e56 100644 --- a/grub-core/disk/host.c +++ b/grub-core/disk/host.c @@ -39,8 +39,7 @@ grub_host_iterate (int (*hook) (const char *name), } static grub_err_t -grub_host_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_host_open (const char *name, grub_disk_t disk) { if (grub_strcmp (name, "host")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 1198d4305..e152b9d89 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -328,8 +328,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_biosdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_biosdisk_open (const char *name, grub_disk_t disk) { grub_uint64_t total_sectors = 0; int drive; diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c index 4be5b5641..94d62bc4f 100644 --- a/grub-core/disk/ieee1275/nand.c +++ b/grub-core/disk/ieee1275/nand.c @@ -58,8 +58,7 @@ grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf); static grub_err_t -grub_nand_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_nand_open (const char *name, grub_disk_t disk) { grub_ieee1275_ihandle_t dev_ihandle = 0; struct grub_nand_data *data = 0; diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 7b7db3a08..2cd43d80a 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -233,8 +233,7 @@ compute_dev_path (const char *name) } static grub_err_t -grub_ofdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_ofdisk_open (const char *name, grub_disk_t disk) { grub_ieee1275_phandle_t dev; char *devpath; diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 21345af57..dca83b7c6 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -148,8 +148,7 @@ grub_loopback_iterate (int (*hook) (const char *name), } static grub_err_t -grub_loopback_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_loopback_open (const char *name, grub_disk_t disk) { struct grub_loopback *dev; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 9e304c001..06e9f6d6a 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -181,8 +181,7 @@ find_lv (const char *name) static const char *scan_for = NULL; static grub_err_t -grub_lvm_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull) +grub_lvm_open (const char *name, grub_disk_t disk) { struct grub_lvm_lv *lv = NULL; int explicit = 0; @@ -192,8 +191,7 @@ grub_lvm_open (const char *name, grub_disk_t disk, lv = find_lv (name); - if (! lv && !scan_depth && - pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) + if (! lv && !scan_depth && explicit) { scan_for = name; scan_depth++; diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index 775234055..ed570c6a0 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -40,8 +40,7 @@ grub_memdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_memdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_memdisk_open (const char *name, grub_disk_t disk) { if (grub_strcmp (name, "memdisk")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index a7d36bfb2..5d8326daf 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -257,7 +257,7 @@ find_array (const char *name) } static grub_err_t -grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) +grub_raid_open (const char *name, grub_disk_t disk) { struct grub_raid_array *array; unsigned n; @@ -268,7 +268,7 @@ grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) array = find_array (name); - if (! array && pull == GRUB_DISK_PULL_RESCAN) + if (! array) { scan_devices (name); if (grub_errno) diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 5ab5177e9..610cc4dc5 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -371,8 +371,7 @@ grub_scsi_iterate (int (*hook) (const char *name), } static grub_err_t -grub_scsi_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_scsi_open (const char *name, grub_disk_t disk) { grub_scsi_dev_t p; grub_scsi_t scsi; diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 022157434..5584030bd 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -206,13 +206,9 @@ grub_disk_dev_iterate (int (*hook) (const char *name)) grub_disk_pull_t pull; for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) - { - if (pull == GRUB_DISK_PULL_RESCAN_UNTYPED) - continue; - for (p = grub_disk_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (hook, pull)) - return 1; - } + for (p = grub_disk_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (hook, pull)) + return 1; return 0; } @@ -243,7 +239,6 @@ grub_disk_open (const char *name) grub_disk_dev_t dev; char *raw = (char *) name; grub_uint64_t current_time; - grub_disk_pull_t pull; grub_dprintf ("disk", "Opening `%s'...\n", name); @@ -270,19 +265,14 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + for (dev = grub_disk_dev_list; dev; dev = dev->next) { - for (dev = grub_disk_dev_list; dev; dev = dev->next) - { - if ((dev->open) (raw, disk, pull) == GRUB_ERR_NONE) - break; - else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - else - goto fail; - } - if (dev) + if ((dev->open) (raw, disk) == GRUB_ERR_NONE) break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; } if (! dev) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index a2f9ce084..59d7a4a2c 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -227,8 +227,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_util_biosdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_util_biosdisk_open (const char *name, grub_disk_t disk) { int drive; struct stat st; diff --git a/include/grub/disk.h b/include/grub/disk.h index efa27a4d2..2b6d02972 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -56,7 +56,6 @@ typedef enum GRUB_DISK_PULL_NONE, GRUB_DISK_PULL_REMOVABLE, GRUB_DISK_PULL_RESCAN, - GRUB_DISK_PULL_RESCAN_UNTYPED, GRUB_DISK_PULL_MAX } grub_disk_pull_t; @@ -74,8 +73,7 @@ struct grub_disk_dev grub_disk_pull_t pull); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*open) (const char *name, struct grub_disk *disk, - grub_disk_pull_t pull); + grub_err_t (*open) (const char *name, struct grub_disk *disk); /* Close the disk DISK. */ void (*close) (struct grub_disk *disk);