diff --git a/ChangeLog b/ChangeLog index a8e3e5284..c388ebd27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,59 @@ +2010-05-31 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use + GRUB_DISK_SIZE_UNKNOWN. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. + +2010-05-31 Jiro SEKIBA + + * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. + * fs/nilfs.c: Support 2nd super block in case 1st one is accidently + corrupted or not synced properly. + +2010-05-31 Vladimir Serbinenko + + * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. + Reported by: Seth Goldberg. + +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect + addition of dest. + Reported by: Seth Goldberg. + +2010-05-31 Vladimir Serbinenko + + * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. + Reported by: Seth Goldberg. + +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check + 64-bit address as signed on MIPS. + +2010-05-28 Colin Watson + + * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not + to the empty string. + +2010-05-28 BVK Chaitanya + + Fix grub-emu issues on NetBSD, with gcc 4.1.3. + + * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. + * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. + * kern/misc.c (__enable_execute_stack): Disable on + GRUB_MACHINE_EMU. + +2010-05-28 Colin Watson + + Make grub-probe work with symbolic links under /dev/mapper as well + as with real block devices. The Linux world seems to be (at best) + in transition here, and GRUB shouldn't get caught in the middle. + + * kern/emu/getroot.c (find_root_device): Follow symbolic links under + /dev/mapper. + 2010-05-27 Colin Watson * util/grub-script-check.c (main): Ensure defined behaviour on empty diff --git a/commands/setpci.c b/commands/setpci.c index fbc7c214e..aa09f5bbb 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -96,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (check_device && grub_pci_get_device (dev) != device) return 0; - if (check_function && grub_pci_get_function (dev) != device) + if (check_function && grub_pci_get_function (dev) != function) return 0; addr = grub_pci_make_address (dev, regaddr); diff --git a/configure.ac b/configure.ac index 54622e5e9..12f89d85e 100644 --- a/configure.ac +++ b/configure.ac @@ -194,7 +194,7 @@ AC_PROG_LEX AC_PROG_MAKE_SET AC_PROG_MKDIR_P -if test "x$LEX" = x; then +if test "x$LEX" = "x:"; then AC_MSG_ERROR([flex is not found]) else version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 94d0e3708..f82f91ff0 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; - total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ + /* TODO: get the correct size. */ + total_sectors = GRUB_DISK_SIZE_UNKNOWN; } else if (drive & 0x80) { diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index e5a4a67fa..d0d9e894f 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) /* XXX: There is no property to read the number of blocks. There should be a property `#blocks', but it is not there. Perhaps it is possible to use seek for this. */ - disk->total_sectors = 0xFFFFFFFFUL; + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; disk->id = (unsigned long) op; diff --git a/fs/nilfs2.c b/fs/nilfs2.c index 7e0415d12..5d32f5f88 100644 --- a/fs/nilfs2.c +++ b/fs/nilfs2.c @@ -49,6 +49,13 @@ #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_MAX 14 +/* nilfs 1st super block posission from beginning of the partition + in 512 block size */ +#define NILFS_1ST_SUPER_BLOCK 2 +/* nilfs 2nd super block posission from end of the partition + in 512 block size */ +#define NILFS_2ND_SUPER_BLOCK 8 + struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) return 1; } +static grub_err_t +grub_nilfs2_load_sb (struct grub_nilfs2_data *data) +{ + grub_disk_t disk = data->disk; + struct grub_nilfs2_super_block sb2; + grub_uint64_t partition_size; + int valid[2]; + int swp = 0; + + /* Read first super block. */ + grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &data->sblock); + /* Make sure if 1st super block is valid. */ + valid[0] = grub_nilfs2_valid_sb (&data->sblock); + + partition_size = grub_disk_get_size (disk); + if (partition_size != GRUB_DISK_SIZE_UNKNOWN) + { + /* Read second super block. */ + grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &sb2); + /* Make sure if 2nd super block is valid. */ + valid[1] = grub_nilfs2_valid_sb (&sb2); + } + else + /* 2nd super block may not exist, so it's invalid. */ + valid[1] = 0; + + + + if (!valid[0] && !valid[1]) + return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + swp = valid[1] && (!valid[0] || + grub_le_to_cpu64 (data->sblock.s_last_cno) < + grub_le_to_cpu64 (sb2.s_last_cno)); + + /* swap if first super block is invalid or older than second one. */ + if (swp) + grub_memcpy (&data->sblock, &sb2, + sizeof (struct grub_nilfs2_super_block)); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + static struct grub_nilfs2_data * grub_nilfs2_mount (grub_disk_t disk) { @@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk) if (!data) return 0; + data->disk = disk; + /* Read the superblock. */ - grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), - &data->sblock); + grub_nilfs2_load_sb (data); if (grub_errno) goto fail; - /* Make sure this is an nilfs2 filesystem. */ - if (!grub_nilfs2_valid_sb (&data->sblock)) - { - grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); - goto fail; - } - nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); /* Read the last segment summary. */ @@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk) if (grub_errno) goto fail; - data->disk = disk; - grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); if (grub_errno) diff --git a/include/grub/disk.h b/include/grub/disk.h index e60b1f3de..e7f807e0e 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_BITS 3 +/* Return value of grub_disk_get_size() in case disk size is unknown. */ +#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 82b4c9124..bad00de71 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -47,6 +47,6 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); #endif char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); -char * canonicalize_file_name (const char *path); +extern char * canonicalize_file_name (const char *path); #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..e62abe089 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -126,9 +126,20 @@ find_root_device (const char *dir, dev_t dev) /* Ignore any error. */ continue; - if (S_ISLNK (st.st_mode)) - /* Don't follow symbolic links. */ + if (S_ISLNK (st.st_mode)) { +#ifdef __linux__ + if (strcmp (dir, "mapper") == 0) { + /* Follow symbolic links under /dev/mapper/; the canonical name + may be something like /dev/dm-0, but the names under + /dev/mapper/ are more human-readable and so we prefer them if + we can get them. */ + if (stat (ent->d_name, &st) < 0) + continue; + } else +#endif /* __linux__ */ + /* Don't follow other symbolic links. */ continue; + } if (S_ISDIR (st.st_mode)) { diff --git a/kern/misc.c b/kern/misc.c index be50c671b..2ba34f235 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1075,3 +1075,4 @@ void __deregister_frame_info (void) { } #endif + diff --git a/loader/multiboot_elfxx.c b/loader/multiboot_elfxx.c index 92a52d3a8..78b7c542c 100644 --- a/loader/multiboot_elfxx.c +++ b/loader/multiboot_elfxx.c @@ -74,7 +74,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); -#ifdef MULTIBOOT_LOAD_ELF64 +#if defined (MULTIBOOT_LOAD_ELF64) && defined (__mips) + /* We still in 32-bit mode. */ + if (ehdr->e_entry < 0xffffffff80000000ULL) + return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); +#else /* We still in 32-bit mode. */ if (ehdr->e_entry > 0xffffffff) return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 7e9cebe49..c9e52e51f 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, = (struct multiboot_tag_module *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; - tag->mod_start = dest + cur->start; + tag->mod_start = cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); diff --git a/normal/main.c b/normal/main.c index 2d493b897..b3544b99f 100644 --- a/normal/main.c +++ b/normal/main.c @@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args, for (i = 0; i < argc; i++) { /* Capture arguments. */ - if (grub_strncmp ("--", args[i], 2) == 0) + if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc) { const char *arg = &args[i][2];