* kern/emu/hostdisk.c: Include <sys/ioctl.h> and <sys/disklabel.h>

on FreeBSD.  Define HAVE_DIOCGDINFO on NetBSD and FreeBSD to reduce
the verbosity of later #ifs.
(find_partition_start): Define this function on FreeBSD too.
(device_is_wholedisk) [__FreeBSD__ || __FreeBSD_kernel__]: New
function.
(grub_util_biosdisk_get_grub_dev): Use partition-start-sector logic
on FreeBSD.
This commit is contained in:
Colin Watson 2010-09-20 12:12:33 +01:00
parent 6439b8ee81
commit a63c31b62d
2 changed files with 65 additions and 61 deletions

View file

@ -1,3 +1,14 @@
2010-09-20 Colin Watson <cjwatson@ubuntu.com>
* kern/emu/hostdisk.c: Include <sys/ioctl.h> and <sys/disklabel.h>
on FreeBSD. Define HAVE_DIOCGDINFO on NetBSD and FreeBSD to reduce
the verbosity of later #ifs.
(find_partition_start): Define this function on FreeBSD too.
(device_is_wholedisk) [__FreeBSD__ || __FreeBSD_kernel__]: New
function.
(grub_util_biosdisk_get_grub_dev): Use partition-start-sector logic
on FreeBSD.
2010-09-20 Yves Blusseau <blusseau@zetam.org> 2010-09-20 Yves Blusseau <blusseau@zetam.org>
* util/grub-editenv.c: Use argp instead of getopt. * util/grub-editenv.c: Use argp instead of getopt.

View file

