2010-08-04 Robert Millan <rmh@gnu.org>

* configure.ac: Remove checks for getfsstat() and getmntany().
	Add checks for `<sys/param.h>' and `<sys/mount.h>'.
	* kern/emu/misc.c [HAVE_GETMNTANY]: Remove `<sys/mnttab.h>'.
	[HAVE_SYS_PARAM_H]: Include `<sys/param.h>'.
	[HAVE_SYS_MOUNT_H]: Include `<sys/mount.h>'.
	[HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove
	function.
	(grub_find_zpool_from_dir): Use statfs() instead of indirect matching
	via find_mount_point_from_dir() and getfsstat() / getmntany().
This commit is contained in:
Robert Millan 2010-08-04 14:45:58 +02:00
parent 0de22aa997
commit d3dd9e80f6
3 changed files with 23 additions and 111 deletions

View File

@ -1,3 +1,15 @@
2010-08-04 Robert Millan <rmh@gnu.org>
* configure.ac: Remove checks for getfsstat() and getmntany().
Add checks for `<sys/param.h>' and `<sys/mount.h>'.
* kern/emu/misc.c [HAVE_GETMNTANY]: Remove `<sys/mnttab.h>'.
[HAVE_SYS_PARAM_H]: Include `<sys/param.h>'.
[HAVE_SYS_MOUNT_H]: Include `<sys/mount.h>'.
[HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove
function.
(grub_find_zpool_from_dir): Use statfs() instead of indirect matching
via find_mount_point_from_dir() and getfsstat() / getmntany().
2010-08-04 Robert Millan <rmh@gnu.org>
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)

View File

@ -247,8 +247,8 @@ else
fi
# Check for functions and headers.
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat getmntany)
AC_CHECK_HEADERS(libzfs.h libnvpair.h)
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h)
# For opendisk() and getrawpartition() on NetBSD.
# Used in util/deviceiter.c and in util/hostdisk.c.

View File

@ -32,10 +32,6 @@
#include <limits.h>
#endif
#ifdef HAVE_GETMNTANY
# include <sys/mnttab.h>
#endif
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/env.h>
@ -57,7 +53,11 @@
# include <grub/util/libnvpair.h>
#endif
#ifdef HAVE_GETFSSTAT
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
@ -276,120 +276,20 @@ grub_get_libzfs_handle (void)
#endif /* HAVE_LIBZFS */
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
/* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */
static char *
find_mount_point_from_dir (const char *dir)
{
struct stat st;
typeof (st.st_dev) fs;
char *prev, *next, *slash, *statdir;
if (stat (dir, &st) == -1)
error (1, errno, "stat (%s)", dir);
fs = st.st_dev;
prev = xstrdup (dir);
while (1)
{
/* Remove last slash. */
next = xstrdup (prev);
slash = strrchr (next, '/');
if (! slash)
{
free (next);
free (prev);
return NULL;
}
*slash = '\0';
/* A next empty string counts as /. */
if (next[0] == '\0')
statdir = "/";
else
statdir = next;
if (stat (statdir, &st) == -1)
error (1, errno, "stat (%s)", next);
if (st.st_dev != fs)
{
/* Found mount point. */
free (next);
return prev;
}
free (prev);
prev = next;
/* We've already seen an empty string, which means we
reached /. Nothing left to do. */
if (prev[0] == '\0')
{
free (prev);
return xstrdup ("/");
}
}
}
/* ZFS has similar problems to those of btrfs (see above). */
void
grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs)
{
struct statfs mnt;
char *slash;
char *mnt_point;
*poolname = *poolfs = NULL;
mnt_point = find_mount_point_from_dir (dir);
#if defined(HAVE_GETFSSTAT) /* FreeBSD and GNU/kFreeBSD */
{
int mnt_count = getfsstat (NULL, 0, MNT_WAIT);
if (mnt_count == -1)
error (1, errno, "getfsstat");
struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt));
mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT);
if (mnt_count == -1)
error (1, errno, "getfsstat");
unsigned int i;
for (i = 0; i < (unsigned) mnt_count; i++)
if (!strcmp (mnt[i].f_fstypename, "zfs")
&& !strcmp (mnt[i].f_mntonname, mnt_point))
{
*poolname = xstrdup (mnt[i].f_mntfromname);
break;
}
free (mnt);
}
#elif defined(HAVE_GETMNTANY) /* OpenSolaris */
{
FILE *mnttab = fopen ("/etc/mnttab", "r");
struct mnttab mp;
struct mnttab mpref =
{
.mnt_special = NULL,
.mnt_mountp = mnt_point,
.mnt_fstype = "zfs",
.mnt_mntopts = NULL,
.mnt_time = NULL,
};
if (getmntany (mnttab, &mp, &mpref) == 0)
*poolname = xstrdup (mp.mnt_special);
fclose (mnttab);
}
#endif
if (! *poolname)
if (statfs (dir, &mnt) != 0)
return;
*poolname = xstrdup (mnt.f_mntfromname);
slash = strchr (*poolname, '/');
if (slash)
{