* New Bazaar snapshot.

- Add btrfs probing support, currently only in the single-device case
    (closes: #540786).
  - Fix grub-emu build on mips/powerpc/sparc.
This commit is contained in:
Colin Watson 2010-06-02 01:31:43 +01:00
commit 5d918965eb
17 changed files with 253 additions and 65 deletions

View File

@ -1,3 +1,73 @@
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include
kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes.
2010-06-01 Colin Watson <cjwatson@ubuntu.com>
Add btrfs probing support, currently only in the single-device case.
* kern/emu/getroot.c (find_root_device_from_mountinfo): New
function.
(grub_guess_root_device): Call find_root_device_from_mountinfo
before looking in /dev.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* 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 <jir@unicus.jp>
* 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 <phcoder@gmail.com>
* normal/main.c (grub_normal_add_menu_entry): Avoid going out of args.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect
addition of dest.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* commands/setpci.c (grub_setpci_iter): Fix an incorrect function check.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check
64-bit address as signed on MIPS.
2010-05-28 Colin Watson <cjwatson@ubuntu.com>
* configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not
to the empty string.
2010-05-28 BVK Chaitanya <bvk.groups@gmail.com>
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 <cjwatson@ubuntu.com>
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 <cjwatson@ubuntu.com> 2010-05-27 Colin Watson <cjwatson@ubuntu.com>
* util/grub-script-check.c (main): Ensure defined behaviour on empty * util/grub-script-check.c (main): Ensure defined behaviour on empty

View File

@ -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) if (check_device && grub_pci_get_device (dev) != device)
return 0; return 0;
if (check_function && grub_pci_get_function (dev) != device) if (check_function && grub_pci_get_function (dev) != function)
return 0; return 0;
addr = grub_pci_make_address (dev, regaddr); addr = grub_pci_make_address (dev, regaddr);

View File

@ -1,7 +1,5 @@
# -*- makefile -*- # -*- makefile -*-
COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)
kernel_img_RELOCATABLE = yes kernel_img_RELOCATABLE = yes
pkglib_PROGRAMS = kernel.img pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \
@ -22,14 +20,14 @@ TARGET_NO_STRIP = yes
ifneq ($(TARGET_NO_MODULES), yes) ifneq ($(TARGET_NO_MODULES), yes)
kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c
else
kernel_img_SOURCES += grub_emu_init.c
endif
ifneq ($(target_cpu), i386) ifneq ($(target_cpu), i386)
ifneq ($(target_cpu), x86_64) ifneq ($(target_cpu), x86_64)
kernel_img_SOURCES += kern/$(target_cpu)/cache.S kernel_img_SOURCES += kern/$(target_cpu)/cache.S
endif endif
endif endif
else
kernel_img_SOURCES += grub_emu_init.c
endif
# For halt.mod. # For halt.mod.
pkglib_MODULES += halt.mod pkglib_MODULES += halt.mod

View File

