From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 14:44:13 +0000 (+0100) Subject: merge mainline into nestpart X-Git-Tag: 1.99~1005^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9ea504d256817e4b4afc8b1126569c279e3d19a;p=thirdparty%2Fgrub.git merge mainline into nestpart --- c9ea504d256817e4b4afc8b1126569c279e3d19a diff --cc conf/i386-pc.rmk index 02675be91,c662d75cc..024db4822 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@@ -94,20 -75,21 +75,21 @@@ util/grub-mkrawimage.c_DEPENDENCIES = M util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ util/i386/pc/grub-setup.c util/hostdisk.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/list.c kern/fs.c kern/env.c fs/fshelp.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/msdos.c partmap/gpt.c \ + partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c \ + util/raid.c util/lvm.c \ grub_setup_init.c sbin_SCRIPTS += grub-install diff --cc conf/sparc64-ieee1275.rmk index a428c14d1,0bb8ff8b4..78e511e31 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@@ -78,11 -61,11 +61,11 @@@ grub_setup_SOURCES = util/sparc64/ieee1 fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/amiga.c partmap/apple.c partmap/msdos.c \ - partmap/sun.c partmap/acorn.c \ + partmap/amiga.c partmap/apple.c partmap/msdos.c \ + partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c gnulib/progname.c \ + util/raid.c util/lvm.c gnulib/progname.c \ grub_setup_init.c # For grub-ofpathname. diff --cc include/grub/partition.h index 9feb9459d,faa89cea6..80a9c15f0 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@@ -74,39 -77,12 +74,25 @@@ int EXPORT_FUNC(grub_partition_iterate const grub_partition_t partition)); char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); -int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap)); -void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); +extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); -void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); +static inline void +grub_partition_map_register (grub_partition_map_t partmap) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); +} + +static inline void +grub_partition_map_unregister (grub_partition_map_t partmap) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); +} + +#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next) - #ifdef GRUB_UTIL - void grub_msdos_partition_map_init (void); - void grub_msdos_partition_map_fini (void); - void grub_amiga_partition_map_init (void); - void grub_amiga_partition_map_fini (void); - void grub_apple_partition_map_init (void); - void grub_apple_partition_map_fini (void); - void grub_sun_partition_map_init (void); - void grub_sun_partition_map_fini (void); - void grub_gpt_partition_map_init (void); - void grub_gpt_partition_map_fini (void); - void grub_apple_partition_map_init (void); - void grub_apple_partition_map_fini (void); - #endif static inline grub_disk_addr_t grub_partition_get_start (const grub_partition_t p) diff --cc partmap/acorn.c index f3b36106e,d9b26b9e2..677ec61d5 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@@ -130,11 -182,13 +130,11 @@@ acorn_partition_map_iterate (grub_disk_ /* Partition map type. */ static struct grub_partition_map grub_acorn_partition_map = { - .name = "part_acorn", + .name = "acorn", .iterate = acorn_partition_map_iterate, - .probe = acorn_partition_map_probe, - .get_name = acorn_partition_map_get_name }; - GRUB_MOD_INIT(acorn_partition_map) + GRUB_MOD_INIT(part_acorn) { grub_partition_map_register (&grub_acorn_partition_map); } diff --cc partmap/amiga.c index b5fba0dbc,d96f6e9d0..f21c5b243 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@@ -136,11 -191,13 +136,11 @@@ amiga_partition_map_iterate (grub_disk_ /* Partition map type. */ static struct grub_partition_map grub_amiga_partition_map = { - .name = "part_amiga", + .name = "amiga", .iterate = amiga_partition_map_iterate, - .probe = amiga_partition_map_probe, - .get_name = amiga_partition_map_get_name }; - GRUB_MOD_INIT(amiga_partition_map) + GRUB_MOD_INIT(part_amiga) { grub_partition_map_register (&grub_amiga_partition_map); } diff --cc partmap/apple.c index b9d3e9174,92e10a793..e162d18d7 --- a/partmap/apple.c +++ b/partmap/apple.c @@@ -181,11 -234,13 +181,11 @@@ apple_partition_map_iterate (grub_disk_ /* Partition map type. */ static struct grub_partition_map grub_apple_partition_map = { - .name = "part_apple", + .name = "apple", .iterate = apple_partition_map_iterate, - .probe = apple_partition_map_probe, - .get_name = apple_partition_map_get_name }; - GRUB_MOD_INIT(apple_partition_map) + GRUB_MOD_INIT(part_apple) { grub_partition_map_register (&grub_apple_partition_map); } diff --cc partmap/bsdlabel.c index f4df7e1fa,000000000..d28f36d07 mode 100644,000000..100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@@ -1,97 -1,0 +1,97 @@@ +/* bsdlabel.c - Read BSD style partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2006,2007,2008,2009 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 . + */ + +#include +#include +#include +#include +#include +#include + +static struct grub_partition_map grub_bsdlabel_partition_map; + + +static grub_err_t +bsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition_bsd_disk_label label; + struct grub_partition p; + grub_disk_addr_t delta = 0; + unsigned pos; + + /* BSDLabel offsets are absolute even when it's embed inside partition. */ + delta = grub_partition_get_start (disk->partition); + + /* Read the BSD label. */ + if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, + 0, sizeof (label), &label)) + return grub_errno; + + /* Check if it is valid. */ + if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR + * GRUB_DISK_SECTOR_SIZE; + + for (p.number = 0; + p.number < grub_cpu_to_le16 (label.num_partitions); + p.number++) + { + struct grub_partition_bsd_entry be; + + p.offset = pos / GRUB_DISK_SECTOR_SIZE; + p.index = pos % GRUB_DISK_SECTOR_SIZE; + + if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be)) + return grub_errno; + + p.start = grub_le_to_cpu32 (be.offset) - delta; + p.len = grub_le_to_cpu32 (be.size); + p.partmap = &grub_bsdlabel_partition_map; + + if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + if (hook (disk, &p)) + return grub_errno; + + pos += sizeof (struct grub_partition_bsd_entry); + } + + return GRUB_ERR_NONE; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_bsdlabel_partition_map = + { + .name = "bsd", + .iterate = bsdlabel_partition_map_iterate, + }; + - GRUB_MOD_INIT(bsd_partition_map) ++GRUB_MOD_INIT(part_bsd) +{ + grub_partition_map_register (&grub_bsdlabel_partition_map); +} + - GRUB_MOD_FINI(bsd_partition_map) ++GRUB_MOD_FINI(part_bsd) +{ + grub_partition_map_unregister (&grub_bsdlabel_partition_map); +} diff --cc partmap/gpt.c index 8b799d4d5,3cf8a3e7a..9dd88bec1 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@@ -112,11 -169,13 +112,11 @@@ gpt_partition_map_iterate (grub_disk_t /* Partition map type. */ static struct grub_partition_map grub_gpt_partition_map = { - .name = "part_gpt", + .name = "gpt", .iterate = gpt_partition_map_iterate, - .probe = gpt_partition_map_probe, - .get_name = gpt_partition_map_get_name }; - GRUB_MOD_INIT(gpt_partition_map) + GRUB_MOD_INIT(part_gpt) { grub_partition_map_register (&grub_gpt_partition_map); } diff --cc partmap/msdos.c index bafd86eb6,fb69fb335..3898d09fa --- a/partmap/msdos.c +++ b/partmap/msdos.c @@@ -137,11 -315,13 +137,11 @@@ pc_partition_map_iterate (grub_disk_t d /* Partition map type. */ static struct grub_partition_map grub_msdos_partition_map = { - .name = "part_msdos", + .name = "msdos", .iterate = pc_partition_map_iterate, - .probe = pc_partition_map_probe, - .get_name = pc_partition_map_get_name }; - GRUB_MOD_INIT(pc_partition_map) + GRUB_MOD_INIT(part_msdos) { grub_partition_map_register (&grub_msdos_partition_map); } diff --cc partmap/sun.c index f3801bc88,1c45cb388..7a7eaef27 --- a/partmap/sun.c +++ b/partmap/sun.c @@@ -148,11 -153,62 +148,11 @@@ sun_partition_map_iterate (grub_disk_t /* Partition map type. */ static struct grub_partition_map grub_sun_partition_map = { - .name = "part_sun", + .name = "sun", .iterate = sun_partition_map_iterate, - .probe = sun_partition_map_probe, - .get_name = sun_partition_map_get_name }; - GRUB_MOD_INIT(sun_partition_map) + GRUB_MOD_INIT(part_sun) { grub_partition_map_register (&grub_sun_partition_map); } diff --cc parttool/msdospart.c index 57921f35f,6ce48a977..006a87def --- a/parttool/msdospart.c +++ b/parttool/msdospart.c @@@ -138,12 -138,12 +138,12 @@@ static grub_err_t grub_pcpart_type (con return GRUB_ERR_NONE; } - GRUB_MOD_INIT (pcpart) + GRUB_MOD_INIT (msdospart) { - activate_table_handle = grub_parttool_register ("part_msdos", + activate_table_handle = grub_parttool_register ("msdos", grub_pcpart_boot, grub_pcpart_bootargs); - type_table_handle = grub_parttool_register ("part_msdos", + type_table_handle = grub_parttool_register ("msdos", grub_pcpart_type, grub_pcpart_typeargs); diff --cc util/hostdisk.c index 9ecb5b324,0f51a7a0b..61cc7b9d2 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@@ -334,30 -379,44 +379,47 @@@ open_device (const grub_disk_t disk, gr { int is_partition = 0; char dev[PATH_MAX]; + grub_disk_addr_t part_start = 0; + + part_start = grub_partition_get_start (disk->partition); strcpy (dev, map[disk->id].device); - if (disk->partition && sector >= disk->partition->start + if (disk->partition && sector >= part_start && strncmp (map[disk->id].device, "/dev/", 5) == 0) - is_partition = linux_find_partition (dev, disk->partition->start); + is_partition = linux_find_partition (dev, part_start); - /* Open the partition. */ - grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); - fd = open (dev, flags); - if (fd < 0) + if (data->dev && strcmp (data->dev, dev) == 0 && + data->access_mode == (flags & O_ACCMODE)) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); - return -1; + grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev); + fd = data->fd; + } + else + { + free (data->dev); + if (data->fd != -1) + close (data->fd); + + /* Open the partition. */ + grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); + fd = open (dev, flags); + if (fd < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); + return -1; + } + + /* Flush the buffer cache to the physical disk. + XXX: This also empties the buffer cache. */ + ioctl (fd, BLKFLSBUF, 0); + + data->dev = xstrdup (dev); + data->access_mode = (flags & O_ACCMODE); + data->fd = fd; } - - /* Flush the buffer cache to the physical disk. - XXX: This also empties the buffer cache. */ - ioctl (fd, BLKFLSBUF, 0); if (is_partition) - sector -= disk->partition->start; + sector -= part_start; } #else /* ! __linux__ */ #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) @@@ -984,24 -1071,39 +1074,24 @@@ grub_util_biosdisk_get_grub_dev (const struct hd_geometry hdg; int dos_part = -1; int bsd_part = -1; - auto int find_partition (grub_disk_t disk, + auto int find_partition (grub_disk_t dsk, const grub_partition_t partition); - int find_partition (grub_disk_t disk __attribute__ ((unused)), + int find_partition (grub_disk_t dsk __attribute__ ((unused)), const grub_partition_t partition) { - struct grub_msdos_partition *pcdata = NULL; - - if (strcmp (partition->partmap->name, "part_msdos") == 0) - pcdata = partition->data; + grub_disk_addr_t part_start = 0; + grub_util_info ("Partition %d starts from %lu", + partition->number, partition->start); - if (pcdata) - { - if (pcdata->bsd_part < 0) - grub_util_info ("DOS partition %d starts from %lu", - pcdata->dos_part, partition->start); - else - grub_util_info ("BSD partition %d,%c starts from %lu", - pcdata->dos_part, pcdata->bsd_part + 'a', - partition->start); - } - else - { - grub_util_info ("Partition %d starts from %lu", - partition->index, partition->start); - } + part_start = grub_partition_get_start (partition); - if (hdg.start == partition->start) + if (hdg.start == part_start) { - if (pcdata) + if (partition->parent) { - dos_part = pcdata->dos_part; - bsd_part = pcdata->bsd_part; + dos_part = partition->parent->number; + bsd_part = partition->number; } else {