]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2010-08-01 Robert Millan <rmh@gnu.org>
authorRobert Millan <rmh@aybabtu.com>
Sun, 1 Aug 2010 20:59:02 +0000 (22:59 +0200)
committerRobert Millan <rmh@aybabtu.com>
Sun, 1 Aug 2010 20:59:02 +0000 (22:59 +0200)
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
(grub_find_zpool_from_mount_point): New function prototypes.

* kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
* kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.

* kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
* kern/emu/misc.c (grub_find_mount_point_from_dir): ... this.  Remove
`static' attribute.

* kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
finding zpool from mount point into ...
* kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.

* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
requested path is part of a ZFS pool, use
grub_find_zpool_from_mount_point() to detect its filesystem name,
and generate a path with `/fsname@path' syntax.

ChangeLog
include/grub/emu/misc.h
kern/emu/getroot.c
kern/emu/misc.c

index daf5517dc788852fd0f3f8549f3aac6d38b5f21f..2956129b3332be2f09ab252fef488311bbeb1a3d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2010-08-01  Robert Millan  <rmh@gnu.org>
+
+       * include/grub/emu/misc.h (grub_find_mount_point_from_dir)
+       (grub_find_zpool_from_mount_point): New function prototypes.
+
+       * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
+       * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
+
+       * kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
+       * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this.  Remove
+       `static' attribute.
+
+       * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
+       finding zpool from mount point into ...
+       * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
+
+       * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
+       requested path is part of a ZFS pool, use
+       grub_find_zpool_from_mount_point() to detect its filesystem name,
+       and generate a path with `/fsname@path' syntax.
+
 2010-08-01  Colin Watson  <cjwatson@ubuntu.com>
 
        * include/grub/util/libzfs.h (libzfs_init): Set argument list to
 
        * kern/misc.c (grub_memset): Optimise to reduce cache stalls.
 
+2010-08-01  Robert Millan  <rmh@gnu.org>
+
+       * include/grub/emu/misc.h (grub_find_mount_point_from_dir)
+       (grub_find_zpool_from_mount_point): New function prototypes.
+
+       * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
+       * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
+
+       * kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
+       * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this.  Remove
+       `static' attribute.
+
+       * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
+       finding zpool from mount point into ...
+       * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
+
+       * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
+       requested path is part of a ZFS pool, use
+       grub_find_zpool_from_mount_point() to detect its filesystem name,
+       and generate a path with `/fsname@path' syntax.
+
 2010-08-01  Robert Millan  <rmh@gnu.org>
 
        Prevent accidental use of uninitialized libzfs_handle.
index dc48d91a8fdc104c6e4095331a5a6961dcba0725..5047a940652112995a63c03c98d5c3608948d54a 100644 (file)
@@ -44,7 +44,13 @@ extern const char *program_name;
 void grub_init_all (void);
 void grub_fini_all (void);
 
-char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result));
+char *grub_find_mount_point_from_dir (const char *dir)
+  __attribute__ ((warn_unused_result));
+void grub_find_zpool_from_mount_point (const char *mnt_point,
+                                      char **poolname, char **poolfs);
+
+char *grub_make_system_path_relative_to_its_root (const char *path)
+  __attribute__ ((warn_unused_result));
 
 void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result));
 void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result));
index 032608d1bc983176a732f0e5a918125f545af644..32044536da72149a3dd2a2218e421c5edf6b8103 100644 (file)
 # include <grub/util/libnvpair.h>
 #endif
 
-#ifdef HAVE_GETFSSTAT
-# include <sys/mount.h>
-#endif
-
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/emu/misc.h>
@@ -98,66 +94,6 @@ xgetcwd (void)
   return path;
 }
 
-#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
-
-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 ("/");
-       }
-    }
-}
-
-#endif
-
 #ifdef __linux__
 
 /* Statting something on a btrfs filesystem always returns a virtual device
@@ -239,52 +175,20 @@ find_root_device_from_mountinfo (const char *dir)
 #endif /* __linux__ */
 
 #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
