* Makefile.util.def (grub-mkimage): Add LIBGEOM to ldadd.
(grub-mkrelpath): Likewise.
(grub-script-check): Likewise.
(grub-editenv): Likewise.
(grub-mkpasswd-pbkdf2): Likewise.
(grub-fstest): Likewise.
(grub-mkfont): Likewise.
(grub-mkdevicemap): Likewise.
(grub-probe): Likewise.
(grub-setup): Likewise.
(grub-ofpathname): Likewise.
(grub-mklayout): Likewise.
(example_unit_test): Likewise.
(grub-menulst2cfg): Likewise.
* grub-core/Makefile.core.def (grub-emu): Likewise.
(grub-emu-lite): Likewise.
* configure.ac: Check for -lgeom on FreeBSD and set LIBGEOM.
* grub-core/kern/emu/hostdisk.c [FreeBSD]: Include libgeom.h. Don't
define HAVE_DIOCGDINFO.
(follow_geom_up) [FreeBSD]: New function.
(find_partition_start) [FreeBSD]: Rewritten using follow_geom_up.
(convert_system_partition_to_system_disk) [FreeBSD]: Likewise.
(grub_util_biosdisk_get_grub_dev) [FreeBSD]: Use FreeBSD path
unconditionally of HAVE_DIOCGDINFO.
+2011-03-26 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Use libgeom on FreeBSD to detect partitions.
+
+ * Makefile.util.def (grub-mkimage): Add LIBGEOM to ldadd.
+ (grub-mkrelpath): Likewise.
+ (grub-script-check): Likewise.
+ (grub-editenv): Likewise.
+ (grub-mkpasswd-pbkdf2): Likewise.
+ (grub-fstest): Likewise.
+ (grub-mkfont): Likewise.
+ (grub-mkdevicemap): Likewise.
+ (grub-probe): Likewise.
+ (grub-setup): Likewise.
+ (grub-ofpathname): Likewise.
+ (grub-mklayout): Likewise.
+ (example_unit_test): Likewise.
+ (grub-menulst2cfg): Likewise.
+ * grub-core/Makefile.core.def (grub-emu): Likewise.
+ (grub-emu-lite): Likewise.
+ * configure.ac: Check for -lgeom on FreeBSD and set LIBGEOM.
+ * grub-core/kern/emu/hostdisk.c [FreeBSD]: Include libgeom.h. Don't
+ define HAVE_DIOCGDINFO.
+ (follow_geom_up) [FreeBSD]: New function.
+ (find_partition_start) [FreeBSD]: Rewritten using follow_geom_up.
+ (convert_system_partition_to_system_disk) [FreeBSD]: Likewise.
+ (grub_util_biosdisk_get_grub_dev) [FreeBSD]: Use FreeBSD path
+ unconditionally of HAVE_DIOCGDINFO.
+
2011-03-26 Vladimir Serbinenko <phcoder@gmail.com>
Fix FreeBSD compilation problem.
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBLZMA)';
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"';
};
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)';
};
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(freetype_libs)';
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_GRUB_MKFONT;
};
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = i386_pc;
enable = sparc64_ieee1275;
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)';
enable = sparc64_ieee1275;
};
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
data = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
AC_SUBST([LIBDEVMAPPER])
+LIBGEOM=
+if test x$host_kernel = xkfreebsd; then
+ AC_CHECK_LIB([geom], [geom_gettree], [],
+ [AC_MSG_ERROR([Your platform requires libgeom])])
+ LIBGEOM="-lgeom"
+fi
+
+AC_SUBST([LIBGEOM])
+
AC_CHECK_LIB([lzma], [lzma_code],
[LIBLZMA="-llzma"
AC_DEFINE([HAVE_LIBLZMA], [1],
ldadd = 'kernel.img$(EXEEXT)';
ldadd = '$(MODULE_FILES)';
- ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
emu_nodist = symlist.c;
ldadd = 'kernel.img$(EXEEXT)';
- ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
+ ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
# include <libdevmapper.h>
#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <libgeom.h>
+#elif defined(__NetBSD__)
# define HAVE_DIOCGDINFO
# include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */
}
#endif /* HAVE_DEVICE_MAPPER */
-#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+/* FIXME: geom actually gives us the whole container hierarchy.
+ It can be used more efficiently than this. */
+static void
+follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
+{
+ struct gmesh mesh;
+ struct gclass *class;
+ int error;
+ struct ggeom *geom;
+
+ grub_util_info ("following geom '%s'", name);
+
+ error = geom_gettree (&mesh);
+ if (error != 0)
+ grub_util_error ("couldn't open geom");
+
+ LIST_FOREACH (class, &mesh.lg_class, lg_class)
+ if (strcasecmp (class->lg_name, "part") == 0)
+ break;
+ if (!class)
+ grub_util_error ("couldn't open geom part");
+
+ LIST_FOREACH (geom, &class->lg_geom, lg_geom)
+ {
+ struct gprovider *provider;
+ LIST_FOREACH (provider, &geom->lg_provider, lg_provider)
+ if (strcmp (provider->lg_name, name) == 0)
+ {
+ char *name_tmp = xstrdup (geom->lg_name);
+ grub_disk_addr_t off = 0;
+ struct gconfig *config;
+ grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name);
+
+ follow_geom_up (name_tmp, &off, name_out);
+ free (name_tmp);
+ LIST_FOREACH (config, &provider->lg_config, lg_config)
+ if (strcasecmp (config->lg_name, "start") == 0)
+ off += strtoull (config->lg_val, 0, 10);
+ if (off_out)
+ *off_out = off;
+ return;
+ }
+ }
+ grub_util_info ("geom '%s' has no parent", name);
+ if (name_out)
+ *name_out = xstrdup (name);
+ if (off_out)
+ *off_out = 0;
+}
+
+static grub_disk_addr_t
+find_partition_start (const char *dev)
+{
+ grub_disk_addr_t out;
+ if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0)
+ return 0;
+ follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL);
+
+ return out;
+}
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
static grub_disk_addr_t
find_partition_start (const char *dev)
{
path[8] = 0;
return path;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ char *out, *out2;
+ if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
+ return xstrdup (os_dev);
+ follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out);
+
+ out2 = xasprintf ("/dev/%s", out);
+ free (out);
+
+ return out2;
+#elif defined(__APPLE__)
char *path = xstrdup (os_dev);
if (strncmp ("/dev/", path, 5) == 0)
{
#endif
return make_device_name (drive, -1, -1);
-#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
+#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and