diff --git a/ChangeLog b/ChangeLog index 7e18ca0f5..76b709dad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2009-04-11 Andrey Shuvikov + + * util/hostdisk.c [__FreeBSD__]: Include sys/disk.h. + (grub_util_biosdisk_open) [__FreeBSD__]: Add support for + FreeBSD. Check if a device is a character device. Use + DIOCGMEDIASIZE to get the size. + (convert_system_partition_to_system_disk) [__FreeBSD__]: Add + support for FreeBSD. + (grub_util_biosdisk_get_grub_dev) [__FreeBSD__]: Check if OS_DEV + is a character device instead of a block device. Add support for + FreeBSD device names. + + * util/getroot.c (find_root_device) [__FreeBSD__]: Check if ENT is + a character device instead of a block device. + (grub_util_check_char_device): New function. + + * util/grub-probe.c (probe) [__FreeBSD__]: Check if DEVICE_NAME is + a character device instead of a block device. + + * include/grub/util/getroot.h (grub_util_check_char_device): New + prototype. + 2009-04-11 David S. Miller * conf/sparc64-ieee1275.rmk (kernel_img_LDFLAGS): Link with diff --git a/config.h.in b/config.h.in index e825f7c41..1a9ed6878 100644 --- a/config.h.in +++ b/config.h.in @@ -4,6 +4,9 @@ prefixed with an asterisk */ #undef ABSOLUTE_WITHOUT_ASTERISK +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + /* Define it to \"addr32\" or \"addr32;\" to make GAS happy */ #undef ADDR32 @@ -118,17 +121,52 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -#undef WORDS_BIGENDIAN - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/include/grub/util/getroot.h b/include/grub/util/getroot.h index bf0c55ca4..f9f7f9baa 100644 --- a/include/grub/util/getroot.h +++ b/include/grub/util/getroot.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2003, 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 @@ -30,5 +30,6 @@ char *grub_get_prefix (const char *dir); int grub_util_get_dev_abstraction (const char *os_dev); char *grub_util_get_grub_dev (const char *os_dev); const char *grub_util_check_block_device (const char *blk_dev); +const char *grub_util_check_char_device (const char *blk_dev); #endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/util/getroot.c b/util/getroot.c index e88354e07..daed9124a 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1,7 +1,7 @@ /* getroot.c - Get root device */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,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 @@ -238,7 +238,11 @@ find_root_device (const char *dir, dev_t dev) } } +#ifdef __FreeBSD__ + if (S_ISCHR (st.st_mode) && st.st_rdev == dev) +#else if (S_ISBLK (st.st_mode) && st.st_rdev == dev) +#endif { #ifdef __linux__ /* Skip device names like /dev/dm-0, which are short-hand aliases @@ -519,3 +523,18 @@ grub_util_check_block_device (const char *blk_dev) else return 0; } + +const char * +grub_util_check_char_device (const char *blk_dev) +{ + struct stat st; + + if (stat (blk_dev, &st) < 0) + grub_util_error ("Cannot stat `%s'", blk_dev); + + if (S_ISCHR (st.st_mode)) + return (blk_dev); + else + return 0; +} + diff --git a/util/grub-probe.c b/util/grub-probe.c index 4811d7b9e..194c62bb7 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -1,7 +1,7 @@ /* grub-probe.c - probe device information for a given path */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 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 @@ -112,8 +112,13 @@ probe (const char *path, char *device_name) if (path == NULL) { +#if defined(__FreeBSD__) + if (! grub_util_check_char_device (device_name)) + grub_util_error ("%s is not a character device.\n", device_name); +#else if (! grub_util_check_block_device (device_name)) grub_util_error ("%s is not a block device.\n", device_name); +#endif } else device_name = grub_guess_root_device (path); diff --git a/util/hostdisk.c b/util/hostdisk.c index bea3fb98f..001777e8e 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -1,7 +1,7 @@ /* biosdisk.c - emulate biosdisk */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,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 @@ -86,6 +86,10 @@ struct hd_geometry # define FLOPPY_MAJOR 2 #endif +#ifdef __FreeBSD__ +# include /* DIOCGMEDIASIZE */ +#endif + struct { char *drive; @@ -179,7 +183,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } -#elif defined(__linux__) || defined(__CYGWIN__) +#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) { unsigned long long nr; int fd; @@ -188,13 +192,21 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) if (fd == -1) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); +# if defined(__FreeBSD__) + if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode)) +# else if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) +# endif { close (fd); goto fail; } +# if defined(__FreeBSD__) + if (ioctl (fd, DIOCGMEDIASIZE, &nr)) +# else if (ioctl (fd, BLKGETSIZE64, &nr)) +# endif { close (fd); goto fail; @@ -746,6 +758,22 @@ convert_system_partition_to_system_disk (const char *os_dev) path[8] = 0; return path; +#elif defined(__FreeBSD__) + char *path = xstrdup (os_dev); + if (strncmp ("/dev/", path, 5) == 0) + { + char *p; + for (p = path + 5; *p; ++p) + if (grub_isdigit(*p)) + { + p = strchr (p, 's'); + if (p) + *p = '\0'; + break; + } + } + return path; + #else # warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly." return xstrdup (os_dev); @@ -793,7 +821,11 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } +#if defined(__FreeBSD__) + if (! S_ISCHR (st.st_mode)) +#else if (! S_ISBLK (st.st_mode)) +#endif return make_device_name (drive, -1, -1); #if defined(__linux__) || defined(__CYGWIN__) @@ -938,6 +970,40 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return make_device_name (drive, dos_part, bsd_part); } +#elif defined(__FreeBSD__) + /* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?". */ + { + int dos_part = -1; + int bsd_part = -1; + + if (strncmp ("/dev/", os_dev, 5) == 0) + { + char *p, *q; + long int n; + + for (p = os_dev + 5; *p; ++p) + if (grub_isdigit(*p)) + { + p = strchr (p, 's'); + if (p) + { + p++; + n = strtol (p, &q, 10); + if (p != q && n != LONG_MIN && n != LONG_MAX) + { + dos_part = (int) n - 1; + + if (*q >= 'a' && *q <= 'g') + bsd_part = *q - 'a'; + } + } + break; + } + } + + return make_device_name (drive, dos_part, bsd_part); + } + #else # warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly." return make_device_name (drive, -1, -1);