@ -102,9 +102,15 @@ struct hd_geometry
# include <libdevmapper.h> # include <libdevmapper.h>
#endif #endif
#if defined(__NetBSD__) #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
# define HAVE_DIOCGDINFO
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */ # include <sys/disklabel.h> /* struct disklabel */
#else /* !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) */
# undef HAVE_DIOCGDINFO
#endif /* defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
#if defined(__NetBSD__)
# ifdef HAVE_GETRAWPARTITION # ifdef HAVE_GETRAWPARTITION
# include <util.h> /* getrawpartition */ # include <util.h> /* getrawpartition */
# endif /* HAVE_GETRAWPARTITION */ # endif /* HAVE_GETRAWPARTITION */
@ -328,17 +334,17 @@ device_is_mapped (const char *dev)
} }
#endif /* HAVE_DEVICE_MAPPER */ #endif /* HAVE_DEVICE_MAPPER */
#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) #if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
static grub_disk_addr_t static grub_disk_addr_t
find_partition_start (const char *dev) find_partition_start (const char *dev)
{ {
int fd; int fd;
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
struct hd_geometry hdg; struct hd_geometry hdg;
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
struct disklabel label; struct disklabel label;
int p_index; int p_index;
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
# ifdef HAVE_DEVICE_MAPPER # ifdef HAVE_DEVICE_MAPPER
if (grub_device_mapper_supported () && device_is_mapped (dev)) { if (grub_device_mapper_supported () && device_is_mapped (dev)) {
@ -412,36 +418,38 @@ devmapper_fail:
if (fd == -1) if (fd == -1)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
"cannot open `%s' while attempting to get disk geometry", dev); "cannot open `%s' while attempting to get disk geometry", dev);
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
"cannot open `%s' while attempting to get disk label", dev); "cannot open `%s' while attempting to get disk label", dev);
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
return 0; return 0;
} }
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
if (ioctl (fd, HDIO_GETGEO, &hdg)) if (ioctl (fd, HDIO_GETGEO, &hdg))
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
# if defined(__NetBSD__)
configure_device_driver (fd); configure_device_driver (fd);
# endif /* defined(__NetBSD__) */
if (ioctl (fd, DIOCGDINFO, &label) == -1) if (ioctl (fd, DIOCGDINFO, &label) == -1)
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
{ {
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
"cannot get disk geometry of `%s'", dev); "cannot get disk geometry of `%s'", dev);
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
"cannot get disk label of `%s'", dev); "cannot get disk label of `%s'", dev);
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
close (fd); close (fd);
return 0; return 0;
} }
close (fd); close (fd);
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
return hdg.start; return hdg.start;
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
p_index = dev[strlen(dev) - 1] - 'a'; p_index = dev[strlen(dev) - 1] - 'a';
if (p_index >= label.d_npartitions) if (p_index >= label.d_npartitions)
@ -451,9 +459,9 @@ devmapper_fail:
return 0; return 0;
} }
return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; return (grub_disk_addr_t) label.d_partitions[p_index].p_offset;
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
} }
#endif /* __linux__ || __CYGWIN__ */ #endif /* __linux__ || __CYGWIN__ || HAVE_DIOCGDINFO */
#ifdef __linux__ #ifdef __linux__
/* Cache of partition start sectors for each disk. */ /* Cache of partition start sectors for each disk. */
@ -996,8 +1004,7 @@ grub_util_biosdisk_fini (void)
/* /*
* Note: we do not use the new partition naming scheme as dos_part does not * Note: we do not use the new partition naming scheme as dos_part does not
* necessarily correspond to an msdos partition. See e.g. the FreeBSD code * necessarily correspond to an msdos partition.
* in function grub_util_biosdisk_get_grub_dev.
*/ */
static char * static char *
make_device_name (int drive, int dos_part, int bsd_part) make_device_name (int drive, int dos_part, int bsd_part)
@ -1349,6 +1356,27 @@ device_is_wholedisk (const char *os_dev)
} }
#endif /* defined(__NetBSD__) */ #endif /* defined(__NetBSD__) */
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int
device_is_wholedisk (const char *os_dev)
{
const char *p;
if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return 0;
for (p = os_dev + sizeof ("/dev/") - 1; *p; ++p)
if (grub_isdigit (*p))
{
if (strchr (p, 's'))
return 0;
break;
}
return 1;
}
#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
static int static int
find_system_device (const char *os_dev, struct stat *st, int add) find_system_device (const char *os_dev, struct stat *st, int add)
{ {
@ -1422,7 +1450,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
#endif #endif
return make_device_name (drive, -1, -1); return make_device_name (drive, -1, -1);
#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) #if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS /* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial. partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and Here, get the start sector of a partition by HDIO_GETGEO, and
@ -1432,8 +1460,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
does not count the extended partition and missing primary does not count the extended partition and missing primary
partitions. Use same method as on Linux here. partitions. Use same method as on Linux here.
For NetBSD, proceed as for Linux, except that the start sector is For NetBSD and FreeBSD, proceed as for Linux, except that the start
obtained from the disk label. */ sector is obtained from the disk label. */
{ {
char *name, *partname; char *name, *partname;
grub_disk_t disk; grub_disk_t disk;
@ -1461,13 +1489,13 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
name = make_device_name (drive, -1, -1); name = make_device_name (drive, -1, -1);
# if !defined(__NetBSD__) # if !defined(HAVE_DIOCGDINFO)
if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
return name; return name;
# else /* defined(__NetBSD__) */ # else /* defined(HAVE_DIOCGDINFO) */
/* Since os_dev and convert_system_partition_to_system_disk (os_dev) are /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
* different, we know that os_dev cannot be a floppy device. */ * different, we know that os_dev cannot be a floppy device. */
# endif /* !defined(__NetBSD__) */ # endif /* !defined(HAVE_DIOCGDINFO) */
start = find_partition_start (os_dev); start = find_partition_start (os_dev);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
@ -1536,41 +1564,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return make_device_name (drive, dos_part, bsd_part); return make_device_name (drive, dos_part, bsd_part);
} }
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
/* FreeBSD uses "/dev/[a-z]+[0-9]+([sp][0-9]+[a-z]?)?". */
{
int dos_part = -1;
int bsd_part = -1;
if (strncmp ("/dev/", os_dev, 5) == 0)
{
const char *p;
char *q;
long int n;
for (p = os_dev + 5; *p; ++p)
if (grub_isdigit(*p))
{
p = strpbrk (p, "sp"); /* msdos or apple (or ... ?) partition map */
if (p)
{
p++;
n = strtol (p, &q, 10);
if (p != q && n != GRUB_LONG_MIN && n != GRUB_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 #else
# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly." # warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
return make_device_name (drive, -1, -1); return make_device_name (drive, -1, -1);