-
-/* ZFS has similar problems to those of btrfs (see above).  */
 static char *
 find_root_device_from_libzfs (const char *dir)
 {
-  char *device = NULL;
-  char *poolname = NULL;
-  char *poolfs = NULL;
+  char *device;
+  char *poolname;
+  char *poolfs;
   char *mnt_point;
-  char *slash;
-
-  mnt_point = find_mount_point_from_dir (dir);
-
-#ifdef HAVE_GETFSSTAT
-  {
-    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);
-  }
-#endif
 
+  mnt_point = grub_find_mount_point_from_dir (dir);
+  grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
   if (! poolname)
-    return NULL;
-
-  slash = strchr (poolname, '/');
-  if (slash)
     {
-      *slash = '\0';
-      poolfs = slash + 1;
+      free (mnt_point);
+      return NULL;
     }
 
   {
@@ -317,6 +221,8 @@ find_root_device_from_libzfs (const char *dir)
   }
 
   free (poolname);
+  if (poolfs)
+    free (poolfs);
 
   return device;
 }
index 851da7a077ada84ed4180462c481b993b14004ea..0d71ef3d6d68a1bf91fa860a02913359a8dabea1 100644 (file)
@@ -19,6 +19,7 @@
 #include <config.h>
 
 #include <errno.h>
+#include <error.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 # include <libdevmapper.h>
 #endif
 
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+# include <grub/util/libzfs.h>
+# include <grub/util/libnvpair.h>
+#endif
+
+#ifdef HAVE_GETFSSTAT
+# include <sys/mount.h>
+#endif
+
 int verbosity;
 
 void
@@ -236,6 +246,114 @@ get_win32_path (const char *path)
 }
 #endif
 
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+/* Not ZFS-specific in itself, but for now it's only used by ZFS-related code.  */
+char *
+grub_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 ("/");
+       }
+    }
+}
+#endif
+
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+
+/* ZFS has similar problems to those of btrfs (see above).  */
+void
+grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs)
+{
+  char *slash;
+
+  *poolname = *poolfs = NULL;
+
+#ifdef HAVE_GETFSSTAT
+  {
+    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);
+  }
+#endif
+
+  if (! *poolname)
+    return;
+
+  slash = strchr (*poolname, '/');
+  if (slash)
+    {
+      *slash = '\0';
+      *poolfs = xstrdup (slash + 1);
+    }
+  else
+    *poolfs = xstrdup ("");
+}
+#endif
+
 /* This function never prints trailing slashes (so that its output
    can be appended a slash unconditionally).  */
 char *
@@ -243,16 +361,26 @@ grub_make_system_path_relative_to_its_root (const char *path)
 {
   struct stat st;
   char *p, *buf, *buf2, *buf3;
+  char *mnt_point, *poolname = NULL, *poolfs = NULL, *ret;
   uintptr_t offset = 0;
   dev_t num;
   size_t len;
 
   /* canonicalize.  */
   p = canonicalize_file_name (path);
-
   if (p == NULL)
     grub_util_error ("failed to get canonical path of %s", path);
 
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+  /* For ZFS sub-pool filesystems, could be extended to others (btrfs?).  */
+  mnt_point = grub_find_mount_point_from_dir (p);
+  if (mnt_point)
+    {
+      grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
+      free (mnt_point);
+    }
+#endif
+
   len = strlen (p) + 1;
   buf = xstrdup (p);
   free (p);
@@ -331,7 +459,15 @@ grub_make_system_path_relative_to_its_root (const char *path)
       len--;
     }
 
-  return buf3;
+  if (poolfs)
+    {
+      ret = xasprintf ("/%s@%s", poolfs, buf3);
+      free (buf3);
+    }
+  else
+    ret = buf3;
+
+  return ret;
 }
 
 #ifdef HAVE_DEVICE_MAPPER