@ -192,7 +192,7 @@ AC_PROG_LEX
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_MKDIR_P AC_PROG_MKDIR_P
if test "x$LEX" = x; then if test "x$LEX" = "x:"; then
AC_MSG_ERROR([flex is not found]) AC_MSG_ERROR([flex is not found])
else else
version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`

8
debian/changelog vendored
View File

@ -1,5 +1,11 @@
grub2 (1.98+20100527-3) UNRELEASED; urgency=low grub2 (1.98+20100602-1) UNRELEASED; urgency=low
* New Bazaar snapshot.
- Add btrfs probing support, currently only in the single-device case
(closes: #540786).
- Fix grub-emu build on mips/powerpc/sparc.
[ Colin Watson ]
* Reorganise configure and build targets in debian/rules to use stamp * Reorganise configure and build targets in debian/rules to use stamp
files. configure/* never existed and build/* was always a directory, so files. configure/* never existed and build/* was always a directory, so
make never considered either of them up to date (closes: #450505). make never considered either of them up to date (closes: #450505).

View File

@ -1,37 +0,0 @@
Description: Make grub-probe work with symlinks under /dev/mapper
Previously, real block devices were more common here, but the Linux world
seems to be moving towards symlinks. GRUB shouldn't get caught in the
middle and should just work with both.
Author: Colin Watson <cjwatson@ubuntu.com>
Bug-Debian: http://bugs.debian.org/550704
Forwarded: http://lists.gnu.org/archive/html/grub-devel/2010-05/msg00196.html
Applied-Upstream: http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/2403
Last-Update: 2010-05-28
Index: b/kern/emu/getroot.c
===================================================================
--- a/kern/emu/getroot.c
+++ b/kern/emu/getroot.c
@@ -126,9 +126,20 @@
/* 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))
{

View File

@ -7,4 +7,3 @@
904_disable_floppies.diff 904_disable_floppies.diff
907_grub.cfg_400.diff 907_grub.cfg_400.diff
908_gfxpayload_keep_default.diff 908_gfxpayload_keep_default.diff
909_mapper_symlink.diff

View File

@ -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->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
data->sectors = 32; 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) else if (drive & 0x80)
{ {

View File

@ -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 /* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */ is possible to use seek for this. */
disk->total_sectors = 0xFFFFFFFFUL; disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
disk->id = (unsigned long) op; disk->id = (unsigned long) op;

View File

@ -49,6 +49,13 @@
#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
#define NILFS_BTREE_LEVEL_MAX 14 #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 struct grub_nilfs2_inode
{ {
grub_uint64_t i_blocks; grub_uint64_t i_blocks;
@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
return 1; 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 * static struct grub_nilfs2_data *
grub_nilfs2_mount (grub_disk_t disk) grub_nilfs2_mount (grub_disk_t disk)
{ {
@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk)
if (!data) if (!data)
return 0; return 0;
data->disk = disk;
/* Read the superblock. */ /* Read the superblock. */
grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), grub_nilfs2_load_sb (data);
&data->sblock);
if (grub_errno) if (grub_errno)
goto fail; 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)); nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
/* Read the last segment summary. */ /* Read the last segment summary. */
@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk)
if (grub_errno) if (grub_errno)
goto fail; goto fail;
data->disk = disk;
grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
if (grub_errno) if (grub_errno)

View File

@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
#define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_SIZE 8
#define GRUB_DISK_CACHE_BITS 3 #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. */ /* This is called from the memory manager. */
void grub_disk_cache_invalidate_all (void); void grub_disk_cache_invalidate_all (void);

View File

@ -46,5 +46,6 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...);
#endif #endif
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
extern char * canonicalize_file_name (const char *path);
#endif /* GRUB_EMU_MISC_H */ #endif /* GRUB_EMU_MISC_H */

View File

@ -80,6 +80,86 @@ xgetcwd (void)
return path; return path;
} }
#ifdef __linux__
/* Statting something on a btrfs filesystem always returns a virtual device
major/minor pair rather than the real underlying device, because btrfs
can span multiple underlying devices (and even if it's currently only
using a single device it can be dynamically extended onto another). We
can't deal with the multiple-device case yet, but in the meantime, we can
at least cope with the single-device case by scanning
/proc/self/mountinfo. */
static char *
find_root_device_from_mountinfo (const char *dir)
{
FILE *fp;
char *buf = NULL;
size_t len = 0;
char *ret = NULL;
fp = fopen ("/proc/self/mountinfo", "r");
if (! fp)
return NULL; /* fall through to other methods */
while (getline (&buf, &len, fp) > 0)
{
int mnt_id, parent_mnt_id;
unsigned int major, minor;
char enc_root[PATH_MAX], enc_path[PATH_MAX];
int count;
size_t enc_path_len;
const char *sep;
char fstype[PATH_MAX], device[PATH_MAX];
struct stat st;
if (sscanf (buf, "%d %d %u:%u %s %s%n",
&mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path,
&count) < 6)
continue;
if (strcmp (enc_root, "/") != 0)
continue; /* only a subtree is mounted */
enc_path_len = strlen (enc_path);
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
(dir[enc_path_len] && dir[enc_path_len] != '/'))
continue;
/* This is a parent of the requested directory. /proc/self/mountinfo
is in mount order, so it must be the closest parent we've
encountered so far. If it's virtual, return its device node;
otherwise, carry on to try to find something closer. */
free (ret);
ret = NULL;
if (major != 0)
continue; /* not a virtual device */
sep = strstr (buf + count, " - ");
if (!sep)
continue;
sep += sizeof (" - ") - 1;
if (sscanf (sep, "%s %s", fstype, device) != 2)
continue;
if (stat (device, &st) < 0)
continue;
if (!S_ISBLK (st.st_mode))
continue; /* not a block device */
ret = strdup (device);
}
free (buf);
fclose (fp);
return ret;
}
#endif /* __linux__ */
#ifdef __MINGW32__ #ifdef __MINGW32__
static char * static char *
@ -126,9 +206,20 @@ find_root_device (const char *dir, dev_t dev)
/* Ignore any error. */ /* Ignore any error. */
continue; continue;
if (S_ISLNK (st.st_mode)) if (S_ISLNK (st.st_mode)) {
/* Don't follow symbolic links. */ #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; continue;
}
if (S_ISDIR (st.st_mode)) if (S_ISDIR (st.st_mode))
{ {
@ -355,6 +446,12 @@ grub_guess_root_device (const char *dir)
#else /* !__GNU__ */ #else /* !__GNU__ */
struct stat st; struct stat st;
#ifdef __linux__
os_dev = find_root_device_from_mountinfo (dir);
if (os_dev)
return os_dev;
#endif /* __linux__ */
if (stat (dir, &st) < 0) if (stat (dir, &st) < 0)
grub_util_error ("cannot stat `%s'", dir); grub_util_error ("cannot stat `%s'", dir);

View File

@ -1058,7 +1058,7 @@ grub_abort (void)
void abort (void) __attribute__ ((alias ("grub_abort"))); void abort (void) __attribute__ ((alias ("grub_abort")));
#endif #endif
#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) #if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
/* Some gcc versions generate a call to this function /* Some gcc versions generate a call to this function
in trampolines for nested functions. */ in trampolines for nested functions. */
void __enable_execute_stack (void *addr __attribute__ ((unused))) void __enable_execute_stack (void *addr __attribute__ ((unused)))
@ -1075,3 +1075,4 @@ void __deregister_frame_info (void)
{ {
} }
#endif #endif

View File

@ -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) 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"); 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. */ /* We still in 32-bit mode. */
if (ehdr->e_entry > 0xffffffff) if (ehdr->e_entry > 0xffffffff)
return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");

View File

@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
= (struct multiboot_tag_module *) ptrorig; = (struct multiboot_tag_module *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->type = MULTIBOOT_TAG_TYPE_MODULE;
tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; 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; tag->mod_end = tag->mod_start + cur->size;
grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);

View File

@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
/* Capture arguments. */ /* 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]; const char *arg = &args[i][2];