From 4ace38464ec58623dbf061eedb9d34a4f4acfb8b Mon Sep 17 00:00:00 2001 From: robertmh Date: Thu, 20 Apr 2006 13:46:46 +0000 Subject: [PATCH] Fixes for kernel of FreeBSD: * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl before opening a device for writing. * util/grub-install.in: Devices don't have this "r" prefix anymore. --- ChangeLog | 7 +++++++ grub/asmstub.c | 33 ++++++++++++++++++++++++++++++++- util/grub-install.in | 4 ++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d61cabc9b..c7eedd910 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-04-20 Robert Millan + + Fixes for kernel of FreeBSD: + * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl + before opening a device for writing. + * util/grub-install.in: Devices don't have this "r" prefix anymore. + 2006-04-16 Yoshinori K. Okuji * docs/multiboot.texi: Correct the offset of address diff --git a/grub/asmstub.c b/grub/asmstub.c index ab95b4b6f..0ded179ca 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -55,6 +55,10 @@ int grub_stage2 (void); # endif /* ! BLKFLSBUF */ #endif /* __linux__ */ +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) +# include +#endif + /* We want to prevent any circularararity in our stubs, as well as libc name clashes. */ #define WITHOUT_LIBC_STUBS 1 @@ -777,7 +781,34 @@ get_diskinfo (int drive, struct geometry *geometry) /* Open read/write, or read-only if that failed. */ if (! read_only) - disks[drive].flags = open (devname, O_RDWR); + { +/* By default, kernel of FreeBSD does not allow overwriting MBR */ +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) +#define GEOM_SYSCTL "kern.geom.debugflags" + int old_flags, flags; + size_t sizeof_int = sizeof (int); + + if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0) + grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); + + if ((old_flags & 0x10) == 0) + { + /* "allow foot shooting", see geom(4) */ + flags = old_flags | 0x10; + + if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0) + grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); + } +#endif + disks[drive].flags = open (devname, O_RDWR); +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) + if (flags != old_flags) + { + if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0) + grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); + } +#endif + } if (disks[drive].flags == -1) { diff --git a/util/grub-install.in b/util/grub-install.in index 2e598b05f..39d6cb0f3 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -112,8 +112,8 @@ convert () { tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'` tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;; freebsd* | kfreebsd*-gnu) - tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \ - | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'` + tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \ + | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'` tmp_part=`echo "$1" \ | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \ | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`